Merge pull request #2499 from coreos-inc/docker-400

Better error messages for Docker errors
This commit is contained in:
josephschorr 2017-04-03 11:39:07 -04:00 committed by GitHub
commit 3f0f8159b7
2 changed files with 25 additions and 14 deletions

View file

@ -80,9 +80,9 @@ class ManifestUnverified(V2RegistryException):
class NameInvalid(V2RegistryException): class NameInvalid(V2RegistryException):
def __init__(self, detail=None): def __init__(self, detail=None, message=None):
super(NameInvalid, self).__init__('NAME_INVALID', super(NameInvalid, self).__init__('NAME_INVALID',
'invalid repository name', message or 'invalid repository name',
detail) detail)
@ -141,9 +141,9 @@ class Unauthorized(V2RegistryException):
class Unsupported(V2RegistryException): class Unsupported(V2RegistryException):
def __init__(self, detail=None): def __init__(self, detail=None, message=None):
super(Unsupported, self).__init__('UNSUPPORTED', super(Unsupported, self).__init__('UNSUPPORTED',
'The operation is unsupported.', message or 'The operation is unsupported.',
detail, detail,
405) 405)
@ -155,3 +155,11 @@ class InvalidLogin(V2RegistryException):
{}, {},
401) 401)
class InvalidRequest(V2RegistryException):
def __init__(self, message=None):
super(InvalidRequest, self).__init__('INVALID_REQUEST',
message or 'Invalid request',
{},
400)

View file

@ -11,7 +11,7 @@ from auth.permissions import (ModifyRepositoryPermission, ReadRepositoryPermissi
CreateRepositoryPermission, AdministerRepositoryPermission) CreateRepositoryPermission, AdministerRepositoryPermission)
from endpoints.decorators import anon_protect from endpoints.decorators import anon_protect
from endpoints.v2 import v2_bp from endpoints.v2 import v2_bp
from endpoints.v2.errors import InvalidLogin from endpoints.v2.errors import InvalidLogin, NameInvalid, InvalidRequest, Unsupported, Unauthorized
from data.interfaces.v2 import pre_oci_model as model from data.interfaces.v2 import pre_oci_model as model
from util.cache import no_cache from util.cache import no_cache
from util.names import parse_namespace_repository, REPOSITORY_NAME_REGEX from util.names import parse_namespace_repository, REPOSITORY_NAME_REGEX
@ -21,8 +21,7 @@ logger = logging.getLogger(__name__)
TOKEN_VALIDITY_LIFETIME_S = 60 * 60 # 1 hour TOKEN_VALIDITY_LIFETIME_S = 60 * 60 # 1 hour
SCOPE_REGEX_TEMPLATE = r'^repository:((?:{}\/)?((?:[\.a-zA-Z0-9_\-]+\/)?[\.a-zA-Z0-9_\-]+)):((?:push|pull|\*)(?:,(?:push|pull|\*))*)$' SCOPE_REGEX_TEMPLATE = r'^repository:((?:{}\/)?((?:[\.a-zA-Z0-9_\-]+\/)*[\.a-zA-Z0-9_\-]+)):((?:push|pull|\*)(?:,(?:push|pull|\*))*)$'
@lru_cache(maxsize=1) @lru_cache(maxsize=1)
def get_scope_regex(): def get_scope_regex():
@ -73,7 +72,7 @@ def generate_registry_jwt(auth_result):
logger.debug('Match: %s', match) logger.debug('Match: %s', match)
logger.debug('len: %s', len(scope_param)) logger.debug('len: %s', len(scope_param))
logger.warning('Unable to decode repository and actions: %s', scope_param) logger.warning('Unable to decode repository and actions: %s', scope_param)
abort(400) raise InvalidRequest('Unable to decode repository and actions: %s' % scope_param)
logger.debug('Match: %s', match.groups()) logger.debug('Match: %s', match.groups())
@ -87,7 +86,11 @@ def generate_registry_jwt(auth_result):
# Ensure that we are never creating an invalid repository. # Ensure that we are never creating an invalid repository.
if not REPOSITORY_NAME_REGEX.match(reponame): if not REPOSITORY_NAME_REGEX.match(reponame):
logger.debug('Found invalid repository name in auth flow: %s', reponame) logger.debug('Found invalid repository name in auth flow: %s', reponame)
abort(400) if len(namespace_and_repo.split('/')) > 1:
msg = 'Nested repositories are not supported. Found: %s' % namespace_and_repo
raise NameInvalid(message=msg)
raise NameInvalid(message='Invalid repository name: %s' % namespace_and_repo)
final_actions = [] final_actions = []
@ -108,7 +111,7 @@ def generate_registry_jwt(auth_result):
if repo: if repo:
if ModifyRepositoryPermission(namespace, reponame).can(): if ModifyRepositoryPermission(namespace, reponame).can():
if repo.kind != 'image': if repo.kind != 'image':
abort(405, invalid_repo_message) raise Unsupported(message=invalid_repo_message)
final_actions.append('push') final_actions.append('push')
else: else:
@ -125,7 +128,7 @@ def generate_registry_jwt(auth_result):
# Grant pull if the user can read the repo or it is public. # Grant pull if the user can read the repo or it is public.
if ReadRepositoryPermission(namespace, reponame).can() or repo_is_public: if ReadRepositoryPermission(namespace, reponame).can() or repo_is_public:
if repo is not None and repo.kind != 'image': if repo is not None and repo.kind != 'image':
abort(405, invalid_repo_message) raise Unsupported(message=invalid_repo_message)
final_actions.append('pull') final_actions.append('pull')
else: else:
@ -135,7 +138,7 @@ def generate_registry_jwt(auth_result):
# Grant * user is admin # Grant * user is admin
if AdministerRepositoryPermission(namespace, reponame).can(): if AdministerRepositoryPermission(namespace, reponame).can():
if repo is not None and repo.kind != 'image': if repo is not None and repo.kind != 'image':
abort(405, invalid_repo_message) raise Unsupported(message=invalid_repo_message)
final_actions.append('*') final_actions.append('*')
else: else:
@ -161,13 +164,13 @@ def generate_registry_jwt(auth_result):
'repository': reponame, 'repository': reponame,
'namespace': namespace, 'namespace': namespace,
} }
tuf_root = get_tuf_root(namespace, reponame) tuf_root = get_tuf_root(namespace, reponame)
elif user is None and token is None: elif user is None and token is None:
# In this case, we are doing an auth flow, and it's not an anonymous pull # In this case, we are doing an auth flow, and it's not an anonymous pull
logger.debug('No user and no token sent for empty scope list') logger.debug('No user and no token sent for empty scope list')
abort(401) raise Unauthorized()
# Send the user event. # Send the user event.
if user is not None: if user is not None: