add config setting to allow protections around package uploads to specific registries

This commit is contained in:
Lucy Cifferello
2023-04-11 20:22:14 -06:00
parent e4756f481d
commit d599a90e8b
4 changed files with 27 additions and 18 deletions

View File

@@ -39,6 +39,7 @@ marketplace-name: "_env:MARKETPLACE_NAME:CHANGE ME"
max-eos-version: "_env:MAX_VERSION:0.3.4.0"
min-eos-version: "_env:MIN_VERSION:0.3.4.0"
run-migration: "_env:RUN_MIGRATION:false"
blacklist: "_env:BLACKLIST:ADD ME"
database:
database: "_env:PG_DATABASE:start9_registry"

View File

@@ -144,11 +144,13 @@ import Yesod (
import Yesod.Auth (YesodAuth (maybeAuthId))
import Yesod.Core.Types (JSONResponse (JSONResponse))
import Database.Persist.Sql (runSqlPool)
import Data.List (elem)
postPkgUploadR :: Handler ()
postPkgUploadR = do
resourcesTemp <- getsYesod $ (</> "temp") . resourcesDir . appSettings
blacklist <- getsYesod $ blacklist . appSettings
createDirectoryIfMissing True resourcesTemp
withTempDirectory resourcesTemp "newpkg" $ \dir -> do
let path = dir </> "temp" <.> "s9pk"
@@ -159,22 +161,25 @@ postPkgUploadR = do
when (isNothing res) $ do
$logError "Failed to extract package"
sendResponseText status500 "Failed to extract package"
PackageManifest{..} <-
PackageManifest{..} <- do
liftIO (decodeFileStrict (dir </> "manifest.json"))
`orThrow` sendResponseText status500 "Failed to parse manifest.json"
renameFile path (dir </> (toS . unPkgId) packageManifestId <.> "s9pk")
let targetPath = pkgRepoFileRoot </> show packageManifestId </> show packageManifestVersion
removePathForcibly targetPath
createDirectoryIfMissing True targetPath
renameDirectory dir targetPath
maybeAuthId >>= \case
Nothing -> do
$logError
"The Impossible has happened, an unauthenticated user has managed to upload a pacakge to this registry"
pure ()
Just name -> do
now <- liftIO getCurrentTime
runDB $ insert_ (Upload (AdminKey name) (PkgRecordKey packageManifestId) packageManifestVersion now)
if (elem packageManifestId blacklist)
then sendResponseText status500 "Package does not belong on this registry."
else do
renameFile path (dir </> (toS . unPkgId) packageManifestId <.> "s9pk")
let targetPath = pkgRepoFileRoot </> show packageManifestId </> show packageManifestVersion
removePathForcibly targetPath
createDirectoryIfMissing True targetPath
renameDirectory dir targetPath
maybeAuthId >>= \case
Nothing -> do
$logError
"The Impossible has happened, an unauthenticated user has managed to upload a pacakge to this registry"
pure ()
Just name -> do
now <- liftIO getCurrentTime
runDB $ insert_ (Upload (AdminKey name) (PkgRecordKey packageManifestId) packageManifestVersion now)
where
retry m = runMaybeT . asum $ replicate 3 (MaybeT $ hush <$> try @_ @SomeException m)

View File

@@ -23,7 +23,7 @@ import Database.Queries (
getDependencyVersions,
getPkgDataSource,
getPkgDependencyData,
serviceQuerySource, fetchLatestApp,
serviceQuerySource,
)
import Foundation (Handler, Route (InstructionsR, LicenseR), RegistryCtx (appSettings))
import Handler.Package.Api (DependencyRes (..), PackageListRes (..), PackageRes (..))

View File

@@ -56,6 +56,7 @@ import Lib.PkgRepository ( EosRepo(EosRepo, eosRepoFileRo
)
import Lib.Types.Emver ( Version )
import Orphans.Emver ( )
import Lib.Types.Core (PkgId)
-- | Runtime settings to configure this application. These settings can be
-- loaded from various sources: defaults, environment variables, config files,
-- theoretically even a database.
@@ -75,12 +76,12 @@ data AppSettings = AppSettings
-- ^ Should all log messages be displayed?
, errorLogRoot :: !FilePath
, marketplaceName :: !Text
, maxOsVersion :: !Version
, minOsVersion :: !Version
, maxOsVersion :: !Version
, minOsVersion :: !Version
, registryHostname :: !Text
, registryVersion :: !Version
, resourcesDir :: !FilePath
, needsMigration :: !Bool
, needsMigration :: !Bool
, sslAuto :: !Bool
, sslCertLocation :: !FilePath
, sslCsrLocation :: !FilePath
@@ -88,6 +89,7 @@ data AppSettings = AppSettings
, sslPath :: !FilePath
, staticBinDir :: !FilePath
, torPort :: !AppPort
, blacklist :: ![PkgId]
}
instance Has PkgRepo AppSettings where
extract = liftA2 PkgRepo ((</> "apps") . resourcesDir) staticBinDir
@@ -120,6 +122,7 @@ instance FromJSON AppSettings where
sslPath <- o .: "ssl-path"
staticBinDir <- o .: "static-bin-dir"
torPort <- o .: "tor-port"
blacklist <- o .: "blacklist"
let sslKeyLocation = sslPath </> "key.pem"
let sslCsrLocation = sslPath </> "certificate.csr"