Add json support for postPasswordR

This commit is contained in:
Sibi Prabakaran 2016-12-06 18:17:19 +05:30
parent b6cd72f49f
commit 85bd15d109
No known key found for this signature in database
GPG Key ID: D19E3E0EBB557613

View File

@ -72,7 +72,8 @@ import Safe (readMay)
import System.IO.Unsafe (unsafePerformIO) import System.IO.Unsafe (unsafePerformIO)
import qualified Text.Email.Validate import qualified Text.Email.Validate
import Network.HTTP.Types.Status (status400) import Network.HTTP.Types.Status (status400)
import Data.Aeson.Types (Parser(..), Result(..), parseMaybe, withObject) import Data.Aeson.Types (Parser(..), Result(..), parseMaybe, withObject, (.:?))
import Data.Maybe (isJust, isNothing, fromJust)
loginR, registerR, forgotPasswordR, setpassR :: AuthRoute loginR, registerR, forgotPasswordR, setpassR :: AuthRoute
loginR = PluginR "email" ["login"] loginR = PluginR "email" ["login"]
@ -645,54 +646,81 @@ defaultSetPasswordHandler needOld = do
fsAttrs = [("autofocus", "")] fsAttrs = [("autofocus", "")]
} }
parsePassword :: Value -> Parser (Text, Text, Maybe Text)
parsePassword = withObject "password" (\obj -> do
email' <- obj .: "new"
pass <- obj .: "confirm"
curr <- obj .:? "current"
return (email', pass, curr))
postPasswordR :: YesodAuthEmail master => HandlerT Auth (HandlerT master IO) TypedContent postPasswordR :: YesodAuthEmail master => HandlerT Auth (HandlerT master IO) TypedContent
postPasswordR = do postPasswordR = do
maid <- lift maybeAuthId maid <- lift maybeAuthId
(creds :: Result Value) <- lift parseJsonBody
let jcreds = case creds of
Error _ -> Nothing
Success val -> parseMaybe parsePassword val
let doJsonParsing = isJust jcreds
case maid of case maid of
Nothing -> loginErrorMessageI LoginR Msg.BadSetPass Nothing -> loginErrorMessageI LoginR Msg.BadSetPass
Just aid -> do Just aid -> do
tm <- getRouteToParent tm <- getRouteToParent
needOld <- lift $ needOldPassword aid needOld <- lift $ needOldPassword aid
if not needOld then confirmPassword aid tm else do if not needOld then confirmPassword aid tm jcreds else do
current <- lift $ runInputPost $ ireq textField "current" res <- lift $ runInputPostResult $ ireq textField "current"
let fcurrent = case res of
FormSuccess currentPass -> Just currentPass
_ -> Nothing
let current = if doJsonParsing
then getThird jcreds
else fcurrent
mrealpass <- lift $ getPassword aid mrealpass <- lift $ getPassword aid
case mrealpass of case mrealpass of
Nothing -> Nothing ->
lift $ loginErrorMessage (tm setpassR) "You do not currently have a password set on your account" lift $ loginErrorMessage (tm setpassR) "You do not currently have a password set on your account"
Just realpass Just realpass
| isValidPass current realpass -> confirmPassword aid tm | isNothing current -> loginErrorMessageI LoginR Msg.BadSetPass
| isValidPass (fromJust current) realpass -> confirmPassword aid tm jcreds
| otherwise -> | otherwise ->
lift $ loginErrorMessage (tm setpassR) "Invalid current password, please try again" lift $ loginErrorMessage (tm setpassR) "Invalid current password, please try again"
where where
msgOk = Msg.PassUpdated msgOk = Msg.PassUpdated
confirmPassword aid tm = do getThird (Just (_,_,t)) = t
(new, confirm) <- lift $ runInputPost $ (,) getThird Nothing = Nothing
getNewConfirm (Just (a,b,_)) = Just (a,b)
getNewConfirm _ = Nothing
confirmPassword aid tm jcreds = do
res <- lift $ runInputPostResult $ (,)
<$> ireq textField "new" <$> ireq textField "new"
<*> ireq textField "confirm" <*> ireq textField "confirm"
let creds = if (isJust jcreds)
if new /= confirm then getNewConfirm jcreds
then loginErrorMessageI setpassR Msg.PassMismatch else case res of
else do FormSuccess res' -> Just res'
isSecure <- lift $ checkPasswordSecurity aid new _ -> Nothing
case isSecure of case creds of
Nothing -> loginErrorMessageI setpassR Msg.PassMismatch
Just (new, confirm) ->
if new /= confirm
then loginErrorMessageI setpassR Msg.PassMismatch
else do
isSecure <- lift $ checkPasswordSecurity aid new
case isSecure of
Left e -> lift $ loginErrorMessage (tm setpassR) e Left e -> lift $ loginErrorMessage (tm setpassR) e
Right () -> do Right () -> do
salted <- liftIO $ saltPass new salted <- liftIO $ saltPass new
y <- lift $ do y <- lift $ do
setPassword aid salted setPassword aid salted
deleteSession loginLinkKey deleteSession loginLinkKey
addMessageI "success" msgOk addMessageI "success" msgOk
getYesod getYesod
mr <- lift getMessageRender mr <- lift getMessageRender
selectRep $ do selectRep $ do
provideRep $ provideRep $
fmap asHtml $ lift $ redirect $ afterPasswordRoute y fmap asHtml $ lift $ redirect $ afterPasswordRoute y
provideJsonMessage (mr msgOk) provideJsonMessage (mr msgOk)
saltLength :: Int saltLength :: Int
saltLength = 5 saltLength = 5