packages feed

servant-auth-token 0.5.5.0 → 0.5.6.0

raw patch · 4 files changed

+41/−23 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Servant.Server.Auth.Token.Model: readPwHash :: ByteString -> Maybe (Int, ByteString, ByteString)

Files

CHANGELOG.md view
@@ -1,7 +1,12 @@+0.5.6.0+=======++* Allow passing client side hashed passwords for signup and restore.+ 0.5.5.0 ======= -* Allow passing client side hashed password to signin endpoint. +* Allow passing client side hashed password to signin endpoint.  0.5.4.0 =======
servant-auth-token.cabal view
@@ -1,5 +1,5 @@ name:                servant-auth-token-version:             0.5.5.0+version:             0.5.6.0 synopsis:            Servant based API and server for token based authorisation description:         Please see README.md homepage:            https://github.com/ncrashed/servant-auth-token#readme
src/Servant/Server/Auth/Token.hs view
@@ -176,17 +176,6 @@         then return user         else err --- | Try to parse a password hash.-readPwHash :: BC.ByteString -> Maybe (Int, BC.ByteString, BC.ByteString)-readPwHash pw | length broken /= 4-                || algorithm /= "sha256"-                || BC.length hash /= 44 = Nothing-              | otherwise = case BC.readInt strBS of-                              Just (strength, _) -> Just (strength, salt, hash)-                              Nothing -> Nothing-    where broken = BC.split '|' pw-          [algorithm, strBS, salt, hash] = broken- -- | Implementation of "signin" method authSigninPost :: AuthHandler m   => AuthSigninPostBody -- ^ Holds login, password and token lifetime
src/Servant/Server/Auth/Token/Model.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE MultiWayIf #-} {-| Module      : Servant.Server.Auth.Token.Model Description : Internal operations with RDBMS@@ -59,6 +60,7 @@   , patchUserGroup   -- * Low-level   , makeUserInfo+  , readPwHash   ) where  import Control.Monad@@ -66,15 +68,10 @@ import Control.Monad.Except (ExceptT) import Control.Monad.IO.Class import Control.Monad.Reader (ReaderT)-import qualified Control.Monad.RWS.Lazy as LRWS-import qualified Control.Monad.RWS.Strict as SRWS-import qualified Control.Monad.State.Lazy as LS-import qualified Control.Monad.State.Strict as SS-import qualified Control.Monad.Writer.Lazy as LW-import qualified Control.Monad.Writer.Strict as SW import Control.Monad.Trans.Class (MonadTrans(lift)) import Crypto.PasswordStore import Data.Aeson.WithField+import Data.ByteString (ByteString) import Data.Int import Data.Maybe import Data.Monoid@@ -82,7 +79,14 @@ import Data.Time import GHC.Generics +import qualified Control.Monad.RWS.Lazy as LRWS+import qualified Control.Monad.RWS.Strict as SRWS+import qualified Control.Monad.State.Lazy as LS+import qualified Control.Monad.State.Strict as SS+import qualified Control.Monad.Writer.Lazy as LW+import qualified Control.Monad.Writer.Strict as SW import qualified Data.ByteString as BS+import qualified Data.ByteString.Char8 as BC import qualified Data.Foldable as F import qualified Data.List as L import qualified Data.Sequence as S@@ -479,13 +483,33 @@   deleteUserPermissions uid   forM_ perms $ void . insertUserPerm . UserPerm uid +-- | Try to parse a password hash.+readPwHash :: BC.ByteString -> Maybe (Int, BC.ByteString, BC.ByteString)+readPwHash pw | length broken /= 4+                || algorithm /= "sha256"+                || BC.length hash /= 44 = Nothing+              | otherwise = case BC.readInt strBS of+                              Just (strength, _) -> Just (strength, salt, hash)+                              Nothing -> Nothing+    where broken = BC.split '|' pw+          [algorithm, strBS, salt, hash] = broken++-- | Hash password with given strengh, you can pass already hashed password+-- to specified strength+makeHashedPassword :: MonadIO m => Int -> Password -> m Password+makeHashedPassword strength pass =liftIO $ case readPwHash . passToByteString $ pass of+  Nothing ->  fmap byteStringToPass $ makePassword (passToByteString pass) strength+  Just (passStrength, passSalt, passHash) -> if+    | passStrength >= strength -> pure pass+    | otherwise -> pure $ byteStringToPass $ strengthenPassword (passToByteString pass) strength+ -- | Creation of new user createUser :: HasStorage m => Int -> Login -> Password -> Email -> [Permission] -> m UserImplId createUser strength login pass email perms = do-  pass' <- liftIO $ makePassword (passToByteString pass) strength+  pass' <- makeHashedPassword strength pass   i <- insertUserImpl UserImpl {       userImplLogin = login-    , userImplPassword = byteStringToPass pass'+    , userImplPassword = pass'     , userImplEmail = email     }   forM_ perms $ void . insertUserPerm . UserPerm i@@ -531,8 +555,8 @@ setUserPassword' :: MonadIO m => Int -- ^ Password strength   -> Password -> UserImpl -> m UserImpl setUserPassword' strength pass user = do-  pass' <- liftIO $ makePassword (passToByteString pass) strength-  return $ user { userImplPassword = byteStringToPass pass' }+  pass' <- makeHashedPassword strength pass+  return $ user { userImplPassword = pass' }  -- | Get all groups the user belongs to getUserGroups :: HasStorage m => UserImplId -> m [UserGroupId]