Prevent registry operations against disabled namespaces

Allows admins to completely wall off a namespace by disabling it

Fixes https://jira.coreos.com/browse/QUAY-869
This commit is contained in:
Joseph Schorr 2018-05-22 18:36:04 -04:00
parent 6ffafe44d3
commit f86c087b3b
14 changed files with 102 additions and 1 deletions

View file

@ -99,6 +99,12 @@ def registry_server_executor(app):
model.repository.create_repository(namespace, name, user, repo_kind='application')
return 'OK'
def disable_namespace(namespace):
namespace_obj = model.user.get_namespace_user(namespace)
namespace_obj.enabled = False
namespace_obj.save()
return 'OK'
executor = LiveServerExecutor()
executor.register('generate_csrf', generate_csrf)
executor.register('set_supports_direct_download', set_supports_direct_download)
@ -111,6 +117,7 @@ def registry_server_executor(app):
executor.register('break_database', break_database)
executor.register('reload_app', reload_app)
executor.register('create_app_repository', create_app_repository)
executor.register('disable_namespace', disable_namespace)
return executor

View file

@ -23,6 +23,7 @@ class V1Protocol(RegistryProtocol):
Failures.APP_REPOSITORY: 405,
Failures.INVALID_REPOSITORY: 404,
Failures.DISALLOWED_LIBRARY_NAMESPACE: 400,
Failures.NAMESPACE_DISABLED: 400,
},
V1ProtocolSteps.GET_IMAGES: {
Failures.UNAUTHENTICATED: 403,
@ -30,11 +31,13 @@ class V1Protocol(RegistryProtocol):
Failures.APP_REPOSITORY: 405,
Failures.ANONYMOUS_NOT_ALLOWED: 401,
Failures.DISALLOWED_LIBRARY_NAMESPACE: 400,
Failures.NAMESPACE_DISABLED: 400,
},
V1ProtocolSteps.PUT_TAG: {
Failures.MISSING_TAG: 404,
Failures.INVALID_TAG: 400,
Failures.INVALID_IMAGES: 400,
Failures.NAMESPACE_DISABLED: 400,
},
}

View file

@ -25,6 +25,7 @@ class V2Protocol(RegistryProtocol):
Failures.APP_REPOSITORY: 405,
Failures.ANONYMOUS_NOT_ALLOWED: 401,
Failures.INVALID_REPOSITORY: 400,
Failures.NAMESPACE_DISABLED: 400,
},
V2ProtocolSteps.GET_MANIFEST: {
Failures.UNKNOWN_TAG: 404,

View file

@ -50,6 +50,7 @@ class Failures(Enum):
INVALID_IMAGES = 'invalid-images'
UNSUPPORTED_CONTENT_TYPE = 'unsupported-content-type'
INVALID_BLOB = 'invalid-blob'
NAMESPACE_DISABLED = 'namespace-disabled'
class ProtocolOptions(object):

View file

@ -644,6 +644,36 @@ def test_chunked_uploading_mismatched_chunks(manifest_protocol, random_layer_dat
images, credentials=credentials, options=options)
def test_pull_disabled_namespace(pusher, puller, basic_images, liveserver_session,
app_reloader, liveserver, registry_server_executor):
""" Test: Attempt to pull a repository from a disabled namespace results in an error. """
credentials = ('devtable', 'password')
# Push a new repository.
pusher.push(liveserver_session, 'buynlarge', 'someneworgrepo', 'latest', basic_images,
credentials=credentials)
# Disable the namespace.
registry_server_executor.on(liveserver).disable_namespace('buynlarge')
# Attempt to pull, which should fail.
puller.pull(liveserver_session, 'buynlarge', 'someneworgrepo', 'latest', basic_images,
credentials=credentials, expected_failure=Failures.NAMESPACE_DISABLED)
def test_push_disabled_namespace(pusher, basic_images, liveserver_session,
app_reloader, liveserver, registry_server_executor):
""" Test: Attempt to push a repository from a disabled namespace results in an error. """
credentials = ('devtable', 'password')
# Disable the namespace.
registry_server_executor.on(liveserver).disable_namespace('buynlarge')
# Attempt to push, which should fail.
pusher.push(liveserver_session, 'buynlarge', 'someneworgrepo', 'latest', basic_images,
credentials=credentials, expected_failure=Failures.NAMESPACE_DISABLED)
@pytest.mark.parametrize('public_catalog, credentials, expected_repos', [
# No public access and no credentials => No results.
(False, None, None),