Merge pull request #1961 from coreos-inc/session-cookies
Enable permanent sessions
This commit is contained in:
commit
129d2851f7
6 changed files with 66 additions and 5 deletions
|
@ -141,6 +141,9 @@ class DefaultConfig(object):
|
|||
# Super user config. Note: This MUST BE an empty list for the default config.
|
||||
SUPER_USERS = []
|
||||
|
||||
# Feature Flag: Whether sessions are permanent.
|
||||
FEATURE_PERMANENT_SESSIONS = True
|
||||
|
||||
# Feature Flag: Whether super users are supported.
|
||||
FEATURE_SUPER_USERS = True
|
||||
|
||||
|
|
|
@ -562,7 +562,7 @@ class Signin(ApiResource):
|
|||
'invite_code': {
|
||||
'type': 'string',
|
||||
'description': 'The optional invite code'
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -579,7 +579,6 @@ class Signin(ApiResource):
|
|||
username = signin_data['username']
|
||||
password = signin_data['password']
|
||||
invite_code = signin_data.get('invite_code', '')
|
||||
|
||||
return conduct_signin(username, password, invite_code=invite_code)
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ from config import frontend_visible_config
|
|||
from external_libraries import get_external_javascript, get_external_css
|
||||
from util.names import parse_namespace_repository
|
||||
from util.secscan import PRIORITY_LEVELS
|
||||
from util.timedeltastring import convert_to_timedelta
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -108,16 +109,20 @@ def param_required(param_name, allow_body=False):
|
|||
return wrapper
|
||||
|
||||
|
||||
def common_login(db_user):
|
||||
def common_login(db_user, permanent_session=True):
|
||||
if login_user(LoginWrappedDBUser(db_user.uuid, db_user)):
|
||||
logger.debug('Successfully signed in as: %s (%s)' % (db_user.username, db_user.uuid))
|
||||
new_identity = QuayDeferredPermissionUser.for_user(db_user)
|
||||
identity_changed.send(app, identity=new_identity)
|
||||
session['login_time'] = datetime.datetime.now()
|
||||
|
||||
if permanent_session and features.PERMANENT_SESSIONS:
|
||||
session_timeout_str = app.config.get('SESSION_TIMEOUT', '31d')
|
||||
session.permanent = True
|
||||
session.permanent_session_lifetime = convert_to_timedelta(session_timeout_str)
|
||||
|
||||
# Inform our user analytics that we have a new "lead"
|
||||
user_analytics.create_lead(db_user.email, db_user.username)
|
||||
|
||||
return True
|
||||
else:
|
||||
logger.debug('User could not be logged in, inactive?.')
|
||||
|
|
|
@ -113,6 +113,13 @@ def google_oauth_callback():
|
|||
if not user_data or not user_data.get('id', None) or not user_data.get('email', None):
|
||||
return render_ologin_error('Google')
|
||||
|
||||
if not user_data.get('verified_email', False):
|
||||
return render_ologin_error(
|
||||
'Google',
|
||||
'A verified e-mail address is required for login. Please verify your ' +
|
||||
'e-mail address in Google and try again.',
|
||||
)
|
||||
|
||||
username = get_email_username(user_data)
|
||||
metadata = {
|
||||
'service_username': user_data['email']
|
||||
|
@ -196,6 +203,13 @@ def google_oauth_attach():
|
|||
if not user_data or not user_data.get('id', None):
|
||||
return render_ologin_error('Google')
|
||||
|
||||
if not user_data.get('verified_email', False):
|
||||
return render_ologin_error(
|
||||
'Google',
|
||||
'A verified e-mail address is required for login. Please verify your ' +
|
||||
'e-mail address in Google and try again.',
|
||||
)
|
||||
|
||||
google_id = user_data['id']
|
||||
user_obj = current_user.db_user()
|
||||
|
||||
|
|
|
@ -393,7 +393,6 @@ def confirm_email():
|
|||
user_analytics.change_email(old_email, new_email)
|
||||
|
||||
common_login(user)
|
||||
|
||||
return redirect(url_for('web.user', tab='email') if new_email else url_for('web.index'))
|
||||
|
||||
|
||||
|
|
41
util/timedeltastring.py
Normal file
41
util/timedeltastring.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
from datetime import timedelta
|
||||
|
||||
def convert_to_timedelta(time_val):
|
||||
"""
|
||||
From: code.activestate.com/recipes/577894-convert-strings-like-5d-and-60s-to-timedelta-objec
|
||||
|
||||
Given a *time_val* (string) such as '5d', returns a timedelta object
|
||||
representing the given value (e.g. timedelta(days=5)). Accepts the
|
||||
following '<num><char>' formats:
|
||||
|
||||
========= ======= ===================
|
||||
Character Meaning Example
|
||||
========= ======= ===================
|
||||
s Seconds '60s' -> 60 Seconds
|
||||
m Minutes '5m' -> 5 Minutes
|
||||
h Hours '24h' -> 24 Hours
|
||||
d Days '7d' -> 7 Days
|
||||
========= ======= ===================
|
||||
|
||||
Examples::
|
||||
|
||||
>>> convert_to_timedelta('7d')
|
||||
datetime.timedelta(7)
|
||||
>>> convert_to_timedelta('24h')
|
||||
datetime.timedelta(1)
|
||||
>>> convert_to_timedelta('60m')
|
||||
datetime.timedelta(0, 3600)
|
||||
>>> convert_to_timedelta('120s')
|
||||
datetime.timedelta(0, 120)
|
||||
"""
|
||||
num = int(time_val[:-1])
|
||||
if time_val.endswith('s'):
|
||||
return timedelta(seconds=num)
|
||||
elif time_val.endswith('m'):
|
||||
return timedelta(minutes=num)
|
||||
elif time_val.endswith('h'):
|
||||
return timedelta(hours=num)
|
||||
elif time_val.endswith('d'):
|
||||
return timedelta(days=num)
|
||||
else:
|
||||
raise ValueError('Unknown suffix on timedelta: %s' % time_val)
|
Reference in a new issue