Portability | Portable |
---|---|
Stability | Stable |
Maintainer | pbrisbin@gmail.com |
Safe Haskell | None |
WARNING: This module was not designed with security in mind, and is not suitable for production sites. In the near future, it will likely be either deprecated or rewritten to have a more secure implementation. For more information, see: https://github.com/yesodweb/yesod/issues/668.
A yesod-auth AuthPlugin designed to look users up in Persist where their user id's and a salted SHA1 hash of their password is stored.
Example usage:
-- import the function import Auth.HashDB -- make sure you have an auth route mkYesodData "MyApp" [$parseRoutes| / RootR GET /auth AuthR Auth getAuth |] -- make your app an instance of YesodAuth using this plugin instance YesodAuth MyApp where type AuthId MyApp = UserId loginDest _ = RootR logoutDest _ = RootR getAuthId = getAuthIdHashDB AuthR (Just . UniqueUser) authPlugins = [authHashDB (Just . UniqueUser)] -- include the migration function in site startup withServer :: (Application -> IO a) -> IO a withServer f = withConnectionPool $ \p -> do runSqlPool (runMigration migrateUsers) p let h = DevSite p
Note that function which converts username to unique identifier must be same.
Your app must be an instance of YesodPersist. and the username, salt and hashed-passwords should be added to the database.
echo -n 'MySaltMyPassword' | sha1sum
can be used to get the hash from the commandline.
- class HashDBUser user where
- userPasswordHash :: user -> Maybe Text
- userPasswordSalt :: user -> Maybe Text
- setUserHashAndSalt :: Text -> Text -> user -> user
- setSaltAndPasswordHash :: Text -> Text -> user -> user
- data family Unique record1
- setPassword :: (MonadIO m, HashDBUser user) => Text -> user -> m user
- validateUser :: (YesodPersist yesod, b ~ YesodPersistBackend yesod, PersistMonadBackend (b (HandlerT yesod IO)) ~ PersistEntityBackend user, PersistUnique (b (HandlerT yesod IO)), PersistEntity user, HashDBUser user) => Unique user -> Text -> HandlerT yesod IO Bool
- authHashDB :: (YesodAuth m, YesodPersist m, HashDBUser user, PersistEntity user, b ~ YesodPersistBackend m, PersistMonadBackend (b (HandlerT m IO)) ~ PersistEntityBackend user, PersistUnique (b (HandlerT m IO))) => (Text -> Maybe (Unique user)) -> AuthPlugin m
- getAuthIdHashDB :: (YesodAuth master, YesodPersist master, HashDBUser user, PersistEntity user, Key user ~ AuthId master, b ~ YesodPersistBackend master, PersistMonadBackend (b (HandlerT master IO)) ~ PersistEntityBackend user, PersistUnique (b (HandlerT master IO))) => (AuthRoute -> Route master) -> (Text -> Maybe (Unique user)) -> Creds master -> HandlerT master IO (Maybe (AuthId master))
- type User = UserGeneric SqlBackend
- data UserGeneric backend = User {
- userUsername :: !Text
- userPassword :: !Text
- userSalt :: !Text
- type UserId = KeyBackend SqlBackend User
- data family EntityField record1 ($a)
- migrateUsers :: forall m. (MonadBaseControl IO m, MonadIO m, MonadLogger m) => Migration (SqlPersistT m)
Documentation
class HashDBUser user whereSource
Interface for data type which holds user info. It's just a collection of getters and setters
userPasswordHash :: user -> Maybe TextSource
Retrieve password hash from user data
userPasswordSalt :: user -> Maybe TextSource
Retrieve salt for password
Deprecated for the better named setSaltAndPasswordHash
a callback for setPassword
HashDBUser (UserGeneric backend) |
data family Unique record1
Unique keys besided the Key
setPassword :: (MonadIO m, HashDBUser user) => Text -> user -> m userSource
Set password for user. This function should be used for setting passwords. It generates random salt and calculates proper hashes.
Authentification
:: (YesodPersist yesod, b ~ YesodPersistBackend yesod, PersistMonadBackend (b (HandlerT yesod IO)) ~ PersistEntityBackend user, PersistUnique (b (HandlerT yesod IO)), PersistEntity user, HashDBUser user) | |
=> Unique user | User unique identifier |
-> Text | Password in plaint-text |
-> HandlerT yesod IO Bool |
Given a user ID and password in plaintext, validate them against the database values.
authHashDB :: (YesodAuth m, YesodPersist m, HashDBUser user, PersistEntity user, b ~ YesodPersistBackend m, PersistMonadBackend (b (HandlerT m IO)) ~ PersistEntityBackend user, PersistUnique (b (HandlerT m IO))) => (Text -> Maybe (Unique user)) -> AuthPlugin mSource
Prompt for username and password, validate that against a database which holds the username and a hash of the password
:: (YesodAuth master, YesodPersist master, HashDBUser user, PersistEntity user, Key user ~ AuthId master, b ~ YesodPersistBackend master, PersistMonadBackend (b (HandlerT master IO)) ~ PersistEntityBackend user, PersistUnique (b (HandlerT master IO))) | |
=> (AuthRoute -> Route master) | your site's Auth Route |
-> (Text -> Maybe (Unique user)) | gets user ID |
-> Creds master | the creds argument |
-> HandlerT master IO (Maybe (AuthId master)) |
A drop in for the getAuthId method of your YesodAuth instance which can be used if authHashDB is the only plugin in use.
Predefined data type
type User = UserGeneric SqlBackendSource
data UserGeneric backend Source
Generate data base instances for a valid user
User | |
|
Typeable1 UserGeneric | |
PersistFieldSql (UserGeneric backend) | |
PersistEntity (UserGeneric backend) | |
PersistField (UserGeneric backend) | |
HashDBUser (UserGeneric backend) |
type UserId = KeyBackend SqlBackend UserSource
data family EntityField record1 ($a)
An EntityField
is parameterised by the Haskell record it belongs to
and the additional type of that field
migrateUsers :: forall m. (MonadBaseControl IO m, MonadIO m, MonadLogger m) => Migration (SqlPersistT m)Source