module Snap.Snaplet.Auth.AuthManager
  ( 
    AuthManager(..)
    
    , IAuthBackend(..)
    
    , buildAuthUser
  ) where
import           Data.ByteString (ByteString)
import           Data.Text (Text)
import           Data.Time
import           Web.ClientSession
import           Snap.Snaplet
import           Snap.Snaplet.Session
import           Snap.Snaplet.Auth.Types
buildAuthUser :: IAuthBackend r =>
                 r            
              -> Text         
              -> ByteString   
              -> IO (Either AuthFailure AuthUser)
buildAuthUser r unm pass = do
  now <- getCurrentTime
  let au = defAuthUser {
              userLogin     = unm
            , userPassword  = Nothing
            , userCreatedAt = Just now
            , userUpdatedAt = Just now
            }
  au' <- setPassword au pass
  save r au'
class IAuthBackend r where
  
  
  
  save                  :: r -> AuthUser -> IO (Either AuthFailure AuthUser)
  lookupByUserId        :: r -> UserId   -> IO (Maybe AuthUser)
  lookupByLogin         :: r -> Text     -> IO (Maybe AuthUser)
  lookupByEmail         :: r -> Text     -> IO (Maybe AuthUser)
  lookupByRememberToken :: r -> Text     -> IO (Maybe AuthUser)
  destroy               :: r -> AuthUser -> IO ()
data AuthManager b = forall r. IAuthBackend r => AuthManager {
      backend               :: r
        
    , session               :: SnapletLens b SessionManager
        
    , activeUser            :: Maybe AuthUser
        
    , minPasswdLen          :: Int
        
    , rememberCookieName    :: ByteString
        
    , rememberCookieDomain  :: Maybe ByteString
        
    , rememberPeriod        :: Maybe Int
        
    , siteKey               :: Key
        
    , lockout               :: Maybe (Int, NominalDiffTime)
        
    , randomNumberGenerator :: RNG
        
    }
instance IAuthBackend (AuthManager b) where
    save AuthManager{..} u = save backend u
    lookupByUserId AuthManager{..} u = lookupByUserId backend u
    lookupByLogin AuthManager{..} u = lookupByLogin backend u
    lookupByEmail AuthManager{..}  u = lookupByEmail backend u
    lookupByRememberToken AuthManager{..} u = lookupByRememberToken backend u
    destroy AuthManager{..} u = destroy backend u