Skip to content
This repository was archived by the owner on Oct 29, 2021. It is now read-only.

Use context for error #168

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions servant-auth-client/test/Servant/Auth/ClientSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ mgr = unsafePerformIO $ newManager defaultManagerSettings
app :: Application
app = serveWithContext api ctx server
where
ctx = cookieCfg :. jwtCfg :. EmptyContext
ctx = authErrorHandler401 :. cookieCfg :. jwtCfg :. EmptyContext

jwtCfg :: JWTSettings
jwtCfg = defaultJWTSettings theKey
Expand All @@ -125,9 +125,8 @@ cookieCfg = defaultCookieSettings
server :: Server API
server = getInt
where
getInt :: AuthResult User -> Handler Int
getInt (Authenticated u) = return . length $ name u
getInt _ = throwAll err401
getInt :: User -> Handler Int
getInt = return . length . name


-- }}}
Expand Down
8 changes: 7 additions & 1 deletion servant-auth-server/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [PVP Versioning](https://pvp.haskell.org/).

## [Unreleased]

## Changed

- #168 Create AuthErrorHandler for using context for errors (now request
handlers don't need to consider authentication failures). This also removes
`throwAll`, which is no longer necessary [@jkarni]

## [0.4.5.1] - 2020-02-06

## Changed
Expand All @@ -16,7 +22,7 @@ and this project adheres to [PVP Versioning](https://pvp.haskell.org/).

## Changed
- #144 servant 0.16 support and drop GHC 7.10 support [@domenkozar]
- #148 removed unused constaint in HasServer instance for Auth
- #148 removed unused constaint in HasServer instance for Auth
- #154 GHC 8.8 support [@phadej]

### Added
Expand Down
42 changes: 20 additions & 22 deletions servant-auth-server/README.lhs
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,11 @@ data Auth (auths :: [*]) val

What `Auth [Auth1, Auth2] Something :> API` means is that `API` is protected by
*either* `Auth1` *or* `Auth2`, and the result of authentication will be of type
`AuthResult Something`, where :
`Something` (which is what your handlers will see).

~~~ haskell
data AuthResult val
= BadPassword
| NoSuchUser
| Authenticated val
| Indefinite
~~~

Your handlers will get a value of type `AuthResult Something`, and can decide
what to do with it.
If:


~~~ haskell

Expand All @@ -79,12 +72,10 @@ type Protected


-- | 'Protected' will be protected by 'auths', which we still have to specify.
protected :: Servant.Auth.Server.AuthResult User -> Server Protected
-- If we get an "Authenticated v", we can trust the information in v, since
-- it was signed by a key we trust.
protected (Servant.Auth.Server.Authenticated user) = return (name user) :<|> return (email user)
-- Otherwise, we return a 401.
protected _ = throwAll err401
protected :: User -> Server Protected
-- We can trust that the User is accurate, since the information was signed by
-- a key we trust
protected user = return (name user) :<|> return (email user)

type Unprotected =
"login"
Expand All @@ -105,7 +96,7 @@ server cs jwts = protected :<|> unprotected cs jwts
~~~

The code is common to all authentications. In order to pick one or more specific
authentication methods, all we need to do is provide the expect configuration
authentication methods, we need to do is provide the expected configuration
parameters.

## API tokens
Expand All @@ -121,11 +112,18 @@ mainWithJWT = do
-- We generate the key for signing tokens. This would generally be persisted,
-- and kept safely
myKey <- generateKey
-- Adding some configurations. All authentications require CookieSettings to
-- be in the context.
-- Adding some configurations. This is specific to JWT
let jwtCfg = defaultJWTSettings myKey
cfg = defaultCookieSettings :. jwtCfg :. EmptyContext
--- Here we actually make concrete
-- All authentications also require an AuthErrorHandler to be in the context.
-- That determines how to deal with authentications that failed (because
-- secrets were not present, or because they were incorrect, or because they don't
-- work for the specific type). In this case, we user authErrorHandler401,
-- which returns 401 for no secrets, 403 otherwise
authErrHandler = authErrorHandler401
-- Here we put everything inside the Servant Context. For technical reasons,
-- all authentications require CookieSettings to be in the context
cfg = defaultCookieSettings :. authErrHandler :. jwtCfg :. EmptyContext
-- Here we actually make concrete the auth type
api = Proxy :: Proxy (API '[JWT])
_ <- forkIO $ run 7249 $ serveWithContext api cfg (server defaultCookieSettings jwtCfg)

Expand Down Expand Up @@ -213,7 +211,7 @@ mainWithCookies = do
-- Adding some configurations. 'Cookie' requires, in addition to
-- CookieSettings, JWTSettings (for signing), so everything is just as before
let jwtCfg = defaultJWTSettings myKey
cfg = defaultCookieSettings :. jwtCfg :. EmptyContext
cfg = defaultCookieSettings :. authErrorHandler401 :. jwtCfg :. EmptyContext
--- Here is the actual change
api = Proxy :: Proxy (API '[Cookie])
run 7249 $ serveWithContext api cfg (server defaultCookieSettings jwtCfg)
Expand Down
4 changes: 2 additions & 2 deletions servant-auth-server/servant-auth-server.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ library
, entropy >= 0.4.1.3 && < 0.5
, http-types >= 0.12.2 && < 0.13
, jose >= 0.7.0.0 && < 0.9
, lens >= 4.16.1 && < 4.19
, lens >= 4.16.1 && < 4.20
, memory >= 0.14.16 && < 0.16
, monad-time >= 0.3.1.0 && < 0.4
, mtl >= 2.2.2 && < 2.3
, network-uri >= 2.6 && < 2.7
, servant >= 0.13 && < 0.18
, servant-auth == 0.3.*
, servant-server >= 0.13 && < 0.18
Expand All @@ -67,7 +68,6 @@ library
Servant.Auth.Server.Internal.Cookie
Servant.Auth.Server.Internal.FormLogin
Servant.Auth.Server.Internal.JWT
Servant.Auth.Server.Internal.ThrowAll
Servant.Auth.Server.Internal.Types
Servant.Auth.Server.SetCookieOrphan
default-language: Haskell2010
Expand Down
Loading