1+ from gettext import gettext as _
2+
13from django .contrib .auth import get_user_model
2- from django .contrib .auth .models import Group
4+ from django .contrib .auth .models import Group , Permission
5+ from django .shortcuts import get_object_or_404
36from drf_spectacular .utils import extend_schema
4- from rest_framework import mixins
7+ from guardian .models .models import GroupObjectPermission
8+ from rest_framework import mixins , status
59from rest_framework .decorators import action
610from rest_framework .response import Response
11+ from rest_framework .serializers import ValidationError
712
813from pulpcore .app .viewsets .base import NamedModelViewSet
914from pulpcore .app .serializers .user import (
1015 GroupSerializer ,
1116 GroupUserSerializer ,
12- ObjectPermissionSerializer ,
17+ PermissionSerializer ,
1318 UserSerializer ,
1419)
1520
@@ -29,16 +34,14 @@ class UserViewSet(
2934 queryset = get_user_model ().objects .all ()
3035
3136 @extend_schema (description = "List user permissions." ,)
32- @action (detail = True , methods = ["get" ], serializer_class = ObjectPermissionSerializer )
37+ @action (detail = True , methods = ["get" ], serializer_class = PermissionSerializer )
3338 def permissions (self , request , pk ):
3439 """
3540 List user permissions.
3641 """
3742 user = self .get_object ()
38- object_permission = ObjectPermissionSerializer (
39- user .userobjectpermission_set .all (), many = True
40- )
41- permissions = ObjectPermissionSerializer (user .user_permissions .all (), many = True )
43+ object_permission = PermissionSerializer (user .userobjectpermission_set .all (), many = True )
44+ permissions = PermissionSerializer (user .user_permissions .all (), many = True )
4245 return Response (object_permission .data + permissions .data )
4346
4447
@@ -58,28 +61,220 @@ class GroupViewSet(
5861 """
5962
6063 endpoint_name = "groups"
64+ router_lookup = "group"
6165 serializer_class = GroupSerializer
6266 queryset = Group .objects .all ()
6367
64- @extend_schema (description = "List group permissions." ,)
65- @action (detail = True , methods = ["get" ], serializer_class = ObjectPermissionSerializer )
66- def permissions (self , request , pk ):
68+
69+ class GroupModelPermissionViewSet (NamedModelViewSet ):
70+ """
71+ ViewSet for Model Permissions that belongs to a Group.
72+
73+ NOTE: This API endpoint is in "tech preview" and subject to change
74+
75+ """
76+
77+ endpoint_name = "model_permissions"
78+ nest_prefix = "groups"
79+ router_lookup = "model_permission"
80+ parent_viewset = GroupViewSet
81+ parent_lookup_kwargs = {"group_pk" : "group__pk" }
82+ serializer_class = PermissionSerializer
83+ queryset = Permission .objects .all ()
84+
85+ def get_model_permission (self , request ):
86+ """Get model permission"""
87+ data = {}
88+ for key , value in request .data .items ():
89+ if key == "permission" :
90+ data ["codename" ] = value .split ("." )[- 1 ]
91+ continue
92+
93+ if key == "pulp_href" :
94+ if "id" in data .keys ():
95+ continue
96+ data ["id" ] = value .strip ("/" ).split ("/" )[- 1 ]
97+ continue
98+
99+ data [key ] = value
100+
101+ return get_object_or_404 (Permission , ** data )
102+
103+ @extend_schema (description = "Retrieve a model permission from a group." )
104+ def retrieve (self , request , group_pk , pk ):
105+ instance = get_object_or_404 (Permission , pk = pk )
106+ serializer = PermissionSerializer (instance , context = {"group_pk" : group_pk })
107+ return Response (serializer .data )
108+
109+ @extend_schema (description = "List group permissions." , responses = {200 : PermissionSerializer })
110+ def list (self , request , group_pk ):
111+ """
112+ List group model permissions.
113+ """
114+ group = Group .objects .get (pk = group_pk )
115+ queryset = group .permissions .all ()
116+
117+ page = self .paginate_queryset (queryset )
118+ if page is not None :
119+ serializer = PermissionSerializer (page , context = {"group_pk" : group_pk }, many = True )
120+ return self .get_paginated_response (serializer .data )
121+
122+ serializer = PermissionSerializer (queryset , context = {"group_pk" : group_pk }, many = True )
123+ return Response (serializer .data )
124+
125+ @extend_schema (
126+ description = "Add a model permission to a group." , responses = {201 : PermissionSerializer },
127+ )
128+ def create (self , request , group_pk ):
129+ """
130+ Add a model permission to a group.
131+ """
132+ group = Group .objects .get (pk = group_pk )
133+ permission = self .get_model_permission (request )
134+ group .permissions .add (permission )
135+ group .save ()
136+ serializer = PermissionSerializer (permission , context = {"group_pk" : group_pk })
137+ return Response (serializer .data , status = status .HTTP_201_CREATED )
138+
139+ @extend_schema (description = "Remove a model permission from a group." )
140+ def destroy (self , request , group_pk , pk ):
141+ """
142+ Remove a model permission from a group.
143+ """
144+ group = Group .objects .get (pk = group_pk )
145+ permission = get_object_or_404 (Permission , pk = pk )
146+ group .permissions .remove (permission )
147+ group .save ()
148+ return Response (status = status .HTTP_204_NO_CONTENT )
149+
150+
151+ class GroupObjectPermissionViewSet (NamedModelViewSet ):
152+ """
153+ ViewSet for Object Permissions that belongs to a Group.
154+
155+ NOTE: This API endpoint is in "tech preview" and subject to change
156+
157+ """
158+
159+ endpoint_name = "object_permissions"
160+ nest_prefix = "groups"
161+ router_lookup = "object_permission"
162+ parent_viewset = GroupViewSet
163+ parent_lookup_kwargs = {"group_pk" : "group__pk" }
164+ serializer_class = PermissionSerializer
165+ queryset = Permission .objects .all ()
166+
167+ def get_model_permission (self , request ):
168+ """Get model permission"""
169+ codename = request .data ["permission" ].split ("." )[- 1 ]
170+ return get_object_or_404 (Permission , codename = codename )
171+
172+ @extend_schema (description = "Retrieve a model permission from a group." )
173+ def retrieve (self , request , group_pk , pk ):
174+ instance = get_object_or_404 (GroupObjectPermission , pk = pk )
175+ serializer = PermissionSerializer (instance , context = {"group_pk" : group_pk })
176+ return Response (serializer .data )
177+
178+ @extend_schema (
179+ description = "List group object permissions." , responses = {200 : PermissionSerializer }
180+ )
181+ def list (self , request , group_pk ):
67182 """
68- List group permissions.
183+ List group object permissions.
69184 """
70- group = self .get_object ()
71- object_permission = ObjectPermissionSerializer (
72- group .groupobjectpermission_set .all (), many = True
185+ group = Group .objects .get (pk = group_pk )
186+ queryset = group .groupobjectpermission_set .all ()
187+
188+ page = self .paginate_queryset (queryset )
189+ if page is not None :
190+ serializer = PermissionSerializer (page , context = {"group_pk" : group_pk }, many = True )
191+ return self .get_paginated_response (serializer .data )
192+
193+ serializer = PermissionSerializer (queryset , context = {"group_pk" : group_pk }, many = True )
194+ return Response (serializer .data )
195+
196+ @extend_schema (
197+ description = "Add an object permission to a group." , responses = {201 : PermissionSerializer },
198+ )
199+ def create (self , request , group_pk ):
200+ """
201+ Create an object permission to a group.
202+ """
203+ group = Group .objects .get (pk = group_pk )
204+ permission = self .get_model_permission (request )
205+ object_pk = request .data ["obj" ].strip ("/" ).split ("/" )[- 1 ]
206+ object_permission = GroupObjectPermission (
207+ group = group ,
208+ permission = permission ,
209+ content_type_id = permission .content_type_id ,
210+ object_pk = object_pk ,
73211 )
74- permissions = ObjectPermissionSerializer (group .permissions .all (), many = True )
75- return Response (object_permission .data + permissions .data )
212+ object_permission .save ()
213+ serializer = PermissionSerializer (object_permission , context = {"group_pk" : group_pk })
214+ return Response (serializer .data , status = status .HTTP_201_CREATED )
215+
216+ @extend_schema (description = "Remove an object permission from a group." )
217+ def destroy (self , request , group_pk , pk ):
218+ """
219+ Delete an object permission from a group.
220+ """
221+ object_permission = get_object_or_404 (GroupObjectPermission , pk = pk , group_id = group_pk )
222+ object_permission .delete ()
223+ return Response (status = status .HTTP_204_NO_CONTENT )
224+
76225
77- @extend_schema (description = "List group users." ,)
78- @action (detail = True , methods = ["get" ], serializer_class = GroupUserSerializer )
79- def users (self , request , pk ):
226+ class GroupUserViewSet (NamedModelViewSet ):
227+ """
228+ ViewSet for Users that belongs to a Group.
229+
230+ NOTE: This API endpoint is in "tech preview" and subject to change
231+
232+ """
233+
234+ endpoint_name = "users"
235+ nest_prefix = "groups"
236+ router_lookup = "user"
237+ parent_viewset = GroupViewSet
238+ parent_lookup_kwargs = {"group_pk" : "groups__pk" }
239+ serializer_class = GroupUserSerializer
240+ queryset = get_user_model ().objects .all ()
241+
242+ def list (self , request , group_pk ):
80243 """
81244 List group users.
82245 """
83- group = self .get_object ()
84- serializer = GroupUserSerializer (group .user_set .all (), many = True )
246+ group = Group .objects .get (pk = group_pk )
247+ queryset = group .user_set .all ()
248+
249+ page = self .paginate_queryset (queryset )
250+ if page is not None :
251+ serializer = GroupUserSerializer (page , context = {"request" : None }, many = True )
252+ return self .get_paginated_response (serializer .data )
253+
254+ serializer = self .get_serializer (queryset , many = True )
85255 return Response (serializer .data )
256+
257+ def create (self , request , group_pk ):
258+ """
259+ Add a user to a group.
260+ """
261+ group = Group .objects .get (pk = group_pk )
262+ if not request .data :
263+ raise ValidationError (
264+ _ ("Please provide one of the following values for User: 'pk', 'id', 'username'" )
265+ )
266+ user = get_object_or_404 (get_user_model (), ** request .data )
267+ group .user_set .add (user )
268+ group .save ()
269+ serializer = GroupUserSerializer (user , context = {"request" : None })
270+ return Response (serializer .data , status = status .HTTP_201_CREATED )
271+
272+ def destroy (self , request , group_pk , pk ):
273+ """
274+ Remove a user from a group.
275+ """
276+ group = Group .objects .get (pk = group_pk )
277+ user = get_object_or_404 (get_user_model (), pk = pk )
278+ group .user_set .remove (user )
279+ group .save ()
280+ return Response (status = status .HTTP_204_NO_CONTENT )
0 commit comments