Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/5-internal/sqservices-1118-2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Tag integration tests for certification.
2 changes: 2 additions & 0 deletions libs/zauth/test/ZAuth.hs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ testExpired p = do
x <- liftIO $ runValidate p $ check t
liftIO $ Left Expired @=? x

-- @END

testSignAndVerify :: V.Env -> Create ()
testSignAndVerify p = do
u <- liftIO nextRandom
Expand Down
10 changes: 10 additions & 0 deletions services/brig/test/integration/API/User/Account.hs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ testCreateUserWithInvalidVerificationCode brig = do
]
postUserRegister' regEmail brig !!! const 404 === statusCode

-- @END

testUpdateUserEmailByTeamOwner :: Brig -> Http ()
testUpdateUserEmailByTeamOwner brig = do
(_, teamOwner, emailOwner : otherTeamMember : _) <- createPopulatedBindingTeamWithNamesAndHandles brig 2
Expand Down Expand Up @@ -305,6 +307,8 @@ testCreateUserEmptyName brig = do
post (brig . path "/register" . contentJson . body p)
!!! const 400 === statusCode

-- @END

-- The testCreateUserLongName test conforms to the following testing standards:
-- @SF.Provisioning @TSFI.RESTfulAPI @S2
--
Expand All @@ -319,6 +323,8 @@ testCreateUserLongName brig = do
post (brig . path "/register" . contentJson . body p)
!!! const 400 === statusCode

-- @END

testCreateUserAnon :: Brig -> Galley -> Http ()
testCreateUserAnon brig galley = do
let p =
Expand Down Expand Up @@ -437,6 +443,8 @@ testCreateUserConflict _ brig = do
const 409 === statusCode
const (Just "key-exists") === fmap Error.label . responseJsonMaybe

-- @END

-- The testCreateUserInvalidEmailOrPhone test conforms to the following testing standards:
-- @SF.Provisioning @TSFI.RESTfulAPI @S2
--
Expand Down Expand Up @@ -468,6 +476,8 @@ testCreateUserInvalidEmailOrPhone _ brig = do
post (brig . path "/register" . contentJson . body reqPhone)
!!! const 400 === statusCode

-- @END

testCreateUserBlacklist :: Opt.Opts -> Brig -> AWS.Env -> Http ()
testCreateUserBlacklist (Opt.setRestrictUserCreation . Opt.optSettings -> Just True) _ _ = pure ()
testCreateUserBlacklist _ brig aws =
Expand Down
8 changes: 8 additions & 0 deletions services/brig/test/integration/API/User/Auth.hs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,8 @@ testLoginFailure brig = do
login brig (PasswordLogin (LoginByEmail badmail) defPassword Nothing) PersistentCookie
!!! const 403 === statusCode

-- @END

testThrottleLogins :: Opts.Opts -> Brig -> Http ()
testThrottleLogins conf b = do
-- Get the maximum amount of times we are allowed to login before
Expand Down Expand Up @@ -455,6 +457,8 @@ testLimitRetries conf brig = do
liftIO $ threadDelay (1000000 * 2)
login brig (defEmailLogin email) SessionCookie !!! const 200 === statusCode

-- @END

-------------------------------------------------------------------------------
-- LegalHold Login

Expand Down Expand Up @@ -599,6 +603,8 @@ testInvalidCookie z b = do
const 403 === statusCode
const (Just "expired") =~= responseBody

-- @END

testInvalidToken :: Brig -> Http ()
testInvalidToken b = do
-- Syntactically invalid
Expand Down Expand Up @@ -967,6 +973,8 @@ testTooManyCookies config b = do
)
xxx -> error ("Unexpected status code when logging in: " ++ show xxx)

-- @END

testLogout :: Brig -> Http ()
testLogout b = do
Just email <- userEmail <$> randomUser b
Expand Down
10 changes: 10 additions & 0 deletions services/brig/test/integration/API/User/Client.hs
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,8 @@ testTooManyClients opts brig = do
const (Just "too-many-clients") === fmap Error.label . responseJsonMaybe
const (Just "application/json;charset=utf-8") === getHeader "Content-Type"

-- @END

-- The testRemoveClient test conforms to the following testing standards:
-- @SF.Provisioning @TSFI.RESTfulAPI @S2
--
Expand Down Expand Up @@ -489,6 +491,8 @@ testRemoveClient hasPwd brig cannon = do
newClientCookie = Just defCookieLabel
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot mark the correct line in this file but there is a @END tag missing around line 446

Copy link
Contributor

