Fix issue with Docker 1.8.3 and pulling public repos with no creds

We now return the valid subset of auth scopes requested.

Adds a test for this case and adds testing of all returned JWTs in the V2 login tests
This commit is contained in:
Joseph Schorr 2016-01-22 16:49:32 -05:00
parent 566a91f003
commit 8cd38569d6
5 changed files with 202 additions and 148 deletions

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,