Haskell Servant passes user data to auth handler

I use a user monad (with a reader) to easily pass data, such as a database pool, to my handlers (before using the user monad, which I used to pass as an argument to fn).

Here is how I defined my regular monad:

newtype Controller a = Controller
    { runController :: ReaderT ServerEnvironment Handler a
    } deriving ( Functor, Applicative, Monad, MonadReader ServerEnvironment, 
                 MonadError ServantErr, MonadIO )

This ServerEnvironmentis the usual data type that I use to transfer my data.

The problem is that for mine AuthHandlerI need to specifically use the function with:

r -> Handler usr

as an authentication handler, I cannot use my custom handler, which will be:

r -> Controller usr

and I also have no way to pass mine ConnectionPool, because the signature cannot be:

ConnPool -> r -> Handler usr

, servant IO?

+4
1

AuthHandler, , ! , main, .., :

type API = 
  ... :<|> (AuthProtect "myProtection" :> ...) :<|> ...

type instance AuthServerData (AuthProtect "myProtection") = User

server :: ServerEnvironment -> Server API
server env = ...

setupEnv :: IO ServerEnvironment
setupEnv = ..

-- This is essentially a 'Controller'.
authenticate :: ServerEnvironment -> Handler User
authenticate conn = ...

main :: IO ()
main = do
  env <- setupEnv
  -- Now, because we have access to the env, we can turn our
  -- 'authenticate' into the right type before putting it
  -- in the context
  let ctx = authenticate env :. EmptyContext
  run 8080 $ serveWithContext myAPI (server conn) ctx
+7

Source: https://habr.com/ru/post/1664830/


All Articles