@mythsunwind mythsunwind Dec 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fisx I see also that in this file there is a space missing between @SF.Channel and @TSFI.RESTfulAPI in the lines before:

  • "rejects saml responses with invalid issuer entity id"
  • "rejects saml responses signed with the wrong private key"
  • "rejects saml responses to requests not in cassandra:spar.authreq"
  • "rejects saml responses already seen (and recorded in cassandra:spar.authresp)"

Additionally please change @SF.CHANNEL into @SF.Channel

}

-- @END

-- The testRemoveClientShortPwd test conforms to the following testing standards:
-- @SF.Provisioning @TSFI.RESTfulAPI @S2
--
Expand Down Expand Up @@ -521,6 +525,8 @@ testRemoveClientShortPwd brig = do
newClientCookie = Just defCookieLabel
}

-- @END

-- The testRemoveClientIncorrectPwd test conforms to the following testing standards:
-- @SF.Provisioning @TSFI.RESTfulAPI @S2
--
Expand Down Expand Up @@ -553,6 +559,8 @@ testRemoveClientIncorrectPwd brig = do
newClientCookie = Just defCookieLabel
}

-- @END

testUpdateClient :: Opt.Opts -> Brig -> Http ()
testUpdateClient opts brig = do
uid <- userId <$> randomUser brig
Expand Down Expand Up @@ -760,6 +768,8 @@ testAddMultipleTemporary brig galley = do
. zUser u
return $ Vec.length <$> (preview _Array =<< responseJsonMaybe @Value r)

-- @END

testPreKeyRace :: Brig -> Http ()
testPreKeyRace brig = do
uid <- userId <$> randomUser brig
Expand Down
2 changes: 2 additions & 0 deletions services/brig/test/integration/API/User/Handles.hs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ testHandleUpdate brig cannon = do
put (brig . path "/self/handle" . contentJson . zUser uid2 . zConn "c" . body update)
!!! const 200 === statusCode

-- @END

testHandleRace :: Brig -> Http ()
testHandleRace brig = do
us <- replicateM 10 (userId <$> randomUser brig)
Expand Down
16 changes: 16 additions & 0 deletions services/galley/test/integration/API.hs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,8 @@ postCryptoMessageVerifyMsgSentAndRejectIfMissingClient = do
liftIO $ assertBool "unexpected equal clients" (bc /= bc2)
assertNoMsg wsB2 (wsAssertOtr qconv qalice ac bc cipher)

-- @END

-- @SF.Separation @TSFI.RESTfulAPI @S2
-- This test verifies basic mismatch behavior of the the JSON endpoint.
postCryptoMessageVerifyRejectMissingClientAndRepondMissingPrekeysJson :: TestM ()
Expand All @@ -478,6 +480,8 @@ postCryptoMessageVerifyRejectMissingClientAndRepondMissingPrekeysJson = do
Map.keys (userClientMap (getUserClientPrekeyMap p)) @=? [eve]
Map.keys <$> Map.lookup eve (userClientMap (getUserClientPrekeyMap p)) @=? Just [ec]

-- @END

-- @SF.Separation @TSFI.RESTfulAPI @S2
-- This test verifies basic mismatch behaviour of the protobuf endpoint.
postCryptoMessageVerifyRejectMissingClientAndRepondMissingPrekeysProto :: TestM ()
Expand Down Expand Up @@ -506,6 +510,8 @@ postCryptoMessageVerifyRejectMissingClientAndRepondMissingPrekeysProto = do
Map.keys (userClientMap (getUserClientPrekeyMap p)) @=? [eve]
Map.keys <$> Map.lookup eve (userClientMap (getUserClientPrekeyMap p)) @=? Just [ec]

-- @END

-- | This test verifies behaviour when an unknown client posts the message. Only
-- tests the Protobuf endpoint.
postCryptoMessageNotAuthorizeUnknownClient :: TestM ()
Expand Down Expand Up @@ -547,6 +553,8 @@ postMessageClientNotInGroupDoesNotReceiveMsg = do
checkEveGetsMsg
checkChadDoesNotGetMsg

-- @END

-- @SF.Separation @TSFI.RESTfulAPI @S2
-- This test verifies that when a client sends a message not to all clients of a group then the server should reject the message and sent a notification to the sender (412 Missing clients).
-- The test is somewhat redundant because this is already tested as part of other tests already. This is a stand alone test that solely tests the behavior described above.
Expand Down Expand Up @@ -575,6 +583,8 @@ postMessageRejectIfMissingClients = do
mkMsg :: ByteString -> (UserId, ClientId) -> (UserId, ClientId, Text)
mkMsg text (userId, clientId) = (userId, clientId, toBase64Text text)

