mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-04-05 03:00:15 -04:00
Make password reset emails store information in hardcache
Password reset links now stored in the hardcache (they will exist until the expiration, and never get evicted). Additionally, if the password reset link has expired, the user will be redirected to reddit.com/password?expired=true, with an error message prompting them to try again.
This commit is contained in:
@@ -1665,12 +1665,12 @@ class ApiController(RedditController):
|
||||
form.set_html(".status", _("try again tomorrow"))
|
||||
|
||||
|
||||
@validatedForm(cache_evt = VCacheKey('reset', ('key',)),
|
||||
@validatedForm(cache_evt = VHardCacheKey('email-reset', ('key',)),
|
||||
password = VPassword(['passwd', 'passwd2']))
|
||||
def POST_resetpassword(self, form, jquery, cache_evt, password):
|
||||
if form.has_errors('name', errors.EXPIRED):
|
||||
cache_evt.clear()
|
||||
form.redirect('/password')
|
||||
form.redirect('/password?expired=true')
|
||||
elif form.has_errors('passwd', errors.BAD_PASSWORD):
|
||||
pass
|
||||
elif form.has_errors('passwd2', errors.BAD_PASSWORD_MATCH):
|
||||
|
||||
@@ -815,7 +815,7 @@ class FormsController(RedditController):
|
||||
Award.give_if_needed("verified_email", c.user)
|
||||
return self.redirect(dest)
|
||||
|
||||
@validate(cache_evt = VCacheKey('reset', ('key',)),
|
||||
@validate(cache_evt = VHardCacheKey('email-reset', ('key',)),
|
||||
key = nop('key'))
|
||||
def GET_resetpassword(self, cache_evt, key):
|
||||
"""page hit once a user has been sent a password reset email
|
||||
@@ -829,10 +829,10 @@ class FormsController(RedditController):
|
||||
|
||||
done = False
|
||||
if not key and request.referer:
|
||||
referer_path = request.referer.split(g.domain)[-1]
|
||||
referer_path = request.referer.split(g.domain)[-1]
|
||||
done = referer_path.startswith(request.fullpath)
|
||||
elif not getattr(cache_evt, "user", None):
|
||||
return self.abort404()
|
||||
return self.redirect("/password?expired=true")
|
||||
return BoringPage(_("reset password"),
|
||||
content=ResetPassword(key=key, done=done)).render()
|
||||
|
||||
|
||||
@@ -1154,13 +1154,14 @@ class CachedUser(object):
|
||||
|
||||
class VCacheKey(Validator):
|
||||
def __init__(self, cache_prefix, param, *a, **kw):
|
||||
self.cache = g.cache
|
||||
self.cache_prefix = cache_prefix
|
||||
Validator.__init__(self, param, *a, **kw)
|
||||
|
||||
def run(self, key):
|
||||
c_user = CachedUser(self.cache_prefix, None, key)
|
||||
if key:
|
||||
uid = g.cache.get(str(self.cache_prefix + "_" + key))
|
||||
uid = self.cache.get(str(self.cache_prefix + "_" + key))
|
||||
if uid:
|
||||
try:
|
||||
c_user.user = Account._byID(uid, data = True)
|
||||
@@ -1169,6 +1170,11 @@ class VCacheKey(Validator):
|
||||
return c_user
|
||||
self.set_error(errors.EXPIRED)
|
||||
|
||||
class VHardCacheKey(VCacheKey):
|
||||
def __init__(self, cache_prefix, param, *a, **kw):
|
||||
VCacheKey.__init__(self, cache_prefix, param, *a, **kw)
|
||||
self.cache = g.hardcache
|
||||
|
||||
class VOneOf(Validator):
|
||||
def __init__(self, param, options = (), *a, **kw):
|
||||
Validator.__init__(self, param, *a, **kw)
|
||||
|
||||
@@ -83,12 +83,12 @@ def password_email(user):
|
||||
"""
|
||||
from r2.lib.pages import PasswordReset
|
||||
|
||||
reset_count_key = "reset_count_%s" % user._id
|
||||
reset_count_key = "email-reset_count_%s" % user._id
|
||||
g.cache.add(reset_count_key, 0, time=3600 * 12)
|
||||
if g.cache.incr(reset_count_key) > 3:
|
||||
return False
|
||||
|
||||
reset_count_global = "reset_count_global"
|
||||
reset_count_global = "email-reset_count_global"
|
||||
g.cache.add(reset_count_global, 0, time=3600)
|
||||
if g.cache.incr(reset_count_global) > 1000:
|
||||
raise ValueError("Somebody's beating the hell out of the password reset box")
|
||||
@@ -96,7 +96,7 @@ def password_email(user):
|
||||
key = passhash(randstr(64, reallyrandom = True), user.email)
|
||||
passlink = 'http://' + g.domain + '/resetpassword/' + key
|
||||
g.log.info("Generated password reset link: " + passlink)
|
||||
g.cache.set("reset_%s" % key, user._id, time=1800)
|
||||
g.hardcache.set("email-reset_%s" % key, user._id, time=3600 * 12)
|
||||
_system_email(user.email,
|
||||
PasswordReset(user=user,
|
||||
passlink=passlink).render(style='email'),
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
onsubmit="return post_form(this, 'password');">
|
||||
<h1>${_("what's my password?")}</h1>
|
||||
<p>${_("enter your user name below to receive your login information")}</p>
|
||||
%if request.params.get('expired'):
|
||||
<span class="error">
|
||||
${_("password reset link expired. please try again")}
|
||||
</span>
|
||||
%endif
|
||||
|
||||
<div class="spacer">
|
||||
<%utils:round_field title="${_('username')}">
|
||||
|
||||
Reference in New Issue
Block a user