feat(terminal):危险命令告警功能

This commit is contained in:
peijianbo 2020-10-27 11:35:31 +08:00 committed by 老广
parent 50a4735b07
commit 79b5aa68c8
14 changed files with 373 additions and 183 deletions

View File

@ -10,13 +10,15 @@ UUID_PATTERN = re.compile(r'[0-9a-zA-Z\-]{36}')
def reverse(view_name, urlconf=None, args=None, kwargs=None, def reverse(view_name, urlconf=None, args=None, kwargs=None,
current_app=None, external=False): current_app=None, external=False, api_to_ui=False):
url = dj_reverse(view_name, urlconf=urlconf, args=args, url = dj_reverse(view_name, urlconf=urlconf, args=args,
kwargs=kwargs, current_app=current_app) kwargs=kwargs, current_app=current_app)
if external: if external:
site_url = settings.SITE_URL site_url = settings.SITE_URL
url = site_url.strip('/') + url url = site_url.strip('/') + url
if api_to_ui:
url = url.replace('api/v1', 'ui/#').rstrip('/')
return url return url

View File

@ -245,6 +245,9 @@ class Config(dict):
'SECURITY_LOGIN_CHALLENGE_ENABLED': False, 'SECURITY_LOGIN_CHALLENGE_ENABLED': False,
'SECURITY_LOGIN_CAPTCHA_ENABLED': True, 'SECURITY_LOGIN_CAPTCHA_ENABLED': True,
'SECURITY_DATA_CRYPTO_ALGO': 'aes', 'SECURITY_DATA_CRYPTO_ALGO': 'aes',
'SECURITY_INSECURE_COMMAND': False,
'SECURITY_INSECURE_COMMAND_LEVEL': 5,
'SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER': '',
'HTTP_BIND_HOST': '0.0.0.0', 'HTTP_BIND_HOST': '0.0.0.0',
'HTTP_LISTEN_PORT': 8080, 'HTTP_LISTEN_PORT': 8080,

View File

@ -55,6 +55,9 @@ SECURITY_SERVICE_ACCOUNT_REGISTRATION = DYNAMIC.SECURITY_SERVICE_ACCOUNT_REGISTR
SECURITY_LOGIN_CAPTCHA_ENABLED = CONFIG.SECURITY_LOGIN_CAPTCHA_ENABLED SECURITY_LOGIN_CAPTCHA_ENABLED = CONFIG.SECURITY_LOGIN_CAPTCHA_ENABLED
SECURITY_LOGIN_CHALLENGE_ENABLED = CONFIG.SECURITY_LOGIN_CHALLENGE_ENABLED SECURITY_LOGIN_CHALLENGE_ENABLED = CONFIG.SECURITY_LOGIN_CHALLENGE_ENABLED
SECURITY_DATA_CRYPTO_ALGO = CONFIG.SECURITY_DATA_CRYPTO_ALGO SECURITY_DATA_CRYPTO_ALGO = CONFIG.SECURITY_DATA_CRYPTO_ALGO
SECURITY_INSECURE_COMMAND = DYNAMIC.SECURITY_INSECURE_COMMAND
SECURITY_INSECURE_COMMAND_LEVEL = CONFIG.SECURITY_INSECURE_COMMAND_LEVEL
SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER = DYNAMIC.SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER
# Terminal other setting # Terminal other setting
TERMINAL_PASSWORD_AUTH = DYNAMIC.TERMINAL_PASSWORD_AUTH TERMINAL_PASSWORD_AUTH = DYNAMIC.TERMINAL_PASSWORD_AUTH

