Refactor auth code to be cleaner and more extensible

We move all the auth handling, serialization and deserialization into a new AuthContext interface, and then standardize a registration model for handling of specific auth context types (user, robot, token, etc).
This commit is contained in:
Joseph Schorr 2018-01-05 16:27:03 -05:00
parent 8ba2e71fb1
commit e220b50543
31 changed files with 822 additions and 436 deletions

View file

@ -7,9 +7,7 @@ from flask import request
from app import analytics, userevents, ip_resolver
from data import model
from auth.registry_jwt_auth import get_granted_entity
from auth.auth_context import (get_authenticated_user, get_validated_token,
get_validated_oauth_token, get_validated_app_specific_token)
from auth.auth_context import get_authenticated_context, get_authenticated_user
logger = logging.getLogger(__name__)
@ -22,51 +20,16 @@ def track_and_log(event_name, repo_obj, analytics_name=None, analytics_sample=1,
}
metadata.update(kwargs)
# Add auth context metadata.
analytics_id = 'anonymous'
authenticated_oauth_token = get_validated_oauth_token()
authenticated_user = get_authenticated_user()
authenticated_token = get_validated_token() if not authenticated_user else None
app_specific_token = get_validated_app_specific_token()
if (not authenticated_user and not authenticated_token and not authenticated_oauth_token and
not app_specific_token):
entity = get_granted_entity()
if entity:
authenticated_user = entity.user
authenticated_token = entity.token
authenticated_oauth_token = entity.oauth
app_specific_token = entity.app_specific_token
logger.debug('Logging the %s to Mixpanel and the log system', event_name)
if authenticated_oauth_token:
metadata['oauth_token_id'] = authenticated_oauth_token.id
metadata['oauth_token_application_id'] = authenticated_oauth_token.application.client_id
metadata['oauth_token_application'] = authenticated_oauth_token.application.name
metadata['username'] = authenticated_user.username
analytics_id = 'oauth:{0}'.format(authenticated_oauth_token.id)
elif app_specific_token:
metadata['app_specific_token'] = app_specific_token.uuid
metadata['username'] = authenticated_user.username
analytics_id = 'appspecifictoken:{0}'.format(app_specific_token.uuid)
elif authenticated_user:
metadata['username'] = authenticated_user.username
analytics_id = authenticated_user.username
elif authenticated_token:
metadata['token'] = authenticated_token.friendly_name
metadata['token_code'] = authenticated_token.code
if authenticated_token.kind:
metadata['token_type'] = authenticated_token.kind.name
analytics_id = 'token:{0}'.format(authenticated_token.code)
else:
metadata['public'] = True
analytics_id = 'anonymous'
auth_context = get_authenticated_context()
if auth_context is not None:
analytics_id, context_metadata = auth_context.analytics_id_and_public_metadata()
metadata.update(context_metadata)
# Publish the user event (if applicable)
logger.debug('Checking publishing %s to the user events system', event_name)
if authenticated_user and not authenticated_user.robot:
if auth_context and auth_context.has_nonrobot_user:
logger.debug('Publishing %s to the user events system', event_name)
user_event_data = {
'action': event_name,
@ -74,7 +37,7 @@ def track_and_log(event_name, repo_obj, analytics_name=None, analytics_sample=1,
'namespace': namespace_name,
}
event = userevents.get_event(authenticated_user.username)
event = userevents.get_event(auth_context.authed_user.username)
event.publish_event_data('docker-cli', user_event_data)
# Save the action to mixpanel.
@ -100,6 +63,6 @@ def track_and_log(event_name, repo_obj, analytics_name=None, analytics_sample=1,
# Log the action to the database.
logger.debug('Logging the %s to logs system', event_name)
model.log.log_action(event_name, namespace_name, performer=authenticated_user,
model.log.log_action(event_name, namespace_name, performer=get_authenticated_user(),
ip=request.remote_addr, metadata=metadata, repository=repo_obj)
logger.debug('Track and log of %s complete', event_name)