2020-12-29 16:19:59 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
#
|
2023-07-28 06:32:31 +00:00
|
|
|
from django.utils.translation import gettext_lazy as _
|
2020-12-29 16:19:59 +00:00
|
|
|
from rest_framework import viewsets
|
|
|
|
from rest_framework.decorators import action
|
2022-06-23 05:52:28 +00:00
|
|
|
from rest_framework.exceptions import MethodNotAllowed
|
2023-02-20 08:48:52 +00:00
|
|
|
from rest_framework.response import Response
|
2020-12-29 16:19:59 +00:00
|
|
|
|
2023-10-16 08:40:21 +00:00
|
|
|
from audits.handler import create_or_update_operate_log
|
2023-01-16 11:02:09 +00:00
|
|
|
from common.api import CommonApiMixin
|
2022-11-18 03:30:31 +00:00
|
|
|
from common.const.http import POST, PUT, PATCH
|
2023-10-16 08:40:21 +00:00
|
|
|
from orgs.utils import tmp_to_root_org, tmp_to_org
|
2023-02-20 08:48:52 +00:00
|
|
|
from rbac.permissions import RBACPermission
|
2022-06-23 05:52:28 +00:00
|
|
|
from tickets import filters
|
2022-11-15 02:43:21 +00:00
|
|
|
from tickets import serializers
|
2022-06-23 05:52:28 +00:00
|
|
|
from tickets.models import (
|
2022-08-17 07:44:59 +00:00
|
|
|
Ticket, ApplyAssetTicket, ApplyLoginTicket,
|
|
|
|
ApplyLoginAssetTicket, ApplyCommandTicket
|
2022-06-23 05:52:28 +00:00
|
|
|
)
|
2022-11-15 02:43:21 +00:00
|
|
|
from tickets.permissions.ticket import IsAssignee, IsApplicant
|
2023-10-16 08:40:21 +00:00
|
|
|
from ..const import TicketAction
|
2020-12-29 16:19:59 +00:00
|
|
|
|
2022-06-23 05:52:28 +00:00
|
|
|
__all__ = [
|
2022-08-16 08:05:08 +00:00
|
|
|
'TicketViewSet', 'ApplyAssetTicketViewSet',
|
|
|
|
'ApplyLoginTicketViewSet', 'ApplyLoginAssetTicketViewSet',
|
|
|
|
'ApplyCommandTicketViewSet'
|
2022-06-23 05:52:28 +00:00
|
|
|
]
|
2020-12-29 16:19:59 +00:00
|
|
|
|
|
|
|
|
2021-01-01 23:25:23 +00:00
|
|
|
class TicketViewSet(CommonApiMixin, viewsets.ModelViewSet):
|
2022-11-15 02:43:21 +00:00
|
|
|
serializer_class = serializers.TicketSerializer
|
2020-12-29 16:19:59 +00:00
|
|
|
serializer_classes = {
|
2022-07-13 07:48:55 +00:00
|
|
|
'approve': serializers.TicketApproveSerializer
|
2020-12-29 16:19:59 +00:00
|
|
|
}
|
2022-06-23 05:52:28 +00:00
|
|
|
model = Ticket
|
2022-06-27 06:02:28 +00:00
|
|
|
perm_model = Ticket
|
2022-06-23 05:52:28 +00:00
|
|
|
filterset_class = filters.TicketFilter
|
2020-12-29 16:19:59 +00:00
|
|
|
search_fields = [
|
2022-06-27 02:15:29 +00:00
|
|
|
'title', 'type', 'status'
|
2020-12-29 16:19:59 +00:00
|
|
|
]
|
2022-02-14 07:23:35 +00:00
|
|
|
ordering = ('-date_created',)
|
2022-03-16 06:43:20 +00:00
|
|
|
rbac_perms = {
|
2022-03-16 08:21:00 +00:00
|
|
|
'open': 'tickets.view_ticket',
|
2023-07-28 06:32:31 +00:00
|
|
|
'bulk': 'tickets.change_ticket',
|
2022-03-16 06:43:20 +00:00
|
|
|
}
|
2020-12-29 16:19:59 +00:00
|
|
|
|
2023-02-20 08:48:52 +00:00
|
|
|
def retrieve(self, request, *args, **kwargs):
|
|
|
|
instance = self.get_object()
|
|
|
|
with tmp_to_root_org():
|
|
|
|
serializer = self.get_serializer(instance)
|
|
|
|
data = serializer.data
|
|
|
|
return Response(data)
|
|
|
|
|
2020-12-29 16:19:59 +00:00
|
|
|
def create(self, request, *args, **kwargs):
|
|
|
|
raise MethodNotAllowed(self.action)
|
|
|
|
|
|
|
|
def update(self, request, *args, **kwargs):
|
|
|
|
raise MethodNotAllowed(self.action)
|
|
|
|
|
|
|
|
def destroy(self, request, *args, **kwargs):
|
|
|
|
raise MethodNotAllowed(self.action)
|
|
|
|
|
2023-07-28 06:32:31 +00:00
|
|
|
def ticket_not_allowed(self):
|
|
|
|
if self.model == Ticket:
|
|
|
|
raise MethodNotAllowed(self.action)
|
|
|
|
|
2020-12-29 16:19:59 +00:00
|
|
|
def get_queryset(self):
|
2022-06-23 05:52:28 +00:00
|
|
|
with tmp_to_root_org():
|
|
|
|
queryset = self.model.get_user_related_tickets(self.request.user)
|
2020-12-29 16:19:59 +00:00
|
|
|
return queryset
|
|
|
|
|
2021-01-13 09:49:03 +00:00
|
|
|
def perform_create(self, serializer):
|
|
|
|
instance = serializer.save()
|
2022-12-13 09:36:00 +00:00
|
|
|
instance.save(update_fields=['applicant'])
|
2022-06-23 05:52:28 +00:00
|
|
|
instance.open()
|
2021-01-13 09:49:03 +00:00
|
|
|
|
2022-03-16 06:43:20 +00:00
|
|
|
@action(detail=False, methods=[POST], permission_classes=[RBACPermission, ])
|
2020-12-30 10:14:06 +00:00
|
|
|
def open(self, request, *args, **kwargs):
|
2022-06-27 02:15:29 +00:00
|
|
|
with tmp_to_root_org():
|
|
|
|
return super().create(request, *args, **kwargs)
|
2020-12-29 16:19:59 +00:00
|
|
|
|
2023-10-16 08:40:21 +00:00
|
|
|
@staticmethod
|
|
|
|
def _record_operate_log(ticket, action):
|
|
|
|
with tmp_to_org(ticket.org_id):
|
|
|
|
after = {
|
|
|
|
'ID': str(ticket.id),
|
|
|
|
str(_('Name')): ticket.title,
|
|
|
|
str(_('Applicant')): str(ticket.applicant),
|
|
|
|
}
|
|
|
|
object_name = ticket._meta.object_name
|
|
|
|
resource_type = ticket._meta.verbose_name
|
|
|
|
create_or_update_operate_log(
|
|
|
|
action, resource_type, resource=ticket,
|
|
|
|
after=after, object_name=object_name
|
|
|
|
)
|
|
|
|
|
2022-07-12 07:28:42 +00:00
|
|
|
@action(detail=True, methods=[PUT, PATCH], permission_classes=[IsAssignee, ])
|
2020-12-29 16:19:59 +00:00
|
|
|
def approve(self, request, *args, **kwargs):
|
2023-07-28 06:32:31 +00:00
|
|
|
self.ticket_not_allowed()
|
|
|
|
|
2022-07-12 07:28:42 +00:00
|
|
|
partial = kwargs.pop('partial', False)
|
2021-01-13 09:49:03 +00:00
|
|
|
instance = self.get_object()
|
2022-07-12 07:28:42 +00:00
|
|
|
serializer = self.get_serializer(instance, data=request.data, partial=partial)
|
2022-07-13 08:54:44 +00:00
|
|
|
with tmp_to_root_org():
|
|
|
|
serializer.is_valid(raise_exception=True)
|
2023-09-06 07:13:02 +00:00
|
|
|
instance = serializer.save()
|
2021-08-25 11:02:50 +00:00
|
|
|
instance.approve(processor=request.user)
|
2023-10-16 08:40:21 +00:00
|
|
|
self._record_operate_log(instance, TicketAction.approve)
|
2022-07-12 07:28:42 +00:00
|
|
|
return Response('ok')
|
2020-12-29 16:19:59 +00:00
|
|
|
|
2021-08-16 10:55:33 +00:00
|
|
|
@action(detail=True, methods=[PUT], permission_classes=[IsAssignee, ])
|
2020-12-29 16:19:59 +00:00
|
|
|
def reject(self, request, *args, **kwargs):
|
2021-01-13 09:49:03 +00:00
|
|
|
instance = self.get_object()
|
|
|
|
instance.reject(processor=request.user)
|
2023-10-16 08:40:21 +00:00
|
|
|
self._record_operate_log(instance, TicketAction.reject)
|
2022-07-12 07:28:42 +00:00
|
|
|
return Response('ok')
|
2020-12-29 16:19:59 +00:00
|
|
|
|
2023-02-06 11:28:56 +00:00
|
|
|
@action(detail=True, methods=[PUT], permission_classes=[IsAssignee | IsApplicant, ])
|
2020-12-29 16:19:59 +00:00
|
|
|
def close(self, request, *args, **kwargs):
|
2021-01-13 09:49:03 +00:00
|
|
|
instance = self.get_object()
|
2022-06-23 05:52:28 +00:00
|
|
|
instance.close()
|
2023-10-16 08:40:21 +00:00
|
|
|
self._record_operate_log(instance, TicketAction.close)
|
2022-07-12 07:28:42 +00:00
|
|
|
return Response('ok')
|
2021-08-25 11:02:50 +00:00
|
|
|
|
2023-07-28 06:32:31 +00:00
|
|
|
@action(detail=False, methods=[PUT], permission_classes=[RBACPermission, ])
|
|
|
|
def bulk(self, request, *args, **kwargs):
|
|
|
|
self.ticket_not_allowed()
|
|
|
|
|
|
|
|
allow_action = ('approve', 'reject')
|
|
|
|
action_ = request.query_params.get('action')
|
|
|
|
if action_ not in allow_action:
|
|
|
|
msg = _("The parameter 'action' must be [{}]").format(','.join(allow_action))
|
|
|
|
return Response({'error': msg}, status=400)
|
|
|
|
|
|
|
|
ticket_ids = request.data.get('tickets', [])
|
|
|
|
queryset = self.get_queryset().filter(state='pending').filter(id__in=ticket_ids)
|
|
|
|
for obj in queryset:
|
|
|
|
if not obj.has_current_assignee(request.user):
|
|
|
|
return Response(
|
|
|
|
{'error': f"{_('User does not have permission')}: {obj}"}, status=400
|
|
|
|
)
|
|
|
|
handler = getattr(obj, action_)
|
|
|
|
handler(processor=request.user)
|
|
|
|
return Response('ok')
|
|
|
|
|
2021-08-25 11:02:50 +00:00
|
|
|
|
2022-06-23 05:52:28 +00:00
|
|
|
class ApplyAssetTicketViewSet(TicketViewSet):
|
|
|
|
model = ApplyAssetTicket
|
|
|
|
filterset_class = filters.ApplyAssetTicketFilter
|
2022-11-18 03:30:31 +00:00
|
|
|
serializer_class = serializers.ApplyAssetSerializer
|
2022-06-23 05:52:28 +00:00
|
|
|
serializer_classes = {
|
2022-11-17 09:34:52 +00:00
|
|
|
'open': serializers.ApplyAssetSerializer,
|
|
|
|
'approve': serializers.ApproveAssetSerializer
|
2022-06-23 05:52:28 +00:00
|
|
|
}
|
2021-08-25 11:02:50 +00:00
|
|
|
|
|
|
|
|
2022-06-23 05:52:28 +00:00
|
|
|
class ApplyLoginTicketViewSet(TicketViewSet):
|
|
|
|
model = ApplyLoginTicket
|
|
|
|
filterset_class = filters.ApplyLoginTicketFilter
|
2022-12-06 10:26:07 +00:00
|
|
|
serializer_class = serializers.LoginReviewSerializer
|
2022-06-23 05:52:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ApplyLoginAssetTicketViewSet(TicketViewSet):
|
|
|
|
model = ApplyLoginAssetTicket
|
|
|
|
filterset_class = filters.ApplyLoginAssetTicketFilter
|
2022-12-06 10:26:07 +00:00
|
|
|
serializer_class = serializers.LoginAssetReviewSerializer
|
2021-08-25 11:02:50 +00:00
|
|
|
|
|
|
|
|
2022-06-23 05:52:28 +00:00
|
|
|
class ApplyCommandTicketViewSet(TicketViewSet):
|
|
|
|
model = ApplyCommandTicket
|
|
|
|
filterset_class = filters.ApplyCommandTicketFilter
|
2022-12-06 10:26:07 +00:00
|
|
|
serializer_class = serializers.ApplyCommandReviewSerializer
|