diff --git a/data/model.py b/data/model.py index 94c71e67e..831e66fd3 100644 --- a/data/model.py +++ b/data/model.py @@ -149,7 +149,11 @@ def remove_team(org_name, team_name, removed_by_username): def add_user_to_team(user, team): - return TeamMember.create(user=user, team=team) + try: + return TeamMember.create(user=user, team=team) + except Exception: + raise DataModelException('Unable to add user \'%s\' to team: \'%s\'' % + (user.username, team.name)) def remove_user_from_team(org_name, team_name, username, removed_by_username): @@ -164,7 +168,7 @@ def remove_user_from_team(org_name, team_name, username, removed_by_username): if not found: raise DataModelException('User %s does not belong to team %s' % - (username, teamname)) + (username, team_name)) if username == removed_by_username: admin_team_query = __get_user_admin_teams(org_name, team_name, username) @@ -722,15 +726,13 @@ def delete_team_permission(team_name, namespace_name, repository_name): fetched[0].delete_instance() -def __set_entity_repo_permission(entity_id, entity_table, entity_id_property, - permission_entity_property, namespace_name, - repository_name, role_name): - entity = entity_table.get(entity_id_property == entity_id) +def __set_entity_repo_permission(entity, permission_entity_property, + namespace_name, repository_name, role_name): repo = Repository.get(Repository.name == repository_name, Repository.namespace == namespace_name) new_role = Role.get(Role.name == role_name) - # Fetch any existing permission for this user on the repo + # Fetch any existing permission for this entity on the repo try: entity_attr = getattr(RepositoryPermission, permission_entity_property) perm = RepositoryPermission.get(entity_attr == entity, @@ -750,16 +752,21 @@ def set_user_repo_permission(username, namespace_name, repository_name, if username == namespace_name: raise DataModelException('Namespace owner must always be admin.') - return __set_entity_repo_permission(username, User, User.username, 'user', - namespace_name, repository_name, - role_name) + user = User.get(User.username == username) + return __set_entity_repo_permission(user, 'user', namespace_name, + repository_name, role_name) def set_team_repo_permission(team_name, namespace_name, repository_name, role_name): - return __set_entity_repo_permission(team_name, Team, Team.name, 'team', - namespace_name, repository_name, - role_name) + team = list(Team.select().join(User).where(Team.name == team_name, + User.username == namespace_name)) + if not team: + raise DataModelException('No team \'%s\' in organization \'%s\'.' % + (team_name, namespace_name)) + + return __set_entity_repo_permission(team[0], 'team', namespace_name, + repository_name, role_name) def purge_repository(namespace_name, repository_name): diff --git a/endpoints/api.py b/endpoints/api.py index 65ee2826c..5c2636e47 100644 --- a/endpoints/api.py +++ b/endpoints/api.py @@ -44,24 +44,16 @@ def api_login_required(f): return decorated_view -def required_json_args(*required_args): - def wrap(f): - @wraps(f) - def wrapped(*args, **kwargs): - request_data = request.get_json() - for arg in required_args: - if arg not in request_data: - abort(400) - return f(*args, **kwargs) - return wrapped - return wrap - - @app.errorhandler(model.DataModelException) def handle_dme(ex): return make_response(ex.message, 400) +@app.errorhandler(KeyError) +def handle_dme(ex): + return make_response(ex.message, 400) + + @app.route('/api/') def welcome(): return make_response('welcome', 200) @@ -131,7 +123,6 @@ def change_user_details(): @app.route('/api/user/', methods=['POST']) -@required_json_args('username', 'password', 'email') def create_user_api(): user_data = request.get_json() @@ -158,7 +149,6 @@ def create_user_api(): @app.route('/api/signin', methods=['POST']) -@required_json_args('username', 'password') def signin_api(): signin_data = request.get_json() @@ -198,7 +188,6 @@ def logout(): @app.route("/api/recovery", methods=['POST']) -@required_json_args('email') def send_recovery(): email = request.get_json()['email'] code = model.create_reset_password_email_code(email) @@ -472,7 +461,6 @@ def delete_organization_team_member(orgname, teamname, membername): @app.route('/api/repository', methods=['POST']) @api_login_required -@required_json_args('repository', 'visibility', 'description') def create_repo_api(): owner = current_user.db_user() json = request.get_json() @@ -711,7 +699,6 @@ def get_repo_builds(namespace, repository): @app.route('/api/filedrop/', methods=['POST']) @api_login_required -@required_json_args('mimeType') def get_filedrop_url(): mime_type = request.get_json()['mimeType'] (url, file_id) = user_files.prepare_for_drop(mime_type) @@ -739,9 +726,11 @@ def request_repo_build(namespace, repository): tag) dockerfile_build_queue.put(json.dumps({'build_id': build_request.id})) - return jsonify({ + resp = jsonify({ 'started': True }) + resp.status_code = 201 + return resp abort(403) # Permissions denied @@ -922,7 +911,7 @@ def get_team_permissions(namespace, repository, teamname): (namespace, repository, teamname)) permission = AdministerRepositoryPermission(namespace, repository) if permission.can(): - perm = model.get_team_reponame_permission(username, namespace, repository) + perm = model.get_team_reponame_permission(teamname, namespace, repository) return jsonify(role_view(perm)) abort(403) # Permission denied @@ -940,13 +929,8 @@ def change_user_permissions(namespace, repository, username): logger.debug('Setting permission to: %s for user %s' % (new_permission['role'], username)) - try: - perm = model.set_user_repo_permission(username, namespace, repository, - new_permission['role']) - except model.DataModelException: - logger.warning('User tried to remove themselves as admin.') - abort(409) - + perm = model.set_user_repo_permission(username, namespace, repository, + new_permission['role']) perm_view = role_view(perm) try: @@ -978,12 +962,8 @@ def change_team_permissions(namespace, repository, teamname): logger.debug('Setting permission to: %s for team %s' % (new_permission['role'], teamname)) - try: - perm = model.set_team_repo_permission(teamname, namespace, repository, - new_permission['role']) - except model.DataModelException: - logger.warning('User tried to remove themselves as admin.') - abort(409) + perm = model.set_team_repo_permission(teamname, namespace, repository, + new_permission['role']) resp = jsonify(role_view(perm)) if request.method == 'POST': @@ -1000,12 +980,7 @@ def change_team_permissions(namespace, repository, teamname): def delete_user_permissions(namespace, repository, username): permission = AdministerRepositoryPermission(namespace, repository) if permission.can(): - try: - model.delete_user_permission(username, namespace, repository) - except model.DataModelException: - logger.warning('User tried to remove themselves as admin.') - abort(409) - + model.delete_user_permission(username, namespace, repository) return make_response('Deleted', 204) abort(403) # Permission denied @@ -1018,12 +993,7 @@ def delete_user_permissions(namespace, repository, username): def delete_team_permissions(namespace, repository, teamname): permission = AdministerRepositoryPermission(namespace, repository) if permission.can(): - try: - model.delete_team_permission(teamname, namespace, repository) - except model.DataModelException: - logger.warning('User tried to remove themselves as admin.') - abort(409) - + model.delete_team_permission(teamname, namespace, repository) return make_response('Deleted', 204) abort(403) # Permission denied @@ -1126,7 +1096,6 @@ def subscription_view(stripe_subscription, used_repos): @app.route('/api/user/plan', methods=['PUT']) @api_login_required -@required_json_args('plan') def subscribe_api(): request_data = request.get_json() plan = request_data['plan']