{-# LANGUAGE OverloadedStrings #-}
module Clckwrks.Authenticate.Route where
import Control.Applicative ((<$>))
import Clckwrks.Monad (ClckT(..), plugins)
import Clckwrks.Authenticate.URL (AuthURL(..))
import Clckwrks.Authenticate.Page.AuthModes (authModesPage)
import Clckwrks.Authenticate.Page.Login (loginPage)
import Clckwrks.Authenticate.Page.ChangePassword (changePasswordPanel)
import Clckwrks.Authenticate.Page.ResetPassword (resetPasswordPage)
import Clckwrks.Authenticate.Page.OpenIdRealm (openIdRealmPanel)
import Clckwrks.ProfileData.API (Role(..), requiresRole_)
import Clckwrks.URL (ClckURL)
import Control.Monad.State (get)
import Control.Monad.Trans (lift)
import qualified Data.Set as Set
import Happstack.Authenticate.Core (AuthenticateURL)
import Happstack.Server (Happstack, Response, ServerPartT)
import Web.Routes (RouteT(..), askRouteFn, runRouteT)
import Web.Plugins.Core (getPluginRouteFn, pluginName)
routeAuth :: (AuthenticateURL -> RouteT AuthenticateURL (ServerPartT IO) Response)
-> AuthURL
-> ClckT AuthURL (ServerPartT IO) Response
routeAuth routeAuthenticate u' =
do u <- checkAuth u'
p <- plugins <$> get
~(Just clckShowFn) <- getPluginRouteFn p "clck"
let withClckURL m = ClckT $ RouteT $ \_ -> unRouteT (unClckT m) clckShowFn
case u of
(Auth authenticateURL) ->
do p <- plugins <$> get
~(Just authShowFn) <- getPluginRouteFn p "authenticate"
lift $ runRouteT routeAuthenticate (authShowFn . Auth) authenticateURL
Login -> withClckURL loginPage
ResetPassword -> withClckURL resetPasswordPage
ChangePassword -> withClckURL changePasswordPanel
OpenIdRealm -> withClckURL openIdRealmPanel
AuthModes -> authModesPage u
checkAuth :: (Happstack m, Monad m) =>
AuthURL
-> ClckT AuthURL m AuthURL
checkAuth url =
do p <- plugins <$> get
~(Just clckShowFn) <- getPluginRouteFn p "clck"
let requiresRole = requiresRole_ clckShowFn
case url of
(Auth {}) -> pure url
Login -> pure url
ResetPassword -> pure url
AuthModes -> requiresRole (Set.fromList [Administrator]) url
ChangePassword -> requiresRole (Set.fromList [Visitor]) url
OpenIdRealm -> requiresRole (Set.fromList [Administrator]) url