{-# LANGUAGE TemplateHaskell, FlexibleInstances, FlexibleContexts,
MultiParamTypeClasses, DeriveDataTypeable, TypeFamilies,
TypeSynonymInstances #-}
module Session where
import qualified Data.Map as M
import Control.Monad.Reader
import Control.Monad.State (modify,put,get,gets)
import Data.Generics
import HAppS.State
import SessionState
import UserState
data TutorialState = TutorialState {
sessions :: Sessions SessionData,
users :: M.Map String User
} deriving (Show,Read,Typeable,Data)
instance Version TutorialState
$(deriveSerialize ''TutorialState)
instance Component TutorialState where
type Dependencies TutorialState = End
initialValue = TutorialState { sessions = (Sessions M.empty),
users = M.empty }
authUser :: String -> String -> Query TutorialState Bool
authUser name pass = do
users <- askUsers
return $ (Just pass) == liftM password (M.lookup name users)
askUsers :: Query TutorialState (M.Map String User)
askUsers = return . users =<< ask
askSessions :: Query TutorialState (Sessions SessionData)
askSessions = return . sessions =<< ask
modUsers :: ( M.Map String User -> M.Map String User ) -> Update TutorialState ()
modUsers f = modify (\s -> (TutorialState (sessions s) (f $ users s)))
modSessions :: (Sessions SessionData -> Sessions SessionData) -> Update TutorialState ()
modSessions f = modify (\s -> (TutorialState (f $ sessions s) (users s)))
isUser :: String -> Query TutorialState Bool
isUser name = liftM (M.member name) askUsers
addUser :: String -> User -> Update TutorialState ()
addUser name u = modUsers $ M.insert name u
listUsers :: Query TutorialState [String]
listUsers = liftM M.keys askUsers
newSession :: SessionData -> Update TutorialState SessionKey
newSession u = do
key <- getRandom
modSessions $ Sessions . (M.insert key u) . unsession
return key
delSession :: SessionKey -> Update TutorialState ()
delSession sk = modSessions $ Sessions . (M.delete sk) . unsession
getSession::SessionKey -> Query TutorialState (Maybe SessionData)
getSession key = liftM (M.lookup key . unsession) askSessions
numSessions :: Query TutorialState Int
numSessions = liftM (M.size . unsession) askSessions
-- define types which are upper case of methods below, eg AddUser, AuthUser...
-- these types work with HApppS query/update machinery
-- in ghci, try :i AddUser
$(mkMethods ''TutorialState
['addUser
,'authUser
,'isUser
, 'listUsers
, 'getSession
, 'newSession
, 'delSession
, 'numSessions]
)