Merge pull request #3365 from quay/joseph.schorr/QUAY-1332/anon-access-header

Have the V2 registry endpoints raise Unauthorized with the proper header when anonymous access is disabled
This commit is contained in:
Joseph Schorr 2019-02-18 13:08:25 -05:00 committed by GitHub
commit 15ec09cb58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 19 additions and 5 deletions

View file

@ -107,6 +107,9 @@ def _require_repo_permission(permission_class, scopes=None, allow_public=False):
raise Unsupported(detail=msg) raise Unsupported(detail=msg)
if repository_ref.is_public: if repository_ref.is_public:
if not features.ANONYMOUS_ACCESS:
raise Unauthorized(repository=repository, scopes=scopes)
return func(namespace_name, repo_name, *args, **kwargs) return func(namespace_name, repo_name, *args, **kwargs)
raise Unauthorized(repository=repository, scopes=scopes) raise Unauthorized(repository=repository, scopes=scopes)

View file

@ -49,6 +49,7 @@ class V2Protocol(RegistryProtocol):
Failures.UNKNOWN_TAG: 404, Failures.UNKNOWN_TAG: 404,
Failures.UNAUTHORIZED: 401, Failures.UNAUTHORIZED: 401,
Failures.DISALLOWED_LIBRARY_NAMESPACE: 400, Failures.DISALLOWED_LIBRARY_NAMESPACE: 400,
Failures.ANONYMOUS_NOT_ALLOWED: 401,
}, },
V2ProtocolSteps.GET_BLOB: { V2ProtocolSteps.GET_BLOB: {
Failures.GEO_BLOCKED: 403, Failures.GEO_BLOCKED: 403,
@ -523,9 +524,11 @@ class V2Protocol(RegistryProtocol):
# Perform auth and retrieve a token. # Perform auth and retrieve a token.
token, _ = self.auth(session, credentials, namespace, repo_name, scopes=scopes, token, _ = self.auth(session, credentials, namespace, repo_name, scopes=scopes,
expected_failure=expected_failure) expected_failure=expected_failure)
if token is None: if token is None and not options.attempt_pull_without_token:
return None return None
headers = {}
if token:
headers = { headers = {
'Authorization': 'Bearer ' + token, 'Authorization': 'Bearer ' + token,
} }
@ -544,6 +547,9 @@ class V2Protocol(RegistryProtocol):
tag_name), tag_name),
expected_status=(200, expected_failure, V2ProtocolSteps.GET_MANIFEST), expected_status=(200, expected_failure, V2ProtocolSteps.GET_MANIFEST),
headers=headers) headers=headers)
if response.status_code == 401:
assert 'WWW-Authenticate' in response.headers
response.encoding = 'utf-8' response.encoding = 'utf-8'
if expected_failure is not None: if expected_failure is not None:
return None return None

View file

@ -82,6 +82,7 @@ class ProtocolOptions(object):
self.request_addr = None self.request_addr = None
self.skip_blob_push_checks = False self.skip_blob_push_checks = False
self.ensure_ascii = True self.ensure_ascii = True
self.attempt_pull_without_token = False
@add_metaclass(ABCMeta) @add_metaclass(ABCMeta)

View file

@ -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)): with FeatureFlagValue('ANONYMOUS_ACCESS', False, registry_server_executor.on(liveserver)):
# Attempt again to pull the (now public) repo anonymously, which should fail since # Attempt again to pull the (now public) repo anonymously, which should fail since
# the feature flag for anonymous access is turned off. # 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, 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. # Using a non-public user should now succeed.
puller.pull(liveserver_session, 'public', 'newrepo', 'latest', basic_images, puller.pull(liveserver_session, 'public', 'newrepo', 'latest', basic_images,