Portability | non-portable |
---|---|
Stability | experimental |
Maintainer | mail@n-sch.de |
Happstack.Auth offers an easy way to implement user authentication for Happstack web applications. It uses Happstack.State as database back-end and SHA512 for password encryption. Session safety is ensured by a HTTP header fingerprint (client ip & user-agent) and a configurable session timeout.
To use this module, add the AuthState
to your state dependencies, for
example:
import Happstack.Auth instance Component MyState where type Dependencies MyState = AuthState :+: End initialValue = ...
One of the first things in your response monad should be updateTimeout
to
make sure session timeouts are updated correctly.
- register :: (MonadIO m, FilterMonad Response m, ServerMonad m) => Minutes -> Username -> Password -> m a -> m a -> m a
- changePassword :: MonadIO m => Username -> Password -> Password -> m Bool
- setPassword :: MonadIO m => Username -> Password -> m Bool
- updateTimeout :: (MonadIO m, FilterMonad Response m, MonadPlus m, ServerMonad m) => Minutes -> m ()
- performLogin :: (MonadIO m, FilterMonad Response m, ServerMonad m) => Minutes -> User -> m a -> m a
- performLogout :: (MonadIO m, FilterMonad Response m) => SessionKey -> m ()
- loginHandler :: (MonadIO m, FilterMonad Response m, MonadPlus m, ServerMonad m) => Minutes -> Maybe String -> Maybe String -> m a -> (Maybe Username -> Maybe Password -> m a) -> m a
- logoutHandler :: (ServerMonad m, MonadPlus m, MonadIO m, FilterMonad Response m) => m a -> m a
- withSession :: MonadIO m => (SessionData -> ServerPartT m a) -> ServerPartT m a -> ServerPartT m a
- loginGate :: MonadIO m => ServerPartT m a -> ServerPartT m a -> ServerPartT m a
- getSessionData :: (MonadIO m, MonadPlus m, ServerMonad m) => m (Maybe SessionData)
- getSessionKey :: (MonadIO m, MonadPlus m, ServerMonad m) => m (Maybe SessionKey)
- clearSessionCookie :: FilterMonad Response m => m ()
- addUser :: MonadIO m => Username -> Password -> m (Maybe User)
- getUser :: MonadIO m => Username -> m (Maybe User)
- getUserById :: MonadIO m => UserId -> m (Maybe User)
- delUser :: MonadIO m => Username -> m ()
- updateUser :: MonadIO m => User -> m ()
- authUser :: MonadIO m => Username -> Password -> m (Maybe User)
- isUser :: MonadIO m => Username -> m Bool
- listUsers :: MonadIO m => m [Username]
- numUsers :: MonadIO m => m Int
- askUsers :: MonadIO m => m UserDB
- newSession :: MonadIO m => SessionData -> m SessionKey
- getSession :: MonadIO m => SessionKey -> m (Maybe SessionData)
- setSession :: MonadIO m => SessionKey -> SessionData -> m ()
- delSession :: MonadIO m => SessionKey -> m ()
- clearAllSessions :: MonadIO m => m ()
- numSessions :: MonadIO m => m Int
- getSessions :: MonadIO m => m (Sessions SessionData)
- clearExpiredSessions :: MonadIO m => m ()
- data User
- userName :: User -> Username
- userId :: User -> UserId
- type Username = String
- type Password = String
- data UserId
- data SessionData = SessionData {}
- data SessionKey
- type Minutes = Int
- data AuthState
- authProxy :: Proxy AuthState
High level functions
User registration
:: (MonadIO m, FilterMonad Response m, ServerMonad m) | |
=> Minutes | Session timeout |
-> Username | |
-> Password | |
-> m a | User exists response |
-> m a | Success response |
-> m a |
Register a new user
Session management
updateTimeout :: (MonadIO m, FilterMonad Response m, MonadPlus m, ServerMonad m) => Minutes -> m ()Source
Update the session timeout of logged in users. Add this to the top of your application route, for example:
appRoute :: ServerPart Response appRoute = updateTimeout 5 >> msum [ {- your routing here -} ]
:: (MonadIO m, FilterMonad Response m, ServerMonad m) | |
=> Minutes | Session timeout |
-> User | |
-> m a | Run with modified headers, including the new session cookie |
-> m a |
performLogout :: (MonadIO m, FilterMonad Response m) => SessionKey -> m ()Source
:: (MonadIO m, FilterMonad Response m, MonadPlus m, ServerMonad m) | |
=> Minutes | Session timeout |
-> Maybe String | POST field to look for username (default: "username") |
-> Maybe String | POST field to look for password (default: "password") |
-> m a | Success response |
-> (Maybe Username -> Maybe Password -> m a) | Fail response. Arguments: Post data |
-> m a |
Handles data from a login form to log the user in.
:: (ServerMonad m, MonadPlus m, MonadIO m, FilterMonad Response m) | |
=> m a | Response after logout |
-> m a |
:: MonadIO m | |
=> (SessionData -> ServerPartT m a) | Logged in response |
-> ServerPartT m a | Not logged in response |
-> ServerPartT m a |
Run a ServerPartT
with the SessionData
of the currently logged in user
(if available)
:: MonadIO m | |
=> ServerPartT m a | Logged in |
-> ServerPartT m a | Not registered |
-> ServerPartT m a |
Require a login
getSessionData :: (MonadIO m, MonadPlus m, ServerMonad m) => m (Maybe SessionData)Source
Get the SessionData
of the currently logged in user
getSessionKey :: (MonadIO m, MonadPlus m, ServerMonad m) => m (Maybe SessionKey)Source
Get the identifier for the current session
clearSessionCookie :: FilterMonad Response m => m ()Source
Basic functions
Users
updateUser :: MonadIO m => User -> m ()Source
Update (replace) a user
askUsers :: MonadIO m => m UserDBSource
Warning: This UserDB
uses the internal types from
Happstack.Auth.Data.Internal
Sessions
newSession :: MonadIO m => SessionData -> m SessionKeySource
getSession :: MonadIO m => SessionKey -> m (Maybe SessionData)Source
setSession :: MonadIO m => SessionKey -> SessionData -> m ()Source
delSession :: MonadIO m => SessionKey -> m ()Source
clearAllSessions :: MonadIO m => m ()Source
numSessions :: MonadIO m => m IntSource
getSessions :: MonadIO m => m (Sessions SessionData)Source
Warning: This Sessions
uses the internal types from
Happstack.Auth.Data.Internal
clearExpiredSessions :: MonadIO m => m ()Source
Data types
These data types collide with the data definitions used internaly in Happstack.Auth.Data.Internal. However, if you need both modules you might want to import the Data module qualified:
import Happstack.Auth import qualified Happstack.Auth.Data.Internal as AuthD
Abstract user identification
data SessionData Source
SessionData | |
|
data SessionKey Source
Abstract session identification
Add this to your Dependency-List of your application state