diff --git a/config.py b/config.py index fdb96fdf9..373dfaea2 100644 --- a/config.py +++ b/config.py @@ -1,6 +1,7 @@ class FlaskConfig(object): SECRET_KEY = '1cb18882-6d12-440d-a4cc-b7430fb5f884' + class MailConfig(object): MAIL_SERVER = 'email-smtp.us-east-1.amazonaws.com' MAIL_USE_TLS = True @@ -11,5 +12,6 @@ class MailConfig(object): MAIL_FAIL_SILENTLY = False TESTING = False + class ProductionConfig(FlaskConfig, MailConfig): - pass \ No newline at end of file + pass diff --git a/data/model.py b/data/model.py index 69cc79dbc..6e5dd0c17 100644 --- a/data/model.py +++ b/data/model.py @@ -58,8 +58,10 @@ def get_user(username): return None -def get_matching_users(username_prefix): - return list(User.select().where(User.username ** (username_prefix + '%')).limit(10)) +def get_matching_users(username_prefix): + query = User.select().where(User.username ** (username_prefix + '%')) + return list(query.limit(10)) + def verify_user(username, password): try: @@ -94,7 +96,10 @@ def get_token(code): def get_matching_repositories(repo_term): - return list(Repository.select().where(Repository.name ** ('%' + repo_term + '%') | Repository.namespace ** ('%' + repo_term + '%') | Repository.description ** ('%' + repo_term + '%')).limit(10)) + clauses = (Repository.name ** ('%' + repo_term + '%') | + Repository.namespace ** ('%' + repo_term + '%') | + Repository.description ** ('%' + repo_term + '%')) + return list(Repository.select().where(clauses).limit(10)) def change_password(user, new_password): @@ -187,6 +192,7 @@ def get_repository_images(namespace_name, repository_name): return joined.where(Repository.name == repository_name, Repository.namespace == namespace_name) + def get_tag_images(namespace_name, repository_name, tag_name): joined = Image.select().join(RepositoryTag).join(Repository) fetched = list(joined.where(Repository.name == repository_name, @@ -195,6 +201,7 @@ def get_tag_images(namespace_name, repository_name, tag_name): return fetched + def list_repository_tags(namespace_name, repository_name): select = RepositoryTag.select(RepositoryTag, Image) with_repo = select.join(Repository) @@ -290,6 +297,7 @@ def set_user_repo_permission(username, namespace_name, repository_name, role=new_role) return new_perm + def delete_user_permission(username, namespace_name, repository_name): if username == namespace_name: raise DataModelException('Namespace owner must always be admin.') diff --git a/endpoints/api.py b/endpoints/api.py index 49e2778ee..fc07f3a5e 100644 --- a/endpoints/api.py +++ b/endpoints/api.py @@ -64,8 +64,9 @@ def match_repos_api(prefix): 'description': repo.description, } - repos = [repo_view(repo) for repo in model.get_matching_repositories(prefix) if - ReadRepositoryPermission(repo.namespace, repo.name).can()] + matching = model.get_matching_repositories(prefix) + repos = [repo_view(repo) for repo in matching + if ReadRepositoryPermission(repo.namespace, repo.name).can()] response = { 'repositories': repos } @@ -98,7 +99,7 @@ def list_repos_api(): @parse_repository_name def update_repo_api(namespace, repository): permission = ModifyRepositoryPermission(namespace, repository) - if permission.can(): + if permission.can(): repo = model.get_repository(namespace, repository) if repo: values = request.get_json() @@ -107,7 +108,7 @@ def update_repo_api(namespace, repository): return jsonify({ 'success': True }) - + abort(404) @@ -124,7 +125,7 @@ def image_view(image): @parse_repository_name def get_repo_api(namespace, repository): logger.debug('Get repo: %s/%s' % (namespace, repository)) - + def tag_view(tag): image = model.get_tag_image(namespace, repository, tag.name) if not image: @@ -136,7 +137,7 @@ def get_repo_api(namespace, repository): } permission = ReadRepositoryPermission(namespace, repository) - if permission.can(): + if permission.can(): repo = model.get_repository(namespace, repository) if repo: tags = model.list_repository_tags(namespace, repository) @@ -162,14 +163,15 @@ def role_view(repo_perm_obj): } -@app.route('/api/repository//tag//images', methods=['GET']) +@app.route('/api/repository//tag//images', + methods=['GET']) @login_required @parse_repository_name def list_tag_images(namespace, repository, tag): permission = ReadRepositoryPermission(namespace, repository) if permission.can(): images = model.get_tag_images(namespace, repository, tag) - + return jsonify({ 'images': [image_view(image) for image in images] }) @@ -186,7 +188,7 @@ def list_repo_permissions(namespace, repository): repo_perms = model.get_all_repo_users(namespace, repository) return jsonify({ - 'permissions': {repo_perm.user.username: role_view(repo_perm) + 'permissions': {repo_perm.user.username: role_view(repo_perm) for repo_perm in repo_perms} }) @@ -234,6 +236,7 @@ def change_permissions(namespace, repository, username): abort(403) # Permission denied + @app.route('/api/repository//permissions/', methods=['DELETE']) @login_required diff --git a/util/validation.py b/util/validation.py index 9f5682677..9121a23e2 100644 --- a/util/validation.py +++ b/util/validation.py @@ -14,6 +14,7 @@ def validate_username(username): len(username) > 1 and len(username) < 256) + def validate_password(password): # No whitespace and minimum length of 8 if re.search(r'\s', password):