Skip to content

Commit 6ce7c5d

Browse files
authored
Merge pull request haskell#1469 from TuongNM/check-candidate-upload
Check candidate uploads against main index
2 parents 54b7847 + 4e2b45b commit 6ce7c5d

File tree

2 files changed

+34
-9
lines changed

2 files changed

+34
-9
lines changed

src/Distribution/Server/Features/PackageCandidates.hs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -406,10 +406,13 @@ candidatesFeature ServerEnv{serverBlobStore = store}
406406
candWarnings = uploadWarnings uresult,
407407
candPublic = True -- do withDataFn
408408
}
409-
void $ updateState candidatesState $ AddCandidate candidate
410-
let group = maintainersGroup (packageName pkgid)
411-
liftIO $ Group.addUserToGroup group uid
412-
return candidate
409+
checkCandidate "Upload failed" uid regularIndex candidate >>= \case
410+
Just failed -> throwError failed
411+
Nothing -> do
412+
void $ updateState candidatesState $ AddCandidate candidate
413+
let group = maintainersGroup (packageName pkgid)
414+
liftIO $ Group.addUserToGroup group uid
415+
return candidate
413416

414417
-- | Helper function for uploadCandidate.
415418
processCandidate :: (PackageId -> Bool) -> PackageIndex PkgInfo -> Users.UserId -> UploadResult -> IO (Maybe ErrorResponse)
@@ -473,12 +476,16 @@ candidatesFeature ServerEnv{serverBlobStore = store}
473476

474477

475478
-- | Helper function for publishCandidate that ensures it's safe to insert into the main index.
479+
checkPublish :: forall m. MonadIO m => Users.UserId -> PackageIndex PkgInfo -> CandPkgInfo -> m (Maybe ErrorResponse)
480+
checkPublish = checkCandidate "Publish failed"
481+
482+
-- | Helper function that ensures it would be safe to insert a package candidate into the main index.
476483
--
477484
-- TODO: share code w/ 'Distribution.Server.Features.Upload.processUpload'
478-
checkPublish :: forall m. MonadIO m => Users.UserId -> PackageIndex PkgInfo -> CandPkgInfo -> m (Maybe ErrorResponse)
479-
checkPublish uid packages candidate
485+
checkCandidate :: forall m. MonadIO m => String -> Users.UserId -> PackageIndex PkgInfo -> CandPkgInfo -> m (Maybe ErrorResponse)
486+
checkCandidate errorTitle uid packages candidate
480487
| Just _ <- find ((== candVersion) . packageVersion) pkgs
481-
= return $ Just $ ErrorResponse 403 [] "Publish failed" [MText "Package name and version already exist in the database"]
488+
= return $ Just $ ErrorResponse 403 [] errorTitle [MText "Package name and version already exist in the database"]
482489

483490
| packageExists packages candidate = return Nothing
484491

@@ -487,7 +494,7 @@ candidatesFeature ServerEnv{serverBlobStore = store}
487494
PackageIndex.Unambiguous (mp:_) -> do
488495
group <- liftIO $ (Group.queryUserGroup . maintainersGroup . packageName) mp
489496
if not $ uid `Group.member` group
490-
then return $ Just $ ErrorResponse 403 [] "Publish failed" (caseClash [mp])
497+
then return $ Just $ ErrorResponse 403 [] errorTitle (caseClash [mp])
491498
else return Nothing
492499

493500
PackageIndex.Unambiguous [] -> return Nothing -- can this ever occur?
@@ -496,7 +503,7 @@ candidatesFeature ServerEnv{serverBlobStore = store}
496503
let matchingPackages = concatMap (take 1) mps
497504
groups <- mapM (liftIO . Group.queryUserGroup . maintainersGroup . packageName) matchingPackages
498505
if not . any (uid `Group.member`) $ groups
499-
then return $ Just $ ErrorResponse 403 [] "Publish failed" (caseClash matchingPackages)
506+
then return $ Just $ ErrorResponse 403 [] errorTitle (caseClash matchingPackages)
500507
else return Nothing
501508

502509
-- no case-neighbors

tests/HighLevelTest.hs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,27 @@ runPackageUploadTests = do
185185
xs <- getUrl NoAuth "/package/testpackage-1.0.0.0/upload-time"
186186
unless (xs == uploadTimeISO2) $
187187
die ("Bad upload time: " ++ show xs)
188+
do info "Trying to upload existing testpackage as candidate"
189+
postFile isForbidden
190+
(Auth "HackageTestUser1" "testpass1")
191+
"/packages/candidates/" "package"
192+
(testpackageTarFilename, testpackageTarFileContent)
193+
do info "Trying to upload testPackage case-variant as candidate"
194+
-- Upload as another user as maintainers of an existing package are
195+
-- allowed to upload case-variants of it.
196+
createUserDirect (Auth "admin" "admin") "HackageTestUser2" "testpass2"
197+
post (Auth "admin" "admin") "/packages/uploaders/" [
198+
("user", "HackageTestUser2")
199+
]
200+
postFile isForbidden
201+
(Auth "HackageTestUser2" "testpass2")
202+
"/packages/candidates/" "package"
203+
(testpackageTarFilenameVariant, testpackageTarFileContentVariant)
188204
where
189205
(testpackageTarFilename, testpackageTarFileContent, _, _, _, _) =
190206
testpackage
207+
(testpackageTarFilenameVariant, testpackageTarFileContentVariant, _, _, _, _) =
208+
mkPackage "testPackage"
191209
uploadTime = "Tue Oct 18 20:54:28 UTC 2010"
192210
uploadTimeISO = "2010-10-18T20:54:28Z"
193211
uploadTimeISO2 = "2020-10-18T20:54:28Z"

0 commit comments

Comments
 (0)