From d17a86c80338c30231f7aa5e8246524d157ff7dc Mon Sep 17 00:00:00 2001 From: RegisSinjari Date: Tue, 19 Mar 2024 08:30:45 +0100 Subject: [PATCH] [FIXES #11995] Implement endpoint to unregister as a project manager --- geonode/people/tests.py | 114 ++++++++++++++++++++++++++++++++++++++++ geonode/people/views.py | 29 ++++++++++ 2 files changed, 143 insertions(+) diff --git a/geonode/people/tests.py b/geonode/people/tests.py index dc89fd3c3e1..894d936a2d9 100644 --- a/geonode/people/tests.py +++ b/geonode/people/tests.py @@ -61,6 +61,7 @@ def setUp(self): self.groups = Group.objects.all()[:3] self.group_ids = ",".join(str(element.pk) for element in self.groups) self.bar = GroupProfile.objects.get(slug="bar") + self.group_profiles = [GroupProfile.objects.create(title=f"group_{c}", slug=f"slug_{c}") for c in range(5)] def test_redirect_on_get_request(self): """ @@ -911,3 +912,116 @@ def test_delete_a_user_with_resource(self): # bobby cant be deleted self.assertNotEqual(get_user_model().objects.filter(username="bobby").first(), None) self.assertTrue("user_has_resources" in response.json()["errors"][0]) + + def test_remove_self_from_group_manager_all(self): + """ + user is manager of some groups + and is quitting all + """ + bobby = get_user_model().objects.get(username="bobby") + for group in self.group_profiles: + group.join(bobby) + group.promote(bobby) + + self.assertTrue(self.client.login(username="bobby", password="bob")) + self.assertTrue(bobby.is_authenticated) + # assert that bobby is manager of these groups + for group in self.group_profiles: + self.assertTrue(bobby in group.get_managers()) + # call the api that removes him from all assigned groups as manager + response = self.client.post( + path=f"{reverse('users-list')}/{bobby.pk}/remove_from_group_manager", + data={"groups": "ALL"}, + ) + self.assertTrue(response.status_code == 200) + # check that bobby is manager no more + for group in self.group_profiles: + self.assertFalse(bobby in group.get_managers()) + self.assertTrue(group.title in response.json()["success"]) + + def test_remove_self_as_group_manager_list(self): + """ + user is manager of some groups + and is quitting some of them + """ + bobby = get_user_model().objects.get(username="bobby") + + for group in self.group_profiles: + group.join(bobby) + group.promote(bobby) + + self.assertTrue(self.client.login(username="bobby", password="bob")) + self.assertTrue(bobby.is_authenticated) + # assert that bobby is manager of these groups + for group in self.group_profiles: + self.assertTrue(bobby in group.get_managers()) + # call the api that removes him from all assigned groups as manager + response = self.client.post( + path=f"{reverse('users-list')}/{bobby.pk}/remove_from_group_manager", + data={"groups": ",".join([str(group.group_id) for group in self.group_profiles[:3]])}, + ) + self.assertTrue(response.status_code == 200) + # check that bobby is no more manager in the first groups + for group in self.group_profiles[:3]: + self.assertFalse(bobby in group.get_managers()) + self.assertTrue(group.title in response.json()["success"]) + # but still manager in the others + for group in self.group_profiles[4:]: + self.assertTrue(bobby in group.get_managers()) + + def test_remove_user_as_group_manager_empty(self): + """ + user is manager of some groups + and is sending empty payload + """ + bobby = get_user_model().objects.get(username="bobby") + + for group in self.group_profiles: + group.join(bobby) + group.promote(bobby) + + self.assertTrue(self.client.login(username="bobby", password="bob")) + self.assertTrue(bobby.is_authenticated) + # assert that bobby is manager of these groups + for group in self.group_profiles: + self.assertTrue(bobby in group.get_managers()) + # call the api that removes him from all assigned groups as manager + response = self.client.post( + path=f"{reverse('users-list')}/{bobby.pk}/remove_from_group_manager", + data={"groups": ""}, + ) + self.assertTrue(response.status_code == 400) + self.assertTrue("Empty payload" in response.json()["error"]) + # check that bobby is still manager at all groups + for group in self.group_profiles: + self.assertTrue(bobby in group.get_managers()) + + def test_remove_user_as_group_manager_of_invalid_groups(self): + """ + user is manager of some groups + and is trying to remove himself as a manger of a group hes not part of + """ + bobby = get_user_model().objects.get(username="bobby") + for group in self.group_profiles: + group.join(bobby) + group.promote(bobby) + newgroup = GroupProfile.objects.create(title="newgroup") + self.assertTrue(self.client.login(username="bobby", password="bob")) + self.assertTrue(bobby.is_authenticated) + # assert that bobby is manager of these groups + for group in self.group_profiles: + self.assertTrue(bobby in group.get_managers()) + # and not for the new group + self.assertFalse(bobby in newgroup.get_managers()) + # call the api that removes him from all assigned groups as manager" + response = self.client.post( + path=f"{reverse('users-list')}/{bobby.pk}/remove_from_group_manager", + data={"groups": newgroup.group_id}, + ) + self.assertTrue(response.status_code == 400) + # check that bobby is still manager at all groups + for group in self.group_profiles: + self.assertTrue(bobby in group.get_managers()) + # assert the invalid group is in the payload + self.assertTrue("Following groups were invalid" in response.json()["error"]) + self.assertTrue(f"{newgroup.group_id}" in response.json()["error"]) diff --git a/geonode/people/views.py b/geonode/people/views.py index 184f6a28b60..5459b729c23 100644 --- a/geonode/people/views.py +++ b/geonode/people/views.py @@ -251,6 +251,35 @@ def groups(self, request, pk=None): groups = GroupProfile.objects.filter(id__in=qs_ids) return Response(GroupProfileSerializer(embed=True, many=True).to_representation(groups)) + @action(detail=True, methods=["post"]) + def remove_from_group_manager(self, request, pk=None): + user = self.get_object() # admini + target_ids = request.data.get("groups", "") + user_groups = [] + invalid_groups = [] + + if not target_ids: + return Response({"error": "Empty payload"}, status=400) + + if target_ids == "ALL": + user_groups = GroupProfile.groups_for_user(user) + else: + target_ids = set(map(int, target_ids.split(","))) + user_groups = GroupProfile.groups_for_user(user).filter(group_id__in=target_ids) + # check for invalid groups: + invalid_groups.extend(target_ids - set(ug.group_id for ug in user_groups)) + + for group in user_groups: + group.demote(user) + group_names = [group.title for group in user_groups] + + payload = {"success": f"User removed as a group manager from : {', '.join(group_names)}"} + + if invalid_groups: + payload["error"] = f"Following groups were invalid : {invalid_groups}" + return Response(payload, status=400) + return Response(payload, status=200) + class ProfileAutocomplete(autocomplete.Select2QuerySetView): def get_queryset(self):