Skip to content

Commit f56e284

Browse files
committed
Access can now take a client ID
1 parent 68ae6ab commit f56e284

File tree

5 files changed

+46
-32
lines changed

5 files changed

+46
-32
lines changed

libs/wire-api/src/Wire/API/Routes/Public/Brig.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1151,9 +1151,10 @@ type AuthAPI =
11511151
\ Every other combination is invalid.\
11521152
\ Access tokens can be given as query parameter or authorisation\
11531153
\ header, with the latter being preferred."
1154+
:> QueryParam "client_id" ClientId
11541155
:> Cookies '["zuid" ::: SomeUserToken]
1155-
:> CanThrow 'BadCredentials
11561156
:> Bearer SomeAccessToken
1157+
:> CanThrow 'BadCredentials
11571158
:> MultiVerb1 'POST '[JSON] TokenResponse
11581159
)
11591160
:<|> Named

libs/wire-api/src/Wire/API/User/Auth.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ import Data.ByteString.Conversion
6868
import qualified Data.ByteString.Lazy as LBS
6969
import Data.Code as Code
7070
import Data.Handle (Handle)
71-
import Data.Id (UserId)
71+
import Data.Id
7272
import Data.Json.Util
7373
import Data.Misc (PlainTextPassword (..))
7474
import Data.SOP

services/brig/src/Brig/API/Auth.hs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,25 @@ import Wire.API.User.Auth.ReAuth
5050
import Wire.API.User.Auth.Sso
5151

5252
accessH ::
53+
Maybe ClientId ->
5354
[Either Text SomeUserToken] ->
5455
Maybe (Either Text SomeAccessToken) ->
5556
Handler r SomeAccess
56-
accessH ut' mat' = do
57+
accessH mcid ut' mat' = do
5758
ut <- handleTokenErrors ut'
5859
mat <- traverse handleTokenError mat'
5960
partitionTokens ut mat
60-
>>= either (uncurry access) (uncurry access)
61+
>>= either (uncurry (access mcid)) (uncurry (access mcid))
6162

62-
access :: TokenPair u a => NonEmpty (Token u) -> Maybe (Token a) -> Handler r SomeAccess
63-
access t mt =
63+
access ::
64+
TokenPair u a =>
65+
Maybe ClientId ->
66+
NonEmpty (Token u) ->
67+
Maybe (Token a) ->
68+
Handler r SomeAccess
69+
access mcid t mt =
6470
traverse mkUserTokenCookie
65-
=<< wrapHttpClientE (Auth.renewAccess (List1 t) mt) !>> zauthError
71+
=<< wrapHttpClientE (Auth.renewAccess (List1 t) mt mcid) !>> zauthError
6672

6773
sendLoginCode :: SendLoginCode -> Handler r LoginCodeTimeout
6874
sendLoginCode (SendLoginCode phone call force) = do

services/brig/src/Brig/User/Auth.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,12 +253,13 @@ renewAccess ::
253253
) =>
254254
List1 (ZAuth.Token u) ->
255255
Maybe (ZAuth.Token a) ->
256+
Maybe ClientId ->
256257
ExceptT ZAuth.Failure m (Access u)
257-
renewAccess uts at = do
258+
renewAccess uts at mcid = do
258259
(uid, ck) <- validateTokens uts at
259260
lift . Log.debug $ field "user" (toByteString uid) . field "action" (Log.val "User.renewAccess")
260261
catchSuspendInactiveUser uid ZAuth.Expired
261-
ck' <- lift $ nextCookie ck
262+
ck' <- lift $ nextCookie ck mcid
262263
at' <- lift $ newAccessToken (fromMaybe ck ck') at
263264
pure $ Access at' ck'
264265

