{-# OPTIONS_GHC -Wno-orphans #-}

-- | Swagger implementation of 'JWTAuth'' trait.
module WebGear.Swagger.Trait.Auth.JWT where

import Data.String (fromString)
import Data.Swagger
import Data.Typeable (Proxy (..))
import GHC.TypeLits (KnownSymbol, symbolVal)
import WebGear.Core.Request (Request)
import WebGear.Core.Trait (Absence, Attribute, Get (..), With)
import WebGear.Core.Trait.Auth.JWT (JWTAuth' (..))
import WebGear.Swagger.Handler (SwaggerHandler (..))
import WebGear.Swagger.Trait.Auth (addSecurityScheme)

instance (KnownSymbol scheme) => Get (SwaggerHandler m) (JWTAuth' x scheme m e a) where
  {-# INLINE getTrait #-}
  getTrait ::
    JWTAuth' x scheme m e a ->
    SwaggerHandler m (Request `With` ts) (Either (Absence (JWTAuth' x scheme m e a)) (Attribute (JWTAuth' x scheme m e a) Request))
  getTrait :: forall (ts :: [*]).
JWTAuth' x scheme m e a
-> SwaggerHandler
     m
     (With Request ts)
     (Either
        (Absence (JWTAuth' x scheme m e a))
        (Attribute (JWTAuth' x scheme m e a) Request))
getTrait JWTAuth' x scheme m e a
_ =
    let schemeName :: Text
schemeName = String -> Text
forall a. IsString a => String -> a
fromString (Proxy scheme -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @scheme))
        -- Swagger 2.0 does not support JWT: https://stackoverflow.com/a/32995636
        scheme :: SecurityScheme
scheme =
          SecurityScheme
            { _securitySchemeType :: SecuritySchemeType
_securitySchemeType =
                ApiKeyParams -> SecuritySchemeType
SecuritySchemeApiKey
                  ( ApiKeyParams
                      { _apiKeyName :: Text
_apiKeyName = Text
"JWT"
                      , _apiKeyIn :: ApiKeyLocation
_apiKeyIn = ApiKeyLocation
ApiKeyHeader
                      }
                  )
            , _securitySchemeDescription :: Maybe Text
_securitySchemeDescription = Text -> Maybe Text
forall a. a -> Maybe a
Just (Text
"Enter the token with the `" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
schemeName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
": ` prefix")
            }
     in (Swagger -> State Documentation Swagger)
-> SwaggerHandler
     m
     (With Request ts)
     (Either
        (Absence (JWTAuth' x scheme m e a))
        (Attribute (JWTAuth' x scheme m e a) Request))
forall {k} {k1} {k2} (m :: k) (a :: k1) (b :: k2).
(Swagger -> State Documentation Swagger) -> SwaggerHandler m a b
SwaggerHandler ((Swagger -> State Documentation Swagger)
 -> SwaggerHandler
      m
      (With Request ts)
      (Either
         (Absence (JWTAuth' x scheme m e a))
         (Attribute (JWTAuth' x scheme m e a) Request)))
-> (Swagger -> State Documentation Swagger)
-> SwaggerHandler
     m
     (With Request ts)
     (Either
        (Absence (JWTAuth' x scheme m e a))
        (Attribute (JWTAuth' x scheme m e a) Request))
forall a b. (a -> b) -> a -> b
$ Text -> SecurityScheme -> Swagger -> State Documentation Swagger
forall (m :: * -> *).
MonadState Documentation m =>
Text -> SecurityScheme -> Swagger -> m Swagger
addSecurityScheme Text
schemeName SecurityScheme
scheme