Add data interface for api-permissions for v2-2

This commit is contained in:
Evan Cordell 2017-07-18 14:16:41 -04:00
parent fe6760749a
commit a68ec6966e
4 changed files with 304 additions and 134 deletions

View file

@ -4,55 +4,27 @@ import logging
from flask import request
from app import avatar
from endpoints.api import (resource, nickname, require_repo_admin, RepositoryParamResource,
log_action, request_error, validate_json_request, path_param)
from endpoints.exception import NotFound
from data import model
from permission_models_pre_oci import pre_oci_model as model
from permission_models_interface import DeleteException, SaveException
logger = logging.getLogger(__name__)
def role_view(repo_perm_obj):
return {
'role': repo_perm_obj.role.name,
}
def wrap_role_view_user(role_json, user):
role_json['name'] = user.username
role_json['is_robot'] = user.robot
if not user.robot:
role_json['avatar'] = avatar.get_data_for_user(user)
return role_json
def wrap_role_view_org(role_json, user, org_members):
role_json['is_org_member'] = user.robot or user.username in org_members
return role_json
def wrap_role_view_team(role_json, team):
role_json['name'] = team.name
role_json['avatar'] = avatar.get_data_for_team(team)
return role_json
@resource('/v1/repository/<apirepopath:repository>/permissions/team/')
@path_param('repository', 'The full path of the repository. e.g. namespace/name')
class RepositoryTeamPermissionList(RepositoryParamResource):
""" Resource for repository team permissions. """
@require_repo_admin
@nickname('listRepoTeamPermissions')
def get(self, namespace, repository):
def get(self, namespace_name, repository_name):
""" List all team permission. """
repo_perms = model.permission.get_all_repo_teams(namespace, repository)
def wrapped_role_view(repo_perm):
return wrap_role_view_team(role_view(repo_perm), repo_perm.team)
repo_perms = model.get_repo_permissions_by_team(namespace_name, repository_name)
return {
'permissions': {repo_perm.team.name: wrapped_role_view(repo_perm)
'permissions': {repo_perm.team_name: repo_perm.to_dict()
for repo_perm in repo_perms}
}
@ -63,38 +35,10 @@ class RepositoryUserPermissionList(RepositoryParamResource):
""" Resource for repository user permissions. """
@require_repo_admin
@nickname('listRepoUserPermissions')
def get(self, namespace, repository):
def get(self, namespace_name, repository_name):
""" List all user permissions. """
# Lookup the organization (if any).
org = None
try:
org = model.organization.get_organization(namespace) # Will raise an error if not org
except model.InvalidOrganizationException:
# This repository isn't under an org
pass
# Load the permissions.
repo_perms = model.user.get_all_repo_users(namespace, repository)
# Determine how to wrap the role(s).
def wrapped_role_view(repo_perm):
return wrap_role_view_user(role_view(repo_perm), repo_perm.user)
role_view_func = wrapped_role_view
if org:
users_filter = {perm.user for perm in repo_perms}
org_members = model.organization.get_organization_member_set(org, users_filter=users_filter)
current_func = role_view_func
def wrapped_role_org_view(repo_perm):
return wrap_role_view_org(current_func(repo_perm), repo_perm.user, org_members)
role_view_func = wrapped_role_org_view
return {
'permissions': {perm.user.username: role_view_func(perm) for perm in repo_perms}
}
perms = model.get_repo_permissions_by_user(namespace_name, repository_name)
return {'permissions': {p.username: p.to_dict() for p in perms}}
@resource('/v1/repository/<apirepopath:repository>/permissions/user/<username>/transitive')
@ -105,19 +49,16 @@ class RepositoryUserTransitivePermission(RepositoryParamResource):
or via a team. """
@require_repo_admin
@nickname('getUserTransitivePermission')
def get(self, namespace, repository, username):
def get(self, namespace_name, repository_name, username):
""" Get the fetch the permission for the specified user. """
user = model.user.get_user(username)
if not user:
roles = model.get_repo_roles(username, namespace_name, repository_name)
if not roles:
raise NotFound
repo = model.repository.get_repository(namespace, repository)
if not repo:
raise NotFound
permissions = list(model.permission.get_user_repo_permissions(user, repo))
return {
'permissions': [role_view(permission) for permission in permissions]
'permissions': [r.to_dict() for r in roles]
}
@ -149,69 +90,48 @@ class RepositoryUserPermission(RepositoryParamResource):
@require_repo_admin
@nickname('getUserPermissions')
def get(self, namespace, repository, username):
""" Get the Fetch the permission for the specified user. """
logger.debug('Get repo: %s/%s permissions for user %s', namespace, repository, username)
perm = model.permission.get_user_reponame_permission(username, namespace, repository)
perm_view = wrap_role_view_user(role_view(perm), perm.user)
try:
org = model.organization.get_organization(namespace)
org_members = model.organization.get_organization_member_set(org, users_filter={perm.user})
perm_view = wrap_role_view_org(perm_view, perm.user, org_members)
except model.InvalidOrganizationException:
# This repository is not part of an organization
pass
return perm_view
def get(self, namespace_name, repository_name, username):
""" Get the permission for the specified user. """
logger.debug('Get repo: %s/%s permissions for user %s', namespace_name, repository_name, username)
perm = model.get_repo_permission_for_user(username, namespace_name, repository_name)
return perm.to_dict()
@require_repo_admin
@nickname('changeUserPermissions')
@validate_json_request('UserPermission')
def put(self, namespace, repository, username): # Also needs to respond to post
def put(self, namespace_name, repository_name, username): # Also needs to respond to post
""" Update the perimssions for an existing repository. """
new_permission = request.get_json()
logger.debug('Setting permission to: %s for user %s', new_permission['role'], username)
try:
perm = model.permission.set_user_repo_permission(username, namespace, repository,
new_permission['role'])
except model.DataModelException as ex:
perm = model.set_repo_permission_for_user(username, namespace_name, repository_name,
new_permission['role'])
resp = perm.to_dict()
except SaveException as ex:
raise request_error(exception=ex)
perm_view = wrap_role_view_user(role_view(perm), perm.user)
try:
org = model.organization.get_organization(namespace)
org_members = model.organization.get_organization_member_set(org, users_filter={perm.user})
perm_view = wrap_role_view_org(perm_view, perm.user, org_members)
except model.InvalidOrganizationException:
# This repository is not part of an organization
pass
except model.DataModelException as ex:
raise request_error(exception=ex)
log_action('change_repo_permission', namespace,
{'username': username, 'repo': repository,
'namespace': namespace,
log_action('change_repo_permission', namespace_name,
{'username': username, 'repo': repository_name,
'namespace': namespace_name,
'role': new_permission['role']},
repo=model.repository.get_repository(namespace, repository))
repo_name=repository_name)
return perm_view, 200
return resp, 200
@require_repo_admin
@nickname('deleteUserPermissions')
def delete(self, namespace, repository, username):
def delete(self, namespace_name, repository_name, username):
""" Delete the permission for the user. """
try:
model.permission.delete_user_permission(username, namespace, repository)
except model.DataModelException as ex:
model.delete_repo_permission_for_user(username, namespace_name, repository_name)
except DeleteException as ex:
raise request_error(exception=ex)
log_action('delete_repo_permission', namespace,
{'username': username, 'repo': repository, 'namespace': namespace},
repo=model.repository.get_repository(namespace, repository))
log_action('delete_repo_permission', namespace_name,
{'username': username, 'repo': repository_name, 'namespace': namespace_name},
repo_name=repository_name)
return '', 204
@ -244,39 +164,46 @@ class RepositoryTeamPermission(RepositoryParamResource):
@require_repo_admin
@nickname('getTeamPermissions')
def get(self, namespace, repository, teamname):
def get(self, namespace_name, repository_name, teamname):
""" Fetch the permission for the specified team. """
logger.debug('Get repo: %s/%s permissions for team %s', namespace, repository, teamname)
perm = model.permission.get_team_reponame_permission(teamname, namespace, repository)
return role_view(perm)
logger.debug('Get repo: %s/%s permissions for team %s', namespace_name, repository_name, teamname)
role = model.get_repo_role_for_team(teamname, namespace_name, repository_name)
return role.to_dict()
@require_repo_admin
@nickname('changeTeamPermissions')
@validate_json_request('TeamPermission')
def put(self, namespace, repository, teamname):
def put(self, namespace_name, repository_name, teamname):
""" Update the existing team permission. """
new_permission = request.get_json()
logger.debug('Setting permission to: %s for team %s', new_permission['role'], teamname)
perm = model.permission.set_team_repo_permission(teamname, namespace, repository,
new_permission['role'])
try:
perm = model.set_repo_permission_for_team(teamname, namespace_name, repository_name,
new_permission['role'])
resp = perm.to_dict()
except SaveException as ex:
raise request_error(exception=ex)
log_action('change_repo_permission', namespace,
{'team': teamname, 'repo': repository,
log_action('change_repo_permission', namespace_name,
{'team': teamname, 'repo': repository_name,
'role': new_permission['role']},
repo=model.repository.get_repository(namespace, repository))
return wrap_role_view_team(role_view(perm), perm.team), 200
repo_name=repository_name)
return resp, 200
@require_repo_admin
@nickname('deleteTeamPermissions')
def delete(self, namespace, repository, teamname):
def delete(self, namespace_name, repository_name, teamname):
""" Delete the permission for the specified team. """
model.permission.delete_team_permission(teamname, namespace, repository)
log_action('delete_repo_permission', namespace,
{'team': teamname, 'repo': repository},
repo=model.repository.get_repository(namespace, repository))
try:
model.delete_repo_permission_for_team(teamname, namespace_name, repository_name)
except DeleteException as ex:
raise request_error(exception=ex)
log_action('delete_repo_permission', namespace_name,
{'team': teamname, 'repo': repository_name},
repo_name=repository_name)
return '', 204