-- @END

-- @SF.Separation @TSFI.RESTfulAPI @S2
-- This test verifies behaviour under various values of ignore_missing and
-- report_missing. Only tests the JSON endpoint.
Expand Down Expand Up @@ -633,6 +643,8 @@ postCryptoMessageVerifyCorrectResponseIfIgnoreAndReportMissingQueryParam = do
where
listToByteString = BS.intercalate "," . map toByteString'

-- @END

-- | Sets up a conversation on Backend A known as "owning backend". All user's
-- on this backend have names begining with 'A'. The conversation has a couple
-- of users from backend B and one user from backend C.
Expand Down Expand Up @@ -832,6 +844,8 @@ postMessageQualifiedLocalOwningBackendMissingClients = do
assertMismatchQualified mempty expectedMissing mempty mempty
WS.assertNoEvent (1 # Second) [wsBob, wsChad]

-- @END

-- | Sets up a conversation on Backend A known as "owning backend". One of the
-- users from Backend A will send the message, it is expected that message will
-- be sent successfully.
Expand Down Expand Up @@ -1056,6 +1070,8 @@ postMessageQualifiedLocalOwningBackendIgnoreMissingClients = do
assertMismatchQualified mempty expectedMissing mempty mempty
WS.assertNoEvent (1 # Second) [wsBob, wsChad]

-- @END

postMessageQualifiedLocalOwningBackendFailedToSendClients :: TestM ()
postMessageQualifiedLocalOwningBackendFailedToSendClients = do
-- WS receive timeout
Expand Down
38 changes: 24 additions & 14 deletions services/spar/test-integration/Test/Spar/APISpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,8 @@ specInitiateLogin = do
specFinalizeLogin :: SpecWith TestEnv
specFinalizeLogin = do
describe "POST /sso/finalize-login" $ do
-- @SF.CHANNEL@TSFI.RESTfulAPI @S2 @S3
-- Receiving an invalid SAML token from client should not give the user a valid access token
context "access denied" $ do
-- @SF.Channel @TSFI.RESTfulAPI @S2 @S3
context "rejectsSAMLResponseSayingAccessNotGranted" $ do
it "responds with a very peculiar 'forbidden' HTTP response" $ do
(_, tid, idp, (_, privcreds)) <- registerTestIdPWithMeta
authnreq <- negotiateAuthnRequest idp
Expand All @@ -222,6 +221,8 @@ specFinalizeLogin = do
bdy `shouldContain` "}, receiverOrigin)"
hasPersistentCookieHeader sparresp `shouldBe` Left "no set-cookie header"

-- @END

context "access granted" $ do
let loginSuccess :: HasCallStack => ResponseLBS -> TestSpar ()
loginSuccess sparresp = liftIO $ do
Expand Down Expand Up @@ -295,9 +296,8 @@ specFinalizeLogin = do
authnresp <- runSimpleSP $ mkAuthnResponse privcreds idp3 spmeta authnreq True
loginSuccess =<< submitAuthnResponse tid3 authnresp

-- @SF.CHANNEL@TSFI.RESTfulAPI @S2 @S3
-- Receiving an invalid SAML token from client should not give the user a valid access token
context "idp sends user to two teams with same issuer, nameid" $ do
-- @SF.Channel @TSFI.RESTfulAPI @S2 @S3
context "rejectsSAMLResponseInWrongTeam" $ do
it "fails" $ do
skipIdPAPIVersions
[ WireIdPAPIV1
Expand All @@ -321,6 +321,8 @@ specFinalizeLogin = do
authnresp <- runSimpleSP $ mkAuthnResponseWithSubj subj privcreds idp2 spmeta authnreq True
loginFailure =<< submitAuthnResponse tid2 authnresp

-- @END

context "user is created once, then deleted in team settings, then can login again." $ do
it "responds with 'allowed'" $ do
(ownerid, teamid, idp, (_, privcreds)) <- registerTestIdPWithMeta
Expand Down Expand Up @@ -414,8 +416,8 @@ specFinalizeLogin = do
g (c : s) = c : g s
g "" = ""

-- @SF.CHANNEL@TSFI.RESTfulAPI @S2 @S3
it "rejects saml responses with invalid issuer entity id" $ do
-- @SF.Channel @TSFI.RESTfulAPI @S2 @S3
it "rejectsSAMLResponseFromWrongIssuer" $ do
let mkareq = negotiateAuthnRequest
mkaresp privcreds idp spmeta authnreq =
mkAuthnResponse
Expand All @@ -433,8 +435,10 @@ specFinalizeLogin = do
(cs . fromJust . responseBody $ sparresp) `shouldContainInBase64` "Input {iName = \"SAMLResponse\""
check mkareq mkaresp submitaresp checkresp

-- @SF.CHANNEL@TSFI.RESTfulAPI @S2 @S3
it "rejects saml responses signed with the wrong private key" $ do
-- @END

-- @SF.Channel @TSFI.RESTfulAPI @S2 @S3
it "rejectsSAMLResponseSignedWithWrongKey" $ do
(_, _, _, (_, badprivcreds)) <- registerTestIdPWithMeta
let mkareq = negotiateAuthnRequest
mkaresp _ idp spmeta authnreq =
Expand All @@ -448,8 +452,10 @@ specFinalizeLogin = do
checkresp sparresp = statusCode sparresp `shouldBe` 400
check mkareq mkaresp submitaresp checkresp

-- @SF.CHANNEL@TSFI.RESTfulAPI @S2 @S3
it "rejects saml responses to requests not in cassandra:spar.authreq" $ do
-- @END

-- @SF.Channel @TSFI.RESTfulAPI @S2 @S3
it "rejectsSAMLResponseIfRequestIsStale" $ do
let mkareq idp = do
req <- negotiateAuthnRequest idp
runSpar $ AReqIDStore.unStore (req ^. SAML.rqID)
Expand All @@ -462,8 +468,10 @@ specFinalizeLogin = do
(cs . fromJust . responseBody $ sparresp) `shouldContain` "bad InResponseTo attribute(s)"
check mkareq mkaresp submitaresp checkresp

-- @SF.CHANNEL@TSFI.RESTfulAPI @S2 @S3
it "rejects saml responses already seen (and recorded in cassandra:spar.authresp)" $ do
-- @END

-- @SF.Channel @TSFI.RESTfulAPI @S2 @S3
it "rejectsSAMLResponseIfResponseIsStale" $ do
let mkareq = negotiateAuthnRequest
mkaresp privcreds idp spmeta authnreq = mkAuthnResponse privcreds idp spmeta authnreq True
submitaresp teamid authnresp = do
Expand All @@ -474,6 +482,8 @@ specFinalizeLogin = do
(cs . fromJust . responseBody $ sparresp) `shouldContain` "<title>wire:sso:error:forbidden</title>"
check mkareq mkaresp submitaresp checkresp

-- @END

context "IdP changes response format" $ do
it "treats NameId case-insensitively" $ do
(_ownerid, tid, idp, (_, privcreds)) <- registerTestIdPWithMeta
Expand Down
6 changes: 5 additions & 1 deletion services/spar/test-integration/Test/Spar/Scim/AuthSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ testCreateTokenAuthorizesOnlyAdmins = do
(mkUser Galley.RoleAdmin >>= createToken')
!!! const 200 === statusCode

-- @END

-- | Test that for a user with a password, token creation requires reauthentication (i.e. the
-- field @"password"@ should be provided).
--
Expand Down Expand Up @@ -362,7 +364,7 @@ testDeletedTokensAreUnlistable = do
----------------------------------------------------------------------------
-- Miscellaneous tests

-- @SF.PROVISIONING @TSFI.RESTfulAPI @S2
-- @SF.Provisioning @TSFI.RESTfulAPI @S2
-- This test verifies that the SCIM API responds with an authentication error
-- and can't be used if it receives an invalid secret token
-- or if no token is provided at all
Expand All @@ -374,3 +376,5 @@ testAuthIsNeeded = do
listUsers_ (Just invalidToken) Nothing (env ^. teSpar) !!! checkErr 401 Nothing
-- Try to do @GET /Users@ without a token and check that it fails
listUsers_ Nothing Nothing (env ^. teSpar) !!! checkErr 401 Nothing

-- @END
2 changes: 2 additions & 0 deletions services/spar/test-integration/Test/Spar/Scim/UserSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,8 @@ testCreateRejectsInvalidHandle = do
createUser_ (Just tok) (user {Scim.User.userName = "#invalid name"}) (env ^. teSpar)
!!! const 400 === statusCode

-- @END

-- | Test that user creation fails if handle is already in use (even on different team).
testCreateRejectsTakenHandle :: TestSpar ()
testCreateRejectsTakenHandle = do
Expand Down