Binary file not shown.

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n" "Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-10-27 10:29+0800\n" "POT-Creation-Date: 2020-11-10 15:38+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n" "Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\n" "Language-Team: JumpServer team<ibuler@qq.com>\n"
@ -17,18 +17,30 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: applications/const.py:53 #: applications/const.py:53 applications/models/application.py:34
msgid "Custom" msgid "Custom"
msgstr "自定义" msgstr "自定义"
#: applications/models/application.py:61 applications/models/database_app.py:29
#: applications/serializers/database_app.py:16
#: applications/serializers/remote_app.py:69
#: users/templates/users/user_granted_database_app.html:37
msgid "Database"
msgstr "数据库"
#: applications/models/application.py:62
msgid "Remote app"
msgstr "远程应用"
#: applications/models/application.py:122
#: applications/models/database_app.py:18 applications/models/k8s_app.py:11 #: applications/models/database_app.py:18 applications/models/k8s_app.py:11
#: applications/models/remote_app.py:21 assets/models/asset.py:149 #: applications/models/remote_app.py:21 assets/models/asset.py:149
#: assets/models/base.py:232 assets/models/cluster.py:18 #: assets/models/base.py:232 assets/models/cluster.py:18
#: assets/models/cmd_filter.py:21 assets/models/domain.py:21 #: assets/models/cmd_filter.py:21 assets/models/domain.py:21
#: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24 #: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24
#: orgs/models.py:23 perms/models/base.py:48 settings/models.py:27 #: orgs/models.py:23 perms/models/base.py:48 settings/models.py:27
#: terminal/models.py:27 terminal/models.py:348 terminal/models.py:380 #: terminal/models.py:28 terminal/models.py:356 terminal/models.py:388
#: terminal/models.py:417 users/forms/profile.py:20 users/models/group.py:15 #: terminal/models.py:425 users/forms/profile.py:20 users/models/group.py:15
#: users/models/user.py:505 users/templates/users/_select_user_modal.html:13 #: users/models/user.py:505 users/templates/users/_select_user_modal.html:13
#: users/templates/users/user_asset_permission.html:37 #: users/templates/users/user_asset_permission.html:37
#: users/templates/users/user_asset_permission.html:154 #: users/templates/users/user_asset_permission.html:154
@ -46,30 +58,33 @@ msgstr "自定义"
msgid "Name" msgid "Name"
msgstr "名称" msgstr "名称"
#: applications/models/application.py:123 assets/models/asset.py:198
#: assets/models/domain.py:27 assets/models/domain.py:54
msgid "Domain"
msgstr "网域"
#: applications/models/application.py:124
#: applications/serializers/application.py:16 assets/models/label.py:21
#: perms/models/application_permission.py:19
#: perms/serializers/application/permission.py:16
#: perms/serializers/application/user_permission.py:33
msgid "Category"
msgstr "分类"
#: applications/models/application.py:125
#: applications/models/database_app.py:22 applications/models/k8s_app.py:14 #: applications/models/database_app.py:22 applications/models/k8s_app.py:14
#: assets/models/cmd_filter.py:52 terminal/models.py:382 terminal/models.py:419 #: applications/serializers/application.py:17 assets/models/cmd_filter.py:52
#: tickets/models/ticket.py:40 #: perms/models/application_permission.py:20
#: perms/serializers/application/permission.py:17
#: perms/serializers/application/user_permission.py:34 terminal/models.py:390
#: terminal/models.py:427 tickets/models/ticket.py:40
#: users/templates/users/user_granted_database_app.html:35 #: users/templates/users/user_granted_database_app.html:35
msgid "Type" msgid "Type"
msgstr "类型" msgstr "类型"
#: applications/models/database_app.py:25 ops/models/adhoc.py:146
#: users/templates/users/user_granted_database_app.html:36
msgid "Host"
msgstr "主机"
#: applications/models/database_app.py:27 assets/models/asset.py:195
#: assets/models/domain.py:52
msgid "Port"
msgstr "端口"
#: applications/models/database_app.py:29
#: users/templates/users/user_granted_database_app.html:37
msgid "Database"
msgstr "数据库"
# msgid "Date created" # msgid "Date created"
# msgstr "创建日期" # msgstr "创建日期"
#: applications/models/application.py:128
#: applications/models/database_app.py:33 applications/models/k8s_app.py:18 #: applications/models/database_app.py:33 applications/models/k8s_app.py:18
#: applications/models/remote_app.py:45 assets/models/asset.py:154 #: applications/models/remote_app.py:45 assets/models/asset.py:154
#: assets/models/asset.py:230 assets/models/base.py:237 #: assets/models/asset.py:230 assets/models/base.py:237
@ -77,8 +92,8 @@ msgstr "数据库"
#: assets/models/cmd_filter.py:57 assets/models/domain.py:22 #: assets/models/cmd_filter.py:57 assets/models/domain.py:22
#: assets/models/domain.py:55 assets/models/group.py:23 #: assets/models/domain.py:55 assets/models/group.py:23
#: assets/models/label.py:23 ops/models/adhoc.py:37 orgs/models.py:26 #: assets/models/label.py:23 ops/models/adhoc.py:37 orgs/models.py:26
#: perms/models/base.py:56 settings/models.py:32 terminal/models.py:37 #: perms/models/base.py:56 settings/models.py:32 terminal/models.py:38
#: terminal/models.py:387 terminal/models.py:424 tickets/models/ticket.py:43 #: terminal/models.py:395 terminal/models.py:432 tickets/models/ticket.py:43
#: users/models/group.py:16 users/models/user.py:538 #: users/models/group.py:16 users/models/user.py:538
#: users/templates/users/user_detail.html:115 #: users/templates/users/user_detail.html:115
#: users/templates/users/user_granted_database_app.html:38 #: users/templates/users/user_granted_database_app.html:38
@ -91,6 +106,22 @@ msgstr "数据库"
msgid "Comment" msgid "Comment"
msgstr "备注" msgstr "备注"
#: applications/models/database_app.py:25
#: applications/serializers/database_app.py:13 ops/models/adhoc.py:146
#: users/templates/users/user_granted_database_app.html:36
msgid "Host"
msgstr "主机"
#: applications/models/database_app.py:27
#: applications/serializers/database_app.py:14
#: applications/serializers/database_app.py:21
#: applications/serializers/database_app.py:25
#: applications/serializers/database_app.py:29
#: applications/serializers/remote_app.py:68 assets/models/asset.py:195
#: assets/models/domain.py:52
msgid "Port"
msgstr "端口"
#: applications/models/database_app.py:41 #: applications/models/database_app.py:41
#: perms/forms/database_app_permission.py:44 #: perms/forms/database_app_permission.py:44
#: perms/models/database_app_permission.py:18 #: perms/models/database_app_permission.py:18
@ -105,7 +136,8 @@ msgstr "数据库应用"
msgid "Kubernetes" msgid "Kubernetes"
msgstr "" msgstr ""
#: applications/models/k8s_app.py:16 assets/models/cluster.py:40 #: applications/models/k8s_app.py:16 applications/serializers/k8s_app.py:9
#: assets/models/cluster.py:40
msgid "Cluster" msgid "Cluster"
msgstr "集群" msgstr "集群"
@ -114,14 +146,14 @@ msgstr "集群"
msgid "KubernetesApp" msgid "KubernetesApp"
msgstr "Kubernetes应用" msgstr "Kubernetes应用"
#: applications/models/remote_app.py:23 assets/models/asset.py:364 #: applications/models/remote_app.py:23 assets/models/asset.py:363
#: assets/models/authbook.py:26 assets/models/gathered_user.py:14 #: assets/models/authbook.py:26 assets/models/gathered_user.py:14
#: assets/serializers/admin_user.py:32 assets/serializers/asset_user.py:47 #: assets/serializers/admin_user.py:32 assets/serializers/asset_user.py:47
#: assets/serializers/asset_user.py:84 assets/serializers/system_user.py:46 #: assets/serializers/asset_user.py:84 assets/serializers/system_user.py:45
#: assets/serializers/system_user.py:186 audits/models.py:38 #: assets/serializers/system_user.py:186 audits/models.py:38
#: perms/forms/asset_permission.py:89 perms/models/asset_permission.py:92 #: perms/forms/asset_permission.py:89 perms/models/asset_permission.py:92
#: templates/index.html:82 terminal/backends/command/models.py:19 #: templates/index.html:82 terminal/backends/command/models.py:19
#: terminal/backends/command/serializers.py:13 terminal/models.py:188 #: terminal/backends/command/serializers.py:13 terminal/models.py:192
#: users/templates/users/user_asset_permission.html:40 #: users/templates/users/user_asset_permission.html:40
#: users/templates/users/user_asset_permission.html:70 #: users/templates/users/user_asset_permission.html:70
#: users/templates/users/user_granted_remote_app.html:36 #: users/templates/users/user_granted_remote_app.html:36
@ -177,6 +209,77 @@ msgstr "创建日期"
msgid "RemoteApp" msgid "RemoteApp"
msgstr "远程应用" msgstr "远程应用"
#: applications/serializers/remote_app.py:36 assets/models/user.py:99
#: templates/_nav.html:39 xpack/plugins/change_auth_plan/models.py:52
msgid "Assets"
msgstr "资产管理"
#: applications/serializers/remote_app.py:37
#: applications/serializers/remote_app.py:58
#: applications/serializers/remote_app.py:66
#: applications/serializers/remote_app.py:76
msgid "Remote App path"
msgstr "远程应用列表"
#: applications/serializers/remote_app.py:59
#: applications/serializers/remote_app.py:77
msgid "Target URL"
msgstr "目标URL"
#: applications/serializers/remote_app.py:60
#: applications/serializers/remote_app.py:70
#: applications/serializers/remote_app.py:78
#: applications/serializers/remote_app.py:85 assets/models/base.py:233
#: assets/models/gathered_user.py:15 audits/models.py:99
#: authentication/forms.py:11
#: authentication/templates/authentication/login.html:21
#: authentication/templates/authentication/xpack_login.html:101
#: ops/models/adhoc.py:148 users/forms/profile.py:19 users/models/user.py:503
#: users/templates/users/_select_user_modal.html:14
#: users/templates/users/user_detail.html:53
#: users/templates/users/user_list.html:15
#: users/templates/users/user_profile.html:47
#: xpack/plugins/change_auth_plan/models.py:47
#: xpack/plugins/change_auth_plan/models.py:279
msgid "Username"
msgstr "用户名"
#: applications/serializers/remote_app.py:61
#: applications/serializers/remote_app.py:71
#: applications/serializers/remote_app.py:79
#: applications/serializers/remote_app.py:86 assets/models/base.py:234
#: assets/serializers/asset_user.py:71 authentication/forms.py:13
#: authentication/templates/authentication/login.html:29
#: authentication/templates/authentication/xpack_login.html:109
#: users/forms/user.py:22 users/forms/user.py:193
#: users/templates/users/user_otp_check_password.html:13
#: users/templates/users/user_password_update.html:43
#: users/templates/users/user_password_verify.html:18
#: users/templates/users/user_profile_update.html:41
#: users/templates/users/user_pubkey_update.html:41
#: users/templates/users/user_update.html:20
#: xpack/plugins/change_auth_plan/models.py:68
#: xpack/plugins/change_auth_plan/models.py:191
#: xpack/plugins/change_auth_plan/models.py:286
msgid "Password"
msgstr "密码"
#: applications/serializers/remote_app.py:67 assets/models/asset.py:190
#: assets/models/domain.py:51 assets/serializers/asset_user.py:46
#: settings/serializers/settings.py:52
#: users/templates/users/_granted_assets.html:26
#: users/templates/users/user_asset_permission.html:156
msgid "IP"
msgstr "IP"
#: applications/serializers/remote_app.py:83
msgid "Operating parameter"
msgstr "运行参数"
#: applications/serializers/remote_app.py:84
msgid "Target url"
msgstr "目标URL"
#: assets/api/admin_user.py:46 #: assets/api/admin_user.py:46
msgid "Deleted failed, There are related assets" msgid "Deleted failed, There are related assets"
msgstr "删除失败,存在关联资产" msgstr "删除失败,存在关联资产"
@ -222,13 +325,6 @@ msgstr "内部的"
msgid "Platform" msgid "Platform"
msgstr "系统平台" msgstr "系统平台"
#: assets/models/asset.py:190 assets/models/domain.py:51
#: assets/serializers/asset_user.py:46 settings/serializers/settings.py:52
#: users/templates/users/_granted_assets.html:26
#: users/templates/users/user_asset_permission.html:156
msgid "IP"
msgstr "IP"
#: assets/models/asset.py:191 assets/serializers/asset_user.py:45 #: assets/models/asset.py:191 assets/serializers/asset_user.py:45
#: assets/serializers/gathered_user.py:20 settings/serializers/settings.py:51 #: assets/serializers/gathered_user.py:20 settings/serializers/settings.py:51
#: tickets/serializers/request_asset_perm.py:25 #: tickets/serializers/request_asset_perm.py:25
@ -238,21 +334,16 @@ msgid "Hostname"
msgstr "主机名" msgstr "主机名"
#: assets/models/asset.py:194 assets/models/domain.py:53 #: assets/models/asset.py:194 assets/models/domain.py:53
#: assets/models/user.py:97 terminal/serializers/session.py:29 #: assets/models/user.py:103 terminal/serializers/session.py:29
msgid "Protocol" msgid "Protocol"
msgstr "协议" msgstr "协议"
#: assets/models/asset.py:196 assets/serializers/asset.py:69 #: assets/models/asset.py:196 assets/serializers/asset.py:69
#: perms/serializers/user_permission.py:71 #: perms/serializers/asset/user_permission.py:41
msgid "Protocols" msgid "Protocols"
msgstr "协议组" msgstr "协议组"
#: assets/models/asset.py:198 assets/models/domain.py:27 #: assets/models/asset.py:199 assets/models/user.py:98
#: assets/models/domain.py:54
msgid "Domain"
msgstr "网域"
#: assets/models/asset.py:199 assets/models/user.py:92
#: perms/models/asset_permission.py:93 #: perms/models/asset_permission.py:93
#: xpack/plugins/change_auth_plan/models.py:56 #: xpack/plugins/change_auth_plan/models.py:56
#: xpack/plugins/gathered_user/models.py:24 #: xpack/plugins/gathered_user/models.py:24
@ -355,37 +446,6 @@ msgstr "版本"
msgid "AuthBook" msgid "AuthBook"
msgstr "" msgstr ""
#: assets/models/base.py:233 assets/models/gathered_user.py:15
#: audits/models.py:99 authentication/forms.py:11
#: authentication/templates/authentication/login.html:21
#: authentication/templates/authentication/xpack_login.html:101
#: ops/models/adhoc.py:148 users/forms/profile.py:19 users/models/user.py:503
#: users/templates/users/_select_user_modal.html:14
#: users/templates/users/user_detail.html:53
#: users/templates/users/user_list.html:15
#: users/templates/users/user_profile.html:47
#: xpack/plugins/change_auth_plan/models.py:47
#: xpack/plugins/change_auth_plan/models.py:279
msgid "Username"
msgstr "用户名"
#: assets/models/base.py:234 assets/serializers/asset_user.py:71
#: authentication/forms.py:13
#: authentication/templates/authentication/login.html:29
#: authentication/templates/authentication/xpack_login.html:109
#: users/forms/user.py:22 users/forms/user.py:193
#: users/templates/users/user_otp_check_password.html:13
#: users/templates/users/user_password_update.html:43
#: users/templates/users/user_password_verify.html:18
#: users/templates/users/user_profile_update.html:41
#: users/templates/users/user_pubkey_update.html:41
#: users/templates/users/user_update.html:20
#: xpack/plugins/change_auth_plan/models.py:68
#: xpack/plugins/change_auth_plan/models.py:191
#: xpack/plugins/change_auth_plan/models.py:286
msgid "Password"
msgstr "密码"
#: assets/models/base.py:235 xpack/plugins/change_auth_plan/models.py:72 #: assets/models/base.py:235 xpack/plugins/change_auth_plan/models.py:72
#: xpack/plugins/change_auth_plan/models.py:198 #: xpack/plugins/change_auth_plan/models.py:198
#: xpack/plugins/change_auth_plan/models.py:293 #: xpack/plugins/change_auth_plan/models.py:293
@ -446,7 +506,7 @@ msgstr "系统"
msgid "Default Cluster" msgid "Default Cluster"
msgstr "默认Cluster" msgstr "默认Cluster"
#: assets/models/cmd_filter.py:33 assets/models/user.py:102 #: assets/models/cmd_filter.py:33 assets/models/user.py:108
msgid "Command filter" msgid "Command filter"
msgstr "命令过滤器" msgstr "命令过滤器"
@ -455,7 +515,7 @@ msgid "Regex"
msgstr "正则表达式" msgstr "正则表达式"
#: assets/models/cmd_filter.py:41 ops/models/command.py:23 #: assets/models/cmd_filter.py:41 ops/models/command.py:23
#: terminal/backends/command/serializers.py:15 terminal/models.py:197 #: terminal/backends/command/serializers.py:15 terminal/models.py:201
msgid "Command" msgid "Command"
msgstr "命令" msgstr "命令"
@ -471,7 +531,7 @@ msgstr "允许"
msgid "Filter" msgid "Filter"
msgstr "过滤器" msgstr "过滤器"
#: assets/models/cmd_filter.py:53 assets/models/user.py:96 #: assets/models/cmd_filter.py:53 assets/models/user.py:102
msgid "Priority" msgid "Priority"
msgstr "优先级" msgstr "优先级"
@ -545,7 +605,7 @@ msgstr "默认资产组"
#: perms/forms/remote_app_permission.py:40 perms/models/asset_permission.py:169 #: perms/forms/remote_app_permission.py:40 perms/models/asset_permission.py:169
#: perms/models/base.py:49 templates/index.html:78 #: perms/models/base.py:49 templates/index.html:78
#: terminal/backends/command/models.py:18 #: terminal/backends/command/models.py:18
#: terminal/backends/command/serializers.py:12 terminal/models.py:186 #: terminal/backends/command/serializers.py:12 terminal/models.py:190
#: tickets/models/ticket.py:30 tickets/models/ticket.py:136 #: tickets/models/ticket.py:30 tickets/models/ticket.py:136
#: tickets/serializers/request_asset_perm.py:66 #: tickets/serializers/request_asset_perm.py:66
#: tickets/serializers/ticket.py:31 users/forms/group.py:15 #: tickets/serializers/ticket.py:31 users/forms/group.py:15
@ -563,35 +623,31 @@ msgstr "默认资产组"
msgid "User" msgid "User"
msgstr "用户" msgstr "用户"
#: assets/models/label.py:19 assets/models/node.py:397 settings/models.py:28 #: assets/models/label.py:19 assets/models/node.py:396 settings/models.py:28
msgid "Value" msgid "Value"
msgstr "值" msgstr "值"
#: assets/models/label.py:21
msgid "Category"
msgstr "分类"
#: assets/models/node.py:131 #: assets/models/node.py:131
msgid "New node" msgid "New node"
msgstr "新节点" msgstr "新节点"
#: assets/models/node.py:303 users/templates/users/_granted_assets.html:130 #: assets/models/node.py:302 users/templates/users/_granted_assets.html:130
msgid "empty" msgid "empty"
msgstr "空" msgstr "空"
#: assets/models/node.py:396 perms/models/asset_permission.py:144 #: assets/models/node.py:395 perms/models/asset_permission.py:144
msgid "Key" msgid "Key"
msgstr "键" msgstr "键"
#: assets/models/node.py:398 #: assets/models/node.py:397
msgid "Full value" msgid "Full value"
msgstr "全称" msgstr "全称"
#: assets/models/node.py:401 perms/models/asset_permission.py:148 #: assets/models/node.py:400 perms/models/asset_permission.py:148
msgid "Parent key" msgid "Parent key"
msgstr "ssh私钥" msgstr "ssh私钥"
#: assets/models/node.py:410 assets/serializers/system_user.py:45 #: assets/models/node.py:409 assets/serializers/system_user.py:44
#: assets/serializers/system_user.py:185 perms/forms/asset_permission.py:92 #: assets/serializers/system_user.py:185 perms/forms/asset_permission.py:92
#: perms/forms/asset_permission.py:99 #: perms/forms/asset_permission.py:99
#: users/templates/users/user_asset_permission.html:41 #: users/templates/users/user_asset_permission.html:41
@ -601,73 +657,69 @@ msgstr "ssh私钥"
msgid "Node" msgid "Node"
msgstr "节点" msgstr "节点"
#: assets/models/user.py:88 #: assets/models/user.py:94
msgid "Automatic login" msgid "Automatic login"
msgstr "自动登录" msgstr "自动登录"
#: assets/models/user.py:89 #: assets/models/user.py:95
msgid "Manually login" msgid "Manually login"
msgstr "手动登录" msgstr "手动登录"
#: assets/models/user.py:91 #: assets/models/user.py:97
msgid "Username same with user" msgid "Username same with user"
msgstr "用户名与用户相同" msgstr "用户名与用户相同"
#: assets/models/user.py:93 templates/_nav.html:39 #: assets/models/user.py:100 templates/_nav.html:17
#: xpack/plugins/change_auth_plan/models.py:52
msgid "Assets"
msgstr "资产管理"
#: assets/models/user.py:94 templates/_nav.html:17
#: users/views/profile/password.py:42 users/views/profile/pubkey.py:36 #: users/views/profile/password.py:42 users/views/profile/pubkey.py:36
msgid "Users" msgid "Users"
msgstr "用户管理" msgstr "用户管理"
#: assets/models/user.py:95 users/templates/users/user_group_list.html:90 #: assets/models/user.py:101 users/templates/users/user_group_list.html:90
#: users/templates/users/user_profile.html:124 #: users/templates/users/user_profile.html:124
msgid "User groups" msgid "User groups"
msgstr "用户组" msgstr "用户组"
#: assets/models/user.py:98 #: assets/models/user.py:104
msgid "Auto push" msgid "Auto push"
msgstr "自动推送" msgstr "自动推送"
#: assets/models/user.py:99 #: assets/models/user.py:105
msgid "Sudo" msgid "Sudo"
msgstr "Sudo" msgstr "Sudo"
#: assets/models/user.py:100 #: assets/models/user.py:106
msgid "Shell" msgid "Shell"
msgstr "Shell" msgstr "Shell"
#: assets/models/user.py:101 #: assets/models/user.py:107
msgid "Login mode" msgid "Login mode"
msgstr "登录模式" msgstr "登录模式"
#: assets/models/user.py:103 #: assets/models/user.py:109
msgid "SFTP Root" msgid "SFTP Root"
msgstr "SFTP根路径" msgstr "SFTP根路径"
#: assets/models/user.py:104 authentication/models.py:88 #: assets/models/user.py:110 authentication/models.py:88
msgid "Token" msgid "Token"
msgstr "" msgstr ""
#: assets/models/user.py:105 #: assets/models/user.py:111
msgid "Home" msgid "Home"
msgstr "家目录" msgstr "家目录"
#: assets/models/user.py:106 #: assets/models/user.py:112
msgid "System groups" msgid "System groups"
msgstr "用户组" msgstr "用户组"
#: assets/models/user.py:181 audits/models.py:39 #: assets/models/user.py:206 audits/models.py:39
#: perms/forms/asset_permission.py:95 perms/forms/remote_app_permission.py:49 #: perms/forms/asset_permission.py:95 perms/forms/remote_app_permission.py:49
#: perms/models/application_permission.py:22
#: perms/models/asset_permission.py:94 #: perms/models/asset_permission.py:94
#: perms/models/database_app_permission.py:22 #: perms/models/database_app_permission.py:22
#: perms/models/k8s_app_permission.py:22 #: perms/models/k8s_app_permission.py:22
#: perms/models/remote_app_permission.py:16 templates/_nav.html:45 #: perms/models/remote_app_permission.py:16 templates/_nav.html:45
#: terminal/backends/command/models.py:20 #: terminal/backends/command/models.py:20
#: terminal/backends/command/serializers.py:14 terminal/models.py:190 #: terminal/backends/command/serializers.py:14 terminal/models.py:194
#: tickets/serializers/request_asset_perm.py:27 #: tickets/serializers/request_asset_perm.py:27
#: users/templates/users/_granted_assets.html:27 #: users/templates/users/_granted_assets.html:27
#: users/templates/users/user_asset_permission.html:42 #: users/templates/users/user_asset_permission.html:42
@ -725,7 +777,7 @@ msgstr "硬件信息"
msgid "Org name" msgid "Org name"
msgstr "组织名称" msgstr "组织名称"
#: assets/serializers/asset.py:168 assets/serializers/asset.py:199 #: assets/serializers/asset.py:166 assets/serializers/asset.py:197
msgid "Connectivity" msgid "Connectivity"
msgstr "连接" msgstr "连接"
@ -763,27 +815,31 @@ msgstr "密钥不合法"
msgid "value" msgid "value"
msgstr "值" msgstr "值"
#: assets/serializers/node.py:36 #: assets/serializers/node.py:29
msgid "Can't contains: /"
msgstr ""
#: assets/serializers/node.py:39
msgid "The same level node name cannot be the same" msgid "The same level node name cannot be the same"
msgstr "同级别节点名字不能重复" msgstr "同级别节点名字不能重复"
#: assets/serializers/system_user.py:47 assets/serializers/system_user.py:187 #: assets/serializers/system_user.py:46 assets/serializers/system_user.py:187
msgid "Login mode display" msgid "Login mode display"
msgstr "登录模式显示" msgstr "登录模式显示"
#: assets/serializers/system_user.py:87 #: assets/serializers/system_user.py:86
msgid "Username same with user with protocol {} only allow 1" msgid "Username same with user with protocol {} only allow 1"
msgstr "用户名和用户相同的一种协议只允许存在一个" msgstr "用户名和用户相同的一种协议只允许存在一个"
#: assets/serializers/system_user.py:100 #: assets/serializers/system_user.py:99
msgid "* Automatic login mode must fill in the username." msgid "* Automatic login mode must fill in the username."
msgstr "自动登录模式,必须填写用户名" msgstr "自动登录模式,必须填写用户名"
#: assets/serializers/system_user.py:108 #: assets/serializers/system_user.py:107
msgid "Path should starts with /" msgid "Path should starts with /"
msgstr "路径应该以 / 开头" msgstr "路径应该以 / 开头"
#: assets/serializers/system_user.py:119 #: assets/serializers/system_user.py:118
msgid "Password or private key required" msgid "Password or private key required"
msgstr "密码或密钥密码需要一个" msgstr "密码或密钥密码需要一个"
@ -835,25 +891,25 @@ msgstr "更新节点资产硬件信息: {}"
msgid "Gather assets users" msgid "Gather assets users"
msgstr "收集资产上的用户" msgstr "收集资产上的用户"
#: assets/tasks/push_system_user.py:178 #: assets/tasks/push_system_user.py:183
#: assets/tasks/system_user_connectivity.py:89 #: assets/tasks/system_user_connectivity.py:89
msgid "System user is dynamic: {}" msgid "System user is dynamic: {}"
msgstr "系统用户是动态的: {}" msgstr "系统用户是动态的: {}"
#: assets/tasks/push_system_user.py:209 #: assets/tasks/push_system_user.py:214
msgid "Start push system user for platform: [{}]" msgid "Start push system user for platform: [{}]"
msgstr "推送系统用户到平台: [{}]" msgstr "推送系统用户到平台: [{}]"
#: assets/tasks/push_system_user.py:210 #: assets/tasks/push_system_user.py:215
#: assets/tasks/system_user_connectivity.py:81 #: assets/tasks/system_user_connectivity.py:81
msgid "Hosts count: {}" msgid "Hosts count: {}"
msgstr "主机数量: {}" msgstr "主机数量: {}"
#: assets/tasks/push_system_user.py:228 assets/tasks/push_system_user.py:244 #: assets/tasks/push_system_user.py:233 assets/tasks/push_system_user.py:251
msgid "Push system users to assets: {}" msgid "Push system users to assets: {}"
msgstr "推送系统用户到入资产: {}" msgstr "推送系统用户到入资产: {}"
#: assets/tasks/push_system_user.py:236 #: assets/tasks/push_system_user.py:241
msgid "Push system users to asset: {}({}) => {}" msgid "Push system users to asset: {}({}) => {}"
msgstr "推送系统用户到入资产: {}({}) => {}" msgstr "推送系统用户到入资产: {}({}) => {}"
@ -933,7 +989,7 @@ msgid "Symlink"
msgstr "建立软链接" msgstr "建立软链接"
#: audits/models.py:37 audits/models.py:60 audits/models.py:71 #: audits/models.py:37 audits/models.py:60 audits/models.py:71
#: terminal/models.py:193 #: terminal/models.py:197
msgid "Remote addr" msgid "Remote addr"
msgstr "远端地址" msgstr "远端地址"
@ -951,7 +1007,7 @@ msgid "Success"
msgstr "成功" msgstr "成功"
#: audits/models.py:43 ops/models/command.py:28 perms/models/base.py:52 #: audits/models.py:43 ops/models/command.py:28 perms/models/base.py:52
#: terminal/models.py:200 tickets/serializers/request_asset_perm.py:29 #: terminal/models.py:204 tickets/serializers/request_asset_perm.py:29
#: xpack/plugins/change_auth_plan/models.py:177 #: xpack/plugins/change_auth_plan/models.py:177
#: xpack/plugins/change_auth_plan/models.py:308 #: xpack/plugins/change_auth_plan/models.py:308
#: xpack/plugins/gathered_user/models.py:76 #: xpack/plugins/gathered_user/models.py:76
@ -1205,7 +1261,7 @@ msgstr "登录复核 {}"
msgid "SSO auth closed" msgid "SSO auth closed"
msgstr "SSO 认证关闭了" msgstr "SSO 认证关闭了"
#: authentication/errors.py:218 authentication/views/login.py:246 #: authentication/errors.py:218 authentication/views/login.py:247
msgid "Your password is too simple, please change it for security" msgid "Your password is too simple, please change it for security"
msgstr "你的密码过于简单,为了安全,请修改" msgstr "你的密码过于简单,为了安全,请修改"
@ -1358,6 +1414,10 @@ msgstr "正在使用其他认证服务器,请联系管理员"
msgid "One-time password" msgid "One-time password"
msgstr "一次性密码" msgstr "一次性密码"
#: authentication/templates/authentication/login_otp.html:23
#: users/templates/users/user_verify_mfa.html:13
msgid "Open MFA Authenticator and enter the 6-bit dynamic code"
msgstr "请打开MFA验证器输入6位动态码"
#: authentication/templates/authentication/login_otp.html:26 #: authentication/templates/authentication/login_otp.html:26
#: users/templates/users/user_otp_check_password.html:15 #: users/templates/users/user_otp_check_password.html:15
@ -1396,7 +1456,7 @@ msgstr "欢迎回来,请输入用户名和密码登录"
msgid "Please enable cookies and try again." msgid "Please enable cookies and try again."
msgstr "设置你的浏览器支持cookie" msgstr "设置你的浏览器支持cookie"
#: authentication/views/login.py:192 #: authentication/views/login.py:193
msgid "" msgid ""
"Wait for <b>{}</b> confirm, You also can copy link to her/him <br/>\n" "Wait for <b>{}</b> confirm, You also can copy link to her/him <br/>\n"
" Don't close this page" " Don't close this page"
@ -1404,19 +1464,19 @@ msgstr ""
"等待 <b>{}</b> 确认, 你也可以复制链接发给他/她 <br/>\n" "等待 <b>{}</b> 确认, 你也可以复制链接发给他/她 <br/>\n"
" 不要关闭本页面" " 不要关闭本页面"
#: authentication/views/login.py:197 #: authentication/views/login.py:198
msgid "No ticket found" msgid "No ticket found"
msgstr "没有发现工单" msgstr "没有发现工单"
#: authentication/views/login.py:229 #: authentication/views/login.py:230
msgid "Logout success" msgid "Logout success"
msgstr "退出登录成功" msgstr "退出登录成功"
#: authentication/views/login.py:230 #: authentication/views/login.py:231
msgid "Logout success, return login page" msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面" msgstr "退出登录成功,返回到登录页面"
#: authentication/views/login.py:245 #: authentication/views/login.py:246
msgid "Please change your password" msgid "Please change your password"
msgstr "请修改密码" msgstr "请修改密码"
@ -1488,7 +1548,7 @@ msgstr ""
msgid "Marshal data to text field" msgid "Marshal data to text field"
msgstr "" msgstr ""
#: common/fields/model.py:165 #: common/fields/model.py:150
msgid "Encrypt field using Secret Key" msgid "Encrypt field using Secret Key"
msgstr "" msgstr ""
@ -1516,7 +1576,7 @@ msgstr "字段必须唯一"
msgid "Should not contains special characters" msgid "Should not contains special characters"
msgstr "不能包含特殊字符" msgstr "不能包含特殊字符"
#: jumpserver/conf.py:471 templates/_base_only_msg_content.html:27 #: jumpserver/conf.py:477 templates/_base_only_msg_content.html:27
#: xpack/plugins/interface/api.py:18 xpack/plugins/interface/models.py:36 #: xpack/plugins/interface/api.py:18 xpack/plugins/interface/models.py:36
msgid "Welcome to the JumpServer open source fortress" msgid "Welcome to the JumpServer open source fortress"
msgstr "欢迎使用JumpServer开源堡垒机" msgstr "欢迎使用JumpServer开源堡垒机"
@ -1707,11 +1767,11 @@ msgstr "更新任务内容: {}"
msgid "Disk used more than 80%: {} => {}" msgid "Disk used more than 80%: {} => {}"
msgstr "磁盘使用率超过 80%: {} => {}" msgstr "磁盘使用率超过 80%: {} => {}"
#: orgs/api.py:60 #: orgs/api.py:61
msgid "Organization contains undeleted resources" msgid "Organization contains undeleted resources"
msgstr "组织包含未删除的资源" msgstr "组织包含未删除的资源"
#: orgs/api.py:64 #: orgs/api.py:65
msgid "The current organization cannot be deleted" msgid "The current organization cannot be deleted"
msgstr "当前组织不能被删除" msgstr "当前组织不能被删除"
@ -1736,7 +1796,7 @@ msgstr "组织审计员"
msgid "Role" msgid "Role"
msgstr "角色" msgstr "角色"
#: perms/const.py:7 perms/utils/user_asset_permission.py:28 #: perms/const.py:7 perms/utils/asset/user_permission.py:28
msgid "Ungrouped" msgid "Ungrouped"
msgstr "未分组" msgstr "未分组"
@ -1785,6 +1845,14 @@ msgstr "资产和节点至少选一个"
msgid "System users" msgid "System users"
msgstr "系统用户" msgstr "系统用户"
#: perms/models/application_permission.py:21 users/models/user.py:160
msgid "Application"
msgstr "应用程序"
#: perms/models/application_permission.py:26
msgid "Application permission"
msgstr "应用管理"
#: perms/models/asset_permission.py:37 settings/serializers/settings.py:56 #: perms/models/asset_permission.py:37 settings/serializers/settings.py:56
msgid "All" msgid "All"
msgstr "全部" msgstr "全部"
@ -1846,11 +1914,17 @@ msgstr "Kubernetes应用授权"
msgid "RemoteApp permission" msgid "RemoteApp permission"
msgstr "远程应用授权" msgstr "远程应用授权"
#: perms/utils/user_asset_permission.py:30 #: perms/serializers/application/permission.py:53
msgid ""
"The application list contains applications that are different from the "
"permission type. ({})"
msgstr ""
#: perms/utils/asset/user_permission.py:30
msgid "Favorite" msgid "Favorite"
msgstr "收藏夹" msgstr "收藏夹"
#: perms/utils/user_asset_permission.py:514 #: perms/utils/asset/user_permission.py:526
msgid "Please wait while your data is being initialized" msgid "Please wait while your data is being initialized"
msgstr "数据正在初始化,请稍等" msgstr "数据正在初始化,请稍等"
@ -2522,63 +2596,63 @@ msgstr "风险等级"
msgid "Bulk create not support" msgid "Bulk create not support"
msgstr "不支持批量创建" msgstr "不支持批量创建"
#: terminal/models.py:28 #: terminal/models.py:29
msgid "Remote Address" msgid "Remote Address"
msgstr "远端地址" msgstr "远端地址"
#: terminal/models.py:29 #: terminal/models.py:30
msgid "SSH Port" msgid "SSH Port"
msgstr "SSH端口" msgstr "SSH端口"
#: terminal/models.py:30 #: terminal/models.py:31
msgid "HTTP Port" msgid "HTTP Port"
msgstr "HTTP端口" msgstr "HTTP端口"
#: terminal/models.py:31 #: terminal/models.py:32
msgid "Command storage" msgid "Command storage"
msgstr "命令存储" msgstr "命令存储"
#: terminal/models.py:32 #: terminal/models.py:33
msgid "Replay storage" msgid "Replay storage"
msgstr "录像存储" msgstr "录像存储"
#: terminal/models.py:155 #: terminal/models.py:156
msgid "Session Online" msgid "Session Online"
msgstr "在线会话" msgstr "在线会话"
#: terminal/models.py:156 #: terminal/models.py:157
msgid "CPU Usage" msgid "CPU Usage"
msgstr "CPU使用" msgstr "CPU使用"
#: terminal/models.py:157 #: terminal/models.py:158
msgid "Memory Used" msgid "Memory Used"
msgstr "内存使用" msgstr "内存使用"
#: terminal/models.py:158 #: terminal/models.py:159
msgid "Connections" msgid "Connections"
msgstr "连接数" msgstr "连接数"
#: terminal/models.py:159 #: terminal/models.py:160
msgid "Threads" msgid "Threads"
msgstr "线程数" msgstr "线程数"
#: terminal/models.py:160 #: terminal/models.py:161
msgid "Boot Time" msgid "Boot Time"
msgstr "运行时间" msgstr "运行时间"
#: terminal/models.py:192 #: terminal/models.py:196
msgid "Login from" msgid "Login from"
msgstr "登录来源" msgstr "登录来源"
#: terminal/models.py:196 #: terminal/models.py:200
msgid "Replay" msgid "Replay"
msgstr "回放" msgstr "回放"
#: terminal/models.py:201 #: terminal/models.py:205
msgid "Date end" msgid "Date end"
msgstr "结束日期" msgstr "结束日期"
#: terminal/models.py:349 #: terminal/models.py:357
msgid "Args" msgid "Args"
msgstr "参数" msgstr "参数"
@ -2586,37 +2660,73 @@ msgstr "参数"
msgid "Not found" msgid "Not found"
msgstr "没有发现" msgstr "没有发现"
#: tickets/api/request_asset_perm.py:48 #: terminal/utils.py:73
#, python-format
msgid ""
"Insecure Command Alert: [%(name)s->%(login_from)s@%(remote_addr)s] $"
"%(command)s"
msgstr "危险命令告警: [%(name)s->%(login_from)s@%(remote_addr)s] $%(command)s"
#: terminal/utils.py:83
#, python-format
msgid ""
"\n"
" Command: %(command)s\n"
" <br>\n"
" Asset: %(host_name)s (%(host_ip)s)\n"
" <br>\n"
" User: %(user)s\n"
" <br>\n"
" Level: %(risk_level)s\n"
" <br>\n"
" Session: <a href=\"%(session_detail_url)s\">session detail</a>\n"
" <br>\n"
" "
msgstr ""
"\n"
" 命令: %(command)s\n"
" <br>\n"
" 资产: %(host_name)s (%(host_ip)s)\n"
" <br>\n"
" 用户: %(user)s\n"
" <br>\n"
" 等级: %(risk_level)s\n"
" <br>\n"
" 会话: <a href=\"%(session_detail_url)s\">会话详情</a>\n"
" <br>\n"
" "
#: tickets/api/request_asset_perm.py:47
#, python-format #, python-format
msgid "Ticket has %s" msgid "Ticket has %s"
msgstr "工单已%s" msgstr "工单已%s"
#: tickets/api/request_asset_perm.py:94 #: tickets/api/request_asset_perm.py:81
msgid "Confirm assets first" msgid "Confirm assets first"
msgstr "请先确认资产" msgstr "请先确认资产"
#: tickets/api/request_asset_perm.py:97 #: tickets/api/request_asset_perm.py:84
msgid "Confirmed assets changed" msgid "Confirmed assets changed"
msgstr "确认的资产变更了" msgstr "确认的资产变更了"
#: tickets/api/request_asset_perm.py:101 #: tickets/api/request_asset_perm.py:88
msgid "Confirm system-users first" msgid "Confirm system-users first"
msgstr "请先确认系统用户" msgstr "请先确认系统用户"
#: tickets/api/request_asset_perm.py:105 #: tickets/api/request_asset_perm.py:92
msgid "Confirmed system-users changed" msgid "Confirmed system-users changed"
msgstr "确认的系统用户变更了" msgstr "确认的系统用户变更了"
#: tickets/api/request_asset_perm.py:111 tickets/api/request_asset_perm.py:118 #: tickets/api/request_asset_perm.py:98 tickets/api/request_asset_perm.py:105
#: xpack/plugins/cloud/models.py:211 #: xpack/plugins/cloud/models.py:211
msgid "Succeed" msgid "Succeed"
msgstr "成功" msgstr "成功"
#: tickets/api/request_asset_perm.py:125 #: tickets/api/request_asset_perm.py:112
msgid "From request ticket: {} {}" msgid "From request ticket: {} {}"
msgstr "来自工单申请: {} {}" msgstr "来自工单申请: {} {}"
#: tickets/api/request_asset_perm.py:127 #: tickets/api/request_asset_perm.py:114
msgid "{} request assets, approved by {}" msgid "{} request assets, approved by {}"
msgstr "{} 申请资产,通过人 {}" msgstr "{} 申请资产,通过人 {}"
@ -2928,10 +3038,6 @@ msgstr "系统管理员"
msgid "System auditor" msgid "System auditor"
msgstr "系统审计员" msgstr "系统审计员"
#: users/models/user.py:160
msgid "Application"
msgstr "应用程序"
#: users/models/user.py:427 users/templates/users/user_profile.html:90 #: users/models/user.py:427 users/templates/users/user_profile.html:90
msgid "Force enable" msgid "Force enable"
msgstr "强制启用" msgstr "强制启用"
@ -3428,8 +3534,8 @@ msgstr "绑定一次性密码验证器"
#: users/templates/users/user_otp_enable_bind.html:13 #: users/templates/users/user_otp_enable_bind.html:13
msgid "" msgid ""
"Use the MFA Authenticator application to scan the following qr " "Use the MFA Authenticator application to scan the following qr code for a 6-"
"code for a 6-bit verification code" "bit verification code"
msgstr "使用MFA验证器应用扫描以下二维码获取6位验证码" msgstr "使用MFA验证器应用扫描以下二维码获取6位验证码"
#: users/templates/users/user_otp_enable_bind.html:22 #: users/templates/users/user_otp_enable_bind.html:22
@ -3531,10 +3637,6 @@ msgid ""
"operations according to the prompts" "operations according to the prompts"
msgstr "账号保护已开启,请根据提示完成以下操作" msgstr "账号保护已开启,请根据提示完成以下操作"
#: users/templates/users/user_verify_mfa.html:13
msgid "Open MFA Authenticator and enter the 6-bit dynamic code"
msgstr "请打开MFA验证器输入6位动态码"
# msgid "Update user" # msgid "Update user"
# msgstr "更新用户" # msgstr "更新用户"
#: users/utils.py:24 #: users/utils.py:24
@ -4252,9 +4354,6 @@ msgstr "社区版"
#~ msgid "Auditors cannot be join in the user group" #~ msgid "Auditors cannot be join in the user group"
#~ msgstr "审计员不能被加入到用户组" #~ msgstr "审计员不能被加入到用户组"
#~ msgid "Target URL"
#~ msgstr "目标URL"
#~ msgid "Login username" #~ msgid "Login username"
#~ msgstr "登录账号" #~ msgstr "登录账号"
@ -4276,9 +4375,6 @@ msgstr "社区版"
#~ msgid "Target address" #~ msgid "Target address"
#~ msgstr "目标地址" #~ msgstr "目标地址"
#~ msgid "Operating parameter"
#~ msgstr "运行参数"
#~ msgid "Detail" #~ msgid "Detail"
#~ msgstr "详情" #~ msgstr "详情"
@ -4308,9 +4404,6 @@ msgstr "社区版"
#~ msgid "My DatabaseApp" #~ msgid "My DatabaseApp"
#~ msgstr "我的数据库应用" #~ msgstr "我的数据库应用"
#~ msgid "RemoteApp list"
#~ msgstr "远程应用列表"
#~ msgid "Update RemoteApp" #~ msgid "Update RemoteApp"
#~ msgstr "更新远程应用" #~ msgstr "更新远程应用"

