Webanwendung mit FastCGI und Haskell
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

66 lines
2.1KB

  1. {-# LANGUAGE OverloadedStrings #-}
  2. {-# OPTIONS -Wall #-}
  3. module DatabaseData (
  4. connect, addUserC, validateC, Connection, Username, Password,
  5. isLoggedInC, getLoginStringC, isAvailableC
  6. ) where
  7. import System.Random (newStdGen, randomRs)
  8. import Control.Monad.Trans (liftIO)
  9. import qualified Crypto.Hash as C (SHA3_512, Digest, hash)
  10. import Data.ByteString.Char8 (ByteString, pack)
  11. import Database.HDBC
  12. import Database.HDBC.PostgreSQL
  13. import Shared
  14. type Username = String
  15. type Password = String
  16. type Salt = String
  17. connect :: IO Connection
  18. connect = connectPostgreSQL "user=christian dbname=haskweb"
  19. addUserC :: Connection -> Username -> Password -> IO ()
  20. addUserC conn username password = do
  21. gen <- newStdGen
  22. let salt = take 32 $ randomRs ('a', 'z') gen
  23. hashed = hash (password ++ salt)
  24. _ <- run conn
  25. "INSERT INTO webuser (name, password, salt) VALUES (?, ?, ?)"
  26. [toSql username, toSql hashed, toSql salt]
  27. commit conn
  28. getLoginC :: Connection -> Username -> MaybeT IO (Password, Salt)
  29. getLoginC conn username = do
  30. [[pwd, salt]] <- liftIO $ quickQuery' conn
  31. "SELECT password, salt FROM webuser WHERE name=?"
  32. [toSql username]
  33. return (fromSql pwd, fromSql salt)
  34. validateC :: Connection -> Username -> Password -> IO Bool
  35. validateC conn username password = defRunMaybeT False (do
  36. (pwd, salt) <- getLoginC conn username
  37. return $ pwd == hash (password ++ salt) )
  38. isLoggedInC :: Connection -> Username -> String -> IO Bool
  39. isLoggedInC conn username loginString = defRunMaybeT False (do
  40. (pwd, _) <- getLoginC conn username
  41. return $ hash (pwd ++ username) == loginString)
  42. getLoginStringC :: Connection -> Username -> IO (Maybe String)
  43. getLoginStringC conn username = runMaybeT $ do
  44. (pwd, _) <- getLoginC conn username
  45. return $ hash (pwd ++ username)
  46. isAvailableC :: Connection -> Username -> IO Bool
  47. isAvailableC conn username = do
  48. res <- quickQuery' conn "SELECT 1 FROM webuser WHERE name=?" [toSql username]
  49. return $ length res == 0
  50. hash :: String -> String
  51. hash = show . (C.hash :: ByteString -> C.Digest C.SHA3_512) . pack