{-# LANGUAGE DuplicateRecordFields #-}
module WebGear.Core.Trait.Auth.JWT (
JWTAuth' (..),
JWTAuth,
Realm (..),
JWTAuthError (..),
jwtAuth,
optionalJWTAuth,
jwtAuth',
optionalJWTAuth',
) where
import Control.Arrow (ArrowChoice, arr)
import qualified Crypto.JWT as JWT
import Data.Void (Void, absurd)
import GHC.TypeLits (Symbol)
import WebGear.Core.Handler
import WebGear.Core.Modifiers (Existence (..))
import WebGear.Core.Request (Request)
import WebGear.Core.Response (Response)
import WebGear.Core.Trait
import WebGear.Core.Trait.Auth.Common
data JWTAuth' (x :: Existence) (scheme :: Symbol) m e a = JWTAuth'
{
JWTAuth' x scheme m e a -> JWTValidationSettings
jwtValidationSettings :: JWT.JWTValidationSettings
,
JWTAuth' x scheme m e a -> JWKSet
jwkSet :: JWT.JWKSet
,
JWTAuth' x scheme m e a -> ClaimsSet -> m (Either e a)
toJWTAttribute :: JWT.ClaimsSet -> m (Either e a)
}
type JWTAuth = JWTAuth' Required "Bearer"
data JWTAuthError e
=
| JWTAuthSchemeMismatch
| JWTAuthTokenBadFormat JWT.JWTError
| JWTAuthAttributeError e
deriving stock (JWTAuthError e -> JWTAuthError e -> Bool
(JWTAuthError e -> JWTAuthError e -> Bool)
-> (JWTAuthError e -> JWTAuthError e -> Bool)
-> Eq (JWTAuthError e)
forall e. Eq e => JWTAuthError e -> JWTAuthError e -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: JWTAuthError e -> JWTAuthError e -> Bool
$c/= :: forall e. Eq e => JWTAuthError e -> JWTAuthError e -> Bool
== :: JWTAuthError e -> JWTAuthError e -> Bool
$c== :: forall e. Eq e => JWTAuthError e -> JWTAuthError e -> Bool
Eq, Int -> JWTAuthError e -> ShowS
[JWTAuthError e] -> ShowS
JWTAuthError e -> String
(Int -> JWTAuthError e -> ShowS)
-> (JWTAuthError e -> String)
-> ([JWTAuthError e] -> ShowS)
-> Show (JWTAuthError e)
forall e. Show e => Int -> JWTAuthError e -> ShowS
forall e. Show e => [JWTAuthError e] -> ShowS
forall e. Show e => JWTAuthError e -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [JWTAuthError e] -> ShowS
$cshowList :: forall e. Show e => [JWTAuthError e] -> ShowS
show :: JWTAuthError e -> String
$cshow :: forall e. Show e => JWTAuthError e -> String
showsPrec :: Int -> JWTAuthError e -> ShowS
$cshowsPrec :: forall e. Show e => Int -> JWTAuthError e -> ShowS
Show)
instance WebGear.Core.Trait.Trait (JWTAuth' Required scheme m e a) Request where
type Attribute (JWTAuth' Required scheme m e a) Request = a
instance WebGear.Core.Trait.TraitAbsence (JWTAuth' Required scheme m e a) Request where
type Absence (JWTAuth' Required scheme m e a) Request = JWTAuthError e
instance WebGear.Core.Trait.Trait (JWTAuth' Optional scheme m e a) Request where
type Attribute (JWTAuth' Optional scheme m e a) Request = Either (JWTAuthError e) a
instance WebGear.Core.Trait.TraitAbsence (JWTAuth' Optional scheme m e a) Request where
type Absence (JWTAuth' Optional scheme m e a) Request = Void
jwtAuth ::
( WebGear.Core.Trait.Get h (JWTAuth m e t) Request
, ArrowChoice h
) =>
JWTAuth m e t ->
h (WebGear.Core.Trait.Linked req Request, JWTAuthError e) Response ->
Middleware h req (JWTAuth m e t : req)
jwtAuth :: JWTAuth m e t
-> h (Linked req Request, JWTAuthError e) Response
-> Middleware h req (JWTAuth m e t : req)
jwtAuth = forall e t (h :: * -> * -> *) (m :: * -> *) (req :: [*]).
(Get h (JWTAuth' 'Required "Bearer" m e t) Request,
ArrowChoice h) =>
JWTAuth' 'Required "Bearer" m e t
-> h (Linked req Request, JWTAuthError e) Response
-> Middleware h req (JWTAuth' 'Required "Bearer" m e t : req)
forall (s :: Symbol) e t (h :: * -> * -> *) (m :: * -> *)
(req :: [*]).
(Get h (JWTAuth' 'Required s m e t) Request, ArrowChoice h) =>
JWTAuth' 'Required s m e t
-> h (Linked req Request, JWTAuthError e) Response
-> Middleware h req (JWTAuth' 'Required s m e t : req)
jwtAuth' @"Bearer"
optionalJWTAuth ::
( WebGear.Core.Trait.Get h (JWTAuth' Optional "Bearer" m e t) Request
, ArrowChoice h
) =>
JWTAuth' Optional "Bearer" m e t ->
Middleware h req (JWTAuth' Optional "Bearer" m e t : req)
optionalJWTAuth :: JWTAuth' 'Optional "Bearer" m e t
-> Middleware h req (JWTAuth' 'Optional "Bearer" m e t : req)
optionalJWTAuth = forall e t (h :: * -> * -> *) (m :: * -> *) (req :: [*]).
(Get h (JWTAuth' 'Optional "Bearer" m e t) Request,
ArrowChoice h) =>
JWTAuth' 'Optional "Bearer" m e t
-> Middleware h req (JWTAuth' 'Optional "Bearer" m e t : req)
forall (s :: Symbol) e t (h :: * -> * -> *) (m :: * -> *)
(req :: [*]).
(Get h (JWTAuth' 'Optional s m e t) Request, ArrowChoice h) =>
JWTAuth' 'Optional s m e t
-> Middleware h req (JWTAuth' 'Optional s m e t : req)
optionalJWTAuth' @"Bearer"
jwtAuthMiddleware ::
forall s e t x h m req.
( WebGear.Core.Trait.Get h (JWTAuth' x s m e t) Request
, ArrowChoice h
) =>
JWTAuth' x s m e t ->
h (WebGear.Core.Trait.Linked req Request, WebGear.Core.Trait.Absence (JWTAuth' x s m e t) Request) Response ->
Middleware h req (JWTAuth' x s m e t : req)
jwtAuthMiddleware :: JWTAuth' x s m e t
-> h (Linked req Request, Absence (JWTAuth' x s m e t) Request)
Response
-> Middleware h req (JWTAuth' x s m e t : req)
jwtAuthMiddleware JWTAuth' x s m e t
authCfg h (Linked req Request, Absence (JWTAuth' x s m e t) Request)
Response
errorHandler RequestHandler h (JWTAuth' x s m e t : req)
nextHandler =
proc Linked req Request
request -> do
Either
(Absence (JWTAuth' x s m e t) Request)
(Linked (JWTAuth' x s m e t : req) Request)
result <- JWTAuth' x s m e t
-> h (Linked req Request)
(Either
(Absence (JWTAuth' x s m e t) Request)
(Linked (JWTAuth' x s m e t : req) Request))
forall t (ts :: [*]) (h :: * -> * -> *) a.
Get h t a =>
t -> h (Linked ts a) (Either (Absence t a) (Linked (t : ts) a))
WebGear.Core.Trait.probe JWTAuth' x s m e t
authCfg -< Linked req Request
request
case Either
(Absence (JWTAuth' x s m e t) Request)
(Linked (JWTAuth' x s m e t : req) Request)
result of
Left Absence (JWTAuth' x s m e t) Request
err -> h (Linked req Request, Absence (JWTAuth' x s m e t) Request)
Response
errorHandler -< (Linked req Request
request, Absence (JWTAuth' x s m e t) Request
err)
Right Linked (JWTAuth' x s m e t : req) Request
val -> RequestHandler h (JWTAuth' x s m e t : req)
nextHandler -< Linked (JWTAuth' x s m e t : req) Request
val
jwtAuth' ::
forall s e t h m req.
( WebGear.Core.Trait.Get h (JWTAuth' Required s m e t) Request
, ArrowChoice h
) =>
JWTAuth' Required s m e t ->
h (WebGear.Core.Trait.Linked req Request, JWTAuthError e) Response ->
Middleware h req (JWTAuth' Required s m e t : req)
jwtAuth' :: JWTAuth' 'Required s m e t
-> h (Linked req Request, JWTAuthError e) Response
-> Middleware h req (JWTAuth' 'Required s m e t : req)
jwtAuth' = JWTAuth' 'Required s m e t
-> h (Linked req Request, JWTAuthError e) Response
-> Middleware h req (JWTAuth' 'Required s m e t : req)
forall (s :: Symbol) e t (x :: Existence) (h :: * -> * -> *)
(m :: * -> *) (req :: [*]).
(Get h (JWTAuth' x s m e t) Request, ArrowChoice h) =>
JWTAuth' x s m e t
-> h (Linked req Request, Absence (JWTAuth' x s m e t) Request)
Response
-> Middleware h req (JWTAuth' x s m e t : req)
jwtAuthMiddleware
optionalJWTAuth' ::
forall s e t h m req.
( WebGear.Core.Trait.Get h (JWTAuth' Optional s m e t) Request
, ArrowChoice h
) =>
JWTAuth' Optional s m e t ->
Middleware h req (JWTAuth' Optional s m e t : req)
optionalJWTAuth' :: JWTAuth' 'Optional s m e t
-> Middleware h req (JWTAuth' 'Optional s m e t : req)
optionalJWTAuth' JWTAuth' 'Optional s m e t
cfg = JWTAuth' 'Optional s m e t
-> h (Linked req Request,
Absence (JWTAuth' 'Optional s m e t) Request)
Response
-> Middleware h req (JWTAuth' 'Optional s m e t : req)
forall (s :: Symbol) e t (x :: Existence) (h :: * -> * -> *)
(m :: * -> *) (req :: [*]).
(Get h (JWTAuth' x s m e t) Request, ArrowChoice h) =>
JWTAuth' x s m e t
-> h (Linked req Request, Absence (JWTAuth' x s m e t) Request)
Response
-> Middleware h req (JWTAuth' x s m e t : req)
jwtAuthMiddleware JWTAuth' 'Optional s m e t
cfg (h (Linked req Request,
Absence (JWTAuth' 'Optional s m e t) Request)
Response
-> Middleware h req (JWTAuth' 'Optional s m e t : req))
-> h (Linked req Request,
Absence (JWTAuth' 'Optional s m e t) Request)
Response
-> Middleware h req (JWTAuth' 'Optional s m e t : req)
forall a b. (a -> b) -> a -> b
$ ((Linked req Request, Void) -> Response)
-> h (Linked req Request, Void) Response
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr (Void -> Response
forall a. Void -> a
absurd (Void -> Response)
-> ((Linked req Request, Void) -> Void)
-> (Linked req Request, Void)
-> Response
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Linked req Request, Void) -> Void
forall a b. (a, b) -> b
snd)