View File

@ -82,6 +82,8 @@ class SecuritySettingSerializer(serializers.Serializer):
SECURITY_PASSWORD_LOWER_CASE = serializers.BooleanField(required=False) SECURITY_PASSWORD_LOWER_CASE = serializers.BooleanField(required=False)
SECURITY_PASSWORD_NUMBER = serializers.BooleanField(required=False) SECURITY_PASSWORD_NUMBER = serializers.BooleanField(required=False)
SECURITY_PASSWORD_SPECIAL_CHAR = serializers.BooleanField(required=False) SECURITY_PASSWORD_SPECIAL_CHAR = serializers.BooleanField(required=False)
SECURITY_INSECURE_COMMAND = serializers.BooleanField(required=False)
SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER = serializers.CharField(max_length=8192, required=False)
class SettingsSerializer(serializers.Serializer): class SettingsSerializer(serializers.Serializer):

View File

@ -1,25 +1,28 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
import time import time
from django.conf import settings
from django.utils import timezone from django.utils import timezone
from django.shortcuts import HttpResponse from django.shortcuts import HttpResponse
from rest_framework import viewsets from rest_framework import viewsets
from rest_framework import generics from rest_framework import generics
from rest_framework.fields import DateTimeField from rest_framework.fields import DateTimeField
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import status
from django.template import loader from django.template import loader
from orgs.utils import current_org from orgs.utils import current_org
from common.permissions import IsOrgAdminOrAppUser, IsOrgAuditor from common.permissions import IsOrgAdminOrAppUser, IsOrgAuditor, IsAppUser
from common.utils import get_logger from common.utils import get_logger
from terminal.utils import send_command_alert_mail
from terminal.serializers import InsecureCommandAlertSerializer
from ..backends import ( from ..backends import (
get_command_storage, get_multi_command_storage, get_command_storage, get_multi_command_storage,
SessionCommandSerializer, SessionCommandSerializer,
) )
logger = get_logger(__name__) logger = get_logger(__name__)
__all__ = ['CommandViewSet', 'CommandExportApi'] __all__ = ['CommandViewSet', 'CommandExportApi', 'InsecureCommandAlertAPI']
class CommandQueryMixin: class CommandQueryMixin:
@ -134,3 +137,19 @@ class CommandExportApi(CommandQueryMixin, generics.ListAPIView):
filename = 'command-report-{}.html'.format(int(time.time())) filename = 'command-report-{}.html'.format(int(time.time()))
response['Content-Disposition'] = 'attachment; filename="%s"' % filename response['Content-Disposition'] = 'attachment; filename="%s"' % filename
return response return response
class InsecureCommandAlertAPI(generics.CreateAPIView):
permission_classes = [IsAppUser]
serializer_class = InsecureCommandAlertSerializer
def post(self, request, *args, **kwargs):
serializer = InsecureCommandAlertSerializer(data=request.data, many=True)
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:
send_command_alert_mail(command)
return Response()

