diff --git a/r2/r2/controllers/api.py b/r2/r2/controllers/api.py index 580186834..1f6fc8f63 100644 --- a/r2/r2/controllers/api.py +++ b/r2/r2/controllers/api.py @@ -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(), diff --git a/r2/r2/controllers/validator/validator.py b/r2/r2/controllers/validator/validator.py index 383fc8031..b00974ca8 100644 --- a/r2/r2/controllers/validator/validator.py +++ b/r2/r2/controllers/validator/validator.py @@ -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):