services/brig/src/Brig/User/Auth/Cookie.hs

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ import Brig.User.Auth.Cookie.Limit
4646
import qualified Brig.User.Auth.DB.Cookie as DB
4747
import qualified Brig.ZAuth as ZAuth
4848
import Cassandra
49+
import Control.Error.Util
4950
import Control.Lens (to, view)
51+
import Control.Monad.Trans.Maybe
5052
import Data.ByteString.Conversion
5153
import Data.Id
5254
import qualified Data.List as List
@@ -105,31 +107,35 @@ nextCookie ::
105107
MonadClient m
106108
) =>
107109
Cookie (ZAuth.Token u) ->
110+
Maybe ClientId ->
108111
m (Maybe (Cookie (ZAuth.Token u)))
109-
nextCookie c = do
112+
nextCookie c mNewCid = runMaybeT $ do
113+
let mOldCid = ZAuth.userTokenClient (cookieValue c)
114+
-- Keep old client ID by default, but use new one if none was set.
115+
let mcid = mOldCid <|> mNewCid
116+
110117
s <- view settings
111118
now <- liftIO =<< view currentTime
112119
let created = cookieCreated c
113120
let renewAge = fromInteger (setUserCookieRenewAge s)
114-
-- TODO: Also renew the cookie if it was signed with
115-
-- a different zauth key index, regardless of age.
116-
if persist c && diffUTCTime now created > renewAge
117-
then Just <$> getNext
118-
else pure Nothing
119-
where
120-
persist = (PersistentCookie ==) . cookieType
121-
getNext = case cookieSucc c of
122-
Nothing -> renewCookie c
123-
Just ck -> do
124-
let uid = ZAuth.userTokenOf (cookieValue c)
125-
cid = ZAuth.userTokenClient (cookieValue c)
126-
trackSuperseded uid (cookieId c)
127-
cs <- DB.listCookies uid
128-
case List.find (\x -> cookieId x == ck && persist x) cs of
129-
Nothing -> renewCookie c
130-
Just c' -> do
131-
t <- ZAuth.mkUserToken uid cid (cookieIdNum ck) (cookieExpires c')
132-
pure c' {cookieValue = t}
121+
-- Renew the cookie if the client ID has changed, regardless of age.
122+
-- FUTUREWORK: Also renew the cookie if it was signed with a different zauth
123+
-- key index, regardless of age.
124+
when (mcid /= mOldCid) $ do
125+
guard (cookieType c == PersistentCookie)
126+
guard (diffUTCTime now created > renewAge)
127+
lift $ do
128+
c' <- runMaybeT $ do
129+
ck <- hoistMaybe $ cookieSucc c
130+
let uid = ZAuth.userTokenOf (cookieValue c)
131+
lift $ trackSuperseded uid (cookieId c)
132+
cs <- lift $ DB.listCookies uid
133+
c' <-
134+
hoistMaybe $
135+
List.find (\x -> cookieId x == ck && cookieType x == PersistentCookie) cs
136+
t <- lift $ ZAuth.mkUserToken uid mcid (cookieIdNum ck) (cookieExpires c')
137+
pure c' {cookieValue = t}
138+
maybe (renewCookie c mcid) pure c'
133139

134140
-- | Renew the given cookie with a fresh token.
135141
renewCookie ::
@@ -139,13 +145,13 @@ renewCookie ::
139145
MonadClient m
140146
) =>
141147
Cookie (ZAuth.Token u) ->
148+
Maybe ClientId ->
142149
m (Cookie (ZAuth.Token u))
143-
renewCookie old = do
150+
renewCookie old mcid = do
144151
let t = cookieValue old
145152
let uid = ZAuth.userTokenOf t
146-
cid = ZAuth.userTokenClient t
147153
-- Insert new cookie
148-
new <- newCookie uid cid (cookieType old) (cookieLabel old)
154+
new <- newCookie uid mcid (cookieType old) (cookieLabel old)
149155
-- Link the old cookie to the new (successor), keeping it
150156
-- around only for another renewal period so as not to build
151157
-- an ever growing chain of superseded cookies.

0 commit comments

Comments
 (0)