Add flag to enable trust per repo (#2541)
* Add flag to enable trust per repo * Add api for enabling/disabling trust * Add new LogEntryKind for changing repo trust settings Also add tests for repo trust api * Add `set_trust` method to repository * Expose new logkind to UI * Fix registry tests * Rebase migrations and regen test.db * Raise downstreamissue if trust metadata can't be removed * Refactor change_repo_trust * Add show_if to change_repo_trust endpoint
This commit is contained in:
parent
aa1c8d47dd
commit
2661db7485
13 changed files with 176 additions and 12 deletions
|
@ -3,10 +3,14 @@ import pytest
|
|||
import flask
|
||||
from flask_principal import Identity, Principal
|
||||
|
||||
from endpoints.v2.v2auth import get_tuf_root
|
||||
from endpoints.v2.v2auth import get_tuf_root
|
||||
from auth import permissions
|
||||
from util.security.registry_jwt import QUAY_TUF_ROOT, SIGNER_TUF_ROOT
|
||||
from util.security.registry_jwt import QUAY_TUF_ROOT, SIGNER_TUF_ROOT, DISABLED_TUF_ROOT
|
||||
|
||||
from test import testconfig
|
||||
from mock import Mock
|
||||
|
||||
|
||||
def admin_identity(namespace, reponame):
|
||||
identity = Identity('admin')
|
||||
identity.provides.add(permissions._RepositoryNeed(namespace, reponame, 'admin'))
|
||||
|
@ -27,7 +31,7 @@ def read_identity(namespace, reponame):
|
|||
|
||||
def app_with_principal():
|
||||
app = flask.Flask(__name__)
|
||||
app.config.update(SECRET_KEY='secret', TESTING=True)
|
||||
app.config.from_object(testconfig.TestConfig())
|
||||
principal = Principal(app)
|
||||
return app, principal
|
||||
|
||||
|
@ -44,5 +48,17 @@ def test_get_tuf_root(identity, expected):
|
|||
app, principal = app_with_principal()
|
||||
with app.test_request_context('/'):
|
||||
principal.set_identity(identity)
|
||||
actual = get_tuf_root("namespace", "repo")
|
||||
actual = get_tuf_root(Mock(), "namespace", "repo")
|
||||
assert actual == expected, "should be %s, but was %s" % (expected, actual)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('trust_enabled,tuf_root', [
|
||||
(True, QUAY_TUF_ROOT),
|
||||
(False, DISABLED_TUF_ROOT),
|
||||
])
|
||||
def test_trust_disabled(trust_enabled,tuf_root):
|
||||
app, principal = app_with_principal()
|
||||
with app.test_request_context('/'):
|
||||
principal.set_identity(read_identity("namespace", "repo"))
|
||||
actual = get_tuf_root(Mock(trust_enabled=trust_enabled), "namespace", "repo")
|
||||
assert actual == tuf_root, "should be %s, but was %s" % (tuf_root, actual)
|
||||
|
|
|
@ -4,6 +4,7 @@ import re
|
|||
from cachetools import lru_cache
|
||||
from flask import request, jsonify, abort
|
||||
|
||||
import features
|
||||
from app import app, userevents, instance_keys
|
||||
from auth.auth_context import get_authenticated_user, get_validated_token, get_validated_oauth_token
|
||||
from auth.decorators import process_basic_auth
|
||||
|
@ -15,7 +16,8 @@ from endpoints.v2.errors import InvalidLogin, NameInvalid, InvalidRequest, Unsup
|
|||
from data.interfaces.v2 import pre_oci_model as model
|
||||
from util.cache import no_cache
|
||||
from util.names import parse_namespace_repository, REPOSITORY_NAME_REGEX
|
||||
from util.security.registry_jwt import generate_bearer_token, build_context_and_subject, QUAY_TUF_ROOT, SIGNER_TUF_ROOT
|
||||
from util.security.registry_jwt import (generate_bearer_token, build_context_and_subject, QUAY_TUF_ROOT,
|
||||
SIGNER_TUF_ROOT, DISABLED_TUF_ROOT)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -64,7 +66,7 @@ def generate_registry_jwt(auth_result):
|
|||
user_event_data = {
|
||||
'action': 'login',
|
||||
}
|
||||
tuf_root = QUAY_TUF_ROOT
|
||||
tuf_root = DISABLED_TUF_ROOT
|
||||
|
||||
if len(scope_param) > 0:
|
||||
match = get_scope_regex().match(scope_param)
|
||||
|
@ -164,8 +166,7 @@ def generate_registry_jwt(auth_result):
|
|||
'repository': reponame,
|
||||
'namespace': namespace,
|
||||
}
|
||||
|
||||
tuf_root = get_tuf_root(namespace, reponame)
|
||||
tuf_root = get_tuf_root(repo, namespace, reponame)
|
||||
|
||||
elif user is None and token is None:
|
||||
# In this case, we are doing an auth flow, and it's not an anonymous pull
|
||||
|
@ -184,7 +185,10 @@ def generate_registry_jwt(auth_result):
|
|||
return jsonify({'token': token})
|
||||
|
||||
|
||||
def get_tuf_root(namespace, reponame):
|
||||
def get_tuf_root(repo, namespace, reponame):
|
||||
if not features.SIGNING or repo is None or not repo.trust_enabled:
|
||||
return DISABLED_TUF_ROOT
|
||||
|
||||
# Users with write access to a repo will see signer-rooted TUF metadata
|
||||
if ModifyRepositoryPermission(namespace, reponame).can():
|
||||
return SIGNER_TUF_ROOT
|
||||
|
|
Reference in a new issue