View File

@ -27,6 +27,11 @@ class AbstractSessionCommand(OrgModelMixin):
class Meta: class Meta:
abstract = True abstract = True
@classmethod
def get_risk_level_str(cls, risk_level):
risk_mapper = dict(cls.RISK_LEVEL_CHOICES)
return risk_mapper.get(risk_level)
@classmethod @classmethod
def from_dict(cls, d): def from_dict(cls, d):
self = cls() self = cls()

View File

@ -24,3 +24,11 @@ class SessionCommandSerializer(serializers.Serializer):
def get_risk_level_display(obj): def get_risk_level_display(obj):
risk_mapper = dict(AbstractSessionCommand.RISK_LEVEL_CHOICES) risk_mapper = dict(AbstractSessionCommand.RISK_LEVEL_CHOICES)
return risk_mapper.get(obj.risk_level) return risk_mapper.get(obj.risk_level)
class InsecureCommandAlertSerializer(serializers.Serializer):
input = serializers.CharField()
asset = serializers.CharField()
user = serializers.CharField()
risk_level = serializers.IntegerField()
session = serializers.UUIDField()

View File

@ -12,6 +12,7 @@ from django.conf import settings
from django.core.files.storage import default_storage from django.core.files.storage import default_storage
from django.core.cache import cache from django.core.cache import cache
from assets.models import Asset
from users.models import User from users.models import User
from orgs.mixins.models import OrgModelMixin from orgs.mixins.models import OrgModelMixin
from common.mixins import CommonModelMixin from common.mixins import CommonModelMixin
@ -227,6 +228,10 @@ class Session(OrgModelMixin):
local_path = rel_path local_path = rel_path
return local_path return local_path
@property
def asset_obj(self):
return Asset.objects.get(id=self.asset_id)
@property @property
def _date_start_first_has_replay_rdp_session(self): def _date_start_first_has_replay_rdp_session(self):
if self.__class__._DATE_START_FIRST_HAS_REPLAY_RDP_SESSION is None: if self.__class__._DATE_START_FIRST_HAS_REPLAY_RDP_SESSION is None:

