From a9c0e016f34e821bfef3c2c900b326829a79185b Mon Sep 17 00:00:00 2001 From: jakedt Date: Thu, 20 Mar 2014 12:09:25 -0400 Subject: [PATCH] Add the ability to use an oauth token to interact with the index and registry. --- auth/auth.py | 67 ++++++++++++++++++++++++++-------------------- endpoints/index.py | 8 ++++++ 2 files changed, 46 insertions(+), 29 deletions(-) diff --git a/auth/auth.py b/auth/auth.py index e0246fa15..fc317067b 100644 --- a/auth/auth.py +++ b/auth/auth.py @@ -21,6 +21,39 @@ from util.http import abort logger = logging.getLogger(__name__) +def validate_and_apply_oauth_token(token): + validated = oauth.validate_access_token(token) + if not validated: + logger.warning('OAuth access token could not be validated: %s', token) + authenticate_header = { + 'WWW-Authenticate': ('Bearer error="invalid_token", ' + 'error_description="The access token is invalid"'), + } + abort(401, message='OAuth access token could not be validated: %(token)s', + issue='invalid-oauth-token', token=token, header=authenticate_header) + elif validated.expires_at <= datetime.now(): + logger.info('OAuth access with an expired token: %s', token) + authenticate_header = { + 'WWW-Authenticate': ('Bearer error="invalid_token", ' + 'error_description="The access token expired"'), + } + abort(401, message='OAuth access token has expired: %(token)s', + issue='invalid-oauth-token', token=token, headers=authenticate_header) + + # We have a valid token + scope_set = scopes.scopes_from_scope_string(validated.scope) + logger.debug('Successfully validated oauth access token: %s with scope: %s', token, + scope_set) + + set_authenticated_user(validated.authorized_user) + set_validated_oauth_token(validated) + + new_identity = QuayDeferredPermissionUser(validated.authorized_user.username, 'username', + scope_set) + identity_changed.send(app, identity=new_identity) + + + def process_basic_auth(auth): normalized = [part.strip() for part in auth.split(' ') if part] if normalized[0].lower() != 'basic' or len(normalized) != 2: @@ -45,6 +78,10 @@ def process_basic_auth(auth): except model.DataModelException: logger.debug('Invalid token: %s' % credentials[1]) + elif credentials[0] == '$oauthtoken': + oauth_token = credentials[1] + validate_and_apply_oauth_token(oauth_token) + elif '+' in credentials[0]: logger.debug('Trying robot auth with credentials %s' % str(credentials)) # Use as robot auth @@ -120,35 +157,7 @@ def process_oauth(f): return token = normalized[1] - validated = oauth.validate_access_token(token) - if not validated: - logger.warning('OAuth access token could not be validated: %s', token) - authenticate_header = { - 'WWW-Authenticate': ('Bearer error="invalid_token", ' - 'error_description="The access token is invalid"'), - } - abort(401, message='OAuth access token could not be validated: %(token)s', - issue='invalid-oauth-token', token=token, header=authenticate_header) - elif validated.expires_at <= datetime.now(): - logger.info('OAuth access with an expired token: %s', token) - authenticate_header = { - 'WWW-Authenticate': ('Bearer error="invalid_token", ' - 'error_description="The access token expired"'), - } - abort(401, message='OAuth access token has expired: %(token)s', - issue='invalid-oauth-token', token=token, headers=authenticate_header) - - # We have a valid token - scope_set = scopes.scopes_from_scope_string(validated.scope) - logger.debug('Successfully validated oauth access token: %s with scope: %s', token, - scope_set) - - set_authenticated_user(validated.authorized_user) - set_validated_oauth_token(validated) - - new_identity = QuayDeferredPermissionUser(validated.authorized_user.username, 'username', - scope_set) - identity_changed.send(app, identity=new_identity) + validate_and_apply_oauth_token(token) elif not current_user.is_anonymous(): logger.debug('Loading user from cookie: %s', current_user.get_id()) set_authenticated_user_deferred(current_user.get_id()) diff --git a/endpoints/index.py b/endpoints/index.py index 44c088050..33e3c3d79 100644 --- a/endpoints/index.py +++ b/endpoints/index.py @@ -7,6 +7,7 @@ from functools import wraps from collections import OrderedDict from data import model +from data.model import oauth from data.queue import webhook_queue from app import mixpanel, app from auth.auth import process_auth @@ -78,6 +79,13 @@ def create_user(): except model.InvalidTokenException: abort(400, 'Invalid access token.', issue='invalid-access-token') + elif username == '$oauthtoken': + validated = oauth.validate_access_token(password) + if validated is not None: + return success + else: + abort(400, 'Invalid oauth access token.', issue='invalid-oauth-access-token') + elif '+' in username: try: model.verify_robot(username, password)