diff --git a/r2/r2/controllers/api.py b/r2/r2/controllers/api.py index 14511d0e8..137c38411 100644 --- a/r2/r2/controllers/api.py +++ b/r2/r2/controllers/api.py @@ -1150,17 +1150,23 @@ class ApiController(RedditController): if not form.has_errors('name', errors.USER_DOESNT_EXIST, errors.NO_EMAIL_FOR_USER): emailer.password_email(user) + form.set_html(".status", _("an email will be sent to that account's address shortly")) + - @validatedForm(user = VCacheKey('reset', ('key', 'name')), - password = VPassword(['passwd', 'passwd2'])) - def POST_resetpassword(self, form, jquery, user, password): + @validatedForm(cache_evt = VCacheKey('reset', ('key', 'name')), + password = VPassword(['passwd', 'passwd2'])) + def POST_resetpassword(self, form, jquery, cache_evt, password): if errors.BAD_USERNAME in c.errors: + # clear reset event -- the user failed to know their user name + cache_evt.clear() return form.redirect('/password') elif (not form.has_errors('passwd', errors.BAD_PASSWORD) and not form.has_errors('passwd2', errors.BAD_PASSWORD_MATCH) and - user): - change_password(user, password) - self._login(jquery, user, '/resetpassword') + cache_evt.user): + # successfully entered user name and valid new password + change_password(cache_evt.user, password) + self._login(jquery, cache_evt.user, '/resetpassword') + cache_evt.clear() @noresponse(VUser()) diff --git a/r2/r2/controllers/front.py b/r2/r2/controllers/front.py index ab12ef09e..69b1e62a5 100644 --- a/r2/r2/controllers/front.py +++ b/r2/r2/controllers/front.py @@ -95,9 +95,9 @@ class FrontController(RedditController): """The 'what is my password' page""" return BoringPage(_("password"), content=Password()).render() - @validate(user = VCacheKey('reset', ('key', 'name')), + @validate(cache_evt = VCacheKey('reset', ('key', 'name')), key = nop('key')) - def GET_resetpassword(self, user, key): + def GET_resetpassword(self, cache_evt, key): """page hit once a user has been sent a password reset email to verify their identity before allowing them to update their password.""" @@ -105,7 +105,7 @@ class FrontController(RedditController): if not key and request.referer: referer_path = request.referer.split(g.domain)[-1] done = referer_path.startswith(request.fullpath) - elif not user: + elif not cache_evt.user: return self.abort404() return BoringPage(_("reset password"), content=ResetPassword(key=key, done=done)).render() diff --git a/r2/r2/controllers/validator/validator.py b/r2/r2/controllers/validator/validator.py index afd616b2f..52063a70c 100644 --- a/r2/r2/controllers/validator/validator.py +++ b/r2/r2/controllers/validator/validator.py @@ -715,20 +715,27 @@ class VCommentIDs(Validator): class VCacheKey(Validator): def __init__(self, cache_prefix, param, *a, **kw): self.cache_prefix = cache_prefix + self.user = None + self.key = None Validator.__init__(self, param, *a, **kw) + def clear(self): + if self.key and self.cache_prefix: + g.cache.delete(str(self.cache_prefix + "_" + self.key)) + def run(self, key, name): + self.key = key if key: - uid = g.cache.get(str(self.cache_prefix + "_" + key)) + uid = g.cache.get(str(self.cache_prefix + "_" + self.key)) try: a = Account._byID(uid, data = True) - g.cache.delete(str(self.cache_prefix + "_" + key)) + if name and a.name.lower() != name.lower(): + self.set_error(errors.BAD_USERNAME) + else: + self.user = a except NotFound: - return None - if name and a.name.lower() != name.lower(): self.set_error(errors.BAD_USERNAME) - if a: - return a + return self self.set_error(errors.EXPIRED)