diff --git a/apps/assets/backends/db.py b/apps/assets/backends/db.py index aa3e1ef78..0e5d288b9 100644 --- a/apps/assets/backends/db.py +++ b/apps/assets/backends/db.py @@ -4,6 +4,7 @@ from django.utils.translation import ugettext as _ from functools import reduce from django.db.models import F, CharField, Value, IntegerField, Q, Count from django.db.models.functions import Concat +from rest_framework.exceptions import PermissionDenied from common.utils import get_object_or_none from orgs.utils import current_org @@ -250,7 +251,7 @@ class AdminUserBackend(DBBackend): ) def _perform_delete_by_union_id(self, union_id_cleaned): - raise PermissionError(_("Could not remove asset admin user")) + raise PermissionDenied(_("Could not remove asset admin user")) def all(self): qs = self.model.objects.all().annotate( @@ -314,7 +315,7 @@ class AuthbookBackend(DBBackend): authbook_id, asset_id = union_id_cleaned authbook = get_object_or_none(AuthBook, pk=authbook_id) if authbook.is_latest: - raise PermissionError(_("Latest version could not be delete")) + raise PermissionDenied(_("Latest version could not be delete")) AuthBook.objects.filter(id=authbook_id).delete() def all(self): diff --git a/apps/assets/models/authbook.py b/apps/assets/models/authbook.py index 35b7e3894..3a17df7b7 100644 --- a/apps/assets/models/authbook.py +++ b/apps/assets/models/authbook.py @@ -4,6 +4,7 @@ from django.db import models, transaction from django.db.models import Max from django.utils.translation import ugettext_lazy as _ +from rest_framework.exceptions import PermissionDenied from orgs.mixins.models import OrgManager from .base import BaseUser @@ -14,7 +15,7 @@ __all__ = ['AuthBook'] class AuthBookQuerySet(models.QuerySet): def delete(self): if self.count() > 1: - raise PermissionError(_("Bulk delete deny")) + raise PermissionDenied(_("Bulk delete deny")) return super().delete() diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index f1e5b13b4..c34d92992 100644 Binary files a/apps/locale/zh/LC_MESSAGES/django.mo and b/apps/locale/zh/LC_MESSAGES/django.mo differ diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 0acdf61d9..0df73a8ea 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-11 11:06+0800\n" +"POT-Creation-Date: 2021-06-16 17:47+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -119,7 +119,7 @@ msgstr "系统用户" #: acls/models/login_asset_acl.py:22 #: applications/serializers/attrs/application_category/remote_app.py:33 -#: assets/models/asset.py:355 assets/models/authbook.py:26 +#: assets/models/asset.py:355 assets/models/authbook.py:27 #: assets/models/gathered_user.py:14 assets/serializers/admin_user.py:34 #: assets/serializers/asset_user.py:48 assets/serializers/asset_user.py:91 #: assets/serializers/system_user.py:202 audits/models.py:38 @@ -184,7 +184,7 @@ msgstr "格式为逗号分隔的字符串, * 表示匹配所有. " #: users/templates/users/_select_user_modal.html:14 #: xpack/plugins/change_auth_plan/models.py:47 #: xpack/plugins/change_auth_plan/models.py:278 -#: xpack/plugins/cloud/serializers.py:65 +#: xpack/plugins/cloud/serializers.py:51 msgid "Username" msgstr "用户名" @@ -233,7 +233,7 @@ msgstr "所有复核人都不属于组织 `{}`" #: applications/const.py:9 #: applications/serializers/attrs/application_category/db.py:14 #: applications/serializers/attrs/application_type/mysql_workbench.py:26 -#: assets/backends/db.py:278 +#: assets/backends/db.py:279 msgid "Database" msgstr "数据库" @@ -304,7 +304,7 @@ msgid "Cluster" msgstr "集群" #: applications/serializers/attrs/application_category/db.py:11 -#: ops/models/adhoc.py:146 xpack/plugins/cloud/serializers.py:63 +#: ops/models/adhoc.py:146 xpack/plugins/cloud/serializers.py:49 msgid "Host" msgstr "主机" @@ -314,7 +314,7 @@ msgstr "主机" #: applications/serializers/attrs/application_type/oracle.py:11 #: applications/serializers/attrs/application_type/pgsql.py:11 #: assets/models/asset.py:188 assets/models/domain.py:53 -#: xpack/plugins/cloud/serializers.py:64 +#: xpack/plugins/cloud/serializers.py:50 msgid "Port" msgstr "端口" @@ -344,7 +344,7 @@ msgstr "目标URL" #: xpack/plugins/change_auth_plan/models.py:68 #: xpack/plugins/change_auth_plan/models.py:190 #: xpack/plugins/change_auth_plan/models.py:285 -#: xpack/plugins/cloud/serializers.py:67 +#: xpack/plugins/cloud/serializers.py:53 msgid "Password" msgstr "密码" @@ -376,7 +376,7 @@ msgstr "不能删除根节点 ({})" msgid "Deletion failed and the node contains assets" msgstr "删除失败,节点包含资产" -#: assets/backends/db.py:109 assets/models/user.py:304 audits/models.py:39 +#: assets/backends/db.py:110 assets/models/user.py:304 audits/models.py:39 #: perms/models/application_permission.py:31 #: perms/models/asset_permission.py:101 templates/_nav.html:45 #: terminal/backends/command/models.py:20 @@ -390,21 +390,21 @@ msgstr "删除失败,节点包含资产" msgid "System user" msgstr "系统用户" -#: assets/backends/db.py:180 +#: assets/backends/db.py:181 msgid "System user(Dynamic)" msgstr "系统用户(动态)" -#: assets/backends/db.py:232 assets/models/asset.py:196 +#: assets/backends/db.py:233 assets/models/asset.py:196 #: assets/models/cluster.py:19 assets/models/user.py:67 templates/_nav.html:44 -#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers.py:160 +#: xpack/plugins/cloud/models.py:92 xpack/plugins/cloud/serializers.py:146 msgid "Admin user" msgstr "管理用户" -#: assets/backends/db.py:253 +#: assets/backends/db.py:254 msgid "Could not remove asset admin user" msgstr "不能移除资产的管理用户账号" -#: assets/backends/db.py:317 +#: assets/backends/db.py:318 msgid "Latest version could not be delete" msgstr "最新版本的不能被删除" @@ -538,19 +538,19 @@ msgstr "创建者" msgid "Date created" msgstr "创建日期" -#: assets/models/authbook.py:17 +#: assets/models/authbook.py:18 msgid "Bulk delete deny" msgstr "拒绝批量删除" -#: assets/models/authbook.py:27 +#: assets/models/authbook.py:28 msgid "Latest version" msgstr "最新版本" -#: assets/models/authbook.py:28 +#: assets/models/authbook.py:29 msgid "Version" msgstr "版本" -#: assets/models/authbook.py:37 +#: assets/models/authbook.py:38 msgid "AuthBook" msgstr "" @@ -715,7 +715,7 @@ msgstr "ssh私钥" #: users/templates/users/user_asset_permission.html:41 #: users/templates/users/user_asset_permission.html:73 #: users/templates/users/user_asset_permission.html:158 -#: xpack/plugins/cloud/models.py:89 xpack/plugins/cloud/serializers.py:161 +#: xpack/plugins/cloud/models.py:89 xpack/plugins/cloud/serializers.py:147 msgid "Node" msgstr "节点" @@ -1227,17 +1227,25 @@ msgid "SSO" msgstr "" #: audits/signals_handler.py:60 +msgid "Auth Token" +msgstr "认证令牌" + +#: audits/signals_handler.py:61 #: authentication/templates/authentication/login.html:210 #: notifications/backends/__init__.py:12 msgid "WeCom" msgstr "企业微信" -#: audits/signals_handler.py:61 +#: audits/signals_handler.py:62 #: authentication/templates/authentication/login.html:215 #: notifications/backends/__init__.py:13 msgid "DingTalk" msgstr "钉钉" +#: authentication/api/connection_token.py:249 +msgid "Invalid token" +msgstr "无效的令牌" + #: authentication/api/mfa.py:60 msgid "Code is invalid" msgstr "Code无效" @@ -1715,7 +1723,7 @@ msgstr "对象" msgid "The file content overflowed (The maximum length `{}` bytes)" msgstr "文件内容太大 (最大长度 `{}` 字节)" -#: common/drf/parsers/base.py:148 +#: common/drf/parsers/base.py:153 msgid "Parse file error: {}" msgstr "解析文件错误: {}" @@ -1846,7 +1854,7 @@ msgstr "邮件" #: notifications/backends/__init__.py:14 msgid "Site message" -msgstr "" +msgstr "站内信" #: ops/api/celery.py:61 ops/api/celery.py:76 msgid "Waiting task start" @@ -1993,7 +2001,7 @@ msgstr "任务结束" #: ops/notifications.py:13 msgid "Server performance" -msgstr "" +msgstr "监控告警" #: ops/notifications.py:20 msgid "Disk used more than 80%: {} => {}" @@ -2535,100 +2543,100 @@ msgstr "启用企业微信认证" msgid "Enable DingTalk Auth" msgstr "启用钉钉认证" -#: settings/utils/ldap.py:411 +#: settings/utils/ldap.py:417 msgid "Host or port is disconnected: {}" msgstr "主机或端口不可连接: {}" -#: settings/utils/ldap.py:413 +#: settings/utils/ldap.py:419 msgid "The port is not the port of the LDAP service: {}" msgstr "端口不是LDAP服务端口: {}" -#: settings/utils/ldap.py:415 +#: settings/utils/ldap.py:421 msgid "Please add certificate: {}" msgstr "请添加证书" -#: settings/utils/ldap.py:417 settings/utils/ldap.py:444 -#: settings/utils/ldap.py:474 settings/utils/ldap.py:502 +#: settings/utils/ldap.py:423 settings/utils/ldap.py:450 +#: settings/utils/ldap.py:480 settings/utils/ldap.py:508 msgid "Unknown error: {}" msgstr "未知错误: {}" -#: settings/utils/ldap.py:431 +#: settings/utils/ldap.py:437 msgid "Bind DN or Password incorrect" msgstr "绑定DN或密码错误" -#: settings/utils/ldap.py:438 +#: settings/utils/ldap.py:444 msgid "Please enter Bind DN: {}" msgstr "请输入绑定DN: {}" -#: settings/utils/ldap.py:440 +#: settings/utils/ldap.py:446 msgid "Please enter Password: {}" msgstr "请输入密码: {}" -#: settings/utils/ldap.py:442 +#: settings/utils/ldap.py:448 msgid "Please enter correct Bind DN and Password: {}" msgstr "请输入正确的绑定DN和密码: {}" -#: settings/utils/ldap.py:460 +#: settings/utils/ldap.py:466 msgid "Invalid User OU or User search filter: {}" msgstr "不合法的用户OU或用户过滤器: {}" -#: settings/utils/ldap.py:491 +#: settings/utils/ldap.py:497 msgid "LDAP User attr map not include: {}" msgstr "LDAP属性映射没有包含: {}" -#: settings/utils/ldap.py:498 +#: settings/utils/ldap.py:504 msgid "LDAP User attr map is not dict" msgstr "LDAP属性映射不合法" -#: settings/utils/ldap.py:517 +#: settings/utils/ldap.py:523 msgid "LDAP authentication is not enabled" msgstr "LDAP认证没有启用" -#: settings/utils/ldap.py:535 +#: settings/utils/ldap.py:541 msgid "Error (Invalid LDAP server): {}" msgstr "错误 (不合法的LDAP服务器地址): {}" -#: settings/utils/ldap.py:537 +#: settings/utils/ldap.py:543 msgid "Error (Invalid Bind DN): {}" msgstr "错误(不合法的绑定DN): {}" -#: settings/utils/ldap.py:539 +#: settings/utils/ldap.py:545 msgid "Error (Invalid LDAP User attr map): {}" msgstr "错误(不合法的LDAP属性映射): {}" -#: settings/utils/ldap.py:541 +#: settings/utils/ldap.py:547 msgid "Error (Invalid User OU or User search filter): {}" msgstr "错误(不合法的用户OU或用户过滤器): {}" -#: settings/utils/ldap.py:543 +#: settings/utils/ldap.py:549 msgid "Error (Not enabled LDAP authentication): {}" msgstr "错误(没有启用LDAP认证): {}" -#: settings/utils/ldap.py:545 +#: settings/utils/ldap.py:551 msgid "Error (Unknown): {}" msgstr "错误(未知): {}" -#: settings/utils/ldap.py:548 +#: settings/utils/ldap.py:554 msgid "Succeed: Match {} s user" msgstr "成功匹配 {} 个用户" -#: settings/utils/ldap.py:581 +#: settings/utils/ldap.py:587 msgid "Authentication failed (configuration incorrect): {}" msgstr "认证失败(配置错误): {}" -#: settings/utils/ldap.py:583 +#: settings/utils/ldap.py:589 msgid "Authentication failed (before login check failed): {}" msgstr "认证失败(登录前检查失败): {}" -#: settings/utils/ldap.py:585 +#: settings/utils/ldap.py:591 msgid "Authentication failed (username or password incorrect): {}" msgstr "认证失败 (用户名或密码不正确): {}" -#: settings/utils/ldap.py:587 +#: settings/utils/ldap.py:593 msgid "Authentication failed (Unknown): {}" msgstr "认证失败: (未知): {}" -#: settings/utils/ldap.py:590 +#: settings/utils/ldap.py:596 msgid "Authentication success: {}" msgstr "认证成功: {}" @@ -2817,7 +2825,7 @@ msgstr "数据库应用" msgid "Perms" msgstr "权限管理" -#: templates/_nav.html:97 +#: templates/_nav.html:97 terminal/notifications.py:15 msgid "Sessions" msgstr "会话管理" @@ -2841,7 +2849,7 @@ msgstr "Web终端" msgid "File manager" msgstr "文件管理" -#: templates/_nav.html:110 terminal/apps.py:9 terminal/notifications.py:15 +#: templates/_nav.html:110 terminal/apps.py:9 #: terminal/serializers/session.py:40 msgid "Terminal" msgstr "终端" @@ -3273,8 +3281,8 @@ msgid "Replay storage" msgstr "录像存储" #: terminal/notifications.py:35 -msgid "Terminal command alert" -msgstr "终端命令告警" +msgid "Danger command alert" +msgstr "危险命令告警" #: terminal/notifications.py:44 #, python-format @@ -3314,14 +3322,13 @@ msgid "" msgstr "危险命令告警: [%(name)s->%(login_from)s@%(remote_addr)s] $%(command)s" #: terminal/notifications.py:97 -msgid "Batch command alert" -msgstr "批量命令告警" +msgid "Batch danger command alert" +msgstr "批量危险命令告警" #: terminal/notifications.py:108 #, python-format msgid "" "\n" -"
\n" " Assets: %(assets)s\n" "
\n" " User: %(user)s\n" @@ -3337,7 +3344,6 @@ msgid "" " " msgstr "" "\n" -"
\n" " 资产: %(assets)s\n" "
\n" " 用户: %(user)s\n" @@ -3350,10 +3356,10 @@ msgstr "" " ----------------- 命令 ----------------
\n" " " -#: terminal/notifications.py:134 +#: terminal/notifications.py:133 #, python-format msgid "Insecure Web Command Execution Alert: [%(name)s]" -msgstr "Web页面-> 命令执行 告警: [%(name)s]" +msgstr "批量危险命令告警: [%(name)s]" #: terminal/serializers/session.py:33 msgid "User ID" @@ -4051,7 +4057,7 @@ msgid "Security token validation" msgstr "安全令牌验证" #: users/templates/users/_base_otp.html:14 xpack/plugins/cloud/models.py:78 -#: xpack/plugins/cloud/serializers.py:159 +#: xpack/plugins/cloud/serializers.py:145 msgid "Account" msgstr "账户" @@ -4792,7 +4798,7 @@ msgstr "云服务商" msgid "Cloud account" msgstr "云账号" -#: xpack/plugins/cloud/models.py:81 xpack/plugins/cloud/serializers.py:140 +#: xpack/plugins/cloud/models.py:81 xpack/plugins/cloud/serializers.py:126 msgid "Regions" msgstr "地域" @@ -4800,7 +4806,7 @@ msgstr "地域" msgid "Hostname strategy" msgstr "主机名策略" -#: xpack/plugins/cloud/models.py:95 xpack/plugins/cloud/serializers.py:163 +#: xpack/plugins/cloud/models.py:95 xpack/plugins/cloud/serializers.py:149 msgid "Always update" msgstr "总是更新" @@ -4992,24 +4998,20 @@ msgstr "" msgid "Subscription ID" msgstr "" -#: xpack/plugins/cloud/serializers.py:49 -msgid "This field is required" -msgstr "这个字段是必填项" - -#: xpack/plugins/cloud/serializers.py:138 +#: xpack/plugins/cloud/serializers.py:124 msgid "History count" msgstr "执行次数" -#: xpack/plugins/cloud/serializers.py:139 +#: xpack/plugins/cloud/serializers.py:125 msgid "Instance count" msgstr "实例个数" -#: xpack/plugins/cloud/serializers.py:162 +#: xpack/plugins/cloud/serializers.py:148 #: xpack/plugins/gathered_user/serializers.py:20 msgid "Periodic display" msgstr "定时执行" -#: xpack/plugins/cloud/utils.py:65 +#: xpack/plugins/cloud/utils.py:64 msgid "Account unavailable" msgstr "账户无效" @@ -5096,3 +5098,9 @@ msgstr "旗舰版" #: xpack/plugins/license/models.py:77 msgid "Community edition" msgstr "社区版" + +#~ msgid "This field is required" +#~ msgstr "这个字段是必填项" + +#~ msgid "Terminal command alert" +#~ msgstr "终端命令告警" diff --git a/apps/notifications/notifications.py b/apps/notifications/notifications.py index 8563fd214..4c4db11d9 100644 --- a/apps/notifications/notifications.py +++ b/apps/notifications/notifications.py @@ -108,11 +108,7 @@ class Message(metaclass=MessageType): } def get_site_msg_msg(self) -> dict: - msg = self.get_common_msg() - return { - 'subject': msg, - 'message': msg - } + return self.get_email_msg() class SystemMessage(Message): diff --git a/apps/terminal/api/command.py b/apps/terminal/api/command.py index b43910e26..9e3065e99 100644 --- a/apps/terminal/api/command.py +++ b/apps/terminal/api/command.py @@ -204,8 +204,6 @@ class InsecureCommandAlertAPI(generics.CreateAPIView): serializer.is_valid(raise_exception=True) commands = serializer.validated_data for command in commands: - if command['risk_level'] >= settings.SECURITY_INSECURE_COMMAND_LEVEL and \ - settings.SECURITY_INSECURE_COMMAND and \ - settings.SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER: + if command['risk_level'] >= settings.SECURITY_INSECURE_COMMAND_LEVEL: CommandAlertMessage(command).publish_async() return Response() diff --git a/apps/terminal/notifications.py b/apps/terminal/notifications.py index eac9c2f7d..088e8ecc0 100644 --- a/apps/terminal/notifications.py +++ b/apps/terminal/notifications.py @@ -6,33 +6,46 @@ from common.utils import get_logger, reverse from notifications.notifications import SystemMessage from terminal.models import Session, Command from notifications.models import SystemMsgSubscription +from notifications.backends import BACKEND logger = get_logger(__name__) __all__ = ('CommandAlertMessage', 'CommandExecutionAlert') CATEGORY = 'terminal' -CATEGORY_LABEL = _('Terminal') +CATEGORY_LABEL = _('Sessions') class CommandAlertMixin: + def get_dingtalk_msg(self) -> str: + msg = self._get_message() + msg = msg.replace('
', '') + return msg + @classmethod def post_insert_to_db(cls, subscription: SystemMsgSubscription): """ - 兼容操作,试图用 `settings.SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER` 的邮件地址找到 + 兼容操作,试图用 `settings.SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER` 的邮件地址assets_systemuser_assets找到 用户,把用户设置为默认接收者 """ - emails = settings.SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER.split(',') - emails = [email.strip() for email in emails] + from settings.models import Setting + db_setting = Setting.objects.filter(name='SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER').first() + if db_setting: + emails = db_setting.value + emails = emails or settings.SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER + emails = emails.split(',') + emails = [email.strip().strip('"') for email in emails] users = User.objects.filter(email__in=emails) subscription.users.add(*users) + subscription.receive_backends = [BACKEND.EMAIL] + subscription.save() class CommandAlertMessage(CommandAlertMixin, SystemMessage): category = CATEGORY category_label = CATEGORY_LABEL - message_type_label = _('Terminal command alert') + message_type_label = _('Danger command alert') def __init__(self, command): self.command = command @@ -94,7 +107,7 @@ class CommandAlertMessage(CommandAlertMixin, SystemMessage): class CommandExecutionAlert(CommandAlertMixin, SystemMessage): category = CATEGORY category_label = CATEGORY_LABEL - message_type_label = _('Batch command alert') + message_type_label = _('Batch danger command alert') def __init__(self, command): self.command = command @@ -106,7 +119,6 @@ class CommandExecutionAlert(CommandAlertMixin, SystemMessage): assets = ', '.join([str(asset) for asset in command['assets']]) message = _(""" -
Assets: %(assets)s
User: %(user)s