Skip to content

Commit cde9995

Browse files
sudip-khanalsusilnem
authored andcommitted
feat(local-unit): add permission for country admin to edit local unit
1 parent 2960f07 commit cde9995

File tree

2 files changed

+67
-3
lines changed

2 files changed

+67
-3
lines changed

local_units/permissions.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def has_object_permission(self, request, view, obj):
2424

2525

2626
class IsAuthenticatedForLocalUnit(permissions.BasePermission):
27-
message = "Only validators or superusers are allowed to update Local Units"
27+
message = "Only Country admin, Local Unit validators and superusers are allowed to update Local Units"
2828

2929
def has_object_permission(self, request, view, obj):
3030
if request.method not in ["PUT", "PATCH"]:
@@ -35,6 +35,16 @@ def has_object_permission(self, request, view, obj):
3535
if user.is_superuser:
3636
return True
3737

38+
country_id = obj.country_id
39+
try:
40+
country = Country.objects.get(id=country_id)
41+
except Country.DoesNotExist:
42+
return False
43+
# Country admin specific permissions
44+
codename = f"country_admin_{country.id}"
45+
if user.groups.filter(permissions__codename=codename).exists():
46+
return True
47+
# Validator permission
3848
return (
3949
get_local_unit_country_validators(obj).filter(id=user.id).exists()
4050
or get_local_unit_region_validators(obj).filter(id=user.id).exists()

local_units/test_views.py

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,21 +428,28 @@ def setUp(self):
428428
)
429429

430430
self.local_unit_type = LocalUnitType.objects.create(code=1, name="administrative")
431-
431+
management.call_command("make_permissions")
432432
management.call_command("make_local_unit_validator_permissions")
433-
433+
self.country_admin_user = UserFactory.create()
434434
self.country_validator_user = UserFactory.create()
435435
self.region_validator_user = UserFactory.create()
436436
self.global_validator_user = UserFactory.create()
437437
# permissions
438+
country_admin_codename = f"country_admin_{self.country.id}"
438439
country_codename = f"local_unit_country_validator_{self.local_unit_type.id}_{self.country.id}"
439440
region_codename = f"local_unit_region_validator_{self.local_unit_type.id}_{self.region.id}"
440441
global_codename = f"local_unit_global_validator_{self.local_unit_type.id}"
441442

443+
country_admin_permission = Permission.objects.get(codename=country_admin_codename)
442444
country_permission = Permission.objects.get(codename=country_codename)
443445
region_permission = Permission.objects.get(codename=region_codename)
444446
global_permission = Permission.objects.get(codename=global_codename)
445447

448+
# Country admin group
449+
country__admin_group_name = "%s Admins" % self.country.name
450+
country__admin_group = Group.objects.get(name=country__admin_group_name)
451+
country__admin_group.permissions.add(country_admin_permission)
452+
self.country_admin_user.groups.add(country__admin_group)
446453
# Country validator group
447454
country_group_name = f"Local unit validator for {self.local_unit_type.name} {self.country.name}"
448455
country_group = Group.objects.get(name=country_group_name)
@@ -875,6 +882,53 @@ def test_create_local_unit_with_externally_managed_country_and_type(self):
875882
self.assertEqual(response.status_code, 400)
876883
self.assertEqual(LocalUnitChangeRequest.objects.count(), 0)
877884

885+
def test_country_admin_permission_for_local_unit_update(self):
886+
country = CountryFactory.create(
887+
name="India",
888+
iso3="IND",
889+
record_type=CountryType.COUNTRY,
890+
is_deprecated=False,
891+
independent=True,
892+
)
893+
894+
self.india_admin = UserFactory.create(email="[email protected]")
895+
# India admin setup
896+
management.call_command("make_permissions")
897+
country_admin_codename = f"country_admin_{country.id}"
898+
country_admin_permission = Permission.objects.get(codename=country_admin_codename)
899+
country__admin_group_name = "%s Admins" % country.name
900+
country__admin_group = Group.objects.get(name=country__admin_group_name)
901+
country__admin_group.permissions.add(country_admin_permission)
902+
self.india_admin.groups.add(country__admin_group)
903+
local_unit = LocalUnitFactory.create(
904+
country=country,
905+
type=self.local_unit_type,
906+
draft=False,
907+
status=LocalUnit.Status.VALIDATED,
908+
date_of_data="2023-08-08",
909+
)
910+
url = f"/api/v2/local-units/{local_unit.id}/"
911+
data = {
912+
"local_branch_name": "Updated local branch name",
913+
"update_reason_overview": "Needed update for testing",
914+
"type": self.local_unit_type.id,
915+
"location_json": {
916+
"lat": 20.5937,
917+
"lng": 78.9629,
918+
},
919+
}
920+
response = self.client.patch(url, data=data, format="json")
921+
self.assert_401(response)
922+
# Test: different country admin
923+
self.authenticate(self.country_admin_user)
924+
response = self.client.patch(url, data=data, format="json")
925+
self.assert_403(response)
926+
# Test: actual country admin
927+
self.authenticate(self.india_admin)
928+
response = self.client.patch(url, data=data, format="json")
929+
self.assert_200(response)
930+
self.assertEqual(response.data["local_branch_name"], "Updated local branch name")
931+
878932

879933
class TestExternallyManagedLocalUnit(APITestCase):
880934
def setUp(self):

0 commit comments

Comments
 (0)