module Servant.Server.Auth.Token.Restore(
getRestoreCode
, guardRestoreCode
, sendRestoreCode
) where
import Control.Monad
import Control.Monad.IO.Class
import Data.Time.Clock
import Database.Persist.Postgresql
import Servant.API.Auth.Token
import Servant.Server.Auth.Token.Config
import Servant.Server.Auth.Token.Model
import Servant.Server.Auth.Token.Monad
getRestoreCode :: IO RestoreCode -> UserImplId -> UTCTime -> SqlPersistT IO RestoreCode
getRestoreCode generator uid expire = do
t <- liftIO getCurrentTime
mcode <- selectFirst [UserRestoreUser ==. uid, UserRestoreExpire >. t] [Desc UserRestoreExpire]
case mcode of
Nothing -> do
code <- liftIO generator
void $ insert UserRestore {
userRestoreValue = code
, userRestoreUser = uid
, userRestoreExpire = expire
}
return code
Just code -> return $ userRestoreValue . entityVal $ code
guardRestoreCode :: UserImplId -> RestoreCode -> AuthHandler ()
guardRestoreCode uid code = do
t <- liftIO getCurrentTime
mcode <- runDB $ selectFirst [UserRestoreUser ==. uid, UserRestoreValue ==. code
, UserRestoreExpire >. t] [Desc UserRestoreExpire]
case mcode of
Nothing -> throw400 "Invalid restore code"
Just (Entity i rc) -> runDB $ replace i rc { userRestoreExpire = t }
sendRestoreCode :: RespUserInfo -> RestoreCode -> AuthHandler ()
sendRestoreCode user code = do
AuthConfig{..} <- getConfig
liftIO $ restoreCodeSender user code