Webanwendung mit FastCGI und Haskell
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

66 lignes
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