diff --git a/endpoints/decorators.py b/endpoints/decorators.py index 3e91a074c..b863a8062 100644 --- a/endpoints/decorators.py +++ b/endpoints/decorators.py @@ -9,7 +9,7 @@ import features from app import app from auth.auth_context import get_authenticated_context -from util.names import parse_namespace_repository +from util.names import parse_namespace_repository, ImplicitLibraryNamespaceNotAllowed from util.http import abort logger = logging.getLogger(__name__) @@ -26,9 +26,14 @@ def parse_repository_name(include_tag=False, def inner(func): @wraps(func) def wrapper(*args, **kwargs): - repo_name_components = parse_namespace_repository(kwargs[incoming_repo_kwarg], - app.config['LIBRARY_NAMESPACE'], - include_tag=include_tag) + try: + repo_name_components = parse_namespace_repository(kwargs[incoming_repo_kwarg], + app.config['LIBRARY_NAMESPACE'], + include_tag=include_tag, + allow_library=features.LIBRARY_SUPPORT) + except ImplicitLibraryNamespaceNotAllowed: + abort(400) + del kwargs[incoming_repo_kwarg] kwargs[ns_kwarg_name] = repo_name_components[0] kwargs[repo_kwarg_name] = repo_name_components[1] diff --git a/util/names.py b/util/names.py index 9fb6f3064..e8eb72645 100644 --- a/util/names.py +++ b/util/names.py @@ -14,6 +14,13 @@ TAG_REGEX = re.compile(FULL_TAG_PATTERN) TAG_ERROR = ('Invalid tag: must match [A-Za-z0-9_.-], NOT start with "." or "-", ' 'and can contain 1-128 characters') + +class ImplicitLibraryNamespaceNotAllowed(Exception): + """ Exception raised if the implicit library namespace was specified but is + not allowed. """ + pass + + def escape_tag(tag, default='latest'): """ Escapes a Docker tag, ensuring it matches the tag regular expression. """ if not tag: @@ -24,13 +31,16 @@ def escape_tag(tag, default='latest'): return tag[0:127] -def parse_namespace_repository(repository, library_namespace, include_tag=False): +def parse_namespace_repository(repository, library_namespace, include_tag=False, + allow_library=True): repository = repository.encode('unidecode', 'ignore') parts = repository.rstrip('/').split('/', 1) if len(parts) < 2: namespace = library_namespace repository = parts[0] + if not allow_library: + raise ImplicitLibraryNamespaceNotAllowed() else: (namespace, repository) = parts