-- verify that client is allowed to access server
authorize :: IORef Sessions -> IptAdminConfig -> IptAdmin Response -> IptAdminAuth Response
authorize sessionsIORef config requestHandler =
    -- allow 'static' dir without authorisation
    (dir "static" Static.pageHandlers) `mplus` do
        clientIdE <- getDataFn $ lookCookieValue "sessionId"
        isAuthorised <- case clientIdE of
            Left _ ->
                -- liftIO $ syslog Notice $ "sessionId cookie get error: " ++ show e
                return False
            Right a -> do
                sessions <- liftIO $ readIORef sessionsIORef
                let session = Data.Map.lookup a sessions
                case session of
                    Nothing ->
                        -- liftIO $ syslog Notice $ "session was not found: " ++ a
                        -- liftIO $ syslog Notice $ "sessions: " ++ show sessions
                        return False
                    Just _ -> return True
        if isAuthorised
            then
                -- Run IptAdmin monad with state
                mapServerPartT (addStateToStack (either undefined id clientIdE, sessionsIORef, config)) requestHandler
            else
                msum [ dir "login" $ LoginPage.pageHandlers (IptAdmin.AccessControl.authenticate $ cPamName config)
                                                            sessionsIORef
                     , redir "/login"
                     ]
    where
        addStateToStack :: (Monad m) => MainState
                           -> UnWebT (ErrorT String (StateT MainState m)) a
                           -> UnWebT (ErrorT String m) a
        addStateToStack mainState statefulAction =
            mapErrorT (addStateToStack' mainState) statefulAction

        addStateToStack' :: (Monad m) => MainState
                         -> StateT MainState m (Either String a)
                         -> m (Either String a)
        addStateToStack' mainState statefulAction =
            evalStateT statefulAction mainState
authorize :: IORef Sessions -> IptAdminConfig -> IptAdmin Response -> IptAdminAuth Response
authorize sessionsIORef config requestHandler =
    -- allow 'static' dir without authorisation
    (dir "static" Static.pageHandlers) `mplus` do
        clientIdE <- getDataFn $ lookCookieValue "sessionId"
        isAuthorised <- case clientIdE of
            Left _ ->
                -- liftIO $ syslog Notice $ "sessionId cookie get error: " ++ show e
                return False
            Right a -> do
                sessions <- liftIO $ readIORef sessionsIORef
                let session = Data.Map.lookup a sessions
                case session of
                    Nothing ->
                        -- liftIO $ syslog Notice $ "session was not found: " ++ a
                        -- liftIO $ syslog Notice $ "sessions: " ++ show sessions
                        return False
                    Just _ -> return True
        if isAuthorised
            then
                -- Run IptAdmin monad with state
                mapServerPartT (addStateToStack (either undefined id clientIdE, sessionsIORef, config)) requestHandler
            else
                msum [ dir "login" $ LoginPage.pageHandlers (IptAdmin.AccessControl.authenticate $ cPamName config)
                                                            sessionsIORef
                     , redir "/login"
                     ]
    where
        addStateToStack :: (Monad m) => MainState
                           -> UnWebT (ErrorT String (StateT MainState m)) a
                           -> UnWebT (ErrorT String m) a
        addStateToStack mainState statefulAction =
            mapErrorT (addStateToStack' mainState) statefulAction

        addStateToStack' :: (Monad m) => MainState
                         -> StateT MainState m (Either String a)
                         -> m (Either String a)
        addStateToStack' mainState statefulAction =
            evalStateT statefulAction mainState
authorize sessionsIORef config requestHandler =
    -- allow 'static' dir without authorisation
    (dir "static" Static.pageHandlers) `mplus` do
        clientIdE <- getDataFn $ lookCookieValue "sessionId"
        isAuthorised <- case clientIdE of
            Left _ ->
                -- liftIO $ syslog Notice $ "sessionId cookie get error: " ++ show e
                return False
            Right a -> do
                sessions <- liftIO $ readIORef sessionsIORef
                let session = Data.Map.lookup a sessions
                case session of
                    Nothing ->
                        -- liftIO $ syslog Notice $ "session was not found: " ++ a
                        -- liftIO $ syslog Notice $ "sessions: " ++ show sessions
                        return False
                    Just _ -> return True
        if isAuthorised
            then
                -- Run IptAdmin monad with state
                mapServerPartT (addStateToStack (either undefined id clientIdE, sessionsIORef, config)) requestHandler
            else
                msum [ dir "login" $ LoginPage.pageHandlers (IptAdmin.AccessControl.authenticate $ cPamName config)
                                                            sessionsIORef
                     , redir "/login"
                     ]
    where
        addStateToStack :: (Monad m) => MainState
                           -> UnWebT (ErrorT String (StateT MainState m)) a
                           -> UnWebT (ErrorT String m) a
        addStateToStack mainState statefulAction =
            mapErrorT (addStateToStack' mainState) statefulAction

        addStateToStack' :: (Monad m) => MainState
                         -> StateT MainState m (Either String a)
                         -> m (Either String a)
        addStateToStack' mainState statefulAction =
            evalStateT statefulAction mainState