Пример #1
0
    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"])
Пример #2
0
    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
Пример #3
0
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)
Пример #4
0
 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},
     )
Пример #5
0
 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"},
     )
Пример #6
0
    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,
        )
Пример #7
0
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)
Пример #8
0
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)
Пример #9
0
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,
    )
Пример #10
0
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,
    )
Пример #11
0
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)
Пример #12
0
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)
Пример #13
0
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):