Skip to content

Commit

Permalink
Display CVE summary in /security package sub-resource
Browse files Browse the repository at this point in the history
  • Loading branch information
tchoutri committed Nov 17, 2024
1 parent 551ffa9 commit f502cec
Show file tree
Hide file tree
Showing 63 changed files with 10,601 additions and 674 deletions.
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Contributor checklist

- [ ] My PR is related to \<insert ticket number>
- [ ] My PR is related to \<insert ticket number>
- [ ] I have read and understood the [CONTRIBUTING guide](/~https://github.com/flora-pm/flora-server/blob/development/CONTRIBUTING.md)
- [ ] I have inserted my change and a link to this PR in the [CHANGELOG](/~https://github.com/flora-pm/flora-server/blob/development/CHANGELOG.md)
- [ ] I have updated documentation in `./docs/docs` if a public feature has a behaviour change
22 changes: 12 additions & 10 deletions .github/workflows/backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,6 @@ jobs:
ghc-version: "${{ matrix.ghc }}"
cabal-version: "latest"

- uses: actions/setup-node@v4
with:
node-version: "18"
cache: "yarn"
cache-dependency-path: assets/yarn.lock

- name: Configure environment
run: |
./.github/workflows/setup.sh
Expand All @@ -77,20 +71,28 @@ jobs:
echo "${FLORA_DB_HOST}:${FLORA_DB_PORT}:${FLORA_DB_DATABASE}:${FLORA_DB_USER}:${FLORA_DB_PASSWORD}" > .pgpass
cat ~/.pgpass
cabal update
mkdir -p ~/.local/share
git clone /~https://github.com/haskell/security-advisories.git ~/.local/share/security-advisories
cd ~/.local/share/security-advisories
git checkout df64e86a39668c057031fe7e2c679b1003090e03
cd -
- name: "Create freeze file"
run: |
cabal freeze --enable-tests
- name: Cache
uses: actions/cache@v4.1.2
uses: actions/cache@v4
with:
path: ${{ steps.setup-haskell.outputs.cabal-store }}
key: ${{ runner.os }}-ghc-${{ matrix.ghc }}-cabal-${{ hashFiles('./.plan.json') }}
key: ${{ runner.os }}-ghc-${{ matrix.ghc }}-cabal-${{ hashFiles('./dist-newstyle/cache/plan.json') }}
restore-keys: ${{ runner.os }}-ghc-${{ matrix.ghc }}-

- name: Build
run: |
cabal install postgresql-migration
make soufflé
make assets-deps
make build-assets
make build
- name: Test
run: |
set -x
Expand Down
1 change: 0 additions & 1 deletion .plan.json

This file was deleted.

56 changes: 42 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ clean-assets: ## Remove JS artifacts
@cd assets/ && rm -R node_modules
@cd docs/ && rm -R node_modules

db-setup: db-create db-init db-migrate ## Setup the dev database

db-create: ## Create the database
@createdb -h $(FLORA_DB_HOST) -p $(FLORA_DB_PORT) -U $(FLORA_DB_USER) $(FLORA_DB_DATABASE)

db-drop: ## Drop the database
@dropdb -f --if-exists -h $(FLORA_DB_HOST) -p $(FLORA_DB_PORT) -U $(FLORA_DB_USER) $(FLORA_DB_DATABASE)

db-setup: db-create db-init db-migrate ## Setup the dev database

db-init: ## Create the database schema
@migrate init "$(FLORA_DB_CONNSTRING)"

Expand All @@ -56,10 +56,38 @@ db-provision: ## Create categories and repositories
@cabal run -- flora-cli provision-repository --name "horizon" --url https://packages.horizon-haskell.net \
--description "Packages of the Horizon project"

db-provision-test-packages: ## Load development data in the database
db-provision-advisories: ## Load HSEC advisories in the database
@cabal run -- flora-cli provision advisories

db-provision-packages: ## Load development data in the dev database
@cabal run -- flora-cli provision test-packages --repository "hackage"
@cabal run -- flora-cli provision test-packages --repository "cardano"

db-test-create: ## Create the test database
./scripts/run-with-test-config.sh db-create

db-test-setup: db-test-create db-test-init db-test-migrate ## Setup the dev database

db-test-drop: ## Drop the test database
./scripts/run-with-test-config.sh db-drop

db-test-init: ## Create the test database schema
./scripts/run-with-test-config.sh db-init

db-test-migrate: ## Apply test database migrations
./scripts/run-with-test-config.sh db-migrate

db-test-reset: db-test-drop db-test-setup db-test-provision ## Reset the test database

db-test-provision: ## Create categories and repositories
./scripts/run-with-test-config.sh db-provision

db-test-provision-advisories: ## Load HSEC advisories in the test database
./scripts/run-with-test-config.sh db-provision-advisories

db-test-provision-packages: ## Load development data in the database
./scripts/run-with-test-config.sh db-provision-packages

import-from-hackage: ## Imports every cabal file from the ./index-01 directory
@cabal run -- flora-cli import-packages ./01-index

Expand Down Expand Up @@ -125,9 +153,20 @@ tags: ## Generate ctags for the project with `ghc-tags`

design-system: ## Generate the HTML components used by the design system
@cabal run -- flora-cli gen-design-system

start-design-sysytem: ## Start storybook.js
@cd design; yarn storybook

migration: ## Generate timestamped database migration boilerplate files
@if test -z "$$name"; then \
echo "Usage: make migration name=some-name"; \
else \
migName="`date -u '+%Y%m%d%H%M%S'`_$$name"; \
fname="migrations/$$migName.sql"; \
touch "$$fname"; \
echo "Touched $$fname";\
fi

help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.* ?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

Expand All @@ -144,14 +183,3 @@ endif
.PHONY: all $(MAKECMDGOALS)

.DEFAULT_GOAL := help

.PHONY: migration
migration: ## Generate timestamped database migration boilerplate files
@if test -z "$$name"; then \
echo "Usage: make migration name=some-name"; \
else \
migName="`date -u '+%Y%m%d%H%M%S'`_$$name"; \
fname="migrations/$$migName.sql"; \
touch "$$fname"; \
echo "Touched $$fname";\
fi
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
* 🌓 Dark and light modes
* 📱 Mobile user interface

## 📖 Guides
## 📖 Guides

Visit https://flora.pm/documentation for explanations on what Flora can do.

Expand All @@ -66,4 +66,4 @@ To setup a local installation, see [CONTRIBUTING.md#project-setup](https://githu

## 🫶 Special Collaborations

We would like to thank our dear friends at Guérilla Studio ([www](https://guerilla.studio/), [GitHub](/~https://github.com/GuerillaStudio)) for help with accessibility and CSS integration.
We would like to thank our dear friends at Guérilla.Studio ([www](https://guerilla.studio/), [GitHub](/~https://github.com/GuerillaStudio)) for help with accessibility and CSS integration.
23 changes: 17 additions & 6 deletions app/cli/DesignSystem.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Data.ByteString.Lazy (ByteString)
import Data.ByteString.Lazy qualified as ByteString
import Data.Foldable (forM_)
import Data.Functor.Identity (runIdentity)
import Data.Maybe (fromJust)
import Data.Text (Text)
import Data.Text.Lazy qualified as TL
import Data.Time.Calendar.OrdinalDate as Time
Expand All @@ -20,13 +21,16 @@ import Effectful.Fail
import Env
import Lucid
import PyF (fmt)
import Security.Advisories.Core.HsecId qualified as HsecId

import Advisories.Model.Affected.Types
import Distribution.SPDX
import Flora.Environment.Config
import Flora.Model.Category
import Flora.Model.Category qualified as Category
import Flora.Model.Package
import Flora.Search
import FloraWeb.Components.AdvisoryListItem qualified as Component
import FloraWeb.Components.Alert qualified as Component
import FloraWeb.Components.CategoryCard qualified as Component
import FloraWeb.Components.PackageListItem qualified as Component
Expand Down Expand Up @@ -73,6 +77,7 @@ components =
, ("category-card", ComponentTitle "Category", ComponentName "CategoryCard", categoryCardExample)
, ("pagination-area", ComponentTitle "Pagination Area", ComponentName "Pagination", paginationExample)
, ("alerts", ComponentTitle "Alerts", ComponentName "Alert", alertsExample)
, ("advisory-preview", ComponentTitle "Advisories", ComponentName "AdvisoryPreviews", packageAdvisoriesExample)
]

-----------------------
Expand Down Expand Up @@ -133,9 +138,15 @@ paginationExample = div_ $ do
Component.paginationNav 32 1 (SearchPackages "text")

alertsExample :: FloraHTML
alertsExample = div_ $ do
div_ $ do
h4_ "Info alert"
Component.info "Info alert"
h4_ "Error alert"
Component.exception "Error alert!"
alertsExample = div_ $ div_ $ do
h4_ "Info alert"
Component.info "Info alert"
h4_ "Error alert"
Component.exception "Error alert!"

packageAdvisoriesExample :: FloraHTML
packageAdvisoriesExample = do
let advisoryPreviews =
Vector.fromList
[]
ul_ [class_ "advisory-list"] $ Vector.forM_ advisoryPreviews (\preview -> Component.advisoryListItem preview)
74 changes: 54 additions & 20 deletions app/cli/Main.hs
Original file line number Diff line number Diff line change
@@ -1,33 +1,41 @@
module Main where

import Codec.Compression.GZip qualified as GZip
import Control.Monad.Extra (unlessM)
import Data.ByteString.Lazy.Char8 qualified as BS
import Data.List.NonEmpty (NonEmpty)
import Data.Maybe
import Data.Poolboy (poolboySettingsWith)
import Data.Set (Set)
import Data.Text (Text)
import Data.Text qualified as Text
import Data.Text.Display (display)
import DesignSystem (generateComponents)
import Distribution.Version (Version)
import Effectful
import Effectful.Error.Static (Error, runErrorNoCallStack)
import Effectful.Fail
import Effectful.FileSystem
import Effectful.Log (Log, runLog)
import Effectful.Poolboy
import Effectful.PostgreSQL.Transact.Effect
import Effectful.State.Static.Shared (State)
import Effectful.State.Static.Shared qualified as State
import Effectful.Time (Time, runTime)
import Effectful.Trace (Trace)
import Effectful.Trace qualified as Trace
import GHC.Conc
import GHC.Generics (Generic)
import Log qualified
import Log.Backend.StandardOutput qualified as Log
import Monitor.Tracing.Zipkin (Zipkin (..))
import Optics.Core
import Options.Applicative
import Sel.Hashing.Password qualified as Sel
import System.FilePath ((</>))

import Data.Set (Set)
import Effectful.Poolboy
import Effectful.State.Static.Shared (State)
import Effectful.State.Static.Shared qualified as State
import Advisories.Import (importAdvisories)
import Advisories.Import.Error (AdvisoryImportError)
import Flora.Environment
import Flora.Import.Categories (importCategories)
import Flora.Import.Package.Bulk (importAllFilesInRelativeDirectory, importFromIndex)
Expand All @@ -40,6 +48,8 @@ import Flora.Model.PackageIndex.Update qualified as Update
import Flora.Model.User
import Flora.Model.User.Query qualified as Query
import Flora.Model.User.Update
import Flora.Tracing qualified as Tracing
import System.Exit (exitFailure)

data Options = Options
{ cliCommand :: Command
Expand All @@ -59,6 +69,7 @@ data Command
data ProvisionTarget
= Categories
| TestPackages Text
| Advisories
deriving stock (Show, Eq)

data UserCreationOptions = UserCreationOptions
Expand All @@ -72,23 +83,36 @@ data UserCreationOptions = UserCreationOptions

main :: IO ()
main = Log.withStdOutLogger $ \logger -> do
result <- execParser (parseOptions `withInfo` "CLI tool for flora-server")
cliArgs <- execParser (parseOptions `withInfo` "CLI tool for flora-server")
capabilities <- getNumCapabilities
env <- getFloraEnv & runFailIO & runEff
runEff
. State.evalState (mempty @(Set (Namespace, PackageName, Version)))
. withUnliftStrategy (ConcUnlift Ephemeral Unlimited)
. runDB env.pool
. runFailIO
. runTime
. runPoolboy (poolboySettingsWith capabilities)
. ( case env.features.blobStoreImpl of
Just (BlobStoreFS fp) -> runBlobStoreFS fp
_ -> runBlobStorePure
)
. runFileSystem
. runLog "flora-cli" logger Log.LogTrace
$ runOptions result
runTrace <-
if env.environment == Production
then do
zipkin <- liftIO $ Tracing.newZipkin env.mltp.zipkinHost "flora-cli"
pure $ Trace.runTrace zipkin.zipkinTracer
else pure Trace.runNoTrace
result <-
runEff
. runTrace
. runErrorNoCallStack
. State.evalState (mempty @(Set (Namespace, PackageName, Version)))
. withUnliftStrategy (ConcUnlift Ephemeral Unlimited)
. runDB env.pool
. runFailIO
. runTime
. runPoolboy (poolboySettingsWith capabilities)
. ( case env.features.blobStoreImpl of
Just (BlobStoreFS fp) -> runBlobStoreFS fp
_ -> runBlobStorePure
)
. runFileSystem
. runLog "flora-cli" logger Log.LogTrace
$ runOptions cliArgs
case result of
Right _ -> pure ()
Left errors ->
error $ show errors

parseOptions :: Parser Options
parseOptions =
Expand All @@ -114,6 +138,7 @@ parseProvision =
subparser $
command "categories" (pure (Provision Categories) `withInfo` "Load the canonical categories in the system")
<> command "test-packages" (parseProvisionTestPackages `withInfo` "Load the test packages in the database")
<> command "advisories" (pure (Provision Advisories) `withInfo` "Load the security advisories database")

parseProvisionTestPackages :: Parser Command
parseProvisionTestPackages =
Expand Down Expand Up @@ -169,10 +194,19 @@ runOptions
, BlobStoreAPI :> es
, State (Set (Namespace, PackageName, Version)) :> es
, Poolboy :> es
, Error (NonEmpty AdvisoryImportError) :> es
, Trace :> es
)
=> Options
-> Eff es ()
runOptions (Options (Provision Categories)) = importCategories
runOptions (Options (Provision Advisories)) = do
dataDir <- getXdgDirectory XdgData ""
let advisoriesDirectory = dataDir </> "security-advisories"
unlessM (doesDirectoryExist advisoriesDirectory) $ do
Log.logAttention_ $ Text.pack $ "Could not find " <> advisoriesDirectory <> ". Clone /~https://github.com/haskell/security-advisories.git at this location."
liftIO exitFailure
importAdvisories advisoriesDirectory
runOptions (Options (Provision (TestPackages repository))) = importFolderOfCabalFiles "./test/fixtures/Cabal/" repository
runOptions (Options (CreateUser opts)) = do
let username = opts ^. #username
Expand All @@ -189,7 +223,7 @@ runOptions (Options (CreateUser opts)) = do
>>= \admin ->
if canLogin
then pure ()
else lockAccount (admin ^. #userId)
else lockAccount admin.userId
else do
templateUser <- mkUser UserCreationForm{..}
let user = if canLogin then templateUser else templateUser & #userFlags % #canLogin .~ False
Expand Down
1 change: 1 addition & 0 deletions assets/.stylelintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"hue-degree-notation": "number",
"media-feature-range-notation": "prefix",
"import-notation": "string",
"selector-class-pattern": null,
"at-rule-no-unknown": [
true,
{
Expand Down
Loading

0 comments on commit f502cec

Please sign in to comment.