{-|
Module      : UserHandler
Description : Módulo contendo as operações básicas de manipulação de usuários no sistema SIGES.
-}
{-# LANGUAGE OverloadedStrings #-}
module Handlers.UserHandler where

import qualified Data.Text as T

import Manager
import Handlers.DataHandler

instance Show User where
    show :: User -> String
show (User String
nameUsr String
emailUsr Bool
admUsr) = String
"Dados do usuário:       \n\
                                          \Nome: "String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
nameUsr String -> ShowS
forall a. [a] -> [a] -> [a]
++   String
"\n\
                                          \Email: "String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
emailUsr String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"\n\
                                          \Administrador: "String -> ShowS
forall a. [a] -> [a] -> [a]
++ if Bool
admUsr then String
"Sim" else String
"Não"

-- | Esta função considera uma String e decide se um usuário com o e-mail igual a esta String existe no sistema.
userExists :: String -> IO Bool
userExists :: String -> IO Bool
userExists String
emailStr = do
    Maybe UserFull
possibleUser <- String -> IO (Maybe UserFull)
getUser String
emailStr
    Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe UserFull -> Bool
forall a. Maybe a -> Bool
isJust Maybe UserFull
possibleUser)

-- | Dada uma String, esta função a converterá em um Password.
makePass :: String -> Password
makePass :: String -> Password
makePass String
passStr = Text -> Password
mkPassword (Text -> Password) -> Text -> Password
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack String
passStr

-- | Esta função considerará uma String contendo um e-mail e avaliará outra String, decidindo se ela equivale à senha do usuário com o e-mail fornecido. A resposta é então retornada em forma de valor booleano.
correctPassword :: String -> String -> IO Bool
correctPassword :: String -> String -> IO Bool
correctPassword String
emailStr String
passStr = do
    (Just UserFull
user) <- String -> IO (Maybe UserFull)
getUser String
emailStr
    let passHash :: PasswordHash Bcrypt
passHash = Text -> PasswordHash Bcrypt
forall a. Text -> PasswordHash a
PasswordHash (UserFull -> Text
password UserFull
user) :: PasswordHash Bcrypt
        check :: PasswordCheck
check = Password -> PasswordHash Bcrypt -> PasswordCheck
checkPassword (String -> Password
makePass String
passStr) PasswordHash Bcrypt
passHash
    Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (PasswordCheck
check PasswordCheck -> PasswordCheck -> Bool
forall a. Eq a => a -> a -> Bool
== PasswordCheck
PasswordCheckSuccess)

-- | Dada uma String contendo um e-mail, esta função procurará no sistema um Userfull com este e-mail, e retornará a sua versão com as informações essenciais para o funcionamento do sistema, omitindo dados sensíveis: um User.
retrieveUser :: String -> IO User
retrieveUser :: String -> IO User
retrieveUser String
emailStr = do
    (Just UserFull
user) <- String -> IO (Maybe UserFull)
getUser String
emailStr
    User -> IO User
forall (m :: * -> *) a. Monad m => a -> m a
return (User -> IO User) -> User -> IO User
forall a b. (a -> b) -> a -> b
$ User :: String -> String -> Bool -> User
User {nameUser :: String
nameUser= UserFull -> String
name UserFull
user, emailUser :: String
emailUser= UserFull -> String
email UserFull
user, isAdminUser :: Bool
isAdminUser = UserFull -> Bool
isAdmin UserFull
user}

-- | Dadas três Strings contendo respectivamente o e-mail, a senha e o nome do usuário, e um valor booleano indicando se trata-se de um administrador, esta função cria um novo usuário e o armazena no sistema.
registerNewUser :: String -> String -> String -> Bool -> IO ()
registerNewUser :: String -> String -> String -> Bool -> IO ()
registerNewUser String
emailStr String
passwordStr String
nameStr Bool
isAdm = do
    UTCTime
timenow <- IO UTCTime
getCurrentTime
    PasswordHash Bcrypt
passHash <- Password -> IO (PasswordHash Bcrypt)
forall (m :: * -> *).
MonadIO m =>
Password -> m (PasswordHash Bcrypt)
hashPassword (Password -> IO (PasswordHash Bcrypt))
-> Password -> IO (PasswordHash Bcrypt)
forall a b. (a -> b) -> a -> b
$ String -> Password
makePass String
passwordStr
    let passwordText :: Text
passwordText = PasswordHash Bcrypt -> Text
forall a. PasswordHash a -> Text
unPasswordHash PasswordHash Bcrypt
passHash
        newUser :: UserFull
newUser = UserFull :: String -> String -> Text -> String -> Bool -> UserFull
UserFull {email :: String
email=String
emailStr, password :: Text
password=Text
passwordText, name :: String
name=String
nameStr, isAdmin :: Bool
isAdmin=Bool
isAdm, registrationDate :: String
registrationDate=(UTCTime -> String
forall a. Show a => a -> String
show UTCTime
timenow)}
    UserFull -> IO Bool
saveUser UserFull
newUser
    () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- | Esta função recebe um usuário e o remove do sistema.
removeUser :: User -> IO ()
removeUser :: User -> IO ()
removeUser User
user = do
    String -> IO Bool
deleteUser (User -> String
emailUser User
user)
    () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()