You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
jumpserver/apps/tickets/views/approve.py

116 lines
4.2 KiB

# -*- coding: utf-8 -*-
#
from __future__ import unicode_literals
from django.views.generic.base import TemplateView
from django.shortcuts import redirect, reverse
from django.core.cache import cache
from django.utils.translation import ugettext as _
from orgs.utils import tmp_to_root_org
from tickets.models import (
Ticket, ApplyAssetTicket, ApplyApplicationTicket,
ApplyLoginTicket, ApplyLoginAssetTicket, ApplyCommandTicket
)
from tickets.const import TicketType
from tickets.errors import AlreadyClosed
from common.utils import get_logger, FlashMessageUtil
logger = get_logger(__name__)
__all__ = ['TicketDirectApproveView']
class TicketDirectApproveView(TemplateView):
template_name = 'tickets/approve_check_password.html'
redirect_field_name = 'next'
TICKET_SUB_MODEL_MAP = {
TicketType.apply_asset: ApplyAssetTicket,
TicketType.apply_application: ApplyApplicationTicket,
TicketType.login_confirm: ApplyLoginTicket,
TicketType.login_asset_confirm: ApplyLoginAssetTicket,
TicketType.command_confirm: ApplyCommandTicket,
}
@property
def message_data(self):
return {
'title': _('Ticket approval'),
'error': _("This ticket does not exist, "
"the process has ended, or this link has expired"),
'redirect_url': self.login_url,
'auto_redirect': False
}
@property
def login_url(self):
return reverse('authentication:login') + '?admin=1'
def redirect_message_response(self, **kwargs):
message_data = self.message_data
for key, value in kwargs.items():
if isinstance(value, str):
message_data[key] = value
if message_data.get('message'):
message_data.pop('error')
redirect_url = FlashMessageUtil.gen_message_url(message_data)
return redirect(redirect_url)
@staticmethod
def clear(token):
cache.delete(token)
def get_context_data(self, **kwargs):
# 放入工单信息
token = kwargs.get('token')
content = cache.get(token, {}).get('content', [])
if self.request.user.is_authenticated:
prompt_msg = _('Click the button below to approve or reject')
else:
prompt_msg = _('After successful authentication, this ticket can be approved directly')
kwargs.update({
'content': content, 'prompt_msg': prompt_msg,
'login_url': '%s&next=%s' % (
self.login_url,
reverse('tickets:direct-approve', kwargs={'token': token})
),
})
return super().get_context_data(**kwargs)
def get(self, request, *args, **kwargs):
token = kwargs.get('token')
ticket_info = cache.get(token)
if not ticket_info:
return self.redirect_message_response(redirect_url=self.login_url)
return super().get(request, *args, **kwargs)
def post(self, request, **kwargs):
user = request.user
token = kwargs.get('token')
action = request.POST.get('action')
if action not in ['approve', 'reject']:
msg = _('Illegal approval action')
return self.redirect_message_response(error=str(msg))
ticket_info = cache.get(token)
if not ticket_info:
return self.redirect_message_response(redirect_url=self.login_url)
try:
ticket_id = ticket_info.get('ticket_id')
with tmp_to_root_org():
ticket = Ticket.all().get(id=ticket_id)
ticket_sub_model = self.TICKET_SUB_MODEL_MAP[ticket.type]
ticket = ticket_sub_model.objects.get(id=ticket_id)
if not ticket.has_current_assignee(user):
raise Exception(_("This user is not authorized to approve this ticket"))
getattr(ticket, action)(user)
except AlreadyClosed as e:
self.clear(token)
return self.redirect_message_response(error=str(e), redirect_url=self.login_url)
except Exception as e:
return self.redirect_message_response(error=str(e), redirect_url=self.login_url)
self.clear(token)
return self.redirect_message_response(message=_("Success"), redirect_url=self.login_url)