1
0
mirror of https://github.com/quay/quay.git synced 2026-01-26 06:21:37 +03:00
Files
quay/endpoints/api/secscan.py
Kenny Lee Sin Cheong 2b3c3cc584 api: feature to limit org creation to superusers (PROJQUAY-1245) (#1516)
* api: feature to limit org creation to superusers

Introduces the following configuration flags:

FEATURE_SUPERUSERS_ORG_CREATION_ONLY:
    Limit org creation to superusers only

FEATURE_SUPERUSERS_FULL_ACCESS:
    Grant superusers read/write access to registry content in all namespaces

FEATURE_RESTRICTED_USERS:
    Users considered as restricted are not anle to create organization

RESTRICTED_USERS_WHITELIST:
    Whitelist for FEATURE_RESTRICTED_USERS

RESTRICTED_USER_INCLUDE_ROBOTS:
    Whether or not to include the user namespace's robots

RESTRICTED_USER_READ_ONLY:
    Only allow read-only operations for restricted users

* Revert superuser repositorylist endpoint
2022-09-23 09:41:23 -04:00

106 lines
3.2 KiB
Python

"""
List and manage repository vulnerabilities and other security information.
"""
import logging
import features
from enum import Enum, unique
from app import storage
from auth.decorators import process_basic_auth_no_pass
from data.registry_model import registry_model
from data.secscan_model import secscan_model
from data.secscan_model.datatypes import ScanLookupStatus
from endpoints.api import (
require_repo_read,
path_param,
RepositoryParamResource,
resource,
nickname,
show_if,
parse_args,
query_param,
disallow_for_app_repositories,
deprecated,
)
from endpoints.decorators import anon_allowed
from endpoints.exception import NotFound, DownstreamIssue
from endpoints.api.manifest import MANIFEST_DIGEST_ROUTE
from util.parsing import truthy_bool
@unique
class SecurityScanStatus(Enum):
"""
Security scan status enum.
"""
SCANNED = "scanned"
FAILED = "failed"
QUEUED = "queued"
UNSUPPORTED = "unsupported"
MAPPED_STATUSES = {}
MAPPED_STATUSES[ScanLookupStatus.FAILED_TO_INDEX] = SecurityScanStatus.FAILED
MAPPED_STATUSES[ScanLookupStatus.SUCCESS] = SecurityScanStatus.SCANNED
MAPPED_STATUSES[ScanLookupStatus.NOT_YET_INDEXED] = SecurityScanStatus.QUEUED
MAPPED_STATUSES[ScanLookupStatus.UNSUPPORTED_FOR_INDEXING] = SecurityScanStatus.UNSUPPORTED
logger = logging.getLogger(__name__)
def _security_info(manifest_or_legacy_image, include_vulnerabilities=True):
"""
Returns a dict representing the result of a call to the security status API for the given
manifest or image.
"""
result = secscan_model.load_security_information(
manifest_or_legacy_image, include_vulnerabilities=include_vulnerabilities
)
if result.status == ScanLookupStatus.UNKNOWN_MANIFEST_OR_IMAGE:
raise NotFound()
if result.status == ScanLookupStatus.COULD_NOT_LOAD:
raise DownstreamIssue(result.scanner_request_error)
assert result.status in MAPPED_STATUSES
return {
"status": MAPPED_STATUSES[result.status].value,
"data": result.security_information.to_dict()
if result.security_information is not None
else None,
}
@resource(MANIFEST_DIGEST_ROUTE + "/security")
@show_if(features.SECURITY_SCANNER)
@path_param("repository", "The full path of the repository. e.g. namespace/name")
@path_param("manifestref", "The digest of the manifest")
class RepositoryManifestSecurity(RepositoryParamResource):
"""
Operations for managing the vulnerabilities in a repository manifest.
"""
@process_basic_auth_no_pass
@anon_allowed
@require_repo_read(allow_for_superuser=True)
@nickname("getRepoManifestSecurity")
@disallow_for_app_repositories
@parse_args()
@query_param(
"vulnerabilities", "Include vulnerabilities informations", type=truthy_bool, default=False
)
def get(self, namespace, repository, manifestref, parsed_args):
repo_ref = registry_model.lookup_repository(namespace, repository)
if repo_ref is None:
raise NotFound()
manifest = registry_model.lookup_manifest_by_digest(repo_ref, manifestref, allow_dead=True)
if manifest is None:
raise NotFound()
return _security_info(manifest, parsed_args.vulnerabilities)