|
- {-# LANGUAGE OverloadedStrings #-}
- {-# OPTIONS -Wall #-}
-
- module DatabaseData (
- connect, addUserC, validateC, Connection, Username, Password,
- isLoggedInC, getLoginStringC, isAvailableC
- ) where
-
- import System.Random (newStdGen, randomRs)
- import Control.Monad.Trans (liftIO)
-
- import qualified Crypto.Hash as C (SHA3_512, Digest, hash)
- import Data.ByteString.Char8 (ByteString, pack)
-
- import Database.HDBC
- import Database.HDBC.PostgreSQL
-
- import Shared
-
- type Username = String
- type Password = String
- type Salt = String
-
- connect :: IO Connection
- connect = connectPostgreSQL "user=christian dbname=haskweb"
-
- addUserC :: Connection -> Username -> Password -> IO ()
- addUserC conn username password = do
- gen <- newStdGen
- let salt = take 32 $ randomRs ('a', 'z') gen
- hashed = hash (password ++ salt)
- _ <- run conn
- "INSERT INTO webuser (name, password, salt) VALUES (?, ?, ?)"
- [toSql username, toSql hashed, toSql salt]
- commit conn
-
- getLoginC :: Connection -> Username -> MaybeT IO (Password, Salt)
- getLoginC conn username = do
- [[pwd, salt]] <- liftIO $ quickQuery' conn
- "SELECT password, salt FROM webuser WHERE name=?"
- [toSql username]
- return (fromSql pwd, fromSql salt)
-
- validateC :: Connection -> Username -> Password -> IO Bool
- validateC conn username password = defRunMaybeT False (do
- (pwd, salt) <- getLoginC conn username
- return $ pwd == hash (password ++ salt) )
-
- isLoggedInC :: Connection -> Username -> String -> IO Bool
- isLoggedInC conn username loginString = defRunMaybeT False (do
- (pwd, _) <- getLoginC conn username
- return $ hash (pwd ++ username) == loginString)
-
- getLoginStringC :: Connection -> Username -> IO (Maybe String)
- getLoginStringC conn username = runMaybeT $ do
- (pwd, _) <- getLoginC conn username
- return $ hash (pwd ++ username)
-
- isAvailableC :: Connection -> Username -> IO Bool
- isAvailableC conn username = do
- res <- quickQuery' conn "SELECT 1 FROM webuser WHERE name=?" [toSql username]
- return $ length res == 0
-
- hash :: String -> String
- hash = show . (C.hash :: ByteString -> C.Digest C.SHA3_512) . pack
|