Move login throttling logic to a reusable validator.

This commit is contained in:
Max Goodman
2011-11-07 14:50:18 -08:00
parent ea1fb6f97d
commit b1cbc05f49
2 changed files with 26 additions and 15 deletions

View File

@@ -375,20 +375,11 @@ class ApiController(RedditController):
def POST_register(self, *args, **kwargs):
return self._handle_register(*args, **kwargs)
@validatedForm(VDelay("login"),
user = VLogin(['user', 'passwd']),
username = VLength('user', max_length = 100),
rem = VBoolean('rem'))
def _handle_login(self, form, responder, user, username, rem):
if responder.has_errors('vdelay', errors.RATELIMIT):
return
if login_throttle(username, wrong_password = responder.has_errors("passwd",
errors.WRONG_PASSWORD)):
VDelay.record_violation("login", seconds=1, growfast=True)
c.errors.add(errors.WRONG_PASSWORD, field = "passwd")
if not responder.has_errors("passwd", errors.WRONG_PASSWORD):
@validatedForm(user = VThrottledLogin(['user', 'passwd']),
rem = VBoolean('rem'))
def _handle_login(self, form, responder, user, rem):
if not (responder.has_errors("vdelay", errors.RATELIMIT) or
responder.has_errors("passwd", errors.WRONG_PASSWORD)):
self._login(responder, user, rem)
@validatedForm(VCaptcha(),

View File

@@ -855,9 +855,29 @@ class VLogin(VRequired):
password = password.encode('utf8')
user = valid_login(user_name, password)
if not user:
return self.error()
self.error()
return False
return user
class VThrottledLogin(VLogin):
def __init__(self, *args, **kwargs):
VLogin.__init__(self, *args, **kwargs)
self.vdelay = VDelay("login")
self.vlength = VLength("user", max_length=100)
def run(self, username, password):
username = self.vlength.run(username)
self.vdelay.run()
if (errors.RATELIMIT, "vdelay") in c.errors:
return False
user = VLogin.run(self, username, password)
if login_throttle(username, wrong_password=not user):
VDelay.record_violation("login", seconds=1, growfast=True)
c.errors.add(errors.WRONG_PASSWORD, field=self.param[1])
else:
return user
class VSanitizedUrl(Validator):
def run(self, url):