Permalink
Browse files

Keep admin cookie around if actively used.

  • Loading branch information...
1 parent 8814f6a commit a42505c50a5e9010c54b31d101ec5ed3f83ad0f9 @spladug spladug committed with Logan Hanks Mar 14, 2012
Showing with 38 additions and 21 deletions.
  1. +4 −2 r2/example.ini
  2. +9 −6 r2/r2/controllers/reddit_base.py
  3. +1 −0 r2/r2/lib/app_globals.py
  4. +24 −13 r2/r2/models/account.py
View
@@ -387,8 +387,10 @@ REPLY_AGE_LIMIT = 180
VOTE_AGE_LIMIT = 180
# minimum age, in days, of an account to be eligible to create a community
min_membership_create_community = 30
-# how long the admin cookie should be valid for (in seconds)
-ADMIN_COOKIE_TTL = 1800
+# the maximum life of an admin cookie (seconds)
+ADMIN_COOKIE_TTL = 32400
+# the maximum amount of idle time for an admin cookie (seconds)
+ADMIN_COOKIE_MAX_IDLE = 900
# min amount of karma to edit
WIKI_KARMA = 100
@@ -755,11 +755,9 @@ def logout():
c.cookies[g.login_cookie] = Cookie(value='', expires=DELETE)
@staticmethod
- def enable_admin_mode(user):
- expiration_time = datetime.utcnow() + timedelta(seconds=g.ADMIN_COOKIE_TTL)
- expiration = expiration_time.strftime('%a, %d %b %Y %H:%M:%S GMT')
- c.cookies[g.admin_cookie] = Cookie(value=user.make_admin_cookie(),
- expires=expiration)
+ def enable_admin_mode(user, first_login=None):
+ # no expiration time so the cookie dies with the browser session
+ c.cookies[g.admin_cookie] = Cookie(value=user.make_admin_cookie(first_login=first_login))
@staticmethod
def disable_admin_mode(user):
@@ -800,7 +798,12 @@ def pre(self):
admin_cookie = c.cookies.get(g.admin_cookie)
if c.user_is_loggedin and admin_cookie:
- maybe_admin = valid_admin_cookie(admin_cookie.value)
+ maybe_admin, first_login = valid_admin_cookie(admin_cookie.value)
+
+ if maybe_admin:
+ self.enable_admin_mode(c.user, first_login=first_login)
+ else:
+ self.disable_admin_mode(c.user)
if not c.user:
c.user = UnloggedUser(get_browser_langs())
View
@@ -117,6 +117,7 @@ class Globals(object):
'RATELIMIT',
'QUOTA_THRESHOLD',
'ADMIN_COOKIE_TTL',
+ 'ADMIN_COOKIE_MAX_IDLE',
'num_comments',
'max_comments',
'max_comments_gold',
View
@@ -40,6 +40,9 @@
import hashlib
+COOKIE_TIMESTAMP_FORMAT = '%Y-%m-%dT%H:%M:%S'
+
+
class AccountExists(Exception): pass
class Account(Thing):
@@ -208,18 +211,19 @@ def update_last_visit(self, current_time):
def make_cookie(self, timestr=None):
if not self._loaded:
self._load()
- timestr = timestr or time.strftime('%Y-%m-%dT%H:%M:%S')
+ timestr = timestr or time.strftime(COOKIE_TIMESTAMP_FORMAT)
id_time = str(self._id) + ',' + timestr
to_hash = ','.join((id_time, self.password, g.SECRET))
return id_time + ',' + sha.new(to_hash).hexdigest()
- def make_admin_cookie(self, timestr=None):
+ def make_admin_cookie(self, first_login=None, last_request=None):
if not self._loaded:
self._load()
- timestr = timestr or datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S')
- hashable = ','.join((timestr, request.ip, request.user_agent, self.password))
+ first_login = first_login or datetime.utcnow().strftime(COOKIE_TIMESTAMP_FORMAT)
+ last_request = last_request or datetime.utcnow().strftime(COOKIE_TIMESTAMP_FORMAT)
+ hashable = ','.join((first_login, last_request, request.ip, request.user_agent, self.password))
mac = hmac.new(g.SECRET, hashable, hashlib.sha1).hexdigest()
- return ','.join((timestr, mac))
+ return ','.join((first_login, last_request, mac))
def needs_captcha(self):
return not g.disable_captcha and self.link_karma < 1
@@ -582,26 +586,33 @@ def valid_cookie(cookie):
def valid_admin_cookie(cookie):
if g.read_only_mode:
- return False
+ return (False, None)
# parse the cookie
try:
- timestr, hash = cookie.split(',')
+ first_login, last_request, hash = cookie.split(',')
except ValueError:
- return False
+ return (False, None)
# make sure it's a recent cookie
try:
- cookie_time = datetime.strptime(timestr, '%Y-%m-%dT%H:%M:%S')
+ first_login_time = datetime.strptime(first_login, COOKIE_TIMESTAMP_FORMAT)
+ last_request_time = datetime.strptime(last_request, COOKIE_TIMESTAMP_FORMAT)
except ValueError:
- return False
+ return (False, None)
- cookie_age = datetime.utcnow() - cookie_time
+ cookie_age = datetime.utcnow() - first_login_time
if cookie_age.total_seconds() > g.ADMIN_COOKIE_TTL:
- return False
+ return (False, None)
+
+ idle_time = datetime.utcnow() - last_request_time
+ if idle_time.total_seconds() > g.ADMIN_COOKIE_MAX_IDLE:
+ return (False, None)
# validate
- return constant_time_compare(cookie, c.user.make_admin_cookie(timestr))
+ expected_cookie = c.user.make_admin_cookie(first_login, last_request)
+ return (constant_time_compare(cookie, expected_cookie),
+ first_login)
def valid_feed(name, feedhash, path):

0 comments on commit a42505c

Please sign in to comment.