Ensure that we limit the length of repository names
Until now, they'd simply be truncated by the database. Now, we properly check their lengths. Fixes https://jira.coreos.com/browse/QUAY-963
This commit is contained in:
parent
beebe6d5ed
commit
a572fd33c7
6 changed files with 41 additions and 7 deletions
|
@ -96,3 +96,24 @@ def test_list_starred_repos(client):
|
||||||
repos = {r['namespace'] + '/' + r['name'] for r in response['repositories']}
|
repos = {r['namespace'] + '/' + r['name'] for r in response['repositories']}
|
||||||
assert 'devtable/simple' in repos
|
assert 'devtable/simple' in repos
|
||||||
assert 'public/publicrepo' not in repos
|
assert 'public/publicrepo' not in repos
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('repo_name, expected_status', [
|
||||||
|
pytest.param('x' * 255, 201, id='Maximum allowed length'),
|
||||||
|
pytest.param('x' * 256, 400, id='Over allowed length'),
|
||||||
|
pytest.param('a|b', 400, id='Invalid name'),
|
||||||
|
])
|
||||||
|
def test_create_repository(repo_name, expected_status, client):
|
||||||
|
with client_with_identity('devtable', client) as cl:
|
||||||
|
body = {
|
||||||
|
'namespace': 'devtable',
|
||||||
|
'repository': repo_name,
|
||||||
|
'visibility': 'public',
|
||||||
|
'description': 'foo',
|
||||||
|
}
|
||||||
|
|
||||||
|
result = conduct_api_call(client, RepositoryList, 'post', None, body,
|
||||||
|
expected_code=expected_status).json
|
||||||
|
if expected_status == 201:
|
||||||
|
assert result['name'] == repo_name
|
||||||
|
assert model.repository.get_repository('devtable', repo_name).name == repo_name
|
||||||
|
|
|
@ -21,7 +21,8 @@ class V1Protocol(RegistryProtocol):
|
||||||
Failures.UNAUTHENTICATED: 401,
|
Failures.UNAUTHENTICATED: 401,
|
||||||
Failures.UNAUTHORIZED: 403,
|
Failures.UNAUTHORIZED: 403,
|
||||||
Failures.APP_REPOSITORY: 405,
|
Failures.APP_REPOSITORY: 405,
|
||||||
Failures.INVALID_REPOSITORY: 404,
|
Failures.SLASH_REPOSITORY: 404,
|
||||||
|
Failures.INVALID_REPOSITORY: 400,
|
||||||
Failures.DISALLOWED_LIBRARY_NAMESPACE: 400,
|
Failures.DISALLOWED_LIBRARY_NAMESPACE: 400,
|
||||||
Failures.NAMESPACE_DISABLED: 400,
|
Failures.NAMESPACE_DISABLED: 400,
|
||||||
},
|
},
|
||||||
|
|
|
@ -28,6 +28,7 @@ class V2Protocol(RegistryProtocol):
|
||||||
Failures.APP_REPOSITORY: 405,
|
Failures.APP_REPOSITORY: 405,
|
||||||
Failures.ANONYMOUS_NOT_ALLOWED: 401,
|
Failures.ANONYMOUS_NOT_ALLOWED: 401,
|
||||||
Failures.INVALID_REPOSITORY: 400,
|
Failures.INVALID_REPOSITORY: 400,
|
||||||
|
Failures.SLASH_REPOSITORY: 400,
|
||||||
Failures.NAMESPACE_DISABLED: 400,
|
Failures.NAMESPACE_DISABLED: 400,
|
||||||
},
|
},
|
||||||
V2ProtocolSteps.MOUNT_BLOB: {
|
V2ProtocolSteps.MOUNT_BLOB: {
|
||||||
|
|
|
@ -41,6 +41,7 @@ class Failures(Enum):
|
||||||
UNAUTHORIZED = 'unauthorized'
|
UNAUTHORIZED = 'unauthorized'
|
||||||
INVALID_REGISTRY = 'invalid-registry'
|
INVALID_REGISTRY = 'invalid-registry'
|
||||||
INVALID_REPOSITORY = 'invalid-repository'
|
INVALID_REPOSITORY = 'invalid-repository'
|
||||||
|
SLASH_REPOSITORY = 'slash-repository'
|
||||||
APP_REPOSITORY = 'app-repository'
|
APP_REPOSITORY = 'app-repository'
|
||||||
UNKNOWN_TAG = 'unknown-tag'
|
UNKNOWN_TAG = 'unknown-tag'
|
||||||
ANONYMOUS_NOT_ALLOWED = 'anonymous-not-allowed'
|
ANONYMOUS_NOT_ALLOWED = 'anonymous-not-allowed'
|
||||||
|
|
|
@ -362,15 +362,25 @@ def test_image_replication(pusher, basic_images, liveserver_session, app_reloade
|
||||||
assert r.text == 'OK'
|
assert r.text == 'OK'
|
||||||
|
|
||||||
|
|
||||||
def test_push_reponame_with_slashes(pusher, basic_images, liveserver_session, app_reloader):
|
@pytest.mark.parametrize('repo_name, expected_failure', [
|
||||||
""" Test: Attempt to add a repository name with slashes. This should fail as we do not
|
('something', None),
|
||||||
support it.
|
('some/slash', Failures.SLASH_REPOSITORY),
|
||||||
|
pytest.param('x' * 255, None, id='Valid long name'),
|
||||||
|
pytest.param('x' * 256, Failures.INVALID_REPOSITORY, id='Name too long'),
|
||||||
|
])
|
||||||
|
def test_push_reponame(repo_name, expected_failure, pusher, puller, basic_images,
|
||||||
|
liveserver_session, app_reloader):
|
||||||
|
""" Test: Attempt to add a repository with various names.
|
||||||
"""
|
"""
|
||||||
credentials = ('devtable', 'password')
|
credentials = ('devtable', 'password')
|
||||||
|
|
||||||
pusher.push(liveserver_session, 'devtable', 'some/slash', 'latest', basic_images,
|
pusher.push(liveserver_session, 'devtable', repo_name, 'latest', basic_images,
|
||||||
credentials=credentials,
|
credentials=credentials,
|
||||||
expected_failure=Failures.INVALID_REPOSITORY)
|
expected_failure=expected_failure)
|
||||||
|
|
||||||
|
if expected_failure is None:
|
||||||
|
puller.pull(liveserver_session, 'devtable', repo_name, 'latest', basic_images,
|
||||||
|
credentials=credentials)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('tag_name, expected_failure', [
|
@pytest.mark.parametrize('tag_name, expected_failure', [
|
||||||
|
|
|
@ -5,7 +5,7 @@ import anunidecode # Don't listen to pylint's lies. This import is required for
|
||||||
|
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
REPOSITORY_NAME_REGEX = re.compile(r'^[\.a-zA-Z0-9_-]+$')
|
REPOSITORY_NAME_REGEX = re.compile(r'^[\.a-zA-Z0-9_-]{1,255}$')
|
||||||
|
|
||||||
VALID_TAG_PATTERN = r'[\w][\w.-]{0,127}'
|
VALID_TAG_PATTERN = r'[\w][\w.-]{0,127}'
|
||||||
FULL_TAG_PATTERN = r'^[\w][\w.-]{0,127}$'
|
FULL_TAG_PATTERN = r'^[\w][\w.-]{0,127}$'
|
||||||
|
|
Reference in a new issue