Merge pull request #1162 from coreos-inc/publicnocredauth

Fix issue with Docker 1.8.3 and pulling public repos with no creds
This commit is contained in:
josephschorr 2016-01-25 16:07:55 -05:00
commit b081e234f8
5 changed files with 202 additions and 148 deletions

View file

@ -9,7 +9,7 @@ import features
from app import metric_queue
from endpoints.decorators import anon_protect, anon_allowed
from endpoints.v2.errors import V2RegistryException
from endpoints.v2.errors import V2RegistryException, Unauthorized
from auth.auth_context import get_grant_context
from auth.permissions import (ReadRepositoryPermission, ModifyRepositoryPermission,
AdministerRepositoryPermission)
@ -45,7 +45,7 @@ def _require_repo_permission(permission_class, allow_public=False):
(allow_public and
model.repository.repository_is_public(namespace, repo_name))):
return func(namespace, repo_name, *args, **kwargs)
raise abort(401)
raise Unauthorized()
return wrapped
return wrapper

View file

@ -61,6 +61,12 @@ def generate_registry_jwt():
oauthtoken = get_validated_oauth_token()
logger.debug('Authenticated OAuth token: %s', oauthtoken)
auth_credentials_sent = bool(request.headers.get('authorization', ''))
if auth_credentials_sent and not user and not token:
# The auth credentials sent for the user are invalid.
logger.debug('Invalid auth credentials')
abort(401)
access = []
user_event_data = {
'action': 'login',
@ -84,7 +90,7 @@ def generate_registry_jwt():
# Ensure that we are never creating an invalid repository.
if not REPOSITORY_NAME_REGEX.match(reponame):
logger.debug('Found invalid repository name in auth flow: %v', reponame)
logger.debug('Found invalid repository name in auth flow: %s', reponame)
abort(400)
final_actions = []
@ -92,38 +98,30 @@ def generate_registry_jwt():
if 'push' in actions:
# If there is no valid user or token, then the repository cannot be
# accessed.
if user is None and token is None:
logger.debug('No user and no token for requested "push" scope')
abort(401)
# Lookup the repository. If it exists, make sure the entity has modify
# permission. Otherwise, make sure the entity has create permission.
repo = model.repository.get_repository(namespace, reponame)
if repo:
if not ModifyRepositoryPermission(namespace, reponame).can():
logger.debug('No permission to modify repository %v/%v', namespace, reponame)
abort(403)
else:
if not CreateRepositoryPermission(namespace).can() or user is None:
logger.debug('No permission to create repository %v/%v', namespace, reponame)
abort(403)
logger.debug('Creating repository: %s/%s', namespace, reponame)
model.repository.create_repository(namespace, reponame, user)
final_actions.append('push')
if user is not None or token is not None:
# Lookup the repository. If it exists, make sure the entity has modify
# permission. Otherwise, make sure the entity has create permission.
repo = model.repository.get_repository(namespace, reponame)
if repo:
if ModifyRepositoryPermission(namespace, reponame).can():
final_actions.append('push')
else:
logger.debug('No permission to modify repository %s/%s', namespace, reponame)
else:
if CreateRepositoryPermission(namespace).can() and user is not None:
logger.debug('Creating repository: %s/%s', namespace, reponame)
model.repository.create_repository(namespace, reponame, user)
final_actions.append('push')
else:
logger.debug('No permission to create repository %s/%s', namespace, reponame)
if 'pull' in actions:
# Grant pull if the user can read the repo or it is public. We also
# grant it if the user already has push, as they can clearly change
# the repository.
# Grant pull if the user can read the repo or it is public.
if (ReadRepositoryPermission(namespace, reponame).can() or
model.repository.repository_is_public(namespace, reponame) or
'push' in final_actions):
model.repository.repository_is_public(namespace, reponame)):
final_actions.append('pull')
else:
logger.debug('No permission to pull repository %v/%v', namespace, reponame)
abort(403)
logger.debug('No permission to pull repository %s/%s', namespace, reponame)
# Add the access for the JWT.
access.append({
@ -137,6 +135,8 @@ def generate_registry_jwt():
user_action = 'push_start'
elif 'pull' in final_actions:
user_action = 'pull_start'
else:
user_action = 'login'
user_event_data = {
'action': user_action,