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.

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