Skip to content

Commit

Permalink
Add can_delete key to the groups endpoint
Browse files Browse the repository at this point in the history
Used to backend hide remove group button if group cannot be removed by
currently authenticated user
  • Loading branch information
wesleybl committed Sep 25, 2023
1 parent ec00f34 commit f04f82b
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 3 deletions.
30 changes: 27 additions & 3 deletions src/plone/restapi/services/groups/get.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from AccessControl import getSecurityManager
from plone.restapi.interfaces import ISerializeToJson
from plone.restapi.interfaces import ISerializeToJsonSummary
from plone.restapi.services import Service
from Products.CMFCore.permissions import ManagePortal
from Products.CMFCore.utils import getToolByName
from zExceptions import BadRequest
from zope.component import queryMultiAdapter
Expand All @@ -19,6 +21,10 @@ def __init__(self, context, request):
self.params = []
self.query = self.request.form.copy()

@property
def is_zope_manager(self):
return getSecurityManager().checkPermission(ManagePortal, self.context)

def publishTraverse(self, request, name):
# Consume any path segments after /@users as parameters
self.params.append(name)
Expand Down Expand Up @@ -46,7 +52,13 @@ def _get_filtered_groups(self, query, limit):
results = portal_groups.searchGroups(id=query, max_results=limit)
return [portal_groups.getGroupById(group["groupid"]) for group in results]

def can_delete(self, is_zope_manager, roles):
if is_zope_manager:
return True
return "Manager" not in roles

def reply(self):
is_zope_manager = self.is_zope_manager
if len(self.query) > 0 and len(self.params) == 0:
query = self.query.get("query", "")
limit = self.query.get("limit", DEFAULT_SEARCH_RESULTS_LIMIT)
Expand All @@ -57,7 +69,11 @@ def reply(self):
serializer = queryMultiAdapter(
(group, self.request), ISerializeToJsonSummary
)
result.append(serializer())
group_serializer = serializer()
group_serializer["can_delete"] = self.can_delete(
is_zope_manager, group_serializer["roles"]
)
result.append(group_serializer)
return result
else:
raise BadRequest("Query string supplied is not valid")
Expand All @@ -66,12 +82,20 @@ def reply(self):
result = []
for group in self._get_groups():
serializer = queryMultiAdapter((group, self.request), ISerializeToJson)
result.append(serializer())
group_serializer = serializer()
group_serializer["can_delete"] = self.can_delete(
is_zope_manager, group_serializer["roles"]
)
result.append(group_serializer)
return result
# we retrieve the user on the user id not the username
group = self._get_group(self._get_group_id)
if not group:
self.request.response.setStatus(404)
return
serializer = queryMultiAdapter((group, self.request), ISerializeToJson)
return serializer()
group_serializer = serializer()
group_serializer["can_delete"] = self.can_delete(
is_zope_manager, group_serializer["roles"]
)
return group_serializer
10 changes: 10 additions & 0 deletions src/plone/restapi/tests/test_services_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ def test_list_groups(self):
all(["members" in group for group in response.json()]),
"Members key found in groups listing",
)
self.assertTrue(ptgroup.get("can_delete"))

def test_siteadm_groups_can_delete(self):
self.set_siteadm()
response = self.api_session.get("/@groups")

administrators = [
x for x in response.json() if x.get("groupname") == "Administrators"
][0]
self.assertFalse(administrators.get("can_delete"))

def test_add_group(self):
response = self.api_session.post(
Expand Down

0 comments on commit f04f82b

Please sign in to comment.