diff --git a/endpoints/api/__init__.py b/endpoints/api/__init__.py index 194178578..44b767cbb 100644 --- a/endpoints/api/__init__.py +++ b/endpoints/api/__init__.py @@ -5,13 +5,12 @@ from calendar import timegm from email.utils import formatdate from functools import partial, wraps -from flask import Blueprint, request, session +from flask import Blueprint, request, session from flask_restful import Resource, abort, Api, reqparse from flask_restful.utils.cors import crossdomain from jsonschema import validate, ValidationError from app import app, metric_queue -from data import model from auth.permissions import (ReadRepositoryPermission, ModifyRepositoryPermission, AdministerRepositoryPermission, UserReadPermission, UserAdminPermission) @@ -25,6 +24,7 @@ from endpoints.decorators import check_anon_protection from util.metrics.metricqueue import time_decorator from util.names import parse_namespace_repository from util.pagination import encrypt_page_token, decrypt_page_token +from __init__models_pre_oci import pre_oci_model as model logger = logging.getLogger(__name__) @@ -212,14 +212,13 @@ class RepositoryParamResource(ApiResource): def disallow_for_app_repositories(func): @wraps(func) - def wrapped(self, namespace, repository, *args, **kwargs): + def wrapped(self, namespace_name, repository_name, *args, **kwargs): # Lookup the repository with the given namespace and name and ensure it is not an application # repository. - repo = model.repository.get_repository(namespace, repository, kind_filter='application') - if repo: + if model.is_app_repository(namespace_name, repository_name): abort(501) - return func(self, namespace, repository, *args, **kwargs) + return func(self, namespace_name, repository_name, *args, **kwargs) return wrapped @@ -234,7 +233,7 @@ def require_repo_permission(permission_class, scope, allow_public=False): permission = permission_class(namespace, repository) if (permission.can() or (allow_public and - model.repository.repository_is_public(namespace, repository))): + model.repository_is_public(namespace, repository))): return func(self, namespace, repository, *args, **kwargs) raise Unauthorized() return wrapped @@ -350,11 +349,6 @@ def log_action(kind, user_or_orgname, metadata=None, repo=None, repo_name=None): if not metadata: metadata = {} - if repo_name: - repository = model.repository.get_repository(user_or_orgname, repo_name) - else: - repository = repo - oauth_token = get_validated_oauth_token() if oauth_token: metadata['oauth_token_id'] = oauth_token.id @@ -362,14 +356,11 @@ def log_action(kind, user_or_orgname, metadata=None, repo=None, repo_name=None): metadata['oauth_token_application'] = oauth_token.application.name performer = get_authenticated_user() - - if repo_name: - repository = model.repository.get_repository(user_or_orgname, repo_name) - else: - repository = repo - - model.log.log_action(kind, user_or_orgname, performer=performer, ip=request.remote_addr, - metadata=metadata, repository=repository) + + if repo: + repo_name = repo.name + + model.log_action(kind, user_or_orgname, repo_name, performer, request.remote_addr, metadata) def define_json_response(schema_name): diff --git a/endpoints/api/__init__models_interface.py b/endpoints/api/__init__models_interface.py new file mode 100644 index 000000000..974d9e0e1 --- /dev/null +++ b/endpoints/api/__init__models_interface.py @@ -0,0 +1,54 @@ +from abc import ABCMeta, abstractmethod + +from six import add_metaclass + + +@add_metaclass(ABCMeta) +class InitDataInterface(object): + """ + Interface that represents all data store interactions required by __init__. + """ + + @abstractmethod + def is_app_repository(self, namespace_name, repository_name): + """ + + Args: + namespace_name: namespace or user + repository_name: repository + + Returns: + Boolean + """ + pass + + @abstractmethod + def repository_is_public(self, namespace_name, repository_name): + """ + + Args: + namespace_name: namespace or user + repository_name: repository + + Returns: + Boolean + """ + pass + + @abstractmethod + def log_action(self, kind, namespace_name, repository_name, performer, ip, metadata): + """ + + Args: + kind: type of log + user_or_orgname: name of user or organization + performer: user doing the action + ip: originating ip + metadata: metadata + repository: repository the action is related to + + Returns: + None + """ + pass + diff --git a/endpoints/api/__init__models_pre_oci.py b/endpoints/api/__init__models_pre_oci.py new file mode 100644 index 000000000..8db474380 --- /dev/null +++ b/endpoints/api/__init__models_pre_oci.py @@ -0,0 +1,18 @@ +from __init__models_interface import InitDataInterface + +from data import model + +class PreOCIModel(InitDataInterface): + + def is_app_repository(self, namespace_name, repository_name): + return model.repository.get_repository(namespace_name, repository_name, kind_filter='application') is not None + + def repository_is_public(self, namespace_name, repository_name): + return model.repository.repository_is_public(namespace_name, repository_name) + + def log_action(self, kind, namespace_name, repository_name, performer, ip, metadata): + repository = model.repository.get_repository(namespace_name, repository_name) + model.log.log_action(kind, namespace_name, performer=performer, ip=ip, metadata=metadata, repository=repository) + + +pre_oci_model = PreOCIModel() \ No newline at end of file