mirror of https://github.com/jumpserver/jumpserver
commit
d27947919b
|
@ -217,7 +217,7 @@ class SystemUserCommandFilterRuleListApi(generics.ListAPIView):
|
|||
q = Q()
|
||||
if user:
|
||||
q |= Q(users=user)
|
||||
if user_group:
|
||||
if user_groups:
|
||||
q |= Q(user_groups__in=set(user_groups))
|
||||
if system_user:
|
||||
q |= Q(system_users=system_user)
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# Generated by Django 3.1.13 on 2021-12-15 06:36
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
OLD_ACTION_ALLOW = 1
|
||||
NEW_ACTION_ALLOW = 9
|
||||
|
||||
|
||||
def migrate_action(apps, schema_editor):
|
||||
model = apps.get_model("assets", "CommandFilterRule")
|
||||
model.objects.filter(action=OLD_ACTION_ALLOW).update(action=NEW_ACTION_ALLOW)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assets', '0082_auto_20211209_1440'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(migrate_action),
|
||||
migrations.AlterField(
|
||||
model_name='commandfilterrule',
|
||||
name='action',
|
||||
field=models.IntegerField(choices=[(0, 'Deny'), (9, 'Allow'), (2, 'Reconfirm')], default=0, verbose_name='Action'),
|
||||
),
|
||||
]
|
|
@ -68,7 +68,7 @@ class CommandFilterRule(OrgModelMixin):
|
|||
|
||||
class ActionChoices(models.IntegerChoices):
|
||||
deny = 0, _('Deny')
|
||||
allow = 1, _('Allow')
|
||||
allow = 9, _('Allow')
|
||||
confirm = 2, _('Reconfirm')
|
||||
|
||||
id = models.UUIDField(default=uuid.uuid4, primary_key=True)
|
||||
|
|
|
@ -270,7 +270,7 @@ class Saml2AuthCallbackView(View, PrepareRequestMixin):
|
|||
|
||||
class Saml2AuthMetadataView(View, PrepareRequestMixin):
|
||||
|
||||
def get(self, _):
|
||||
def get(self, request):
|
||||
saml_settings = self.get_sp_settings()
|
||||
saml_settings = JmsSaml2Settings(
|
||||
settings=saml_settings, sp_validation_only=True,
|
||||
|
@ -279,8 +279,17 @@ class Saml2AuthMetadataView(View, PrepareRequestMixin):
|
|||
metadata = saml_settings.get_sp_metadata()
|
||||
errors = saml_settings.validate_metadata(metadata)
|
||||
|
||||
key = saml_settings.get_sp_key()
|
||||
cert = saml_settings.get_sp_cert()
|
||||
if not key:
|
||||
errors.append('Not found SP private key')
|
||||
if not cert:
|
||||
errors.append('Not found SP cert')
|
||||
|
||||
if len(errors) == 0:
|
||||
resp = HttpResponse(content=metadata, content_type='text/xml')
|
||||
else:
|
||||
resp = HttpResponseServerError(content=', '.join(errors))
|
||||
content = "Error occur: <br>"
|
||||
content += '<br>'.join(errors)
|
||||
resp = HttpResponseServerError(content=content)
|
||||
return resp
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<b>{% trans 'Login city' %}:</b> {{ city }}({{ ip }})
|
||||
</p>
|
||||
|
||||
-
|
||||
<p>
|
||||
{% trans 'If you suspect that the login behavior is abnormal, please modify the account password in time.' %}
|
||||
</p>
|
|
@ -11,9 +11,8 @@
|
|||
</a>
|
||||
</p>
|
||||
|
||||
-
|
||||
<p>
|
||||
{% trans 'This link is valid for 1 hour. After it expires' %}
|
||||
<a href="{{ forget_password_url }}?email={{ user.email }}">
|
||||
{% trans 'request new one' %}
|
||||
</a>
|
||||
<a href="{{ forget_password_url }}?email={{ user.email }}">{% trans 'request new one' %}</a>
|
||||
</p>
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<b>{% trans 'IP' %}:</b> {{ ip_address }} <br />
|
||||
<b>{% trans 'Browser' %}:</b> {{ browser }}
|
||||
</p>
|
||||
-
|
||||
<p>
|
||||
{% trans 'If the password update was not initiated by you, your account may have security issues' %} <br />
|
||||
{% trans 'If you have any questions, you can contact the administrator' %}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<b>{% trans 'IP' %}:</b> {{ ip_address }} <br />
|
||||
<b>{% trans 'Browser' %}:</b> {{ browser }}
|
||||
</p>
|
||||
-
|
||||
<p>
|
||||
{% trans 'If the public key update was not initiated by you, your account may have security issues' %} <br />
|
||||
{% trans 'If you have any questions, you can contact the administrator' %}
|
||||
|
|
|
@ -151,12 +151,29 @@ class DingTalk:
|
|||
'data': data
|
||||
}
|
||||
data = self._request.post(URL.SEND_MESSAGE_BY_TEMPLATE, json=body, with_token=True)
|
||||
return data
|
||||
|
||||
def send_markdown(self, user_ids, title, msg):
|
||||
body = {
|
||||
'agent_id': self._agentid,
|
||||
'userid_list': ','.join(user_ids),
|
||||
'to_all_user': False,
|
||||
'msg': {
|
||||
'msgtype': 'markdown',
|
||||
'markdown': {
|
||||
'title': title,
|
||||
'text': msg
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.info(f'Dingtalk send markdown to user {user_ids}: {msg}')
|
||||
data = self._request.post(URL.SEND_MESSAGE, json=body, with_token=True)
|
||||
return data
|
||||
|
||||
def send_text(self, user_ids, msg):
|
||||
body = {
|
||||
'agent_id': self._agentid,
|
||||
'userid_list': ','.join(user_ids),
|
||||
# 'dept_id_list': '',
|
||||
'to_all_user': False,
|
||||
'msg': {
|
||||
'msgtype': 'text',
|
||||
|
@ -165,7 +182,7 @@ class DingTalk:
|
|||
}
|
||||
}
|
||||
}
|
||||
logger.info(f'Dingtalk send text: user_ids={user_ids} msg={msg}')
|
||||
logger.info(f'Dingtalk send msg to user {user_ids}: {msg}')
|
||||
data = self._request.post(URL.SEND_MESSAGE, json=body, with_token=True)
|
||||
return data
|
||||
|
||||
|
|
|
@ -90,7 +90,10 @@ class WeCom(RequestMixin):
|
|||
timeout=timeout
|
||||
)
|
||||
|
||||
def send_text(self, users: Iterable, msg: AnyStr, **kwargs):
|
||||
def send_markdown(self, users: Iterable, msg: AnyStr, **kwargs):
|
||||
pass
|
||||
|
||||
def send_text(self, users: Iterable, msg: AnyStr, markdown=False, **kwargs):
|
||||
"""
|
||||
https://open.work.weixin.qq.com/api/doc/90000/90135/90236
|
||||
|
||||
|
@ -115,6 +118,13 @@ class WeCom(RequestMixin):
|
|||
},
|
||||
**extra_params
|
||||
}
|
||||
if markdown:
|
||||
body['msgtype'] = 'markdown'
|
||||
body["markdown"] = {
|
||||
"content": msg
|
||||
}
|
||||
body.pop('text', '')
|
||||
|
||||
logger.info(f'Wecom send text: users={users} msg={msg}')
|
||||
data = self._requests.post(URL.SEND_MESSAGE, json=body, check_errcode_is_0=False)
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9a8f5840c041b5f3188621ec731fa1b4a5da20730ea6394cf5e2b5c9c241a00e
|
||||
size 94712
|
||||
oid sha256:2bf3340b7ca0dc3e698160fe8df980df07ebdecfd9312c5aca230d18a05fea18
|
||||
size 94929
|
||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: JumpServer 0.3.3\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-12-14 17:54+0800\n"
|
||||
"POT-Creation-Date: 2021-12-15 15:41+0800\n"
|
||||
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
|
||||
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
||||
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
||||
|
@ -35,12 +35,12 @@ msgid "Name"
|
|||
msgstr "名称"
|
||||
|
||||
#: acls/models/base.py:27 assets/models/cmd_filter.py:77
|
||||
#: assets/models/user.py:200
|
||||
#: assets/models/user.py:209
|
||||
msgid "Priority"
|
||||
msgstr "优先级"
|
||||
|
||||
#: acls/models/base.py:28 assets/models/cmd_filter.py:77
|
||||
#: assets/models/user.py:200
|
||||
#: assets/models/user.py:209
|
||||
msgid "1-100, the lower the value will be match first"
|
||||
msgstr "优先级可选范围为 1-100 (数值越小越优先)"
|
||||
|
||||
|
@ -209,7 +209,7 @@ msgid ""
|
|||
msgstr "格式为逗号分隔的字符串, * 表示匹配所有. 可选的协议有: {}"
|
||||
|
||||
#: acls/serializers/login_asset_acl.py:55 assets/models/asset.py:214
|
||||
#: assets/models/domain.py:63 assets/models/user.py:201
|
||||
#: assets/models/domain.py:63 assets/models/user.py:210
|
||||
#: terminal/serializers/session.py:30 terminal/serializers/storage.py:69
|
||||
msgid "Protocol"
|
||||
msgstr "协议"
|
||||
|
@ -265,7 +265,7 @@ msgid "Custom"
|
|||
msgstr "自定义"
|
||||
|
||||
#: applications/models/account.py:11 assets/models/authbook.py:19
|
||||
#: assets/models/cmd_filter.py:38 assets/models/user.py:291 audits/models.py:39
|
||||
#: assets/models/cmd_filter.py:38 assets/models/user.py:300 audits/models.py:39
|
||||
#: perms/models/application_permission.py:32
|
||||
#: perms/models/asset_permission.py:101 templates/_nav.html:45
|
||||
#: terminal/backends/command/models.py:20
|
||||
|
@ -306,7 +306,7 @@ msgstr "类别"
|
|||
|
||||
#: applications/models/application.py:171
|
||||
#: applications/serializers/application.py:90 assets/models/cmd_filter.py:76
|
||||
#: assets/models/user.py:199 perms/models/application_permission.py:23
|
||||
#: assets/models/user.py:208 perms/models/application_permission.py:23
|
||||
#: perms/serializers/application/user_permission.py:34
|
||||
#: terminal/models/storage.py:55 terminal/models/storage.py:116
|
||||
#: tickets/models/flow.py:51 tickets/models/ticket.py:48
|
||||
|
@ -523,7 +523,7 @@ msgstr "主机名原始"
|
|||
msgid "Protocols"
|
||||
msgstr "协议组"
|
||||
|
||||
#: assets/models/asset.py:219 assets/models/user.py:191
|
||||
#: assets/models/asset.py:219 assets/models/user.py:200
|
||||
#: perms/models/asset_permission.py:100
|
||||
#: xpack/plugins/change_auth_plan/models/asset.py:44
|
||||
#: xpack/plugins/gathered_user/models.py:24
|
||||
|
@ -536,7 +536,7 @@ msgid "Is active"
|
|||
msgstr "激活"
|
||||
|
||||
#: assets/models/asset.py:223 assets/models/cluster.py:19
|
||||
#: assets/models/user.py:188 assets/models/user.py:340 templates/_nav.html:44
|
||||
#: assets/models/user.py:197 assets/models/user.py:349 templates/_nav.html:44
|
||||
msgid "Admin user"
|
||||
msgstr "特权用户"
|
||||
|
||||
|
@ -790,75 +790,75 @@ msgstr "ssh私钥"
|
|||
msgid "Node"
|
||||
msgstr "节点"
|
||||
|
||||
#: assets/models/user.py:182
|
||||
#: assets/models/user.py:191
|
||||
msgid "Automatic managed"
|
||||
msgstr "托管密码"
|
||||
|
||||
#: assets/models/user.py:183
|
||||
#: assets/models/user.py:192
|
||||
msgid "Manually input"
|
||||
msgstr "手动输入"
|
||||
|
||||
#: assets/models/user.py:187
|
||||
#: assets/models/user.py:196
|
||||
msgid "Common user"
|
||||
msgstr "普通用户"
|
||||
|
||||
#: assets/models/user.py:190
|
||||
#: assets/models/user.py:199
|
||||
msgid "Username same with user"
|
||||
msgstr "用户名与用户相同"
|
||||
|
||||
#: assets/models/user.py:193 assets/serializers/domain.py:29
|
||||
#: assets/models/user.py:202 assets/serializers/domain.py:29
|
||||
#: templates/_nav.html:39
|
||||
#: terminal/templates/terminal/_msg_command_execute_alert.html:16
|
||||
#: xpack/plugins/change_auth_plan/models/asset.py:40
|
||||
msgid "Assets"
|
||||
msgstr "资产"
|
||||
|
||||
#: assets/models/user.py:197 templates/_nav.html:17
|
||||
#: assets/models/user.py:206 templates/_nav.html:17
|
||||
#: users/views/profile/pubkey.py:37
|
||||
msgid "Users"
|
||||
msgstr "用户管理"
|
||||
|
||||
#: assets/models/user.py:198
|
||||
#: assets/models/user.py:207
|
||||
msgid "User groups"
|
||||
msgstr "用户组"
|
||||
|
||||
#: assets/models/user.py:202
|
||||
#: assets/models/user.py:211
|
||||
msgid "Auto push"
|
||||
msgstr "自动推送"
|
||||
|
||||
#: assets/models/user.py:203
|
||||
#: assets/models/user.py:212
|
||||
msgid "Sudo"
|
||||
msgstr "Sudo"
|
||||
|
||||
#: assets/models/user.py:204
|
||||
#: assets/models/user.py:213
|
||||
msgid "Shell"
|
||||
msgstr "Shell"
|
||||
|
||||
#: assets/models/user.py:205
|
||||
#: assets/models/user.py:214
|
||||
msgid "Login mode"
|
||||
msgstr "认证方式"
|
||||
|
||||
#: assets/models/user.py:206
|
||||
#: assets/models/user.py:215
|
||||
msgid "SFTP Root"
|
||||
msgstr "SFTP根路径"
|
||||
|
||||
#: assets/models/user.py:207 authentication/models.py:45
|
||||
#: assets/models/user.py:216 authentication/models.py:45
|
||||
msgid "Token"
|
||||
msgstr ""
|
||||
|
||||
#: assets/models/user.py:208
|
||||
#: assets/models/user.py:217
|
||||
msgid "Home"
|
||||
msgstr "家目录"
|
||||
|
||||
#: assets/models/user.py:209
|
||||
#: assets/models/user.py:218
|
||||
msgid "System groups"
|
||||
msgstr "用户组"
|
||||
|
||||
#: assets/models/user.py:212
|
||||
#: assets/models/user.py:221
|
||||
msgid "User switch"
|
||||
msgstr "用户切换"
|
||||
|
||||
#: assets/models/user.py:213
|
||||
#: assets/models/user.py:222
|
||||
msgid "Switch from"
|
||||
msgstr "切换自"
|
||||
|
||||
|
@ -1068,24 +1068,24 @@ msgid ""
|
|||
"The task of self-checking is already running and cannot be started repeatedly"
|
||||
msgstr "自检程序已经在运行,不能重复启动"
|
||||
|
||||
#: assets/tasks/push_system_user.py:194
|
||||
#: assets/tasks/push_system_user.py:199
|
||||
msgid "System user is dynamic: {}"
|
||||
msgstr "系统用户是动态的: {}"
|
||||
|
||||
#: assets/tasks/push_system_user.py:234
|
||||
#: assets/tasks/push_system_user.py:239
|
||||
msgid "Start push system user for platform: [{}]"
|
||||
msgstr "推送系统用户到平台: [{}]"
|
||||
|
||||
#: assets/tasks/push_system_user.py:235
|
||||
#: assets/tasks/push_system_user.py:240
|
||||
#: assets/tasks/system_user_connectivity.py:106
|
||||
msgid "Hosts count: {}"
|
||||
msgstr "主机数量: {}"
|
||||
|
||||
#: assets/tasks/push_system_user.py:277 assets/tasks/push_system_user.py:310
|
||||
#: assets/tasks/push_system_user.py:282 assets/tasks/push_system_user.py:315
|
||||
msgid "Push system users to assets: {}"
|
||||
msgstr "推送系统用户到入资产: {}"
|
||||
|
||||
#: assets/tasks/push_system_user.py:289
|
||||
#: assets/tasks/push_system_user.py:294
|
||||
msgid "Push system users to asset: {}({}) => {}"
|
||||
msgstr "推送系统用户到入资产: {}({}) => {}"
|
||||
|
||||
|
@ -2785,23 +2785,23 @@ msgstr "测试成功"
|
|||
msgid "Test mail sent to {}, please check"
|
||||
msgstr "邮件已经发送{}, 请检查"
|
||||
|
||||
#: settings/api/ldap.py:152
|
||||
#: settings/api/ldap.py:157
|
||||
msgid "Synchronization start, please wait."
|
||||
msgstr "同步开始,请稍等"
|
||||
|
||||
#: settings/api/ldap.py:156
|
||||
#: settings/api/ldap.py:161
|
||||
msgid "Synchronization is running, please wait."
|
||||
msgstr "同步正在运行,请稍等"
|
||||
|
||||
#: settings/api/ldap.py:161
|
||||
#: settings/api/ldap.py:166
|
||||
msgid "Synchronization error: {}"
|
||||
msgstr "同步错误: {}"
|
||||
|
||||
#: settings/api/ldap.py:194
|
||||
#: settings/api/ldap.py:199
|
||||
msgid "Get ldap users is None"
|
||||
msgstr "获取 LDAP 用户为 None"
|
||||
|
||||
#: settings/api/ldap.py:203
|
||||
#: settings/api/ldap.py:208
|
||||
msgid "Imported {} users successfully (Organization: {})"
|
||||
msgstr "成功导入 {} 个用户 ( 组织: {} )"
|
||||
|
||||
|
@ -5516,31 +5516,31 @@ msgstr "账号保护已开启,请根据提示完成以下操作"
|
|||
msgid "Open MFA Authenticator and enter the 6-bit dynamic code"
|
||||
msgstr "请打开 MFA 验证器,输入 6 位动态码"
|
||||
|
||||
#: users/views/profile/otp.py:86
|
||||
#: users/views/profile/otp.py:87
|
||||
msgid "Already bound"
|
||||
msgstr "已经绑定"
|
||||
|
||||
#: users/views/profile/otp.py:87
|
||||
#: users/views/profile/otp.py:88
|
||||
msgid "MFA already bound, disable first, then bound"
|
||||
msgstr "MFA(OTP) 已经绑定,请先禁用,再绑定"
|
||||
|
||||
#: users/views/profile/otp.py:114
|
||||
#: users/views/profile/otp.py:115
|
||||
msgid "OTP enable success"
|
||||
msgstr "MFA(OTP) 启用成功"
|
||||
|
||||
#: users/views/profile/otp.py:115
|
||||
#: users/views/profile/otp.py:116
|
||||
msgid "OTP enable success, return login page"
|
||||
msgstr "MFA(OTP) 启用成功,返回到登录页面"
|
||||
|
||||
#: users/views/profile/otp.py:157
|
||||
#: users/views/profile/otp.py:158
|
||||
msgid "Disable OTP"
|
||||
msgstr "禁用虚拟 MFA(OTP)"
|
||||
|
||||
#: users/views/profile/otp.py:163
|
||||
#: users/views/profile/otp.py:164
|
||||
msgid "OTP disable success"
|
||||
msgstr "MFA(OTP) 禁用成功"
|
||||
|
||||
#: users/views/profile/otp.py:164
|
||||
#: users/views/profile/otp.py:165
|
||||
msgid "OTP disable success, return login page"
|
||||
msgstr "MFA(OTP) 禁用成功,返回登录页面"
|
||||
|
||||
|
@ -5752,15 +5752,19 @@ msgstr "* 请输入正确的密码长度"
|
|||
msgid "* Password length range 6-30 bits"
|
||||
msgstr "* 密码长度范围 6-30 位"
|
||||
|
||||
#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:249
|
||||
#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:236
|
||||
msgid "After many attempts to change the secret, it still failed"
|
||||
msgstr "多次尝试改密后, 依然失败"
|
||||
|
||||
#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:255
|
||||
msgid "Invalid/incorrect password"
|
||||
msgstr "无效/错误 密码"
|
||||
|
||||
#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:251
|
||||
#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:257
|
||||
msgid "Failed to connect to the host"
|
||||
msgstr "连接主机失败"
|
||||
|
||||
#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:253
|
||||
#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:259
|
||||
msgid "Data could not be sent to remote"
|
||||
msgstr "无法将数据发送到远程"
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ class DingTalk(BackendBase):
|
|||
|
||||
def send_msg(self, users, message, subject=None):
|
||||
accounts, __, __ = self.get_accounts(users)
|
||||
return self.dingtalk.send_text(accounts, message)
|
||||
return self.dingtalk.send_markdown(accounts, subject, message)
|
||||
|
||||
|
||||
backend = DingTalk
|
||||
|
|
|
@ -17,7 +17,7 @@ class WeCom(BackendBase):
|
|||
|
||||
def send_msg(self, users, message, subject=None):
|
||||
accounts, __, __ = self.get_accounts(users)
|
||||
return self.wecom.send_text(accounts, message)
|
||||
return self.wecom.send_text(accounts, message, markdown=True)
|
||||
|
||||
|
||||
backend = WeCom
|
||||
|
|
|
@ -94,7 +94,7 @@ class Message(metaclass=MessageType):
|
|||
traceback.print_exc()
|
||||
|
||||
@classmethod
|
||||
def send_test_msg(cls, ding=True):
|
||||
def send_test_msg(cls, ding=True, wecom=False):
|
||||
msg = cls.gen_test_msg()
|
||||
if not msg:
|
||||
return
|
||||
|
@ -104,6 +104,8 @@ class Message(metaclass=MessageType):
|
|||
backends = []
|
||||
if ding:
|
||||
backends.append(BACKEND.DINGTALK)
|
||||
if wecom:
|
||||
backends.append(BACKEND.WECOM)
|
||||
msg.send_msg(users, backends)
|
||||
|
||||
@staticmethod
|
||||
|
@ -113,8 +115,17 @@ class Message(metaclass=MessageType):
|
|||
def get_html_msg(self) -> dict:
|
||||
return self.get_common_msg()
|
||||
|
||||
def get_markdown_msg(self) -> dict:
|
||||
h = HTML2Text()
|
||||
h.body_width = 300
|
||||
msg = self.get_html_msg()
|
||||
content = msg['message']
|
||||
msg['message'] = h.handle(content)
|
||||
return msg
|
||||
|
||||
def get_text_msg(self) -> dict:
|
||||
h = HTML2Text()
|
||||
h.body_width = 90
|
||||
msg = self.get_html_msg()
|
||||
content = msg['message']
|
||||
h.ignore_links = self.text_msg_ignore_links
|
||||
|
@ -130,6 +141,10 @@ class Message(metaclass=MessageType):
|
|||
msg = self.get_text_msg()
|
||||
return msg
|
||||
|
||||
@lazyproperty
|
||||
def markdown_msg(self):
|
||||
return self.get_markdown_msg()
|
||||
|
||||
@lazyproperty
|
||||
def html_msg(self) -> dict:
|
||||
msg = self.get_html_msg()
|
||||
|
@ -167,17 +182,17 @@ class Message(metaclass=MessageType):
|
|||
# 支持不同发送消息的方式定义自己的消息内容,比如有些支持 html 标签
|
||||
def get_dingtalk_msg(self) -> dict:
|
||||
# 钉钉相同的消息一天只能发一次,所以给所有消息添加基于时间的序号,使他们不相同
|
||||
message = self.text_msg['message']
|
||||
message = self.markdown_msg['message']
|
||||
time = local_now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
suffix = '\n{}: {}'.format(_('Time'), time)
|
||||
|
||||
return {
|
||||
'subject': self.text_msg['subject'],
|
||||
'subject': self.markdown_msg['subject'],
|
||||
'message': message + suffix
|
||||
}
|
||||
|
||||
def get_wecom_msg(self) -> dict:
|
||||
return self.text_msg
|
||||
return self.markdown_msg
|
||||
|
||||
def get_feishu_msg(self) -> dict:
|
||||
return self.text_msg
|
||||
|
@ -207,12 +222,12 @@ class Message(metaclass=MessageType):
|
|||
return messages_cls
|
||||
|
||||
@classmethod
|
||||
def test_all_messages(cls):
|
||||
def test_all_messages(cls, ding=True, wecom=False):
|
||||
messages_cls = cls.get_all_sub_messages()
|
||||
|
||||
for _cls in messages_cls:
|
||||
try:
|
||||
msg = _cls.send_test_msg()
|
||||
_cls.send_test_msg(ding=ding, wecom=wecom)
|
||||
except NotImplementedError:
|
||||
continue
|
||||
|
||||
|
|
|
@ -54,6 +54,9 @@ class AdHocDisplay(Display, metaclass=UnSingleton):
|
|||
self.log_file.write(msg)
|
||||
|
||||
def display(self, msg, color=None, stderr=False, screen_only=False, log_only=False, newline=True):
|
||||
if log_only:
|
||||
return
|
||||
|
||||
if color:
|
||||
msg = stringc(msg, color)
|
||||
|
||||
|
@ -62,7 +65,5 @@ class AdHocDisplay(Display, metaclass=UnSingleton):
|
|||
else:
|
||||
msg2 = msg
|
||||
|
||||
if log_only:
|
||||
self._write_to_log_file(msg2)
|
||||
else:
|
||||
self._write_to_screen(msg2, stderr)
|
||||
self._write_to_log_file(msg2)
|
||||
self._write_to_screen(msg2, stderr)
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
</ul>
|
||||
|
||||
<br />
|
||||
-
|
||||
<p>
|
||||
{% trans 'If you have any question, please contact the administrator' %}
|
||||
</p>
|
||||
|
|
|
@ -44,3 +44,10 @@ class BasicSettingSerializer(serializers.Serializer):
|
|||
TICKETS_ENABLED = serializers.BooleanField(required=False, default=True, label=_("Enable tickets"))
|
||||
ANNOUNCEMENT_ENABLED = serializers.BooleanField(label=_('Enable announcement'), default=True)
|
||||
ANNOUNCEMENT = AnnouncementSerializer(label=_("Announcement"))
|
||||
|
||||
@staticmethod
|
||||
def validate_SITE_URL(s):
|
||||
if not s:
|
||||
return 'http://127.0.0.1'
|
||||
return s.strip('/')
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ class TicketFilter(BaseFilterSet):
|
|||
class Meta:
|
||||
model = Ticket
|
||||
fields = (
|
||||
'id', 'title', 'type', 'status', 'applicant', 'assignees__id',
|
||||
'id', 'title', 'type', 'status', 'state', 'applicant', 'assignees__id',
|
||||
'applicant_display',
|
||||
)
|
||||
|
||||
|
|
|
@ -29,9 +29,9 @@ class BaseHandler(object):
|
|||
self._send_applied_mail_to_assignees()
|
||||
is_finished = False
|
||||
else:
|
||||
self._send_processed_mail_to_applicant(self.ticket.processor)
|
||||
self.ticket.set_state_approve()
|
||||
self.ticket.set_status_closed()
|
||||
self._send_processed_mail_to_applicant(self.ticket.processor)
|
||||
is_finished = True
|
||||
|
||||
self.ticket.save()
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<a href="{{ update_password_url }}">{% trans 'Click here update password' %}</a>
|
||||
<br />
|
||||
</p>
|
||||
|
||||
-
|
||||
<p>
|
||||
{% trans 'If your password has expired, please click the link below to' %}
|
||||
<a href="{{ forget_password_url }}?email={{ email }}">{% trans 'Reset password' %}</a>
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
{% trans 'click here to set your password' %}
|
||||
</a>
|
||||
</p>
|
||||
|
||||
|
||||
-
|
||||
<p>
|
||||
{% trans 'This link is valid for 1 hour. After it expires' %}
|
||||
<a href="{{ forget_password_url }}?email={{ user.email }}">{% trans 'request new one' %}</a>
|
||||
|
|
Loading…
Reference in New Issue