View File

@ -3,3 +3,4 @@
from .terminal import * from .terminal import *
from .session import * from .session import *
from .storage import * from .storage import *
from .command import *

View File

@ -0,0 +1,10 @@
# ~*~ coding: utf-8 ~*~
from rest_framework import serializers
class InsecureCommandAlertSerializer(serializers.Serializer):
input = serializers.CharField()
asset = serializers.CharField()
user = serializers.CharField()
risk_level = serializers.IntegerField()
session = serializers.UUIDField()

View File

@ -31,6 +31,7 @@ urlpatterns = [
name='terminal-access-key'), name='terminal-access-key'),
path('terminals/config/', api.TerminalConfig.as_view(), name='terminal-config'), path('terminals/config/', api.TerminalConfig.as_view(), name='terminal-config'),
path('commands/export/', api.CommandExportApi.as_view(), name="command-export"), path('commands/export/', api.CommandExportApi.as_view(), name="command-export"),
path('commands/insecure-command/', api.InsecureCommandAlertAPI.as_view(), name="command-alert"),
path('replay-storages/<uuid:pk>/test-connective/', api.ReplayStorageTestConnectiveApi.as_view(), name='replay-storage-test-connective'), path('replay-storages/<uuid:pk>/test-connective/', api.ReplayStorageTestConnectiveApi.as_view(), name='replay-storage-test-connective'),
path('command-storages/<uuid:pk>/test-connective/', api.CommandStorageTestConnectiveApi.as_view(), name='command-storage-test-connective') path('command-storages/<uuid:pk>/test-connective/', api.CommandStorageTestConnectiveApi.as_view(), name='command-storage-test-connective')
# v2: get session's replay # v2: get session's replay

