diff --git a/auth/auth.py b/auth/auth.py index b8d9065e6..d80915f90 100644 --- a/auth/auth.py +++ b/auth/auth.py @@ -22,9 +22,8 @@ from util.http import abort logger = logging.getLogger(__name__) - -SIGNATURE_PREFIX = 'signature=' - +DEPRECATED_SIGNATURE_PREFIX = 'signature' +SIGNATURE_PREFIX = 'sigv2=' def _load_user_from_cookie(): if not current_user.is_anonymous(): @@ -196,6 +195,9 @@ def process_auth(func): if auth: logger.debug('Validating auth header: %s' % auth) _process_signed_grant(auth) + + # TODO(jschorr): Remove this once the new version is in prod for a day. + _process_token_deprecated(auth) _process_basic_auth(auth) else: logger.debug('No auth header.') @@ -223,3 +225,46 @@ def extract_namespace_repo_from_session(func): return func(session['namespace'], session['repository'], *args, **kwargs) return wrapper + + +def _process_token_deprecated(auth): + normalized = [part.strip() for part in auth.split(' ') if part] + if normalized[0].lower() != 'token' or len(normalized) != 2: + logger.debug('Not an auth token: %s' % auth) + return + + # Skip new tokens. + if SIGNATURE_PREFIX in normalized[1]: + return + + token_details = normalized[1].split(',') + + if len(token_details) != 1: + logger.warning('Invalid token format: %s' % auth) + abort(401, message='Invalid token format: %(auth)s', issue='invalid-auth-token', auth=auth) + + def safe_get(lst, index, default_value): + try: + return lst[index] + except IndexError: + return default_value + + token_vals = {val[0]: safe_get(val, 1, '') for val in + (detail.split('=') for detail in token_details)} + + if DEPRECATED_SIGNATURE_PREFIX not in token_vals: + logger.warning('Token does not contain signature: %s' % auth) + abort(401, message='Token does not contain a valid signature: %(auth)s', + issue='invalid-auth-token', auth=auth) + + try: + token_data = model.load_token_data(token_vals[DEPRECATED_SIGNATURE_PREFIX]) + except model.InvalidTokenException: + logger.warning('Token could not be validated: %s', token_vals[DEPRECATED_SIGNATURE_PREFIX]) + abort(401, message='Token could not be validated: %(auth)s', issue='invalid-auth-token', + auth=auth) + + logger.debug('Successfully validated token: %s', token_data.code) + set_validated_token(token_data) + + identity_changed.send(app, identity=Identity(token_data.code, 'token')) \ No newline at end of file