@@ -129,15 +129,18 @@ import Snap.Core
129129 )
130130import System.Directory (doesFileExist )
131131import System.FilePath ((</>) )
132- import Web.JWT (Signer (.. ))
132+ import Web.JWT (EncodeSigner ( .. ), VerifySigner (.. ))
133133
134- data AuthConfig = AuthConfig Signer Store
134+ data AuthConfig = AuthConfig EncodeSigner VerifySigner Store
135135
136136codeWorldIssuer :: Issuer
137137codeWorldIssuer = Issuer " https://code.world/"
138138
139- jwtSigner :: Secret -> Signer
140- jwtSigner (Secret bytes) = HMACSecret bytes
139+ jwtEncodeSigner :: Secret -> EncodeSigner
140+ jwtEncodeSigner (Secret bytes) = EncodeHMACSecret bytes
141+
142+ jwtVerifySigner :: Secret -> VerifySigner
143+ jwtVerifySigner (Secret bytes) = VerifyHMACSecret bytes
141144
142145jwtAuthType :: ByteString
143146jwtAuthType = " Bearer"
@@ -152,14 +155,16 @@ configureAuth appDir = do
152155 putStrLn $ " Secret key file not found at " ++ secretPath ++ " : skipping configuration of local authentication"
153156 pure Nothing
154157 True -> do
155- signer <- jwtSigner <$> readSecret secretPath
158+ secret <- readSecret secretPath
159+ let encodeSigner = jwtEncodeSigner secret
160+ let verifySigner = jwtVerifySigner secret
156161 let store = Store storePath
157162 storeExists_ <- storeExists store
158163 case storeExists_ of
159164 False -> do
160165 putStrLn $ " Account store database file not found at " ++ storePath ++ " : skipping configuration of local authentication"
161166 pure Nothing
162- True -> pure $ Just (AuthConfig signer store)
167+ True -> pure $ Just (AuthConfig encodeSigner verifySigner store)
163168
164169authRoutes :: AuthConfig -> [(ByteString , Snap () )]
165170authRoutes authConfig =
@@ -183,10 +188,10 @@ optionallyAuthenticated handler authConfig = do
183188 Just authHeaderBS -> authenticatedHelper authConfig (\ userId -> handler $ Just userId) authHeaderBS True
184189
185190authenticatedHelper :: AuthConfig -> (UserId -> Snap () ) -> ByteString -> Bool -> Snap ()
186- authenticatedHelper (AuthConfig signer _) handler authHeaderBS checkExpiry = withSnapExcept $ do
191+ authenticatedHelper (AuthConfig _ verifySigner _) handler authHeaderBS checkExpiry = withSnapExcept $ do
187192 AccessToken issuer _ expiresAt userId <- hoistMaybe (finishWith forbidden403) $ do
188193 j <- parseBearerAuthHeader authHeaderBS
189- parseAccessToken signer j
194+ parseAccessToken verifySigner j
190195
191196 when
192197 (issuer /= codeWorldIssuer)
@@ -201,11 +206,11 @@ authenticatedHelper (AuthConfig signer _) handler authHeaderBS checkExpiry = wit
201206 lift $ handler userId
202207
203208refreshTokenHandler :: AuthConfig -> Snap ()
204- refreshTokenHandler authConfig@ (AuthConfig signer store) = do
209+ refreshTokenHandler authConfig@ (AuthConfig _ verifySigner store) = do
205210 j <- Text. pack . Char8. unpack <$> getRequiredParam " refreshToken"
206211 withSnapExcept $ do
207212 -- 1. Parse refresh token
208- RefreshToken issuer _ expiresAt userId tokenId <- hoistMaybe (finishWith forbidden403) $ parseRefreshToken signer j
213+ RefreshToken issuer _ expiresAt userId tokenId <- hoistMaybe (finishWith forbidden403) $ parseRefreshToken verifySigner j
209214
210215 -- 2. Check issuer
211216 when
@@ -226,7 +231,7 @@ refreshTokenHandler authConfig@(AuthConfig signer store) = do
226231 lift $ generateTokenJson authConfig userId now
227232
228233signInHandler :: AuthConfig -> Snap ()
229- signInHandler authConfig@ (AuthConfig _ store) = withSnapExcept $ do
234+ signInHandler authConfig@ (AuthConfig _ _ store) = withSnapExcept $ do
230235 req <- lift getRequest
231236 (userId, password) <- hoistMaybe (finishWith (unauthorized401 jwtAuthType)) $ do
232237 authHeader <- getHeader " Authorization" req
@@ -261,10 +266,10 @@ signInHandler authConfig@(AuthConfig _ store) = withSnapExcept $ do
261266 generateTokenJson authConfig userId now
262267
263268signOutHandler :: AuthConfig -> Snap ()
264- signOutHandler (AuthConfig signer store) = do
269+ signOutHandler (AuthConfig _ verifySigner store) = do
265270 j <- Text. pack . Char8. unpack <$> getRequiredParam " refreshToken"
266271 withSnapExcept $ do
267- RefreshToken issuer _ _ userId tokenId <- hoistMaybe (finishWith forbidden403) $ parseRefreshToken signer j
272+ RefreshToken issuer _ _ userId tokenId <- hoistMaybe (finishWith forbidden403) $ parseRefreshToken verifySigner j
268273
269274 when
270275 (issuer /= codeWorldIssuer)
@@ -278,7 +283,7 @@ signOutHandler (AuthConfig signer store) = do
278283 lift $ finishWith ok200
279284
280285generateTokenJson :: AuthConfig -> UserId -> UTCTime -> Snap ()
281- generateTokenJson (AuthConfig signer store) userId now = withSnapExcept $ do
286+ generateTokenJson (AuthConfig encodeSigner _ store) userId now = withSnapExcept $ do
282287 -- 1. Generate new token ID
283288 mbNewTokenId <- liftIO $ incrementTokenId store userId
284289 newTokenId <-
@@ -291,19 +296,20 @@ generateTokenJson (AuthConfig signer store) userId now = withSnapExcept $ do
291296 atJson <-
292297 hoistMaybe
293298 (finishWith internalServerError500)
294- (renderAccessToken signer at)
299+ (renderAccessToken encodeSigner at)
295300 let rt = refreshToken codeWorldIssuer now userId newTokenId
296301 rtJson <-
297302 hoistMaybe
298303 (finishWith internalServerError500)
299- (renderRefreshToken signer rt)
304+ (renderRefreshToken encodeSigner rt)
300305
301306 -- 7. HTTP 200 response with tokens
302- lift $ ok200Json $
303- m
304- [ (" accessToken" , Text. unpack atJson),
305- (" refreshToken" , Text. unpack rtJson)
306- ]
307+ lift $
308+ ok200Json $
309+ m
310+ [ (" accessToken" , Text. unpack atJson),
311+ (" refreshToken" , Text. unpack rtJson)
312+ ]
307313
308314satisfiesPasswordPolicy :: Password -> Password -> Bool
309315satisfiesPasswordPolicy (Password passwordRaw) (Password newPasswordRaw)
0 commit comments