This commit is contained in:
Lucy Cifferello
2024-04-16 14:43:35 -04:00
parent 0a41ab2b12
commit a75d9468c0
2 changed files with 61 additions and 78 deletions

View File

@@ -58,7 +58,7 @@ import Handler.Util (
getHashFromQuery, getHashFromQuery,
getVersionFromQuery, getVersionFromQuery,
orThrow, orThrow,
sendResponseText, checkAdminAllowedPkgs, sendResponseText, checkAdminAllowedPkgs, checkAdminAuth,
) )
import Lib.PkgRepository ( import Lib.PkgRepository (
PkgRepo (PkgRepo, pkgRepoFileRoot), PkgRepo (PkgRepo, pkgRepoFileRoot),
@@ -197,18 +197,12 @@ postPkgUploadR = do
removePathForcibly targetPath removePathForcibly targetPath
createDirectoryIfMissing True targetPath createDirectoryIfMissing True targetPath
renameDirectory dir targetPath renameDirectory dir targetPath
maybeAuthId >>= \case (authorized, name) <- checkAdminAuth packageManifestId
Nothing -> do if authorized
$logError then do
"Impossible: an unauthenticated user has managed to upload a pacakge to this registry." now <- liftIO getCurrentTime
pure () runDB $ insert_ (Upload (AdminKey name) (PkgRecordKey packageManifestId)packageManifestVersion now)
Just name -> do else sendResponseText status401 "User not authorized to upload this package."
(authorized, _) <- checkAdminAllowedPkgs packageManifestId name
if authorized
then do
now <- liftIO getCurrentTime
runDB $ insert_ (Upload (AdminKey name) (PkgRecordKey packageManifestId)packageManifestVersion now)
else sendResponseText status401 "User not authorized to upload this package."
else sendResponseText status500 "Package does not belong on this registry." else sendResponseText status500 "Package does not belong on this registry."
where where
retry m = runMaybeT . asum $ replicate 3 (MaybeT $ hush <$> try @_ @SomeException m) retry m = runMaybeT . asum $ replicate 3 (MaybeT $ hush <$> try @_ @SomeException m)
@@ -256,44 +250,32 @@ instance ToJSON IndexPkgReq where
postPkgIndexR :: Handler () postPkgIndexR :: Handler ()
postPkgIndexR = do postPkgIndexR = do
IndexPkgReq{..} <- requireCheckJsonBody IndexPkgReq{..} <- requireCheckJsonBody
maybeAuthId >>= \case (admin, _) <- checkAdminAuth indexPkgReqId
Nothing -> do if admin
$logError then do
"Impossible: an unauthenticated user has accessed the index endpoint." manifest <- getManifestLocation indexPkgReqId indexPkgReqVersion
pure () man <-
Just name -> do liftIO (decodeFileStrict manifest)
(authorized, _) <- checkAdminAllowedPkgs indexPkgReqId name `orThrow` sendResponseText
if authorized status404
then do [i|Could not decode manifest for #{indexPkgReqId}@#{indexPkgReqVersion}|]
manifest <- getManifestLocation indexPkgReqId indexPkgReqVersion pool <- getsYesod appConnPool
man <- runSqlPoolNoTransaction (upsertPackageVersion man) pool Nothing
liftIO (decodeFileStrict manifest) runSqlPool (upsertPackageVersionPlatform indexPkgReqArches man) pool
`orThrow` sendResponseText else sendResponseText status401 "User not authorized to index this package."
status404
[i|Could not decode manifest for #{indexPkgReqId}@#{indexPkgReqVersion}|]
pool <- getsYesod appConnPool
runSqlPoolNoTransaction (upsertPackageVersion man) pool Nothing
runSqlPool (upsertPackageVersionPlatform indexPkgReqArches man) pool
else sendResponseText status401 "User not authorized to index this package."
postPkgDeindexR :: Handler () postPkgDeindexR :: Handler ()
postPkgDeindexR = do postPkgDeindexR = do
IndexPkgReq{..} <- requireCheckJsonBody IndexPkgReq{..} <- requireCheckJsonBody
maybeAuthId >>= \case (admin, _) <- checkAdminAuth indexPkgReqId
Nothing -> do if admin
$logError then do
"Impossible: an unauthenticated user has accessed the deindex endpoint." case indexPkgReqArches of
pure () Nothing -> runDB $ delete (VersionRecordKey (PkgRecordKey indexPkgReqId) indexPkgReqVersion)
Just name -> do Just a -> do
(authorized, _) <- checkAdminAllowedPkgs indexPkgReqId name _ <- traverse (deleteArch indexPkgReqId indexPkgReqVersion) a
if authorized pure ()
then do else sendResponseText status401 "User not authorized to deindex this package."
case indexPkgReqArches of
Nothing -> runDB $ delete (VersionRecordKey (PkgRecordKey indexPkgReqId) indexPkgReqVersion)
Just a -> do
_ <- traverse (deleteArch indexPkgReqId indexPkgReqVersion) a
pure ()
else sendResponseText status401 "User not authorized to deindex this package."
where where
deleteArch :: PkgId -> Version -> OsArch -> Handler () deleteArch :: PkgId -> Version -> OsArch -> Handler ()
deleteArch id v a = runDB $ deleteWhere [VersionPlatformArch ==. a, VersionPlatformVersionNumber ==. v, VersionPlatformPkgId ==. PkgRecordKey id] deleteArch id v a = runDB $ deleteWhere [VersionPlatformArch ==. a, VersionPlatformVersionNumber ==. v, VersionPlatformPkgId ==. PkgRecordKey id]
@@ -345,37 +327,25 @@ deleteCategoryR cat = runDB $ deleteBy (UniqueName cat)
postPkgCategorizeR :: Text -> PkgId -> Handler () postPkgCategorizeR :: Text -> PkgId -> Handler ()
postPkgCategorizeR cat pkg = do postPkgCategorizeR cat pkg = do
maybeAuthId >>= \case (admin, _) <- checkAdminAuth pkg
Nothing -> do if admin
$logError then runDB $ do
"Impossible: an unauthenticated user has accessed the categorize endpoint." catEnt <- getBy (UniqueName cat) `orThrow` sendResponseText status404 [i|Category "#{cat}" does not exist|]
pure () _pkgEnt <- get (PkgRecordKey pkg) `orThrow` sendResponseText status404 [i|Package "#{pkg}" does not exist|]
Just name -> do now <- liftIO getCurrentTime
(authorized, _) <- checkAdminAllowedPkgs pkg name void $
if authorized insertUnique (PkgCategory now (PkgRecordKey pkg) (entityKey catEnt))
then runDB $ do `orThrow` sendResponseText
catEnt <- getBy (UniqueName cat) `orThrow` sendResponseText status404 [i|Category "#{cat}" does not exist|] status403
_pkgEnt <- get (PkgRecordKey pkg) `orThrow` sendResponseText status404 [i|Package "#{pkg}" does not exist|] [i|Package "#{pkg}" is already assigned to category "#{cat}"|]
now <- liftIO getCurrentTime
void $
insertUnique (PkgCategory now (PkgRecordKey pkg) (entityKey catEnt))
`orThrow` sendResponseText
status403
[i|Package "#{pkg}" is already assigned to category "#{cat}"|]
else sendResponseText status401 "User not authorized to categorize this package." else sendResponseText status401 "User not authorized to categorize this package."
deletePkgCategorizeR :: Text -> PkgId -> Handler () deletePkgCategorizeR :: Text -> PkgId -> Handler ()
deletePkgCategorizeR cat pkg = do deletePkgCategorizeR cat pkg = do
maybeAuthId >>= \case (admin, _) <- checkAdminAuth pkg
Nothing -> do if admin
$logError then runDB $ do
"Impossible: an unauthenticated user has accessed the uncategorize endpoint." catEnt <- getBy (UniqueName cat) `orThrow` sendResponseText status404 [i|Category "#{cat}" does not exist|]
pure () deleteBy (UniquePkgCategory (PkgRecordKey pkg) (entityKey catEnt))
Just name -> do else sendResponseText status401 "User not authorized to uncategorize this package."
(authorized, _) <- checkAdminAllowedPkgs pkg name
if authorized
then runDB $ do
catEnt <- getBy (UniqueName cat) `orThrow` sendResponseText status404 [i|Category "#{cat}" does not exist|]
deleteBy (UniquePkgCategory (PkgRecordKey pkg) (entityKey catEnt))
else sendResponseText status401 "User not authorized to uncategorize this package."

View File

@@ -90,6 +90,8 @@ import Data.Bifunctor (Bifunctor(first))
import qualified Data.MultiMap as MM import qualified Data.MultiMap as MM
import Startlude (bimap) import Startlude (bimap)
import Data.List (length) import Data.List (length)
import Control.Monad.Logger (logError)
import Yesod.Auth (YesodAuth(maybeAuthId))
orThrow :: MonadHandler m => m (Maybe a) -> m a -> m a orThrow :: MonadHandler m => m (Maybe a) -> m a -> m a
orThrow action other = orThrow action other =
@@ -264,4 +266,15 @@ checkAdminAllowedPkgs pkgId adminId = do
then do then do
res <- runDB $ getAllowedPkgs pkgId (AdminKey adminId) res <- runDB $ getAllowedPkgs pkgId (AdminKey adminId)
pure $ if length res > 0 then (True, False) else (False, False) pure $ if length res > 0 then (True, False) else (False, False)
else pure (True, True) else pure (True, True)
checkAdminAuth :: PkgId -> Handler (Bool, Text)
checkAdminAuth pkgId = do
maybeAuthId >>= \case
Nothing -> do
$logError
"Impossible: an unauthenticated user has accessed an authenticated endpoint."
pure (False, "")
Just name -> do
(authorized, _) <- checkAdminAllowedPkgs pkgId name
pure (authorized, name)