View File

@ -4,12 +4,15 @@ import os
from django.conf import settings from django.conf import settings
from django.core.files.storage import default_storage from django.core.files.storage import default_storage
from django.utils.translation import ugettext as _
import jms_storage import jms_storage
from common.utils import get_logger from common.tasks import send_mail_async
from common.utils import get_logger, reverse
from settings.models import Setting
from .backends import server_replay_storage from .models import ReplayStorage, Session, Command
from .models import ReplayStorage
logger = get_logger(__name__) logger = get_logger(__name__)
@ -63,3 +66,38 @@ def get_session_replay_url(session):
if local_path is None: if local_path is None:
local_path, url = download_session_replay(session) local_path, url = download_session_replay(session)
return local_path, url return local_path, url
def send_command_alert_mail(command):
session_obj = Session.objects.get(id=command['session'])
subject = _("Insecure Command Alert: [%(name)s->%(login_from)s@%(remote_addr)s] $%(command)s") % {
'name': command['user'],
'login_from': session_obj.get_login_from_display(),
'remote_addr': session_obj.remote_addr,
'command': command['input']
}
recipient_list = settings.SECURITY_INSECURE_COMMAND_EMAIL_RECEIVER.split(',')
message = _("""
Command: %(command)s
<br>
Asset: %(host_name)s (%(host_ip)s)
<br>
User: %(user)s
<br>
Level: %(risk_level)s
<br>
Session: <a href="%(session_detail_url)s">session detail</a>
<br>
""") % {
'command': command['input'],
'host_name': command['asset'],
'host_ip': session_obj.asset_obj.ip,
'user': command['user'],
'risk_level': Command.get_risk_level_str(command['risk_level']),
'session_detail_url': reverse('api-terminal:session-detail',
kwargs={'pk': command['session']},
external=True, api_to_ui=True),
}
logger.debug(message)
send_mail_async.delay(subject, message, recipient_list, html_message=message)