69adc1d41c
Add Chat User Interface Restructure some services Virtual Scrolling Manual change detection for message updates Enhanced Date pipe Message layout Tabbed reusable chat window Deleting messages Further permission checks Delete-prompts Mobile friendly chat usage automatically scroll to bottom
123 lines
3.7 KiB
Python
123 lines
3.7 KiB
Python
from django.conf import settings
|
|
from django.contrib.auth.models import AnonymousUser
|
|
from rest_framework.utils.serializer_helpers import ReturnDict
|
|
|
|
from openslides.utils.auth import has_perm
|
|
from openslides.utils.autoupdate import (
|
|
disable_history,
|
|
inform_changed_data,
|
|
inform_deleted_data,
|
|
)
|
|
from openslides.utils.rest_api import (
|
|
CreateModelMixin,
|
|
DestroyModelMixin,
|
|
GenericViewSet,
|
|
ListModelMixin,
|
|
ModelViewSet,
|
|
Response,
|
|
RetrieveModelMixin,
|
|
detail_route,
|
|
status,
|
|
)
|
|
|
|
from .access_permissions import ChatGroupAccessPermissions, ChatMessageAccessPermissions
|
|
from .models import ChatGroup, ChatMessage
|
|
|
|
|
|
ENABLE_CHAT = getattr(settings, "ENABLE_CHAT", False)
|
|
|
|
|
|
class ChatGroupViewSet(ModelViewSet):
|
|
"""
|
|
API endpoint for chat groups.
|
|
|
|
There are the following views: metadata, list, retrieve, create,
|
|
partial_update, update, destroy and clear.
|
|
"""
|
|
|
|
access_permissions = ChatGroupAccessPermissions()
|
|
queryset = ChatGroup.objects.all()
|
|
|
|
def check_view_permissions(self):
|
|
"""
|
|
Returns True if the user has required permissions.
|
|
"""
|
|
if self.action in ("list", "retrieve"):
|
|
result = True
|
|
else:
|
|
result = has_perm(self.request.user, "chat.can_manage")
|
|
|
|
return result and ENABLE_CHAT
|
|
|
|
def update(self, *args, **kwargs):
|
|
response = super().update(*args, **kwargs)
|
|
# Update all affected chatmessages to update their `access_groups_id` field,
|
|
# which is taken from the updated chatgroup.
|
|
inform_changed_data(ChatMessage.objects.filter(chatgroup=self.get_object()))
|
|
return response
|
|
|
|
@detail_route(methods=["POST"])
|
|
def clear(self, request, *args, **kwargs):
|
|
"""
|
|
Deletes all chat messages of the group.
|
|
"""
|
|
messages = self.get_object().messages.all()
|
|
messages_id = [message.id for message in messages]
|
|
messages.delete()
|
|
collection = ChatMessage.get_collection_string()
|
|
inform_deleted_data((collection, id) for id in messages_id)
|
|
return Response()
|
|
|
|
|
|
class ChatMessageViewSet(
|
|
ListModelMixin,
|
|
RetrieveModelMixin,
|
|
CreateModelMixin,
|
|
DestroyModelMixin,
|
|
GenericViewSet,
|
|
):
|
|
"""
|
|
API endpoint for chat groups.
|
|
|
|
There are the following views: metadata, list, retrieve, create
|
|
"""
|
|
|
|
access_permissions = ChatMessageAccessPermissions()
|
|
queryset = ChatMessage.objects.all()
|
|
|
|
def check_view_permissions(self):
|
|
# The permissions are checked in the view.
|
|
return ENABLE_CHAT and not isinstance(self.request.user, AnonymousUser)
|
|
|
|
def create(self, request, *args, **kwargs):
|
|
serializer = self.get_serializer(data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
|
|
if not serializer.validated_data["chatgroup"].can_access(self.request.user):
|
|
self.permission_denied(self.request)
|
|
|
|
# Do not use the serializer.save since it will put the model in the history.
|
|
validated_data = {
|
|
**serializer.validated_data,
|
|
"username": self.request.user.short_name(),
|
|
"user_id": self.request.user.id,
|
|
}
|
|
chatmessage = ChatMessage(**validated_data)
|
|
chatmessage.save(disable_history=True)
|
|
|
|
return Response(
|
|
ReturnDict(id=chatmessage.id, serializer=serializer),
|
|
status=status.HTTP_201_CREATED,
|
|
)
|
|
|
|
def destroy(self, request, *args, **kwargs):
|
|
if (
|
|
not has_perm(self.request.user, "chat.can_manage")
|
|
and self.get_object().user_id != self.request.user.id
|
|
):
|
|
self.permission_denied(request)
|
|
|
|
disable_history()
|
|
|
|
return super().destroy(request, *args, **kwargs)
|