biscuit-servant: Servant support for the Biscuit security token

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]

Please see the README on GitHub at https://github.com/divarvel/biscuit-haskell#readme


[Skip to Readme]

Properties

Versions 0.1.1.0, 0.2.0.0, 0.2.0.0, 0.2.0.1, 0.2.1.0, 0.3.0.0, 0.3.0.1, 0.4.0.0
Change log ChangeLog.md
Dependencies base (>=4.7 && <5), biscuit-haskell (>=0.2 && <0.3), bytestring (>=0.10 && <0.11), mtl (>=2.2 && <2.3), servant-server (>=0.18 && <0.19), text (>=1.2 && <1.3), wai (>=3.2 && <3.3) [details]
License BSD-3-Clause
Copyright 2021 Clément Delafargue
Author Clément Delafargue
Maintainer clement@delafargue.name
Category Security
Home page https://github.com/divarvel/biscuit-haskell#readme
Bug tracker https://github.com/divarvel/biscuit-haskell/issues
Source repo head: git clone https://github.com/divarvel/biscuit-haskell
Uploaded by clementd at 2022-01-13T20:05:08Z

Modules

[Index] [Quick Jump]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Readme for biscuit-servant-0.2.0.0

[back to package description]

biscuit-servant 🤖 Hackage

Servant combinators to enable biscuit validation in your API trees

Usage

type AppM = WithAuthorizer Handler
type API = RequireBiscuit :> ProtectedAPI

-- /users
-- /users/:userId
type ProtectedAPI =
  "users" :> ( Get '[JSON] [User]
             :<|> Capture "userId" Int :> Get '[JSON] User
             )
app :: PublicKey -> Application
app pk = serveWithContext @API Proxy (genBiscuitCtx pk) server

server :: Server API
server biscuit =
  let handlers = userListHandler :<|> singleUserHandler
      handleAuth =
        handleBiscuit biscuit
        -- `allow if right("admin");` will be the first policy
        -- for every endpoint.
        -- Policies added by endpoints (or sub-apis) will tried after this one.
        . withPriorityAuthorizer [authorizer|allow if right("admin");|]
        -- `deny if true;` will be the last policy for every endpoint.
        -- Policies added by endpoints (or sub-apis) will tried before this one.
        . withFallbackAuthorizer [authorizer|deny if true;|]
  in hoistServer @ProtectedAPI Proxy handleAuth handlers

allUsers :: [User]
allUsers = [ User 1 "Danielle" "George"
           , User 2 "Albert" "Einstein"
           ]

userListHandler :: AppM [User]
userListHandler = withAuthorizer [authorizer|allow if right("userList")|]
  $ pure allUsers

singleUserHandler :: Int -> AppM User
singleUserHandler uid =
  withAuthorizer [authorizer|allow if right("getUser", ${uid})|] $
  let user = find (\user -> userId user == uid) allUsers
   in maybe (throwError error404) (\user -> pure user) user