Repository: akvo/akvo-rsr

Issue:
AdministrativeLocation cannot be deleted as org admin
As an organisation admin (but not RSR admin/superuser), the user is unable to delete an administrative location.  The action fails with a permission denied error. 


Discussion:
Created via Reamaze:

Link: https://rsrsupport.reamaze.com/admin/conversations/project-location-deletion-issue
Assignee: Nadia Gorchakova

Message:
hi RSR Team,

The following issue was reported by Bertrand of EUTF here in CC - see his email below. I could reproduce it like this:

- open a project eg. http://rsr.test.akvo.org/en/myrsr/project_editor/5377/ &lt;http://rsr.test.akvo.org/en/myrsr/project_editor/5377/&gt;
- add a code and vocabulary in these fields (latter field empty):

- save and reopen the link / or refresh
- delete the item
- after clicking on yes an error is shown and indeed the data is not deleted (e.g. checking with refresh):
- the above is reproduced with a normal admin account (mjl.schoonman@gmail.com &lt;mailto:mjl.schoonman@gmail.com&gt; on RSR test) - the account has admin rights on all project for the EUTF organisation

- when I try to reproduce with my akvo account with additional rights (email: marten@akvo.org) I cannot reproduce the issue; the data is correctly deleted. 

thanks for looking into this,
Marten


Resolving patch:
diff --git a/akvo/rsr/models/__init__.py b/akvo/rsr/models/__init__.py
--- a/akvo/rsr/models/__init__.py
+++ b/akvo/rsr/models/__init__.py
@@ -230,6 +230,10 @@
 rules.add_perm('rsr.change_projectlocation', is_rsr_admin | is_org_admin | is_org_project_editor)
 rules.add_perm('rsr.delete_projectlocation', is_rsr_admin | is_org_admin | is_org_project_editor)
 
+rules.add_perm('rsr.add_administrativelocation', is_rsr_admin | is_org_admin | is_org_project_editor)
+rules.add_perm('rsr.change_administrativelocation', is_rsr_admin | is_org_admin | is_org_project_editor)
+rules.add_perm('rsr.delete_administrativelocation', is_rsr_admin | is_org_admin | is_org_project_editor)
+
 rules.add_perm('rsr.add_budgetitem', is_rsr_admin | is_org_admin | is_org_project_editor)
 rules.add_perm('rsr.change_budgetitem', is_rsr_admin | is_org_admin | is_org_project_editor)
 rules.add_perm('rsr.delete_budgetitem', is_rsr_admin | is_org_admin | is_org_project_editor)


Test patch:
diff --git a/akvo/rsr/tests/rest/test_administrative_location.py b/akvo/rsr/tests/rest/test_administrative_location.py
new file mode 100644
--- /dev/null
+++ b/akvo/rsr/tests/rest/test_administrative_location.py
@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*-
+
+"""
+Akvo RSR is covered by the GNU Affero General Public License.
+
+See more details in the license.txt file located at the root folder of the Akvo RSR module.
+For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.
+"""
+
+
+from akvo.rsr.models import (
+    AdministrativeLocation, Employment, Organisation, Partnership, Project,
+    ProjectLocation, User
+)
+from akvo.utils import check_auth_groups
+
+from django.conf import settings
+from django.contrib.auth.models import Group
+from django.test import TestCase, Client
+
+
+class AdministrativeLocationTestCase(TestCase):
+    """Tests the administrative location REST endpoints."""
+
+    def setUp(self):
+        """Setup the database as required."""
+
+        # Create user auth groups
+        check_auth_groups(settings.REQUIRED_AUTH_GROUPS)
+
+        self.project = Project.objects.create(
+            title="REST test project",
+        )
+
+        # Create organisation
+        self.reporting_org = Organisation.objects.create(
+            id=1337,
+            name="Test REST reporting",
+            long_name="Test REST reporting org",
+            new_organisation_type=22
+        )
+
+        Partnership.objects.create(
+            project=self.project,
+            organisation=self.reporting_org,
+            iati_organisation_role=Partnership.IATI_REPORTING_ORGANISATION,
+        )
+
+        location = ProjectLocation.objects.create(location_target=self.project)
+        self.admin_location = AdministrativeLocation.objects.create(location=location)
+
+        self.username = 'test@example.com'
+        self.password = 'password'
+        self.user = User.objects.create(
+            username=self.username,
+            email=self.username,
+            is_active=True
+        )
+        self.user.set_password(self.password)
+        self.user.save()
+        Employment.objects.create(
+            user=self.user,
+            organisation=self.reporting_org,
+            group=Group.objects.get(name='Admins'),
+            is_approved=True
+        )
+
+        self.c = Client(HTTP_HOST=settings.RSR_DOMAIN)
+
+    def test_delete_administrative_location(self):
+        """Checks that org admin can delete an administrative location."""
+
+        # Given
+        assert self.c.login(username=self.user.username, password=self.password)
+
+        # When
+        response = self.c.delete(
+            '/rest/v1/administrative_location/{}/'.format(self.admin_location.id),
+            {'format': 'json'}
+        )
+
+        # Then
+        self.assertEqual(response.status_code, 200)
diff --git a/akvo/rsr/tests/rest/test_permissions.py b/akvo/rsr/tests/rest/test_permissions.py
--- a/akvo/rsr/tests/rest/test_permissions.py
+++ b/akvo/rsr/tests/rest/test_permissions.py
@@ -354,9 +354,8 @@ def populate_model_map():
         }
 
         # one administrative location per project
-        # FIXME: change_* permissions weirdness, different from ProjectLocation permissions!
         model_map[M.AdministrativeLocation] = {
-            'group_count': group_count(8, 4, 4, 4),
+            'group_count': group_count(8, 4, 6, 4),
             'project_relation': 'location__location_target__'
         }