snapframework / snap

Top-level package for the official Snap Framework libraries, includes the snaplets API as well as infrastructure for sessions, auth, and templates.
http://snapframework.com/
BSD 3-Clause "New" or "Revised" License
455 stars 68 forks source link

locking out not working properly? #53

Open adinapoli opened 11 years ago

adinapoli commented 11 years ago

Hi guys, this is probably not an issue but something I'm missing, I'm sure. Consider this:

markAuthFail :: AuthUser
             -> Handler b (AuthManager b) (Either AuthFailure AuthUser)
markAuthFail u = withBackend $ \r -> do
    lo <- gets lockout
    incFailCtr u >>= checkLockout lo >>= liftIO . save r

  where
    --------------------------------------------------------------------------
    incFailCtr u' = return $ u' {
                      userFailedLoginCount = userFailedLoginCount u' + 1
                    }

    --------------------------------------------------------------------------
    checkLockout lo u' =
        case lo of
          Nothing          -> return u'
          Just (mx, wait)  ->
              if userFailedLoginCount u' >= mx
                then do
                  now <- liftIO getCurrentTime
                  let reopen = addUTCTime wait now
                  return $! u' { userLockedOutUntil = Just reopen }
                else return u'

I'm testing what happens what the user has surpassed the number of allowed attempts and must be locked out. I come up with this handler:

    hdl :: Handler App App (Either AuthFailure AuthUser)
    hdl = with auth $ do
        user <- loginByUsername "bar" (ClearText "bar") True
        case user of
          (Left e) -> return $ Left e
          (Right u) ->
              let u' = u {userFailedLoginCount = 99}
                  in do
                      modify (\s -> s { lockout = Just (5, 1000000) })
                      markAuthFail u'

Here I'm trying to modify the lockout parameter of the AuthManager, since by default is Nothing. I'm passing a user with a high number of userFailedLoginCount, and I would expect markAuthFail to return a Just userLockedOutUntil. Correct? Have I written a wrong handler?

Just to be clear, in my Assertion I test something like isJust $ userLockeOutUntil u.

Thanks and bye, A.

adinapoli commented 11 years ago

Just bumping in order to fix this issue down :)