mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-09-15 23:08:20 +00:00
reactor&feat: 重构工单模块 & 支持申请应用工单 (#5352)
* reactor: 修改工单Model,添加工单迁移文件 * reactor: 修改工单Model,添加工单迁移文件 * reactor: 重构工单模块 * reactor: 重构工单模块2 * reactor: 重构工单模块3 * reactor: 重构工单模块4 * reactor: 重构工单模块5 * reactor: 重构工单模块6 * reactor: 重构工单模块7 * reactor: 重构工单模块8 * reactor: 重构工单模块9 * reactor: 重构工单模块10 * reactor: 重构工单模块11 * reactor: 重构工单模块12 * reactor: 重构工单模块13 * reactor: 重构工单模块14 * reactor: 重构工单模块15 * reactor: 重构工单模块16 * reactor: 重构工单模块17 * reactor: 重构工单模块18 * reactor: 重构工单模块19 * reactor: 重构工单模块20 * reactor: 重构工单模块21 * reactor: 重构工单模块22 * reactor: 重构工单模块23 * reactor: 重构工单模块24 * reactor: 重构工单模块25 * reactor: 重构工单模块26 * reactor: 重构工单模块27 * reactor: 重构工单模块28 * reactor: 重构工单模块29 * reactor: 重构工单模块30 * reactor: 重构工单模块31 * reactor: 重构工单模块32 * reactor: 重构工单模块33 * reactor: 重构工单模块34 * reactor: 重构工单模块35 * reactor: 重构工单模块36 * reactor: 重构工单模块37 * reactor: 重构工单模块38 * reactor: 重构工单模块39
This commit is contained in:
@@ -45,5 +45,5 @@ class TicketStatusApi(mixins.AuthMixin, APIView):
|
||||
ticket = self.get_ticket()
|
||||
if ticket:
|
||||
request.session.pop('auth_ticket_id', '')
|
||||
ticket.perform_status('closed', request.user)
|
||||
ticket.close(processor=request.user)
|
||||
return Response('', status=200)
|
||||
|
@@ -187,12 +187,12 @@ class AuthMixin:
|
||||
if not ticket_id:
|
||||
ticket = None
|
||||
else:
|
||||
ticket = Ticket.origin_objects.get(pk=ticket_id)
|
||||
ticket = Ticket.all().filter(id=ticket_id).first()
|
||||
return ticket
|
||||
|
||||
def get_ticket_or_create(self, confirm_setting):
|
||||
ticket = self.get_ticket()
|
||||
if not ticket or ticket.status == ticket.STATUS.CLOSED:
|
||||
if not ticket or ticket.status_closed:
|
||||
ticket = confirm_setting.create_confirm_ticket(self.request)
|
||||
self.request.session['auth_ticket_id'] = str(ticket.id)
|
||||
return ticket
|
||||
@@ -201,12 +201,16 @@ class AuthMixin:
|
||||
ticket = self.get_ticket()
|
||||
if not ticket:
|
||||
raise errors.LoginConfirmOtherError('', "Not found")
|
||||
if ticket.status == ticket.STATUS.OPEN:
|
||||
if ticket.status_open:
|
||||
raise errors.LoginConfirmWaitError(ticket.id)
|
||||
elif ticket.action == ticket.ACTION.APPROVE:
|
||||
elif ticket.is_approved:
|
||||
self.request.session["auth_confirm"] = "1"
|
||||
return
|
||||
elif ticket.action == ticket.ACTION.REJECT:
|
||||
elif ticket.is_rejected:
|
||||
raise errors.LoginConfirmOtherError(
|
||||
ticket.id, ticket.get_action_display()
|
||||
)
|
||||
elif ticket.is_closed:
|
||||
raise errors.LoginConfirmOtherError(
|
||||
ticket.id, ticket.get_action_display()
|
||||
)
|
||||
|
@@ -49,29 +49,37 @@ class LoginConfirmSetting(CommonModelMixin):
|
||||
def get_user_confirm_setting(cls, user):
|
||||
return get_object_or_none(cls, user=user)
|
||||
|
||||
def create_confirm_ticket(self, request=None):
|
||||
from tickets.models import Ticket
|
||||
title = _('Login confirm') + ' {}'.format(self.user)
|
||||
@staticmethod
|
||||
def construct_confirm_ticket_meta(request=None):
|
||||
if request:
|
||||
remote_addr = get_request_ip(request)
|
||||
city = get_ip_city(remote_addr)
|
||||
datetime = timezone.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
body = __("{user_key}: {username}<br>"
|
||||
"IP: {ip}<br>"
|
||||
"{city_key}: {city}<br>"
|
||||
"{date_key}: {date}<br>").format(
|
||||
user_key=__("User"), username=self.user,
|
||||
ip=remote_addr, city_key=_("City"), city=city,
|
||||
date_key=__("Datetime"), date=datetime
|
||||
)
|
||||
login_ip = get_request_ip(request)
|
||||
else:
|
||||
body = ''
|
||||
reviewer = self.reviewers.all()
|
||||
ticket = Ticket.objects.create(
|
||||
user=self.user, title=title, body=body,
|
||||
type=Ticket.TYPE.LOGIN_CONFIRM,
|
||||
)
|
||||
ticket.assignees.set(reviewer)
|
||||
login_ip = ''
|
||||
login_ip = login_ip or '0.0.0.0'
|
||||
login_city = get_ip_city(login_ip)
|
||||
login_datetime = timezone.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
ticket_meta = {
|
||||
'apply_login_ip': login_ip,
|
||||
'apply_login_city': login_city,
|
||||
'apply_login_datetime': login_datetime,
|
||||
}
|
||||
return ticket_meta
|
||||
|
||||
def create_confirm_ticket(self, request=None):
|
||||
from tickets import const
|
||||
from tickets.models import Ticket
|
||||
ticket_title = _('Login confirm') + ' {}'.format(self.user)
|
||||
ticket_applicant = self.user
|
||||
ticket_meta = self.construct_confirm_ticket_meta(request)
|
||||
ticket_assignees = self.reviewers.all()
|
||||
data = {
|
||||
'title': ticket_title,
|
||||
'type': const.TicketTypeChoices.login_confirm.value,
|
||||
'applicant': ticket_applicant,
|
||||
'meta': ticket_meta,
|
||||
}
|
||||
ticket = Ticket.objects.create(**data)
|
||||
ticket.assignees.set(ticket_assignees)
|
||||
return ticket
|
||||
|
||||
def __str__(self):
|
||||
|
@@ -19,7 +19,6 @@ from django.conf import settings
|
||||
from django.urls import reverse_lazy
|
||||
from django.contrib.auth import BACKEND_SESSION_KEY
|
||||
|
||||
from common.const.front_urls import TICKET_DETAIL
|
||||
from common.utils import get_request_ip, get_object_or_none
|
||||
from users.utils import (
|
||||
redirect_user_first_login_or_index
|
||||
@@ -181,6 +180,7 @@ class UserLoginWaitConfirmView(TemplateView):
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
from tickets.models import Ticket
|
||||
from tickets.const import TICKET_DETAIL_URL
|
||||
ticket_id = self.request.session.get("auth_ticket_id")
|
||||
if not ticket_id:
|
||||
ticket = None
|
||||
@@ -189,7 +189,7 @@ class UserLoginWaitConfirmView(TemplateView):
|
||||
context = super().get_context_data(**kwargs)
|
||||
if ticket:
|
||||
timestamp_created = datetime.datetime.timestamp(ticket.date_created)
|
||||
ticket_detail_url = TICKET_DETAIL.format(id=ticket_id)
|
||||
ticket_detail_url = TICKET_DETAIL_URL.format(id=ticket_id)
|
||||
msg = _("""Wait for <b>{}</b> confirm, You also can copy link to her/him <br/>
|
||||
Don't close this page""").format(ticket.assignees_display)
|
||||
else:
|
||||
|
Reference in New Issue
Block a user