From d67991987b9cc80142b46158e5da50ae79279f0f Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Fri, 19 Aug 2016 14:00:21 -0400 Subject: [PATCH] v1: refactor index --- data/model/v1.py | 51 ++++++++++++++++++++++++ endpoints/v1/index.py | 90 +++++++++++++++++++------------------------ image/__init__.py | 3 +- 3 files changed, 93 insertions(+), 51 deletions(-) diff --git a/data/model/v1.py b/data/model/v1.py index 3dfa1e123..209edd3df 100644 --- a/data/model/v1.py +++ b/data/model/v1.py @@ -196,3 +196,54 @@ def find_image_id_by_tag(namespace_name, repo_name, tag_name): def delete_tag(namespace_name, repo_name, tag_name): """ Deletes the given tag from the given repository. """ model.tag.delete_tag(namespace_name, repo_name, tag_name) + + +def load_token(password): + try: + model.token.load_token_data(password) + return True + except model.InvalidTokenException: + return False + + +def verify_robot(username, password): + try: + model.user.verify_robot(username, password) + return True + except model.InvalidRobotException: + return False + + +def change_user_password(user, new_password): + model.user.change_password(user, new_password) + + +def change_user_email(user, new_email_address): + model.user.update_email(user, new_email_address) + + +def get_repository(namespace_name, repo_name): + #repo = model.repository.get_repository(namespace_name, repo_name) + return Repository() + + +def create_repository(namespace_name, repo_name, user): + #repo = model.repository.create_repository(namespace_name, repo_name, user) + pass + + +def repository_is_public(namespace_name, repo_name): + # return model.repository.repository_is_public(namespace_name, repo_name) + pass + + +def validate_oauth_token(password): + if model.oauth_access_token(password): + return True + return False + + +def get_sorted_matching_repositories(search_term, only_public, can_read, limit): + matching_repos = model.repository.get_sorted_matching_repositories(query, only_public, can_read, + limit=5) + return [Repository()] diff --git a/endpoints/v1/index.py b/endpoints/v1/index.py index 82d26837e..bb3270e68 100644 --- a/endpoints/v1/index.py +++ b/endpoints/v1/index.py @@ -6,7 +6,7 @@ from functools import wraps from flask import request, make_response, jsonify, session -from data import model +from data.model import v1 from app import authentication, userevents, metric_queue from auth.auth import process_auth, generate_signed_token from auth.auth_context import get_authenticated_user, get_validated_token, get_validated_oauth_token @@ -85,26 +85,19 @@ def create_user(): success = make_response('"Username or email already exists"', 400) if username == '$token': - try: - model.token.load_token_data(password) + if v1.load_token(password): return success - except model.InvalidTokenException: - abort(400, 'Invalid access token.', issue='invalid-access-token') + abort(400, 'Invalid access token.', issue='invalid-access-token') elif username == '$oauthtoken': - validated = model.oauth.validate_access_token(password) - if validated is not None: + if v1.validate_oauth_token(password): return success - else: - abort(400, 'Invalid oauth access token.', issue='invalid-oauth-access-token') + abort(400, 'Invalid oauth access token.', issue='invalid-oauth-access-token') elif '+' in username: - try: - model.user.verify_robot(username, password) + if v1.verify_robot(username, password): return success - except model.InvalidRobotException: - abort(400, 'Invalid robot account or password.', - issue='robot-login-failure') + abort(400, 'Invalid robot account or password.', issue='robot-login-failure') (verified, error_message) = authentication.verify_and_link_user(username, password, basic_auth=True) @@ -148,23 +141,21 @@ def get_user(): @anon_allowed def update_user(username): permission = UserAdminPermission(username) - if permission.can(): update_request = request.get_json() if 'password' in update_request: logger.debug('Updating user password') - model.user.change_password(get_authenticated_user(), update_request['password']) + v1.change_user_password(get_authenticated_user(), update_request['password']) if 'email' in update_request: logger.debug('Updating user email') - model.user.update_email(get_authenticated_user(), update_request['email']) + v1.change_user_email(get_authenticated_user(), update_request['email']) return jsonify({ 'username': get_authenticated_user().username, - 'email': get_authenticated_user().email, + 'email': get_authenticated_user().email }) - abort(403) @@ -179,7 +170,7 @@ def create_repository(namespace_name, repo_name): abort(400, message='Invalid repository name. Repository names cannot contain slashes.') logger.debug('Looking up repository %s/%s', namespace_name, repo_name) - repo = model.repository.get_repository(namespace_name, repo_name) + repo = v1.get_repository(namespace_name, repo_name) logger.debug('Found repository %s/%s', namespace_name, repo_name) if not repo and get_authenticated_user() is None: @@ -189,15 +180,15 @@ def create_repository(namespace_name, repo_name): issue='no-login') elif repo: - permission = ModifyRepositoryPermission(namespace_name, repo_name) - if not permission.can(): + modify_perm = ModifyRepositoryPermission(namespace_name, repo_name) + if not modify_perm.can(): abort(403, message='You do not have permission to modify repository %(namespace)s/%(repository)s', issue='no-repo-write-permission', namespace=namespace_name, repository=repo_name) else: - permission = CreateRepositoryPermission(namespace_name) - if not permission.can(): + create_perm = CreateRepositoryPermission(namespace_name) + if not create_perm.can(): logger.info('Attempt to create a new repo %s/%s with insufficient perms', namespace_name, repo_name) msg = 'You do not have permission to create repositories in namespace "%(namespace)s"' @@ -207,7 +198,7 @@ def create_repository(namespace_name, repo_name): logger.debug('Creating repository %s/%s with owner: %s', namespace_name, repo_name, get_authenticated_user().username) - repo = model.repository.create_repository(namespace_name, repo_name, get_authenticated_user()) + v1.create_repository(namespace_name, repo_name, get_authenticated_user()) if get_authenticated_user(): user_event_data = { @@ -232,7 +223,7 @@ def update_images(namespace_name, repo_name): if permission.can(): logger.debug('Looking up repository') - repo = model.repository.get_repository(namespace_name, repo_name) + repo = v1.get_repository(namespace_name, repo_name) if not repo: # Make sure the repo actually exists. abort(404, message='Unknown repository', issue='unknown-repo') @@ -262,10 +253,10 @@ def get_repository_images(namespace_name, repo_name): permission = ReadRepositoryPermission(namespace_name, repo_name) # TODO invalidate token? - if permission.can() or model.repository.repository_is_public(namespace_name, repo_name): + if permission.can() or v1.repository_is_public(namespace_name, repo_name): # We can't rely on permissions to tell us if a repo exists anymore logger.debug('Looking up repository') - repo = model.repository.get_repository(namespace_name, repo_name) + repo = v1.get_repository(namespace_name, repo_name) if not repo: abort(404, message='Unknown repository', issue='unknown-repo') @@ -296,27 +287,6 @@ def put_repository_auth(namespace_name, repo_name): abort(501, 'Not Implemented', issue='not-implemented') -def conduct_repo_search(username, query, results): - """ Finds matching repositories. """ - def can_read(repo): - if repo.is_public: - return True - - return ReadRepositoryPermission(repo.namespace_user.username, repo.name).can() - - only_public = username is None - matching_repos = model.repository.get_sorted_matching_repositories(query, only_public, can_read, - limit=5) - - for repo in matching_repos: - results.append({ - 'name': repo.namespace_user.username + '/' + repo.name, - 'description': repo.description, - 'is_public': repo.is_public, - 'href': '/repository/' + repo.namespace_user.username + '/' + repo.name - }) - - @v1_bp.route('/search', methods=['GET']) @process_auth @anon_protect @@ -330,7 +300,7 @@ def get_search(): results = [] if query: - conduct_repo_search(username, query, results) + _conduct_repo_search(username, query, results) data = { "query": query, @@ -341,3 +311,23 @@ def get_search(): resp = make_response(json.dumps(data), 200) resp.mimetype = 'application/json' return resp + + +def _conduct_repo_search(username, query, results): + """ Finds matching repositories. """ + def can_read(repo): + if repo.is_public: + return True + + return ReadRepositoryPermission(repo.namespace_name, repo.name).can() + + only_public = username is None + matching_repos = v1.get_sorted_matching_repositories(query, only_public, can_read, limit=5) + + for repo in matching_repos: + results.append({ + 'name': repo.namespace_name + '/' + repo.name, + 'description': repo.description, + 'is_public': repo.is_public, + 'href': '/repository/' + repo.namespace_name + '/' + repo.name + }) diff --git a/image/__init__.py b/image/__init__.py index e09f7ae72..81485dd23 100644 --- a/image/__init__.py +++ b/image/__init__.py @@ -11,7 +11,8 @@ class ManifestJSON(namedtuple('ManifestJSON', ['digest', 'json', 'media_type'])) """ -class Repository(namedtuple('Repository', ['id', 'name', 'namespace_name'])): +class Repository(namedtuple('Repository', ['id', 'name', 'namespace_name', 'description', + 'is_public'])): """ Repository represents a collection of tags. """