From 7690d5d495ed7742fb74812dd718346bc2a591fe Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Fri, 15 Feb 2019 15:29:57 -0500 Subject: [PATCH] Have the V2 registry endpoints raise Unauthorized with the proper header when anonymous access is disabled Before this change, we'd raise a generic 401, which was breaking containerd and cri-o. Fixes https://jira.coreos.com/browse/QUAY-1332 --- endpoints/v2/__init__.py | 3 +++ test/registry/protocol_v2.py | 14 ++++++++++---- test/registry/protocols.py | 1 + test/registry/registry_tests.py | 6 +++++- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/endpoints/v2/__init__.py b/endpoints/v2/__init__.py index d20ad76df..5252310c5 100644 --- a/endpoints/v2/__init__.py +++ b/endpoints/v2/__init__.py @@ -107,6 +107,9 @@ def _require_repo_permission(permission_class, scopes=None, allow_public=False): raise Unsupported(detail=msg) if repository_ref.is_public: + if not features.ANONYMOUS_ACCESS: + raise Unauthorized(repository=repository, scopes=scopes) + return func(namespace_name, repo_name, *args, **kwargs) raise Unauthorized(repository=repository, scopes=scopes) diff --git a/test/registry/protocol_v2.py b/test/registry/protocol_v2.py index 405d3be4c..221c3af67 100644 --- a/test/registry/protocol_v2.py +++ b/test/registry/protocol_v2.py @@ -49,6 +49,7 @@ class V2Protocol(RegistryProtocol): Failures.UNKNOWN_TAG: 404, Failures.UNAUTHORIZED: 401, Failures.DISALLOWED_LIBRARY_NAMESPACE: 400, + Failures.ANONYMOUS_NOT_ALLOWED: 401, }, V2ProtocolSteps.GET_BLOB: { Failures.GEO_BLOCKED: 403, @@ -523,12 +524,14 @@ class V2Protocol(RegistryProtocol): # Perform auth and retrieve a token. token, _ = self.auth(session, credentials, namespace, repo_name, scopes=scopes, expected_failure=expected_failure) - if token is None: + if token is None and not options.attempt_pull_without_token: return None - headers = { - 'Authorization': 'Bearer ' + token, - } + headers = {} + if token: + headers = { + 'Authorization': 'Bearer ' + token, + } if self.schema2: headers['Accept'] = ','.join(options.accept_mimetypes @@ -544,6 +547,9 @@ class V2Protocol(RegistryProtocol): tag_name), expected_status=(200, expected_failure, V2ProtocolSteps.GET_MANIFEST), headers=headers) + if response.status_code == 401: + assert 'WWW-Authenticate' in response.headers + response.encoding = 'utf-8' if expected_failure is not None: return None diff --git a/test/registry/protocols.py b/test/registry/protocols.py index c28875240..a143f7261 100644 --- a/test/registry/protocols.py +++ b/test/registry/protocols.py @@ -82,6 +82,7 @@ class ProtocolOptions(object): self.request_addr = None self.skip_blob_push_checks = False self.ensure_ascii = True + self.attempt_pull_without_token = False @add_metaclass(ABCMeta) diff --git a/test/registry/registry_tests.py b/test/registry/registry_tests.py index da88aac9a..d22d191a0 100644 --- a/test/registry/registry_tests.py +++ b/test/registry/registry_tests.py @@ -350,8 +350,12 @@ def test_pull_publicrepo_no_anonymous_access(pusher, puller, basic_images, lives with FeatureFlagValue('ANONYMOUS_ACCESS', False, registry_server_executor.on(liveserver)): # Attempt again to pull the (now public) repo anonymously, which should fail since # the feature flag for anonymous access is turned off. + options = ProtocolOptions() + options.attempt_pull_without_token = True + puller.pull(liveserver_session, 'public', 'newrepo', 'latest', basic_images, - expected_failure=Failures.ANONYMOUS_NOT_ALLOWED) + expected_failure=Failures.ANONYMOUS_NOT_ALLOWED, + options=options) # Using a non-public user should now succeed. puller.pull(liveserver_session, 'public', 'newrepo', 'latest', basic_images,