diff --git a/cabal.project b/cabal.project index c515c73ee8..54f49143c9 100644 --- a/cabal.project +++ b/cabal.project @@ -142,7 +142,7 @@ source-repository-package source-repository-package type: git location: https://github.com/wireapp/saml2-web-sso - tag: 4227e38be5c0810012dc472fc6931f6087fbce68 + tag: 30747970da6e024b53707605d138524de6fa53b0 source-repository-package type: git diff --git a/changelog.d/5-internal/bump-saml2-lib b/changelog.d/5-internal/bump-saml2-lib new file mode 100644 index 0000000000..f849116b80 --- /dev/null +++ b/changelog.d/5-internal/bump-saml2-lib @@ -0,0 +1 @@ +Bump saml2-web-sso diff --git a/services/galley/galley.cabal b/services/galley/galley.cabal index bfa1038b0d..9fe26c3e59 100644 --- a/services/galley/galley.cabal +++ b/services/galley/galley.cabal @@ -228,7 +228,7 @@ library , retry >=0.5 , safe >=0.3 , safe-exceptions >=0.1 - , saml2-web-sso >=0.18 + , saml2-web-sso >=0.19 , schema-profunctor , semigroups , servant @@ -325,7 +325,7 @@ executable galley , imports , raw-strings-qq >=1.0 , safe >=0.3 - , saml2-web-sso >=0.18 + , saml2-web-sso >=0.19 , servant-client , ssl-util , tagged @@ -456,7 +456,7 @@ executable galley-integration , raw-strings-qq >=1.0 , retry , safe >=0.3 - , saml2-web-sso >=0.18 + , saml2-web-sso >=0.19 , schema-profunctor , servant , servant-client @@ -559,7 +559,7 @@ executable galley-migrate-data , optparse-applicative , raw-strings-qq >=1.0 , safe >=0.3 - , saml2-web-sso >=0.18 + , saml2-web-sso >=0.19 , servant-client , ssl-util , tagged @@ -680,7 +680,7 @@ executable galley-schema , optparse-applicative , raw-strings-qq >=1.0 , safe >=0.3 - , saml2-web-sso >=0.18 + , saml2-web-sso >=0.19 , servant-client , ssl-util , tagged @@ -759,7 +759,7 @@ test-suite galley-tests , lens , raw-strings-qq >=1.0 , safe >=0.3 - , saml2-web-sso >=0.18 + , saml2-web-sso >=0.19 , servant-client , servant-swagger , ssl-util diff --git a/services/galley/package.yaml b/services/galley/package.yaml index b5e192a42b..7008ec1de4 100644 --- a/services/galley/package.yaml +++ b/services/galley/package.yaml @@ -21,7 +21,7 @@ dependencies: - wire-api-federation - tagged - servant-client -- saml2-web-sso >=0.18 +- saml2-web-sso >=0.19 - transformers library: diff --git a/services/spar/package.yaml b/services/spar/package.yaml index 751fd00333..9fd9e4c5a7 100644 --- a/services/spar/package.yaml +++ b/services/spar/package.yaml @@ -60,7 +60,7 @@ dependencies: - QuickCheck - raw-strings-qq - retry - - saml2-web-sso >= 0.18 + - saml2-web-sso >= 0.19 - servant - servant-multipart - servant-server diff --git a/services/spar/spar.cabal b/services/spar/spar.cabal index 32badbaa38..900af12a7d 100644 --- a/services/spar/spar.cabal +++ b/services/spar/spar.cabal @@ -166,7 +166,7 @@ library , polysemy-wire-zoo , raw-strings-qq , retry - , saml2-web-sso >=0.18 + , saml2-web-sso >=0.19 , servant , servant-multipart , servant-server @@ -281,7 +281,7 @@ executable spar , polysemy-wire-zoo , raw-strings-qq , retry - , saml2-web-sso >=0.18 + , saml2-web-sso >=0.19 , servant , servant-multipart , servant-server @@ -418,7 +418,7 @@ executable spar-integration , random , raw-strings-qq , retry - , saml2-web-sso >=0.18 + , saml2-web-sso >=0.19 , servant , servant-multipart , servant-server @@ -546,7 +546,7 @@ executable spar-migrate-data , polysemy-wire-zoo , raw-strings-qq , retry - , saml2-web-sso >=0.18 + , saml2-web-sso >=0.19 , servant , servant-multipart , servant-server @@ -678,7 +678,7 @@ executable spar-schema , polysemy-wire-zoo , raw-strings-qq , retry - , saml2-web-sso >=0.18 + , saml2-web-sso >=0.19 , servant , servant-multipart , servant-server @@ -809,7 +809,7 @@ test-suite spec , polysemy-wire-zoo , raw-strings-qq , retry - , saml2-web-sso >=0.18 + , saml2-web-sso >=0.19 , servant , servant-multipart , servant-server diff --git a/services/spar/src/Spar/API.hs b/services/spar/src/Spar/API.hs index b8f5a34b23..1cda6c902b 100644 --- a/services/spar/src/Spar/API.hs +++ b/services/spar/src/Spar/API.hs @@ -309,9 +309,9 @@ authresp :: Sem r Void authresp mbtid arbody = logErrors $ SAML2.authResp mbtid (SamlProtocolSettings.spIssuer mbtid) (SamlProtocolSettings.responseURI mbtid) go arbody where - go :: SAML.AuthnResponse -> SAML.AccessVerdict -> Sem r Void - go resp verdict = do - result :: SAML.ResponseVerdict <- verdictHandler mbtid resp verdict + go :: SAML.AuthnResponse -> IdP -> SAML.AccessVerdict -> Sem r Void + go resp verdict idp = do + result :: SAML.ResponseVerdict <- verdictHandler resp idp verdict throw @SparError $ SAML.CustomServant result logErrors :: Sem r Void -> Sem r Void diff --git a/services/spar/src/Spar/App.hs b/services/spar/src/Spar/App.hs index ce3e10ac04..22460e0697 100644 --- a/services/spar/src/Spar/App.hs +++ b/services/spar/src/Spar/App.hs @@ -23,8 +23,7 @@ module Spar.App ( Env (..), throwSparSem, verdictHandler, - GetUserResult (..), - getUserIdByUref, + getUserByUrefUnsafe, getUserIdByScimExternalId, validateEmailIfExists, validateEmail, @@ -60,7 +59,6 @@ import SAML2.WebSSO explainDeniedReason, idpExtraInfo, idpId, - uidTenant, ) import qualified SAML2.WebSSO as SAML import Servant @@ -110,52 +108,27 @@ data Env = Env sparCtxRequestId :: RequestId } --- | Look up user locally in table @spar.user@ or @spar.scim_user@ (depending on the --- argument), then in brig, then return the 'UserId'. If either lookup fails, or user is not --- in a team, return 'Nothing'. +-- | Get a user by UserRef, no matter what the team. -- --- It makes sense to require that users are required to be team members: both IdPs and SCIM --- tokens are created in the context of teams, and the only way for users to be created is as --- team members. If a user is not a team member, it cannot have been created using SAML or --- SCIM. +-- Look up user locally in table @spar.user@ or @spar.scim_user@ (depending on the +-- argument), then in brig, then return the 'User'. If either lookup fails, or user is not +-- in a team, return 'Nothing'. -- -- If a user has been created via scim invite (ie., no IdP present), and has status --- 'PendingInvitation', its 'UserId' will be returned here, since for SCIM purposes it is an +-- 'PendingInvitation', it will be returned here, since for SCIM purposes it is an -- existing (if inactive) user. If 'getUser' is called during SAML authentication, this may -- cause an inactive user to log in, but that's ok: `PendingActivation` means that email and -- password handshake have not been completed; it's still ok for the user to gain access to -- the team with valid SAML credentials. -- --- FUTUREWORK: Remove and reinstatate getUser, in AuthID refactoring PR. (in https://github.com/wireapp/wire-server/pull/1410, undo https://github.com/wireapp/wire-server/pull/1418) -getUserIdByUref :: Members '[BrigAccess, SAMLUserStore] r => Maybe TeamId -> SAML.UserRef -> Sem r (GetUserResult UserId) -getUserIdByUref mbteam uref = userId <$$> getUserByUref mbteam uref - -getUserByUref :: Members '[BrigAccess, SAMLUserStore] r => Maybe TeamId -> SAML.UserRef -> Sem r (GetUserResult User) -getUserByUref mbteam uref = do - muid <- SAMLUserStore.get uref - case muid of - Nothing -> pure GetUserNotFound - Just uid -> do - let withpending = Intra.WithPendingInvitations -- see haddocks above - Intra.getBrigUser withpending uid >>= \case - Nothing -> pure GetUserNotFound - Just user - | isNothing (userTeam user) -> pure GetUserNoTeam - | isJust mbteam && mbteam /= userTeam user -> pure GetUserWrongTeam - | otherwise -> pure $ GetUserFound user - -data GetUserResult usr - = GetUserFound usr - | GetUserNotFound - | GetUserNoTeam - | GetUserWrongTeam - deriving (Eq, Show) - -instance Functor GetUserResult where - fmap f (GetUserFound usr) = GetUserFound (f usr) - fmap _ GetUserNotFound = GetUserNotFound - fmap _ GetUserNoTeam = GetUserNoTeam - fmap _ GetUserWrongTeam = GetUserWrongTeam +-- FUTUREWORK: Remove and reinstate getUser, in AuthID refactoring PR. (in +-- https://github.com/wireapp/wire-server/pull/1410, undo +-- https://github.com/wireapp/wire-server/pull/1418) +-- +-- FUTUREWORK: https://wearezeta.atlassian.net/browse/SQSERVICES-1655 +getUserByUrefUnsafe :: Members '[BrigAccess, SAMLUserStore] r => SAML.UserRef -> Sem r (Maybe User) +getUserByUrefUnsafe uref = do + maybe (pure Nothing) (Intra.getBrigUser Intra.WithPendingInvitations) =<< SAMLUserStore.get uref -- FUTUREWORK: Remove and reinstatate getUser, in AuthID refactoring PR getUserIdByScimExternalId :: Members '[BrigAccess, ScimExternalIdStore] r => TeamId -> Email -> Sem r (Maybe UserId) @@ -202,28 +175,9 @@ createSamlUserWithId teamid buid suid = do SAMLUserStore.insert suid buid -- | If the team has no scim token, call 'createSamlUser'. Otherwise, raise "invalid --- credentials". +-- credentials". (FUTUREWORK: Assumes that `UserRef` is still available globally. See +-- https://wearezeta.atlassian.net/browse/SQSERVICES-1655) autoprovisionSamlUser :: - Members - '[ Random, - GalleyAccess, - BrigAccess, - ScimTokenStore, - IdPConfigStore, - Error SparError, - SAMLUserStore - ] - r => - Maybe TeamId -> - SAML.UserRef -> - Sem r UserId -autoprovisionSamlUser mbteam suid = do - buid <- Id <$> Random.uuid - autoprovisionSamlUserWithId mbteam buid suid - pure buid - --- | Like 'autoprovisionSamlUser', but for an already existing 'UserId'. -autoprovisionSamlUserWithId :: forall r. Members '[ GalleyAccess, @@ -234,28 +188,25 @@ autoprovisionSamlUserWithId :: SAMLUserStore ] r => - Maybe TeamId -> + IdP -> UserId -> SAML.UserRef -> Sem r () -autoprovisionSamlUserWithId mbteam buid suid = do - idp <- case mbteam of - Just team -> IdPConfigStore.getIdPByIssuerV2 (suid ^. uidTenant) team - Nothing -> IdPConfigStore.getIdPByIssuerV1 (suid ^. uidTenant) - guardReplacedIdP idp - guardScimTokens idp +autoprovisionSamlUser idp buid suid = do + guardReplacedIdP + guardScimTokens createSamlUserWithId (idp ^. idpExtraInfo . wiTeam) buid suid validateEmailIfExists buid suid where -- Replaced IdPs are not allowed to create new wire accounts. - guardReplacedIdP :: IdP -> Sem r () - guardReplacedIdP idp = do + guardReplacedIdP :: Sem r () + guardReplacedIdP = do unless (isNothing $ idp ^. idpExtraInfo . wiReplacedBy) $ do throwSparSem $ SparCannotCreateUsersOnReplacedIdP (cs . SAML.idPIdToST $ idp ^. idpId) -- IdPs in teams with scim tokens are not allowed to auto-provision. - guardScimTokens :: IdP -> Sem r () - guardScimTokens idp = do + guardScimTokens :: Sem r () + guardScimTokens = do let teamid = idp ^. idpExtraInfo . wiTeam scimtoks <- ScimTokenStore.lookupByTeam teamid unless (null scimtoks) $ do @@ -301,11 +252,11 @@ verdictHandler :: SAMLUserStore ] r => - Maybe TeamId -> SAML.AuthnResponse -> SAML.AccessVerdict -> + IdP -> Sem r SAML.ResponseVerdict -verdictHandler mbteam aresp verdict = do +verdictHandler aresp verdict idp = do -- [3/4.1.4.2] -- [...] If the containing message is in response to an , then -- the InResponseTo attribute MUST match the request's ID. @@ -314,9 +265,9 @@ verdictHandler mbteam aresp verdict = do format :: Maybe VerdictFormat <- VerdictFormatStore.get reqid resp <- case format of Just VerdictFormatWeb -> - verdictHandlerResult mbteam verdict >>= verdictHandlerWeb + verdictHandlerResult verdict idp >>= verdictHandlerWeb Just (VerdictFormatMobile granted denied) -> - verdictHandlerResult mbteam verdict >>= verdictHandlerMobile granted denied + verdictHandlerResult verdict idp >>= verdictHandlerMobile granted denied Nothing -> -- (this shouldn't happen too often, see 'storeVerdictFormat') throwSparSem SparNoSuchRequest @@ -343,12 +294,12 @@ verdictHandlerResult :: SAMLUserStore ] r => - Maybe TeamId -> SAML.AccessVerdict -> + IdP -> Sem r VerdictHandlerResult -verdictHandlerResult mbteam verdict = do +verdictHandlerResult verdict idp = do Logger.log Logger.Debug $ "entering verdictHandlerResult" - result <- catchVerdictErrors $ verdictHandlerResultCore mbteam verdict + result <- catchVerdictErrors $ verdictHandlerResultCore idp verdict Logger.log Logger.Debug $ "leaving verdictHandlerResult" <> show result pure result @@ -372,8 +323,10 @@ catchVerdictErrors = (`catch` hndlr) -- | If a user attempts to login presenting a new IdP issuer, but there is no entry in -- @"spar.user"@ for her: lookup @"old_issuers"@ from @"spar.idp"@ for the new IdP, and --- traverse the old IdPs in search for the old entry. Return that old entry. -findUserIdWithOldIssuer :: +-- traverse the old issuers in search for the old entry. +-- +-- FUTUREWORK: https://wearezeta.atlassian.net/browse/SQSERVICES-1655 +getUserByUrefViaOldIssuerUnsafe :: forall r. Members '[ BrigAccess, @@ -382,19 +335,17 @@ findUserIdWithOldIssuer :: Error SparError ] r => - Maybe TeamId -> + IdP -> SAML.UserRef -> - Sem r (GetUserResult (SAML.UserRef, UserId)) -findUserIdWithOldIssuer mbteam (SAML.UserRef issuer subject) = do - idp <- case mbteam of - Just team -> IdPConfigStore.getIdPByIssuerV2 issuer team - Nothing -> IdPConfigStore.getIdPByIssuerV1 issuer - let tryFind :: GetUserResult (SAML.UserRef, UserId) -> Issuer -> Sem r (GetUserResult (SAML.UserRef, UserId)) - tryFind found@(GetUserFound _) _ = pure found - tryFind _ oldIssuer = (uref,) <$$> getUserIdByUref mbteam uref + Sem r (Maybe (SAML.UserRef, User)) +getUserByUrefViaOldIssuerUnsafe idp (SAML.UserRef _ subject) = do + let tryFind :: Maybe (SAML.UserRef, User) -> Issuer -> Sem r (Maybe (SAML.UserRef, User)) + tryFind found@(Just _) _ = pure found + tryFind Nothing oldIssuer = (uref,) <$$> getUserByUrefUnsafe uref where uref = SAML.UserRef oldIssuer subject - foldM tryFind GetUserNotFound (idp ^. idpExtraInfo . wiOldIssuers) + + foldM tryFind Nothing (idp ^. idpExtraInfo . wiOldIssuers) -- | After a user has been found using 'findUserWithOldIssuer', update it everywhere so that -- the old IdP is not needed any more next time. @@ -417,38 +368,33 @@ verdictHandlerResultCore :: SAMLUserStore ] r => - Maybe TeamId -> + IdP -> SAML.AccessVerdict -> Sem r VerdictHandlerResult -verdictHandlerResultCore mbteam = \case +verdictHandlerResultCore idp = \case SAML.AccessDenied reasons -> do pure $ VerifyHandlerDenied reasons - SAML.AccessGranted userref -> do + SAML.AccessGranted uref -> do uid :: UserId <- do - viaSparCassandra <- getUserIdByUref mbteam userref - -- race conditions: if the user has been created on spar, but not on brig, 'getUser' - -- returns 'Nothing'. this is ok assuming 'createUser' (called below) is - -- idempotent. - viaSparCassandraOldIssuer <- - case viaSparCassandra of - GetUserFound _ -> pure GetUserNotFound - _ -> findUserIdWithOldIssuer mbteam userref - let err = - SparUserRefInNoOrMultipleTeams . cs $ - show (userref, viaSparCassandra, viaSparCassandraOldIssuer) - case (viaSparCassandra, viaSparCassandraOldIssuer) of - (GetUserNoTeam, _) -> throwSparSem err - (GetUserWrongTeam, _) -> throwSparSem err - (_, GetUserNoTeam) -> throwSparSem err - (_, GetUserWrongTeam) -> throwSparSem err - -- This is the first SSO authentication, so we auto-create a user. We know the user - -- has not been created via SCIM because then we would've ended up in the - -- "reauthentication" branch. - (GetUserNotFound, GetUserNotFound) -> autoprovisionSamlUser mbteam userref - -- If the user is only found under an old (previous) issuer, move it here. - (GetUserNotFound, GetUserFound (oldUserRef, uid)) -> moveUserToNewIssuer oldUserRef userref uid >> pure uid - -- SSO re-authentication (the most common case). - (GetUserFound uid, _) -> pure uid + let team = idp ^. idpExtraInfo . wiTeam + err = SparUserRefInNoOrMultipleTeams . cs . show $ uref + getUserByUrefUnsafe uref >>= \case + Just usr -> do + if userTeam usr == Just team + then pure (userId usr) + else throwSparSem err + Nothing -> do + getUserByUrefViaOldIssuerUnsafe idp uref >>= \case + Just (olduref, usr) -> do + let uid = userId usr + if userTeam usr == Just team + then moveUserToNewIssuer olduref uref uid >> pure uid + else throwSparSem err + Nothing -> do + buid <- Id <$> Random.uuid + autoprovisionSamlUser idp buid uref + pure buid + Logger.log Logger.Debug ("granting sso login for " <> show uid) cky <- BrigAccess.ssoLogin uid pure $ VerifyHandlerGranted cky uid diff --git a/services/spar/src/Spar/Scim/User.hs b/services/spar/src/Spar/Scim/User.hs index 2401223ed7..72dfe7365b 100644 --- a/services/spar/src/Spar/Scim/User.hs +++ b/services/spar/src/Spar/Scim/User.hs @@ -62,7 +62,7 @@ import Network.URI (URI, parseURI) import Polysemy import Polysemy.Input import qualified SAML2.WebSSO as SAML -import Spar.App (GetUserResult (..), getUserIdByScimExternalId, getUserIdByUref, validateEmail, validateEmailIfExists) +import Spar.App (getUserByUrefUnsafe, getUserIdByScimExternalId, validateEmail, validateEmailIfExists) import qualified Spar.Intra.BrigApp as Brig import Spar.Scim.Auth () import Spar.Scim.Types (normalizeLikeStored) @@ -760,9 +760,7 @@ assertExternalIdUnused = [Nothing] "externalId is already taken" --- | --- Check that the UserRef is not taken any user other than the passed 'UserId' --- (it is also acceptable if it is not taken by anybody). +-- | `UserRef` must map to the given `UserId` or to `Nothing`. -- -- ASSUMPTION: every scim user has a 'SAML.UserRef', and the `SAML.NameID` in it corresponds -- to a single `externalId`. @@ -780,13 +778,7 @@ assertExternalIdInAllowedValues allowedValues errmsg tid veid = do lift $ ST.runValidExternalIdBoth (\ma mb -> (&&) <$> ma <*> mb) - ( \uref -> - getUserIdByUref (Just tid) uref <&> \case - (Spar.App.GetUserFound uid) -> Just uid `elem` allowedValues - Spar.App.GetUserNotFound -> Nothing `elem` allowedValues - Spar.App.GetUserNoTeam -> False -- this is never allowed (and also hopefully impossible) - Spar.App.GetUserWrongTeam -> False -- this can happen, but it's violating all our assertions - ) + (\uref -> getUserByUrefUnsafe uref <&> (`elem` allowedValues) . fmap userId) (fmap (`elem` allowedValues) . getUserIdByScimExternalId tid) veid unless isGood $ diff --git a/services/spar/src/Spar/Sem/SAML2.hs b/services/spar/src/Spar/Sem/SAML2.hs index aa0411db81..2642e9e21b 100644 --- a/services/spar/src/Spar/Sem/SAML2.hs +++ b/services/spar/src/Spar/Sem/SAML2.hs @@ -34,6 +34,7 @@ import Imports (Maybe) import Polysemy import SAML2.WebSSO hiding (meta, toggleCookie) import URI.ByteString (URI) +import Wire.API.User.IdentityProvider (IdP) data SAML2 m a where AuthReq :: @@ -45,7 +46,7 @@ data SAML2 m a where Maybe TeamId -> m Issuer -> m URI -> - (AuthnResponse -> AccessVerdict -> m resp) -> + (AuthnResponse -> IdP -> AccessVerdict -> m resp) -> AuthnResponseBody -> SAML2 m resp Meta :: ST -> m Issuer -> m URI -> SAML2 m SPMetadata diff --git a/services/spar/src/Spar/Sem/SAML2/Library.hs b/services/spar/src/Spar/Sem/SAML2/Library.hs index d4bda54c33..bb434989e3 100644 --- a/services/spar/src/Spar/Sem/SAML2/Library.hs +++ b/services/spar/src/Spar/Sem/SAML2/Library.hs @@ -131,10 +131,10 @@ saml2ToSaml2WebSso = AuthResp mitlt ma mb mc ab -> do get_a <- runT ma get_b <- runT mb - get_c <- bindT $ uncurry mc + get_c <- bindT $ \(a, (b, c)) -> mc a b c ins <- getInspectorT s <- getInitialStateT - x <- raise $ unSPImpl $ SAML.authresp mitlt (inspectOrBomb ins get_a) (inspectOrBomb ins get_b) (\x y -> inspectOrBomb ins $ get_c $ (x, y) <$ s) ab + x <- raise $ unSPImpl $ SAML.authresp mitlt (inspectOrBomb ins get_a) (inspectOrBomb ins get_b) (\x y z -> inspectOrBomb ins $ get_c $ (x, (y, z)) <$ s) ab pure $ x <$ s Meta t ma mb -> do get_a <- runT ma diff --git a/services/spar/test-integration/Test/Spar/AppSpec.hs b/services/spar/test-integration/Test/Spar/AppSpec.hs index 9b06e7dc12..806c93fe2d 100644 --- a/services/spar/test-integration/Test/Spar/AppSpec.hs +++ b/services/spar/test-integration/Test/Spar/AppSpec.hs @@ -167,11 +167,7 @@ requestAccessVerdict idp isGranted mkAuthnReq = do then SAML.AccessGranted uref else SAML.AccessDenied [DeniedNoBearerConfSubj, DeniedNoAuthnStatement] outcome :: ResponseVerdict <- do - mbteam <- - asks (^. teWireIdPAPIVersion) <&> \case - User.WireIdPAPIV1 -> Nothing - User.WireIdPAPIV2 -> Just (idp ^. SAML.idpExtraInfo . User.wiTeam) - runSpar $ Spar.verdictHandler mbteam authnresp verdict + runSpar $ Spar.verdictHandler authnresp verdict idp let loc :: URI.URI loc = maybe (error "no location") (either error id . SAML.parseURI' . cs) diff --git a/stack.yaml b/stack.yaml index 5ebff33258..430c751eb2 100644 --- a/stack.yaml +++ b/stack.yaml @@ -87,7 +87,7 @@ extra-deps: # a version > 1.0.0 of wai-middleware-prometheus is available # (required: https://github.com/fimad/prometheus-haskell/pull/45) - git: https://github.com/wireapp/saml2-web-sso - commit: 4227e38be5c0810012dc472fc6931f6087fbce68 # master (Dec 07, 2021) + commit: 30747970da6e024b53707605d138524de6fa53b0 # master (Jul 07, 2022) - git: https://github.com/kim/hs-collectd commit: 885da222be2375f78c7be36127620ed772b677c9 diff --git a/stack.yaml.lock b/stack.yaml.lock index 985811c000..837a4d9aa3 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -26,15 +26,15 @@ packages: commit: 2e3282e5fb27ba8d989c271a0a989823fad7ec43 - completed: name: saml2-web-sso - version: '0.18' + version: '0.19' git: https://github.com/wireapp/saml2-web-sso pantry-tree: size: 4887 - sha256: 9d6d175cc7bbdb57558f25557e4d0d698c4aecc250f6ca03296a3d94671bf657 - commit: 4227e38be5c0810012dc472fc6931f6087fbce68 + sha256: 6682027579687623346c9dd7e946b676c3ae1cc2bdc435c0ea4c7982ac098577 + commit: 30747970da6e024b53707605d138524de6fa53b0 original: git: https://github.com/wireapp/saml2-web-sso - commit: 4227e38be5c0810012dc472fc6931f6087fbce68 + commit: 30747970da6e024b53707605d138524de6fa53b0 - completed: name: collectd version: 0.0.0.2