I'd like to write a function that checks if user's login and hashed password exists in database. Let's assume DB is very simple:
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
User
login String
passHash Hash
UniqueL login
deriving Eq Show
Where Hash
is an alias type Hash = PasswordHash PBKDF2
from https://hackage.haskell.org/package/password-2.0.1.1/docs/Data-Password-PBKDF2.html.
Also, for simplicity let's assume that both login and password are passed to my function as String
.
There's a function in the module called checkPassword
(https://hackage.haskell.org/package/password-2.0.1.1/docs/Data-Password-PBKDF2.html#g:3) that checks if a password produces the required hash. However, I don't know how can I use it in esqualeto where_
clause.
I came up with something like this:
type DB m a = ReaderT SqlBackend m a
checkCredentials ::(MonadIO m, MonadLogger m) => (String, String) -> DB m Bool
checkCredentials (login, password) = do
let hashFunc = (checkPassword $ mkPassword (pack password))
res <-
select $
from $ \user -> do
-- This won't wwork
where_ (user ^. UserLogin ==. val login &&. hashFunc (user ^. UserPassHash) ==. val PasswordCheckSuccess)
return user
return (negate $ null res)
but the part hashFunc (user ^. UserPassHash)
obviously won't work. I guess I need to enter with my hashFunc
into a monad (or two), but I have no idea how to do this.
I noticed that UserPassHash
is of type EntityField User Hash
. I wonder how can I turn it into EntityField User PasswordCheck
.