Completed
Push — master ( a073fc...b77a0e )
by
unknown
01:00
created

GroupMemberViewSet.can_rank()   C

Complexity

Conditions 8

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 8
dl 0
loc 18
rs 6.6666
1
from django.http import Http404
2
3
from rest_framework import viewsets, decorators, status, mixins
4
from rest_framework.response import Response
5
from rest_framework.permissions import IsAuthenticated
6
from dry_rest_permissions.generics import DRYPermissions
7
8
from sigma_core.models.user import User
9
from sigma_core.models.group_member import GroupMember
10
from sigma_core.serializers.user import BasicUserWithPermsSerializer, DetailedUserWithPermsSerializer, DetailedUserSerializer
11
from sigma_core.serializers.group_member import GroupMemberSerializer
12
13
class GroupMemberViewSet(viewsets.ModelViewSet):
14
    queryset = GroupMember.objects.select_related('group', 'user')
15
    serializer_class = GroupMemberSerializer
16
    permission_classes = [IsAuthenticated, DRYPermissions, ]
17
    filter_fields = ('user', 'group', )
18
19
    def create(self, request):
20
        serializer = GroupMemberSerializer(data=request.data)
21
        if not serializer.is_valid():
22
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
23
24
        mem = serializer.save()
25
        return Response(serializer.data, status=status.HTTP_201_CREATED)
26
27
    def destroy(self, request, pk=None):
28
        from sigma_core.models.group import Group
29
        try:
30
            modified_mship = GroupMember.objects.all().select_related('group').get(pk=pk)
31
            group = modified_mship.group
32
            my_mship = GroupMember.objects.all().get(group=group, user=request.user)
33
        except GroupMember.DoesNotExist:
34
            raise Http404()
35
36
        # You can always quit the Group (ie destroy YOUR membership)
37
        if my_mship.id != modified_mship.id:
38
            # Can't modify someone higher than you
39
            if my_mship.perm_rank <= modified_mship.perm_rank:
40
                return Response(status=status.HTTP_403_FORBIDDEN)
41
42
            # Check permission
43
            if group.req_rank_kick > my_mship.perm_rank:
44
                return Response(status=status.HTTP_403_FORBIDDEN)
45
46
        modified_mship.delete()
47
        return Response(status=status.HTTP_204_NO_CONTENT)
48
49
    def can_rank(self, request, modified_mship, my_mship, perm_rank_new):
50
        # You can demote yourself:
51
        demote_self = modified_mship.id == my_mship.id and perm_rank_new < my_mship.perm_rank
52
        group = modified_mship.group
53
54
        # Can't modify someone higher than you, or set rank to higher than you
55
        if (my_mship.perm_rank <= modified_mship.perm_rank or my_mship.perm_rank <= perm_rank_new) and not demote_self:
56
            return False
57
58
        # promote
59
        if perm_rank_new > modified_mship.perm_rank:
60
            if group.req_rank_promote > my_mship.perm_rank:
61
                return False
62
        # demote
63
        else:
64
            if group.req_rank_demote > my_mship.perm_rank and not demote_self:
65
                return False
66
        return True
67
68
    @decorators.detail_route(methods=['put'])
69
    def rank(self, request, pk=None):
70
        from sigma_core.models.group import Group
71
        try:
72
            modified_mship = GroupMember.objects.all().select_related('group').get(pk=pk)
73
            my_mship = GroupMember.objects.all().get(group=modified_mship.group, user=request.user)
74
        except GroupMember.DoesNotExist:
75
            raise Http404()
76
77
        perm_rank_new = request.data.get('perm_rank', None)
78
79
        try:
80
            if perm_rank_new > Group.ADMINISTRATOR_RANK or perm_rank_new < 1 or perm_rank_new == modified_mship.perm_rank:
81
                return Response(status=status.HTTP_400_BAD_REQUEST)
82
        except TypeError:
83
            return Response(status=status.HTTP_400_BAD_REQUEST)
84
85
        if not self.can_rank(request, modified_mship, my_mship, perm_rank_new):
86
            return Response(status=status.HTTP_403_FORBIDDEN)
87
88
        modified_mship.perm_rank = perm_rank_new
89
        modified_mship.save()
90
91
        return Response(GroupMemberSerializer(modified_mship).data, status=status.HTTP_200_OK)
92
93
    @decorators.detail_route(methods=['put'])
94
    def accept_join_request(self, request, pk=None):
95
        try:
96
            gm = GroupMember.objects.select_related('group').get(pk=pk)
97
        except GroupMember.DoesNotExist:
98
            raise Http404()
99
100
        if not request.user.can_accept_join_requests(gm.group):
101
            return Response(status=status.HTTP_403_FORBIDDEN)
102
103
        gm.perm_rank = 1 # default_perm_rank should be 0, so validation is to set perm_rank to 1
104
        gm.save()
105
106
        # TODO: notify user of that change
107
108
        s = GroupMemberSerializer(gm)
109
        return Response(s.data, status=status.HTTP_200_OK)
110