Webanwendung mit FastCGI und Haskell
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

45 行
1.3KB

  1. {-# LANGUAGE OverloadedStrings #-}
  2. {-# OPTIONS -Wall #-}
  3. import System.Random
  4. import Control.Monad.Trans.Maybe
  5. import Control.Monad (guard)
  6. import Control.Monad.Trans
  7. import Data.Maybe
  8. import qualified Crypto.Hash as C (SHA3_512, Digest, hash)
  9. import Data.ByteString.Char8 (ByteString, pack)
  10. import Database.HDBC
  11. import Database.HDBC.PostgreSQL
  12. type Username = String
  13. type Password = String
  14. connect :: IO Connection
  15. connect = connectPostgreSQL "user=christian dbname=haskweb"
  16. addUser :: Connection -> Username -> Password -> IO ()
  17. addUser conn username password = do
  18. gen <- newStdGen
  19. let salt = take 32 $ randomRs ('a', 'z') gen
  20. hashed = hash (password ++ salt)
  21. _ <- run conn
  22. "INSERT INTO webuser (name, password, salt) VALUES (?, ?, ?)"
  23. [toSql username, toSql hashed, toSql salt]
  24. commit conn
  25. validate :: Connection -> Username -> Password -> IO Bool
  26. validate conn username password = fromMaybe False <$> runMaybeT (do
  27. res <- liftIO $ quickQuery' conn
  28. "SELECT password, salt FROM webuser WHERE name=?"
  29. [toSql username]
  30. guard $ length res == 1
  31. guard $ length (head res) == 2
  32. let [pwd, salt] = head res
  33. guard $ fromSql pwd == hash (password ++ fromSql salt)
  34. return True)
  35. hash :: String -> String
  36. hash = show . (C.hash :: ByteString -> C.Digest C.SHA3_512) . pack