diff --git a/auth/permissions.py b/auth/permissions.py index ab168f063..086d4db58 100644 --- a/auth/permissions.py +++ b/auth/permissions.py @@ -33,6 +33,12 @@ class ReadRepositoryPermission(Permission): read_need) +class AdministerRepositoryPermission(Permission): + def __init__(self, namespace, name): + admin_need = _RepositoryNeed(namespace, name, 'admin') + super(AdministerRepositoryPermission, self).__init__(admin_need) + + class UserPermission(Permission): def __init__(self, username): user_need = UserNeed(username) @@ -50,7 +56,7 @@ def on_identity_loaded(sender, identity): user_object = model.get_user(identity.id) identity.provides.add(UserNeed(user_object.username)) - for user in model.get_all_repo_permissions(user_object): + for user in model.get_all_user_permissions(user_object): grant = _RepositoryNeed(user.repositorypermission.repository.namespace, user.repositorypermission.repository.name, user.repositorypermission.role.name) diff --git a/data/model.py b/data/model.py index 2a1bef234..07e2dc4ce 100644 --- a/data/model.py +++ b/data/model.py @@ -66,10 +66,21 @@ def update_email(user, new_email): user.save() -def get_all_repo_permissions(user): - select = User.select(User, Repository, RepositoryPermission) - joined = select.join(RepositoryPermission).join(Repository) - return joined.where(User.username == user.username) +def get_all_user_permissions(user): + select = User.select(User, Repository, RepositoryPermission, Role) + with_repo = select.join(RepositoryPermission).join(Repository) + with_role = with_repo.switch(RepositoryPermission).join(Role) + return with_role.where(User.username == user.username) + + +def get_all_repo_users(namespace_name, repository_name): + select = RepositoryPermission.select(User.username, Role.name, + RepositoryPermission) + with_user = select.join(User) + with_role = with_user.switch(RepositoryPermission).join(Role) + with_repo = with_role.switch(RepositoryPermission).join(Repository) + return with_repo.where(Repository.namespace == namespace_name, + Repository.name == repository_name) def get_repository(namespace, name): diff --git a/endpoints/api.py b/endpoints/api.py index 9f033a958..5cb455da1 100644 --- a/endpoints/api.py +++ b/endpoints/api.py @@ -8,7 +8,8 @@ from data import model from app import app from util.names import parse_repository_name from auth.permissions import (ReadRepositoryPermission, - ModifyRepositoryPermission) + ModifyRepositoryPermission, + AdministerRepositoryPermission) logger = logging.getLogger(__name__) @@ -83,7 +84,7 @@ def get_repo_api(namespace, repository): return { 'id': image.image_id, 'created': image.created, - 'comment': image.comment + 'comment': image.comment, } def tag_view(tag): @@ -93,20 +94,7 @@ def get_repo_api(namespace, repository): return { 'name': tag.name, - 'image': image_view(image) - } - - def repo_view(repository, tags = []): - tag_dict = {} - for tag in tags: - tag_dict[tag.name] = tag_view(tag) - - return { - 'namespace': repository.namespace, - 'name': repository.name, - 'description': repository.description, - 'tags': tag_dict, - 'can_write': ModifyRepositoryPermission(repository.namespace, repository.name).can() + 'image': image_view(image), } permission = ReadRepositoryPermission(namespace, repository) @@ -114,6 +102,46 @@ def get_repo_api(namespace, repository): repo = model.get_repository(namespace, repository) if repo: tags = model.list_repository_tags(namespace, repository) - return jsonify(repo_view(repo, tags = tags)) + tag_dict = {tag.name: tag_view(tag) for tag in tags} + can_write = ModifyRepositoryPermission(namespace, repository).can() + return jsonify({ + 'namespace': namespace, + 'name': repository, + 'description': repo.description, + 'tags': tag_dict, + 'can_write': can_write, + }) - abort(404) + abort(404) # Not fount + abort(403) # Permission denied + + +@app.route('/api/repository//permissions/', methods=['GET']) +@login_required +@parse_repository_name +def list_repo_permissions(namespace, repository): + permission = AdministerRepositoryPermission(namespace, repository) + if permission.can(): + repo_perms = model.get_all_repo_users(namespace, repository) + + return jsonify({ + 'permissions': {repo_perm.user.username: repo_perm.role.name + for repo_perm in repo_perms} + }) + + abort(403) # Permission denied + +@app.route('/api/repository//permissions/', + methods=['PUT']) +@login_required +@parse_repository_name +def change_permissions(namespace, repository, username): + permission = AdministerRepositoryPermission(namespace, repository) + if permission.can(): + new_permission = request.get_json() + + return jsonify({ + 'setting_permission_to': [permission_view(repo_perm) for repo_perm in repo_perms] + }) + + abort(403) # Permission denied \ No newline at end of file