ChatViewSet.add_member()   B
last analyzed

Complexity

Conditions 5

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 35
rs 8.0894
cc 5
1
from django.http import Http404
2
from django.db.models import Q
3
4
from rest_framework import viewsets, decorators, status
5
from rest_framework.response import Response
6
from rest_framework.permissions import IsAuthenticated
7
from dry_rest_permissions.generics import DRYPermissionFiltersBase
8
9
from sigma_core.models.user import User
10
from sigma_chat.models.chat import Chat
11
from sigma_chat.models.chat_member import ChatMember
12
from sigma_chat.serializers.chat import ChatSerializer
13
from sigma_chat.serializers.chat_member import ChatMemberSerializer
14
15
16
class ChatFilterBackend(DRYPermissionFiltersBase):
17
    def filter_queryset(self, request, queryset, view):
18
        """
19
        Limits all list requests w.r.t the Normal Rules of Visibility.
20
        """
21
        user_chats_ids = request.user.user_chatmember.filter(is_member=True).values_list('chat_id', flat=True)
22
        return queryset.prefetch_related('chatmember') \
23
            .filter(chatmember__user=request.user) \
24
            .distinct()
25
26
27
class ChatViewSet(viewsets.ModelViewSet):
28
    queryset = Chat.objects.all()
29
    serializer_class = ChatSerializer
30
    permission_classes = [IsAuthenticated, ]
31
    filter_backends = (ChatFilterBackend, )
32
33
    def update(self, request, pk=None):
34
        try:
35
            chat = Chat.objects.get(pk=pk)
36
        except Chat.DoesNotExist:
37
            raise Http404("Chat %d not found" % pk)
38
39
        if not request.user.is_chat_admin(chat):
40
            return Response(status=status.HTTP_403_FORBIDDEN)
41
        return super(ChatViewSet, self).update(request, pk)
42
43
    def create(self, request):
44
        data = request.data
45
        data['user'] = request.user.id
46
        serializer = self.serializer_class(data=data)
47
48
        if serializer.is_valid():
49
            serializer.save()
50
            return Response(serializer.data, status=status.HTTP_201_CREATED)
51
        else:
52
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
53
54
    @decorators.detail_route(methods=['post'])
55
    def add_member(self, request, pk=None):
56
        """
57
        Add an user in chat pk.
58
        ---
59
        omit_serializer: true
60
        parameters_strategy:
61
            form: replace
62
        parameters:
63
            - name: user_id
64
              type: integer
65
              required: true
66
        """
67
        try:
68
            chat = Chat.objects.get(pk=pk)
69
            user = User.objects.get(pk=request.data.get('user_id', None))
70
            if not request.user.is_chat_admin(chat):
71
                return Response(status=status.HTTP_403_FORBIDDEN)
72
73
            # Already chat member ?
74
            try:
75
                ChatMember.objects.get(user=user.id, chat=chat.id)
76
                return Response("Already Chat member", status=status.HTTP_400_BAD_REQUEST)
77
            except ChatMember.DoesNotExist:
78
                pass
79
80
            c = ChatMember(chat=chat, user=user, is_creator=False, is_admin=False)
81
            c.save()
82
            s = ChatMemberSerializer(c)
83
            return Response(s.data, status=status.HTTP_200_OK)
84
85
        except Chat.DoesNotExist:
86
            raise Http404("Chat {0} not found".format(pk))
87
        except User.DoesNotExist:
88
            raise Http404("User {0} not found".format(request.data.get('user_id', None)))
89
90
    @decorators.detail_route(methods=['put'])
91
    def change_role(self, request, pk=None):
92
        """
93
        Change the permissions of user in chat pk.
94
        ---
95
        omit_serializer: true
96
        parameters_strategy:
97
            form: replace
98
        parameters:
99
            - name: chatmember_id
100
              type: integer
101
              required: true
102
            - name: role
103
              type: string
104
              required: true
105
        """
106
        try:
107
            chat = Chat.objects.get(pk=pk)
108
            chatmember = ChatMember.objects.get(pk=request.data.get('chatmember_id', None))
109
            """
110
                - cannot change the role of the creator
111
                - if has quit the conversation, can rejoin, but administrator cannot force it
112
                - if not admin, only can REjoin conversation if not banned
113
            """
114
            role = request.data.get('role', None)
115
            is_admin = request.user.is_chat_admin(chat)
116
            not_has_left = chatmember.is_member or chatmember.is_banned
117
            has_ragequit = request.user == chatmember.user and not not_has_left
118
            may_change = is_admin and not_has_left
119
120
            if chatmember.is_creator:
121
                return Response(status=status.HTTP_403_FORBIDDEN)
122
123
            chatmember.is_admin = False
124
            chatmember.is_member = False
125
            chatmember.is_banned = False
126
            changed = False
127
            if role == "admin":
128
                if not may_change:
129
                    return Response(status=status.HTTP_401_UNAUTHORIZED)
130
                if has_ragequit:
131
                    return Response(status=status.HTTP_400_BAD_REQUEST)
132
                chatmember.is_admin = True
133
                chatmember.is_member = True
134
                changed = True
135
            if role == "member":
136
                if not may_change:
137
                    if not has_ragequit:
138
                        return Response(status=status.HTTP_401_UNAUTHORIZED)
139
                chatmember.is_member = True
140
                changed = True
141
            if role == "banned":
142
                if not may_change:
143
                    return Response(status=status.HTTP_401_UNAUTHORIZED)
144
                chatmember.is_banned = True
145
                changed = True
146
            if(role == "leave" and request.user == chatmember.user and not request.user.is_chat_banned(chat)):
147
                changed = True
148
            if changed:
149
                chatmember.save()
150
                s = ChatMemberSerializer(chatmember)
151
                return Response(s.data, status=status.HTTP_200_OK)
152
            return Response("Incorrect role.", status=status.HTTP_400_BAD_REQUEST)
153
154
        except Chat.DoesNotExist:
155
            raise Http404("Chat {0} not found".format(pk))
156
        except ChatMember.DoesNotExist:
157
            raise Http404("ChatMember %d not found" % request.data.get('chatmember_id', None))
158