61 lines
1.6 KiB
Haskell
61 lines
1.6 KiB
Haskell
|
|
||
|
module ModelCustom where
|
||
|
|
||
|
import Prelude
|
||
|
|
||
|
import Crypto.BCrypt as Import hiding (hashPassword)
|
||
|
import Database.Persist.Sql
|
||
|
import Safe (fromJustNote)
|
||
|
import qualified Data.Text as T
|
||
|
import qualified Data.Text.Encoding as TE
|
||
|
import qualified Data.Aeson as A
|
||
|
import System.Entropy (getEntropy)
|
||
|
import qualified Data.ByteString.Builder as BB
|
||
|
import qualified Data.ByteString.Lazy as LBS
|
||
|
|
||
|
mkSlug :: Int -> IO T.Text
|
||
|
mkSlug size =
|
||
|
TE.decodeUtf8 . LBS.toStrict . BB.toLazyByteString . BB.byteStringHex <$>
|
||
|
getEntropy size
|
||
|
|
||
|
-- * Bookmark Slug
|
||
|
|
||
|
newtype BmSlug = BmSlug
|
||
|
{ unBmSlug :: T.Text
|
||
|
} deriving (Eq, PersistField, PersistFieldSql, Show, Read, Ord, A.FromJSON, A.ToJSON)
|
||
|
|
||
|
mkBmSlug :: IO BmSlug
|
||
|
mkBmSlug = BmSlug <$> mkSlug 6
|
||
|
|
||
|
-- * Note Slug
|
||
|
|
||
|
newtype NtSlug = NtSlug
|
||
|
{ unNtSlug :: T.Text
|
||
|
} deriving (Eq, PersistField, PersistFieldSql, Show, Read, Ord, A.FromJSON, A.ToJSON)
|
||
|
|
||
|
mkNtSlug :: IO NtSlug
|
||
|
mkNtSlug = NtSlug <$> mkSlug 10
|
||
|
|
||
|
-- * Model Crypto
|
||
|
|
||
|
policy :: HashingPolicy
|
||
|
policy =
|
||
|
HashingPolicy
|
||
|
{ preferredHashCost = 12
|
||
|
, preferredHashAlgorithm = "$2a$"
|
||
|
}
|
||
|
|
||
|
newtype BCrypt = BCrypt
|
||
|
{ unBCrypt :: T.Text
|
||
|
} deriving (Eq, PersistField, PersistFieldSql, Show, Ord, A.FromJSON, A.ToJSON)
|
||
|
|
||
|
hashPassword :: T.Text -> IO BCrypt
|
||
|
hashPassword rawPassword = do
|
||
|
mPassword <- hashPasswordUsingPolicy policy (TE.encodeUtf8 rawPassword)
|
||
|
return
|
||
|
(BCrypt (TE.decodeUtf8 (fromJustNote "Invalid hashing policy" mPassword)))
|
||
|
|
||
|
validatePasswordHash :: BCrypt -> T.Text -> Bool
|
||
|
validatePasswordHash hash' pass = do
|
||
|
validatePassword (TE.encodeUtf8 (unBCrypt hash')) (TE.encodeUtf8 pass)
|