Last active
January 19, 2016 17:31
-
-
Save codedmart/353f61fee2c728a313b7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE OverloadedStrings #-} | |
{-# LANGUAGE KindSignatures #-} | |
{-# LANGUAGE TypeOperators #-} | |
{-# LANGUAGE DataKinds #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE TypeFamilies #-} | |
{-# LANGUAGE DeriveDataTypeable #-} | |
{-# LANGUAGE PolyKinds #-} | |
{-# LANGUAGE ScopedTypeVariables #-} | |
{-# LANGUAGE FlexibleContexts #-} | |
module Lib.Auth where | |
import Data.Typeable (Typeable) | |
import Data.Text () | |
import Data.Text.Encoding (decodeUtf8) | |
import Data.Maybe (fromMaybe) | |
import Data.Aeson (encode) | |
import Network.Wai | |
import Network.HTTP.Types (hContentType) | |
import Servant | |
import Servant.Server.Internal.Router | |
import Servant.API.ContentTypes | |
import Servant.Server.Internal.RoutingApplication | |
import Data.String.Conversions (cs) | |
import Web.JWT (JWTClaimsSet(..)) | |
import Control.Monad.Trans.Maybe | |
import Control.Monad.Reader | |
import Web.Cookie | |
import Data.Map.Lazy (toList) | |
import Lib.ErrorResponse | |
import Lib.Config | |
import Lib.Utils | |
import Lib.JWT | |
data Auth (contentTypes :: [*]) a | |
deriving (Typeable) | |
instance (AllCTUnrender list a, HasServer sublayout, MonadReader AppConfig IO) | |
=> HasServer (Auth list a :> sublayout) where | |
type ServerT (Auth list a :> sublayout) m = | |
a -> ServerT sublayout m | |
route Proxy subserver = WithRequest $ \ request -> | |
route (Proxy :: Proxy sublayout) (addBodyCheck subserver (jwtCheck request)) | |
where | |
jwtCheck :: Request -> IO (RouteResult a) | |
jwtCheck request = do | |
AppConfig _ as <- ask | |
let mheader = lookup "cookie" (requestHeaders request) | |
mc = lookup apiCookie =<< fmap parseCookies mheader | |
contentTypeH = fromMaybe "application/json" $ lookup hContentType $ requestHeaders request | |
fromMaybeT (return $ FailFatal $ serverErr' Forbidden) $ do | |
jwt <- MaybeT $ return mc | |
clms <- MaybeT $ verifyClaims $ decodeUtf8 jwt | |
val <- MaybeT $ return $ lookup "user" $ toList $ unregisteredClaims clms | |
user <- MaybeT $ return $ handleCTypeH (Proxy :: Proxy list) (cs contentTypeH) (encode val) | |
case user of | |
Left e -> return $ FailFatal $ serverErr' Forbidden | |
Right v -> return $ Route v |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment