-- | Plugin to handle authorization. Just a sketch for now.
module Mig.Extra.Plugin.Auth (
  WithAuth (..),
  withHeaderAuth,
) where

import Control.Monad.IO.Class
import Mig.Core

-- | Authorization plugin interface
data WithAuth m token resp = WithAuth
  { forall (m :: * -> *) token resp.
WithAuth m token resp -> token -> m Bool
isValid :: token -> m Bool
  -- ^ check that token is valid
  , forall (m :: * -> *) token resp.
WithAuth m token resp -> token -> m resp
authFail :: token -> m resp
  -- ^ how to respond on failure
  }

-- | Creates plugin that applies check of auth credentials which are passed as HTTP Header with name auth.
withHeaderAuth :: forall m token resp. (IsResp resp, MonadIO m) => WithAuth m token resp -> Header "auth" token -> Plugin m
withHeaderAuth :: forall (m :: * -> *) token resp.
(IsResp resp, MonadIO m) =>
WithAuth m token resp -> Header "auth" token -> Plugin m
withHeaderAuth WithAuth m token resp
env (Header token
token) = forall (m :: * -> *).
MonadIO m =>
(m (Maybe Response) -> m (Maybe Response)) -> Plugin m
processResponse forall a b. (a -> b) -> a -> b
$ \m (Maybe Response)
getResp -> do
  Bool
isOk <- WithAuth m token resp
env.isValid token
token
  if Bool
isOk
    then m (Maybe Response)
getResp
    else forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IsResp a => a -> Response
toResponse forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WithAuth m token resp
env.authFail token
token