def test_authorize_nocsrf_correctheader(self): # Note: Defined in initdb.py form = { "client_id": "deadbeef", "redirect_uri": "http://localhost:8000/o2c.html", "scope": "user:admin", } # Try without the client id being in the whitelist. headers = dict(authorization=gen_basic_auth("devtable", "password")) self.postResponse( "web.authorize_application", headers=headers, form=form, with_csrf=False, expected_code=403, ) # Add the client ID to the whitelist and try again. app.config["DIRECT_OAUTH_CLIENTID_WHITELIST"] = ["deadbeef"] headers = dict(authorization=gen_basic_auth("devtable", "password")) resp = self.postResponse( "web.authorize_application", headers=headers, form=form, with_csrf=False, expected_code=302, ) self.assertTrue("access_token=" in resp.headers["Location"])
def test_authorize_nocsrf_ratelimiting(self): # Note: Defined in initdb.py form = { "client_id": "deadbeef", "redirect_uri": "http://localhost:8000/o2c.html", "scope": "user:admin", } # Try without the client id being in the whitelist a few times, making sure we eventually get rate limited. headers = dict(authorization=gen_basic_auth("devtable", "invalidpassword")) self.postResponse( "web.authorize_application", headers=headers, form=form, with_csrf=False, expected_code=401, ) counter = 0 while True: r = self.postResponse( "web.authorize_application", headers=headers, form=form, with_csrf=False, expected_code=None, ) self.assertNotEqual(200, r.status_code) counter = counter + 1 if counter > 5: self.fail("Exponential backoff did not fire") if r.status_code == 429: break
def test_get_security_info_with_pull_secret(endpoint, client): repository_ref = registry_model.lookup_repository("devtable", "simple") tag = registry_model.get_repo_tag(repository_ref, "latest", include_legacy_image=True) manifest = registry_model.get_manifest_for_tag(tag, backfill_if_necessary=True) params = { "repository": "devtable/simple", "imageid": tag.legacy_image.docker_image_id, "manifestref": manifest.digest, } headers = { "Authorization": gen_basic_auth("devtable", "password"), } conduct_api_call(client, endpoint, "GET", params, None, headers=headers, expected_code=200)
def test_valid_build_trigger_webhook_missing_payload(self): auth_header = gen_basic_auth("devtable", "password") trigger = list(model.build.list_build_triggers("devtable", "building"))[0] self.postResponse( "webhooks.build_trigger_webhook", trigger_uuid=trigger.uuid, expected_code=400, headers={"Authorization": auth_header}, )
def test_valid_build_trigger_webhook_invalid_payload(self): auth_header = gen_basic_auth("devtable", "password") trigger = list(model.build.list_build_triggers("devtable", "building"))[0] self.postResponse( "webhooks.build_trigger_webhook", trigger_uuid=trigger.uuid, expected_code=400, headers={"Authorization": auth_header, "Content-Type": "application/json"}, data={"invalid": "payload"}, )
def test_authorize_nocsrf_withbadheader(self): # Note: Defined in initdb.py form = { "client_id": "deadbeef", "redirect_uri": "http://localhost:8000/o2c.html", "scope": "user:admin", } headers = dict(authorization=gen_basic_auth("devtable", "invalidpassword")) self.postResponse( "web.authorize_application", headers=headers, form=form, with_csrf=False, expected_code=401, )
def test_generate_registry_jwt(scope, username, password, expected_code, expected_scopes, app, client): params = { "service": original_app.config["SERVER_HOSTNAME"], "scope": scope, } if callable(password): password = password(username) headers = {} if username and password: headers["Authorization"] = gen_basic_auth(username, password) resp = conduct_call( client, "v2.generate_registry_jwt", url_for, "GET", params, {}, expected_code, headers=headers, ) if expected_code != 200: return token = resp.json["token"] decoded = decode_bearer_token(token, instance_keys, original_app.config) assert decoded["iss"] == "quay" assert decoded["aud"] == original_app.config["SERVER_HOSTNAME"] assert decoded["sub"] == username if username else "(anonymous)" expected_access = [] for scope in expected_scopes: name, actions_str = scope.split(":") actions = actions_str.split(",") if actions_str else [] expected_access.append({ "type": "repository", "name": name, "actions": actions, }) assert decoded["access"] == expected_access assert len(decoded["context"][CLAIM_TUF_ROOTS]) == len(expected_scopes)
def test_verbs_security(user, endpoint, method, repository, single_repo_path, params, expected_statuses, app, client): headers = {} if user[1] is not None: headers['Authorization'] = gen_basic_auth(user[1], 'password') if single_repo_path: params['repository'] = repository else: (namespace, repo_name) = repository.split('/') params['namespace'] = namespace params['repository'] = repo_name conduct_call(client, 'verbs.' + endpoint, url_for, method, params, expected_code=expected_statuses[user[0]], headers=headers)
def test_verbs_security(user, endpoint, method, repository, single_repo_path, params, expected_statuses, app, client): headers = {} if user[1] is not None: headers["Authorization"] = gen_basic_auth(user[1], "password") if single_repo_path: params["repository"] = repository else: (namespace, repo_name) = repository.split("/") params["namespace"] = namespace params["repository"] = repo_name conduct_call( client, "verbs." + endpoint, url_for, method, params, expected_code=expected_statuses[user[0]], headers=headers, )
def test_start_build_disabled_trigger(app, client): trigger = model.build.list_build_triggers("devtable", "building")[0] trigger.enabled = False trigger.save() params = { "trigger_uuid": trigger.uuid, } headers = { "Authorization": gen_basic_auth("devtable", "password"), } conduct_call( client, "webhooks.build_trigger_webhook", url_for, "POST", params, None, 400, headers=headers, )
import pytest from mock import patch from data.registry_model import registry_model from endpoints.test.shared import gen_basic_auth from endpoints.api.test.shared import conduct_api_call from endpoints.api.secscan import RepositoryManifestSecurity from test.fixtures import * @pytest.mark.parametrize( "endpoint, anonymous_allowed, auth_headers, expected_code", [ pytest.param(RepositoryManifestSecurity, True, gen_basic_auth("devtable", "password"), 200), pytest.param( RepositoryManifestSecurity, False, gen_basic_auth("devtable", "password"), 200 ), pytest.param(RepositoryManifestSecurity, True, None, 401), pytest.param(RepositoryManifestSecurity, False, None, 401), ], ) def test_get_security_info_with_pull_secret( endpoint, anonymous_allowed, auth_headers, expected_code, client ): with patch("features.ANONYMOUS_ACCESS", anonymous_allowed): repository_ref = registry_model.lookup_repository("devtable", "simple") tag = registry_model.get_repo_tag(repository_ref, "latest") manifest = registry_model.get_manifest_for_tag(tag)
def test_generate_registry_jwt( scope, username, password, expected_code, expected_scopes, push_private, visibility, org_create, app, client, ): params = { "service": original_app.config["SERVER_HOSTNAME"], "scope": scope, } if callable(password): password = password(username) headers = {} if username and password: headers["Authorization"] = gen_basic_auth(username, password) original_app.config["CREATE_PRIVATE_REPO_ON_PUSH"] = push_private original_app.config["CREATE_NAMESPACE_ON_PUSH"] = org_create resp = conduct_call( client, "v2.generate_registry_jwt", url_for, "GET", params, {}, expected_code, headers=headers, ) if expected_code != 200: return token = resp.json["token"] decoded = decode_bearer_token(token, instance_keys, original_app.config) assert decoded["iss"] == "quay" assert decoded["aud"] == original_app.config["SERVER_HOSTNAME"] assert decoded["sub"] == username if username else "(anonymous)" expected_access = [] for scope in expected_scopes: name, actions_str = scope.split(":") actions = actions_str.split(",") if actions_str else [] expected_access.append({ "type": "repository", "name": name, "actions": actions, }) assert decoded["access"] == expected_access assert len(decoded["context"][CLAIM_TUF_ROOTS]) == len(expected_scopes) # Test visibility if scope == "repository:devtable/visibility:pull,push,*": assert (model.repository.get_repository( "devtable", "visibility").visibility.name == visibility)
import pytest from mock import patch from data.registry_model import registry_model from endpoints.test.shared import gen_basic_auth from endpoints.api.test.shared import conduct_api_call from endpoints.api.secscan import RepositoryImageSecurity, RepositoryManifestSecurity from test.fixtures import * @pytest.mark.parametrize( "endpoint, anonymous_allowed, auth_headers, expected_code", [ pytest.param(RepositoryImageSecurity, True, gen_basic_auth("devtable", "password"), 200), pytest.param(RepositoryImageSecurity, False, gen_basic_auth("devtable", "password"), 200), pytest.param(RepositoryManifestSecurity, True, gen_basic_auth("devtable", "password"), 200), pytest.param(RepositoryManifestSecurity, False, gen_basic_auth("devtable", "password"), 200), pytest.param(RepositoryImageSecurity, True, None, 401), pytest.param(RepositoryImageSecurity, False, None, 401), pytest.param(RepositoryManifestSecurity, True, None, 401), pytest.param(RepositoryManifestSecurity, False, None, 401), ], ) def test_get_security_info_with_pull_secret(endpoint, anonymous_allowed, auth_headers, expected_code, client):