feat(api): configure team permissions

!5 closes #36
This commit is contained in:
2024-05-30 22:39:15 +09:30
parent 8572b3b3c4
commit c0a09d5d50
5 changed files with 151 additions and 3 deletions

View File

@ -97,6 +97,21 @@ class Team(Group, TenancyObject, SaveHistory):
modified = AutoLastModifiedField()
def permission_list(self) -> list:
permission_list = []
for permission in self.permissions.all():
if str(permission.content_type.app_label + '.' + permission.codename) in permission_list:
continue
permission_list += [ str(permission.content_type.app_label + '.' + permission.codename) ]
return [permission_list, self.permissions.all()]
class TeamUsers(SaveHistory):
class Meta:

View File

@ -33,17 +33,30 @@ class TeamSerializerBase(serializers.ModelSerializer):
class TeamSerializer(TeamSerializerBase):
permissions = serializers.SerializerMethodField('get_url')
def get_url(self, obj):
request = self.context.get('request')
team = Team.objects.get(pk=obj.id)
return request.build_absolute_uri(reverse('_api_team_permission', args=[team.organization_id,team.id]))
class Meta:
model = Team
depth = 1
fields = (
"id",
"name",
"team_name",
'organization',
'permissions',
'url',
)
read_only_fields = [
'permissions'
]

View File

@ -12,6 +12,7 @@ urlpatterns = [
path("organization/", access.OrganizationList.as_view(), name='_api_orgs'),
path("organization/<int:pk>/", access.OrganizationDetail.as_view(), name='_api_organization'),
path("organization/<int:organization_id>/team/<int:group_ptr_id>/", access.TeamDetail.as_view(), name='_api_team'),
path("organization/<int:organization_id>/team/<int:group_ptr_id>/permissions", access.TeamPermissionDetail.as_view(), name='_api_team_permission'),
path("organization/team/", access.TeamList.as_view(), name='_api_teams'),

View File

@ -1,8 +1,10 @@
# from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin
from django.contrib.auth.models import Permission
from rest_framework import generics
from rest_framework import generics, routers, serializers
from rest_framework.response import Response
from access.models import Organization, Team
from api.serializers.access import OrganizationSerializer, TeamSerializer
@ -41,3 +43,111 @@ class TeamDetail(generics.RetrieveUpdateDestroyAPIView):
serializer_class = TeamSerializer
lookup_field = 'group_ptr_id'
class TeamPermissionDetail(routers.APIRootView):
def get(self, request, *args, **kwargs):
return Response(data=Team.objects.get(pk=self.kwargs['group_ptr_id']).permission_list()[0])
def get_view_name(self):
return "Team Permissions"
def delete(self, request, *args, **kwargs):
vals = self.process_request()
remove = vals['remove']
new_permission = Team.objects.get(pk=self.kwargs['group_ptr_id'])
for remove_permission in remove:
new_permission.permissions.remove(remove_permission)
new_permission.save()
return Response(data=Team.objects.get(pk=self.kwargs['group_ptr_id']).permission_list()[0])
def patch(self, request, *args, **kwargs):
vals = self.process_request()
add = vals['add']
new_permission = Team.objects.get(pk=self.kwargs['group_ptr_id'])
for add_permission in add:
new_permission.permissions.add(add_permission)
new_permission.save()
return Response(data=Team.objects.get(pk=self.kwargs['group_ptr_id']).permission_list()[0])
def post(self, request, *args, **kwargs):
vals = self.process_request()
add = vals['add']
remove = vals['remove']
exists = vals['exists']
new_permission = Team.objects.get(pk=self.kwargs['group_ptr_id'])
for add_permission in add:
new_permission.permissions.add(add_permission)
new_permission.save()
for remove_permission in remove:
new_permission.permissions.remove(remove_permission)
new_permission.save()
return Response(data=Team.objects.get(pk=self.kwargs['group_ptr_id']).permission_list()[0])
def process_request(self) -> dict({
"add": list,
"remove": list,
"exists": list
}):
initial_values = Team.objects.get(pk=self.kwargs['group_ptr_id']).permission_list()
add = []
remove = []
exists = []
for request_permission in self.request.data:
fields = request_permission.split('.')
try:
permission = Permission.objects.get(codename=str(fields[1]), content_type__app_label=str(fields[0]))
exists += [ permission.id ]
if permission and request_permission not in initial_values[0]:
add += [ permission.id ]
except:
raise serializers.ValidationError(f'Value was invalid: {request_permission}')
for existing_permission in initial_values[1].all():
if existing_permission.id not in add and existing_permission.id not in exists:
remove += [ existing_permission.id ]
return {
"add": add,
"remove": remove,
"exists": exists
}

View File

@ -61,3 +61,12 @@ Report Format
## User Token
To generate a user token to access the api, use command `python3 manage.py drf_create_token <username>`
## Team Permissions
- url `/api/organization/<organization id>/team/<team id>/permissions`, `HTTP/POST` = replace permissions with those in body
- url `/api/organization/<organization id>/team/<team id>/permissions`, `HTTP/PATCH` = amend permissions to include those in body
- url `/api/organization/<organization id>/team/<team id>/permissions`, `HTTP/DELETE` = delete ALL permissions
HTTP/POST or HTTP/PATCH with list of permission in format `<module name>.<permission>_<model>`. i.e for adding a itam device permission would be `itam.add_device`. if the method is post only the permissions in the post request will remain, the others will be deleted. If method is patch, those in request body will be added.