iptadmin-1.2.0: src/IptAdmin/LoginPage.hs
{-# LANGUAGE OverloadedStrings #-}
module IptAdmin.LoginPage where
import Control.Monad.Error
import Data.IORef
import Data.Map (insert)
import Data.Monoid
import Data.String
import Data.Time
import Happstack.Server.SimpleHTTP hiding (Session)
import Template
import IptAdmin.Render
import IptAdmin.System
import IptAdmin.Types
import IptAdmin.Utils
import System.Random
import Text.Blaze
import qualified Text.Blaze.Html5 as H
import qualified Text.Blaze.Html5.Attributes as A
import Text.Blaze.Renderer.String (renderHtml)
pageHandlers :: (String -> String -> IO (Maybe String)) -> IORef Sessions -> IptAdminAuth Response
pageHandlers authenticate sessionsIORef =
msum [ methodSP GET pageHandlerGet
, methodSP POST (pageHandlerPost authenticate sessionsIORef)
]
pageHandlerGet :: IptAdminAuth Response
pageHandlerGet =
return $ buildResponse $ Template.htmlWrapper $ renderHtml $ do
title
loginForm "" Nothing
pageHandlerPost :: (String -> String -> IO (Maybe String)) -> IORef Sessions -> IptAdminAuth Response
pageHandlerPost authenticate sessionsIORef = do
login <- getInputString "login"
password <- getInputString "password"
when (length login > 30) $
throwError "Login is too long"
when (length password > 50) $
throwError "Password is too long"
-- Первый этап проверки - проверка пользователя unix
authRes <- liftIO $ authenticate login password
case authRes of
Just errorMsg ->
return $ buildResponse $ htmlWrapper $ renderHtml $ do
title
loginForm login $ Just errorMsg
Nothing -> do
-- 1. Генерируем рандомный id
sessionId <- liftIO $ replicateM 50 $ randomRIO ('a', 'z')
-- 2. Добавляем установку кукиса в заголовок
-- 2.1. Собариаем cookie
let sessionIdCookie = mkCookie "sessionId" sessionId
addCookie (MaxAge $ 60 * 60 * 24 * 365 * 10) sessionIdCookie
-- 3. Обновляем состояние
curTime <- liftIO getCurrentTime
iptables <- getIptables
_ <- liftIO $ atomicModifyIORef sessionsIORef
(\ m -> ( insert sessionId (Session curTime
Nothing
iptables
) m
, ()
)
)
-- 4. Редиректим на /show
redir "/show"
loginForm :: String -> Maybe String -> Html
loginForm login mesMay =
H.div ! A.class_ "loginForm" $ do
H.div ! A.class_ "loginForm2" $
H.form ! A.id "loginForm" ! A.method "post" $ do
H.table ! A.class_ "loginForm" $ do
H.tr $ do
H.td ! A.class_ "loginForm" $
H.span ! A.class_ "loginForm" $ "login"
H.td ! A.class_ "loginForm" $
H.input ! A.type_ "text" ! A.name "login" ! A.value (fromString login) ! A.maxlength "30"
H.tr $ do
H.td ! A.class_ "loginForm" $
H.span ! A.class_ "loginForm" $ "password"
H.td ! A.class_ "loginForm" $
H.input ! A.type_ "password" ! A.name "password" ! A.value "" ! A.maxlength "50"
H.input ! A.id "submit" ! A.name "submit" ! A.type_ "submit" ! A.value "Sign in"
maybe mempty fromString mesMay