diff --git a/config/default.py b/config/default.py index dbc40cdf..e06114d6 100644 --- a/config/default.py +++ b/config/default.py @@ -965,3 +965,6 @@ def redirect_func(request): NOTICE_IGNORE_LIST = os.getenv("BKAPP_NOTICE_IGNORE_LIST", []) if isinstance(NOTICE_IGNORE_LIST, str): NOTICE_IGNORE_LIST = [i.lower().strip() for i in NOTICE_IGNORE_LIST.split(",")] + +# SMS 邀请评价限额 +TICKET_INVITE_SMS_COUNT = int(os.getenv("BKAPP_TICKET_INVITE_SMS_COUNT", 10)) diff --git a/itsm/ticket/models/ticket.py b/itsm/ticket/models/ticket.py index 32f65d35..aafc16f8 100644 --- a/itsm/ticket/models/ticket.py +++ b/itsm/ticket/models/ticket.py @@ -227,6 +227,7 @@ from platform_config import BaseTicket from .basic import Model +from ..utils import filter_sensitive_info from ...auth_iam.utils import IamRequest @@ -1399,6 +1400,12 @@ class Meta: def __unicode__(self): return "{}({})".format(self.title, self.sn) + def get_meta(self, is_filter_sensitive_info=True): + """获取单据 meta 信息""" + if not is_filter_sensitive_info: + return self.meta + return filter_sensitive_info(self.meta) + @property def task_schemas(self): # todo 测试后删除 diff --git a/itsm/ticket/serializers/ticket.py b/itsm/ticket/serializers/ticket.py index 730d80a2..a8f0f60f 100644 --- a/itsm/ticket/serializers/ticket.py +++ b/itsm/ticket/serializers/ticket.py @@ -114,7 +114,7 @@ TaskFieldSerializer, ) from itsm.ticket.tasks import remark_notify -from itsm.ticket.utils import compute_list_difference, get_user_profile +from itsm.ticket.utils import compute_list_difference, get_user_profile, filter_sensitive_info from itsm.ticket.validators import CreateTicketValidator, StateOperateValidator from itsm.ticket_status.models import TicketStatus from itsm.workflow.models import WorkflowVersion @@ -675,7 +675,7 @@ def to_client_representation(self): ) supervisors = supervisors.split(",") if supervisors else [] real_supervisors = supervisors + [inst["creator"]] - inst["meta"] = real_ticket["meta"] + inst["meta"] = filter_sensitive_info(real_ticket["meta"]) current_status = real_ticket["current_status"] # 等待审批的条件为在审批节点 并且 单据处在非挂起状态 @@ -874,16 +874,15 @@ def to_representation(self, inst): # 当前步骤、单据状态、优先级来源母单 master_ticket = inst.get_master_ticket() master_or_self_ticket = master_ticket if master_ticket else inst - - if "headers" in master_or_self_ticket.meta: - master_or_self_ticket.meta.pop("headers") + + meta = master_or_self_ticket.get_meta() data.update( current_status=master_or_self_ticket.current_status, current_status_display=master_or_self_ticket.current_status_display, current_steps=master_or_self_ticket.brief_current_steps, priority_name=master_or_self_ticket.priority_name, - meta=master_or_self_ticket.meta, + meta=meta ) can_comment = inst.can_comment(username) or is_email_invite_token diff --git a/itsm/ticket/utils.py b/itsm/ticket/utils.py index bd15c1a7..60c461a9 100644 --- a/itsm/ticket/utils.py +++ b/itsm/ticket/utils.py @@ -22,7 +22,9 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ +import copy import json +from typing import Dict import jmespath import requests @@ -224,3 +226,10 @@ def get_user_profile(username): except Exception: profile = {"name": "", "phone": "", "departments": []} return profile + + +def filter_sensitive_info(ticket_meta: Dict): + meta = copy.deepcopy(ticket_meta) + meta.pop("headers", None) + meta.pop("callback_url", None) + return meta diff --git a/itsm/ticket/validators/misc.py b/itsm/ticket/validators/misc.py index b6356ae4..9cbcd9a6 100644 --- a/itsm/ticket/validators/misc.py +++ b/itsm/ticket/validators/misc.py @@ -22,7 +22,7 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ - +from django.conf import settings from django.utils.translation import ugettext as _ from rest_framework import serializers @@ -30,7 +30,7 @@ from itsm.component.utils.basic import Regex from itsm.component.utils.client_backend_query import get_bk_users from itsm.role.models import UserRole -from itsm.ticket.models import Ticket, TicketComment +from itsm.ticket.models import Ticket, TicketComment, TicketCommentInvite def days_validate(days): @@ -102,6 +102,14 @@ def sms_invite_validate(ticket, numbers, invitor): if not ticket.can_comment(invitor): raise serializers.ValidationError(_('抱歉,您无权发送评价邀请')) + + if settings.TICKET_INVITE_SMS_COUNT: + if len(numbers) > settings.TICKET_INVITE_SMS_COUNT: + raise serializers.ValidationError(_("SMS 发送评价邀请超过限额")) + + invite_count = TicketCommentInvite.objects.filter(comment__ticket__id=ticket.id).count() + if invite_count > settings.TICKET_INVITE_SMS_COUNT: + raise serializers.ValidationError(_("SMS 发送评价邀请超过限额")) for number in numbers: try: diff --git a/itsm/ticket/views/ticket.py b/itsm/ticket/views/ticket.py index acd9dd54..7971958e 100644 --- a/itsm/ticket/views/ticket.py +++ b/itsm/ticket/views/ticket.py @@ -575,7 +575,7 @@ def send_sms(self, request, *args, **kwargs): if fail_numbers else "success", "data": links, - "code": "SEND_SMS_FAILED", + "code": "OK" if len(fail_numbers) == 0 else "SEND_SMS_FAILED", } )