From c83f64d36fa4ef39223fe0c908ec832e0a5f99bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 25 Apr 2016 16:41:57 +0200 Subject: [PATCH] Allow deletion of projects by members of its admin group. --- pillar/application/modules/projects.py | 18 +++++++++++++++++- tests/test_project_management.py | 22 +++++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/pillar/application/modules/projects.py b/pillar/application/modules/projects.py index 0c87a2ed..829e728c 100644 --- a/pillar/application/modules/projects.py +++ b/pillar/application/modules/projects.py @@ -44,6 +44,17 @@ def before_edit_check_permissions(document, original): check_permissions(original, request.method) +def before_delete_project(document): + """Checks permissions before we allow deletion""" + + # Allow admin users to do whatever they want. + # TODO: possibly move this into the check_permissions function. + if user_has_role(u'admin'): + return + + check_permissions(document, request.method) + + def protect_sensitive_fields(document, original): """When not logged in as admin, prevents update to certain fields.""" @@ -53,6 +64,10 @@ def protect_sensitive_fields(document, original): def revert(name): if name not in original: + try: + del document[name] + except KeyError: + pass return document[name] = original[name] @@ -110,7 +125,7 @@ def after_inserting_project(project, db_user): 'users': [], 'groups': [ {'group': admin_group_id, - 'methods': ['GET', 'PUT', 'POST']}, + 'methods': ['GET', 'PUT', 'POST', 'DELETE']}, ] } @@ -222,6 +237,7 @@ def setup_app(app, url_prefix): app.on_replace_projects += protect_sensitive_fields app.on_update_projects += before_edit_check_permissions app.on_update_projects += protect_sensitive_fields + app.on_delete_item_projects += before_delete_project app.on_insert_projects += before_inserting_projects app.on_inserted_projects += after_inserting_projects app.register_blueprint(blueprint, url_prefix=url_prefix) diff --git a/tests/test_project_management.py b/tests/test_project_management.py index ad01e293..8c55c591 100644 --- a/tests/test_project_management.py +++ b/tests/test_project_management.py @@ -165,7 +165,6 @@ class ProjectEditTest(AbstractProjectTest): put_project['category'] = 'software' put_project['user'] = other_user_id - resp = self.client.put(project_url, data=dumps(put_project), headers={'Authorization': self.make_header('token'), @@ -274,6 +273,27 @@ class ProjectEditTest(AbstractProjectTest): self.assertEqual(1, projlist['_meta']['total']) self.assertEqual(u'Prøject El Niño', projlist['_items'][0]['name']) + def test_delete_by_subscriber(self): + # Create test project. + project_info = self._create_user_and_project([u'subscriber']) + project_id = project_info['_id'] + project_url = '/projects/%s' % project_id + + # Create test user. + self._create_user_with_token(['subscriber'], 'mortal-token', user_id='cafef00dbeef') + + # Other user should NOT be able to DELETE. + resp = self.client.delete(project_url, + headers={'Authorization': self.make_header('mortal-token'), + 'If-Match': project_info['_etag']}) + self.assertEqual(403, resp.status_code, resp.data) + + # Owner should be able to DELETE + resp = self.client.delete(project_url, + headers={'Authorization': self.make_header('token'), + 'If-Match': project_info['_etag']}) + self.assertEqual(204, resp.status_code, resp.data) + def _create_user_and_project(self, roles): self._create_user_with_token(roles, 'token') resp = self._create_project(u'Prøject El Niño', 'token')