Merge pull request #3864 from jumpserver/1.5.8

1.5.8
pull/3867/head
BaiJiangJie 2020-04-09 11:36:38 +08:00 committed by GitHub
commit e26eba9919
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 357 additions and 220 deletions

View File

@ -84,7 +84,8 @@ class SimpleMetadataWithFilters(SimpleMetadata):
def get_filters_fields(self, request, view): def get_filters_fields(self, request, view):
fields = [] fields = []
if hasattr(view, 'get_filter_fields'): if hasattr(view, 'get_filter_fields'):
fields = view.get_filter_fields(request) # fields = view.get_filter_fields(request)
fields = view.get_filter_fields()
elif hasattr(view, 'filter_fields'): elif hasattr(view, 'filter_fields'):
fields = view.filter_fields fields = view.filter_fields
return fields return fields

View File

@ -101,6 +101,15 @@ class CustomMetaDictField(serializers.DictField):
filter_value = {k: v for k, v in value.items() if k in fields_names} filter_value = {k: v for k, v in value.items() if k in fields_names}
return filter_value return filter_value
@staticmethod
def strip_value(value):
new_value = {}
for k, v in value.items():
if isinstance(v, str):
v = v.strip()
new_value[k] = v
return new_value
def get_value(self, dictionary): def get_value(self, dictionary):
""" """
反序列化时调用 反序列化时调用
@ -108,4 +117,5 @@ class CustomMetaDictField(serializers.DictField):
value = super().get_value(dictionary) value = super().get_value(dictionary)
value = self.convert_value_key(dictionary, value) value = self.convert_value_key(dictionary, value)
value = self.filter_value_key(dictionary, value) value = self.filter_value_key(dictionary, value)
value = self.strip_value(value)
return value return value

View File

@ -7,6 +7,6 @@ __all__ = ['BASE_DIR', 'PROJECT_DIR', 'VERSION', 'CONFIG', 'DYNAMIC']
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PROJECT_DIR = os.path.dirname(BASE_DIR) PROJECT_DIR = os.path.dirname(BASE_DIR)
VERSION = '1.5.7' VERSION = '1.5.8'
CONFIG = ConfigManager.load_user_config() CONFIG = ConfigManager.load_user_config()
DYNAMIC = ConfigManager.get_dynamic_config(CONFIG) DYNAMIC = ConfigManager.get_dynamic_config(CONFIG)

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-03-23 03:05+0800\n" "POT-Creation-Date: 2020-04-09 10:47+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"
@ -26,9 +26,9 @@ msgstr "自定义"
#: applications/templates/applications/remote_app_list.html:27 #: applications/templates/applications/remote_app_list.html:27
#: applications/templates/applications/user_remote_app_list.html:18 #: applications/templates/applications/user_remote_app_list.html:18
#: assets/forms/domain.py:15 assets/forms/label.py:13 #: assets/forms/domain.py:15 assets/forms/label.py:13
#: assets/models/asset.py:353 assets/models/authbook.py:23 #: assets/models/asset.py:353 assets/models/authbook.py:25
#: assets/models/gathered_user.py:14 assets/serializers/admin_user.py:32 #: assets/models/gathered_user.py:14 assets/serializers/admin_user.py:32
#: assets/serializers/asset_user.py:48 assets/serializers/asset_user.py:85 #: assets/serializers/asset_user.py:47 assets/serializers/asset_user.py:84
#: assets/serializers/system_user.py:44 assets/serializers/system_user.py:176 #: assets/serializers/system_user.py:44 assets/serializers/system_user.py:176
#: assets/templates/assets/admin_user_list.html:23 #: assets/templates/assets/admin_user_list.html:23
#: assets/templates/assets/asset_list.html:170 #: assets/templates/assets/asset_list.html:170
@ -53,12 +53,13 @@ msgstr "自定义"
#: 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
#: xpack/plugins/change_auth_plan/forms.py:74 #: xpack/plugins/change_auth_plan/forms.py:74
#: xpack/plugins/change_auth_plan/models.py:267 #: xpack/plugins/change_auth_plan/models.py:265
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:40 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:40
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:54 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:54
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:13 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:13
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:14 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:14
#: xpack/plugins/cloud/models.py:266 #: xpack/plugins/cloud/models.py:269
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:37
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:47 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:47
#: xpack/plugins/orgs/templates/orgs/org_list.html:17 #: xpack/plugins/orgs/templates/orgs/org_list.html:17
#: xpack/plugins/vault/forms.py:13 xpack/plugins/vault/forms.py:15 #: xpack/plugins/vault/forms.py:13 xpack/plugins/vault/forms.py:15
@ -142,8 +143,8 @@ msgstr "运行参数"
#: perms/templates/perms/remote_app_permission_user.html:49 #: perms/templates/perms/remote_app_permission_user.html:49
#: settings/models.py:26 #: settings/models.py:26
#: settings/templates/settings/_ldap_list_users_modal.html:32 #: settings/templates/settings/_ldap_list_users_modal.html:32
#: terminal/models.py:26 terminal/models.py:334 terminal/models.py:366 #: terminal/models.py:26 terminal/models.py:341 terminal/models.py:373
#: terminal/models.py:403 terminal/templates/terminal/base_storage_list.html:31 #: terminal/models.py:410 terminal/templates/terminal/base_storage_list.html:31
#: terminal/templates/terminal/terminal_detail.html:43 #: terminal/templates/terminal/terminal_detail.html:43
#: terminal/templates/terminal/terminal_list.html:30 users/forms/profile.py:20 #: terminal/templates/terminal/terminal_list.html:30 users/forms/profile.py:20
#: users/models/group.py:15 users/models/user.py:440 #: users/models/group.py:15 users/models/user.py:440
@ -182,7 +183,7 @@ msgstr "名称"
#: assets/templates/assets/cmd_filter_rule_list.html:53 #: assets/templates/assets/cmd_filter_rule_list.html:53
#: audits/templates/audits/login_log_list.html:58 #: audits/templates/audits/login_log_list.html:58
#: perms/templates/perms/remote_app_permission_remote_app.html:50 #: perms/templates/perms/remote_app_permission_remote_app.html:50
#: terminal/models.py:368 terminal/models.py:405 #: terminal/models.py:375 terminal/models.py:412
#: terminal/templates/terminal/base_storage_list.html:32 #: terminal/templates/terminal/base_storage_list.html:32
#: tickets/models/ticket.py:43 tickets/templates/tickets/ticket_detail.html:33 #: tickets/models/ticket.py:43 tickets/templates/tickets/ticket_detail.html:33
#: tickets/templates/tickets/ticket_list.html:35 #: tickets/templates/tickets/ticket_list.html:35
@ -247,8 +248,8 @@ msgstr "数据库"
#: perms/templates/perms/asset_permission_detail.html:97 #: perms/templates/perms/asset_permission_detail.html:97
#: perms/templates/perms/database_app_permission_detail.html:93 #: perms/templates/perms/database_app_permission_detail.html:93
#: perms/templates/perms/remote_app_permission_detail.html:89 #: perms/templates/perms/remote_app_permission_detail.html:89
#: settings/models.py:31 terminal/models.py:36 terminal/models.py:373 #: settings/models.py:31 terminal/models.py:36 terminal/models.py:380
#: terminal/models.py:410 terminal/templates/terminal/base_storage_list.html:33 #: terminal/models.py:417 terminal/templates/terminal/base_storage_list.html:33
#: terminal/templates/terminal/terminal_detail.html:63 #: terminal/templates/terminal/terminal_detail.html:63
#: tickets/templates/tickets/ticket_detail.html:104 users/models/group.py:16 #: tickets/templates/tickets/ticket_detail.html:104 users/models/group.py:16
#: users/models/user.py:473 users/templates/users/user_detail.html:115 #: users/models/user.py:473 users/templates/users/user_detail.html:115
@ -257,13 +258,13 @@ msgstr "数据库"
#: users/templates/users/user_group_detail.html:62 #: users/templates/users/user_group_detail.html:62
#: users/templates/users/user_group_list.html:16 #: users/templates/users/user_group_list.html:16
#: users/templates/users/user_profile.html:138 #: users/templates/users/user_profile.html:138
#: xpack/plugins/change_auth_plan/models.py:77 #: xpack/plugins/change_auth_plan/models.py:75
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:115 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:115
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:19 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:19
#: xpack/plugins/cloud/models.py:53 xpack/plugins/cloud/models.py:136 #: xpack/plugins/cloud/models.py:53 xpack/plugins/cloud/models.py:139
#: xpack/plugins/cloud/templates/cloud/account_detail.html:67 #: xpack/plugins/cloud/templates/cloud/account_detail.html:67
#: xpack/plugins/cloud/templates/cloud/account_list.html:15 #: xpack/plugins/cloud/templates/cloud/account_list.html:15
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:102 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:128
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:18 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:18
#: xpack/plugins/gathered_user/models.py:26 #: xpack/plugins/gathered_user/models.py:26
#: xpack/plugins/orgs/templates/orgs/org_detail.html:59 #: xpack/plugins/orgs/templates/orgs/org_detail.html:59
@ -321,9 +322,9 @@ msgstr "参数"
#: perms/templates/perms/remote_app_permission_detail.html:85 #: perms/templates/perms/remote_app_permission_detail.html:85
#: users/models/user.py:481 users/serializers/group.py:32 #: users/models/user.py:481 users/serializers/group.py:32
#: users/templates/users/user_detail.html:97 #: users/templates/users/user_detail.html:97
#: xpack/plugins/change_auth_plan/models.py:81 #: xpack/plugins/change_auth_plan/models.py:79
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:111 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:111
#: xpack/plugins/cloud/models.py:56 xpack/plugins/cloud/models.py:142 #: xpack/plugins/cloud/models.py:56 xpack/plugins/cloud/models.py:145
#: xpack/plugins/gathered_user/models.py:30 #: xpack/plugins/gathered_user/models.py:30
msgid "Created by" msgid "Created by"
msgstr "创建者" msgstr "创建者"
@ -350,9 +351,9 @@ msgstr "创建者"
#: tickets/templates/tickets/ticket_detail.html:52 users/models/group.py:18 #: tickets/templates/tickets/ticket_detail.html:52 users/models/group.py:18
#: users/templates/users/user_group_detail.html:58 #: users/templates/users/user_group_detail.html:58
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:103 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:103
#: xpack/plugins/cloud/models.py:59 xpack/plugins/cloud/models.py:145 #: xpack/plugins/cloud/models.py:59 xpack/plugins/cloud/models.py:148
#: xpack/plugins/cloud/templates/cloud/account_detail.html:63 #: xpack/plugins/cloud/templates/cloud/account_detail.html:63
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:98 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:108
#: xpack/plugins/orgs/templates/orgs/org_detail.html:55 #: xpack/plugins/orgs/templates/orgs/org_detail.html:55
msgid "Date created" msgid "Date created"
msgstr "创建日期" msgstr "创建日期"
@ -405,7 +406,7 @@ msgstr "远程应用"
#: users/templates/users/user_pubkey_update.html:80 #: users/templates/users/user_pubkey_update.html:80
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:65 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:65
#: xpack/plugins/cloud/templates/cloud/account_create_update.html:29 #: xpack/plugins/cloud/templates/cloud/account_create_update.html:29
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:49 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:52
#: xpack/plugins/gathered_user/templates/gathered_user/task_create_update.html:40 #: xpack/plugins/gathered_user/templates/gathered_user/task_create_update.html:40
#: xpack/plugins/interface/templates/interface/interface.html:72 #: xpack/plugins/interface/templates/interface/interface.html:72
#: xpack/plugins/orgs/templates/orgs/org_create_update.html:29 #: xpack/plugins/orgs/templates/orgs/org_create_update.html:29
@ -739,7 +740,7 @@ msgstr "最新版本的不能被删除"
#: assets/templates/assets/asset_detail.html:194 #: assets/templates/assets/asset_detail.html:194
#: assets/templates/assets/system_user_assets.html:118 #: assets/templates/assets/system_user_assets.html:118
#: perms/models/asset_permission.py:81 #: perms/models/asset_permission.py:81
#: xpack/plugins/change_auth_plan/models.py:56 #: xpack/plugins/change_auth_plan/models.py:54
#: xpack/plugins/gathered_user/models.py:24 #: xpack/plugins/gathered_user/models.py:24
#: xpack/plugins/gathered_user/templates/gathered_user/task_list.html:17 #: xpack/plugins/gathered_user/templates/gathered_user/task_list.html:17
msgid "Nodes" msgid "Nodes"
@ -857,8 +858,8 @@ msgstr "SSH网关支持代理SSH,RDP和VNC"
#: users/templates/users/user_list.html:15 #: users/templates/users/user_list.html:15
#: users/templates/users/user_profile.html:47 #: users/templates/users/user_profile.html:47
#: xpack/plugins/change_auth_plan/forms.py:59 #: xpack/plugins/change_auth_plan/forms.py:59
#: xpack/plugins/change_auth_plan/models.py:47 #: xpack/plugins/change_auth_plan/models.py:45
#: xpack/plugins/change_auth_plan/models.py:263 #: xpack/plugins/change_auth_plan/models.py:261
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:63 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:63
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:53 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:53
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:12 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:12
@ -871,6 +872,7 @@ msgstr "用户名"
#: ops/templates/ops/task_detail.html:95 #: ops/templates/ops/task_detail.html:95
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:82 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:82
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:72 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:72
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:82
msgid "Yes" msgid "Yes"
msgstr "是" msgstr "是"
@ -878,6 +880,7 @@ msgstr "是"
#: ops/templates/ops/task_detail.html:97 #: ops/templates/ops/task_detail.html:97
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:84 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:84
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:74 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:74
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:84
msgid "No" msgid "No"
msgstr "否" msgstr "否"
@ -899,7 +902,7 @@ msgid "Password or private key passphrase"
msgstr "密码或密钥密码" msgstr "密码或密钥密码"
#: assets/forms/user.py:26 assets/models/base.py:234 #: assets/forms/user.py:26 assets/models/base.py:234
#: assets/serializers/asset_user.py:72 #: assets/serializers/asset_user.py:71
#: assets/templates/assets/_asset_user_auth_update_modal.html:21 #: assets/templates/assets/_asset_user_auth_update_modal.html:21
#: assets/templates/assets/_asset_user_auth_view_modal.html:27 #: assets/templates/assets/_asset_user_auth_view_modal.html:27
#: authentication/forms.py:12 #: authentication/forms.py:12
@ -914,13 +917,13 @@ msgstr "密码或密钥密码"
#: users/templates/users/user_profile_update.html:41 #: users/templates/users/user_profile_update.html:41
#: users/templates/users/user_pubkey_update.html:41 #: users/templates/users/user_pubkey_update.html:41
#: users/templates/users/user_update.html:20 #: users/templates/users/user_update.html:20
#: xpack/plugins/change_auth_plan/models.py:68 #: xpack/plugins/change_auth_plan/models.py:66
#: xpack/plugins/change_auth_plan/models.py:183 #: xpack/plugins/change_auth_plan/models.py:181
#: xpack/plugins/change_auth_plan/models.py:270 #: xpack/plugins/change_auth_plan/models.py:268
msgid "Password" msgid "Password"
msgstr "密码" msgstr "密码"
#: assets/forms/user.py:29 assets/serializers/asset_user.py:80 #: assets/forms/user.py:29 assets/serializers/asset_user.py:79
#: assets/templates/assets/_asset_user_auth_update_modal.html:27 #: assets/templates/assets/_asset_user_auth_update_modal.html:27
#: users/models/user.py:467 #: users/models/user.py:467
msgid "Private key" msgid "Private key"
@ -993,7 +996,7 @@ msgid "Internal"
msgstr "内部的" msgstr "内部的"
#: assets/models/asset.py:187 assets/models/domain.py:49 #: assets/models/asset.py:187 assets/models/domain.py:49
#: assets/serializers/asset_user.py:47 #: assets/serializers/asset_user.py:46
#: assets/templates/assets/_asset_list_modal.html:47 #: assets/templates/assets/_asset_list_modal.html:47
#: assets/templates/assets/_asset_user_list.html:20 #: assets/templates/assets/_asset_user_list.html:20
#: assets/templates/assets/asset_detail.html:60 #: assets/templates/assets/asset_detail.html:60
@ -1009,7 +1012,7 @@ msgstr "内部的"
msgid "IP" msgid "IP"
msgstr "IP" msgstr "IP"
#: assets/models/asset.py:188 assets/serializers/asset_user.py:46 #: assets/models/asset.py:188 assets/serializers/asset_user.py:45
#: assets/serializers/gathered_user.py:20 #: assets/serializers/gathered_user.py:20
#: assets/templates/assets/_asset_list_modal.html:46 #: assets/templates/assets/_asset_list_modal.html:46
#: assets/templates/assets/_asset_user_auth_update_modal.html:9 #: assets/templates/assets/_asset_user_auth_update_modal.html:9
@ -1120,11 +1123,11 @@ msgstr "主机名原始"
msgid "Labels" msgid "Labels"
msgstr "标签管理" msgstr "标签管理"
#: assets/models/authbook.py:24 ops/templates/ops/task_detail.html:70 #: assets/models/authbook.py:26 ops/templates/ops/task_detail.html:70
msgid "Latest version" msgid "Latest version"
msgstr "最新版本" msgstr "最新版本"
#: assets/models/authbook.py:25 #: assets/models/authbook.py:27
#: assets/templates/assets/_asset_user_list.html:22 #: assets/templates/assets/_asset_user_list.html:22
#: ops/templates/ops/adhoc_history.html:56 #: ops/templates/ops/adhoc_history.html:56
#: ops/templates/ops/adhoc_history_detail.html:55 #: ops/templates/ops/adhoc_history_detail.html:55
@ -1132,19 +1135,19 @@ msgstr "最新版本"
msgid "Version" msgid "Version"
msgstr "版本" msgstr "版本"
#: assets/models/authbook.py:34 #: assets/models/authbook.py:36
msgid "AuthBook" msgid "AuthBook"
msgstr "" 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:70
#: xpack/plugins/change_auth_plan/models.py:190 #: xpack/plugins/change_auth_plan/models.py:188
#: xpack/plugins/change_auth_plan/models.py:277 #: xpack/plugins/change_auth_plan/models.py:275
msgid "SSH private key" msgid "SSH private key"
msgstr "ssh密钥" msgstr "ssh密钥"
#: assets/models/base.py:236 xpack/plugins/change_auth_plan/models.py:75 #: assets/models/base.py:236 xpack/plugins/change_auth_plan/models.py:73
#: xpack/plugins/change_auth_plan/models.py:186 #: xpack/plugins/change_auth_plan/models.py:184
#: xpack/plugins/change_auth_plan/models.py:273 #: xpack/plugins/change_auth_plan/models.py:271
msgid "SSH public key" msgid "SSH public key"
msgstr "ssh公钥" msgstr "ssh公钥"
@ -1190,7 +1193,7 @@ msgid "Default"
msgstr "默认" msgstr "默认"
#: assets/models/cluster.py:36 assets/models/label.py:14 #: assets/models/cluster.py:36 assets/models/label.py:14
#: users/models/user.py:595 #: users/models/user.py:600
msgid "System" msgid "System"
msgstr "系统" msgstr "系统"
@ -1323,7 +1326,7 @@ msgstr "默认资产组"
#: tickets/models/ticket.py:128 tickets/templates/tickets/ticket_detail.html:32 #: tickets/models/ticket.py:128 tickets/templates/tickets/ticket_detail.html:32
#: tickets/templates/tickets/ticket_list.html:34 #: tickets/templates/tickets/ticket_list.html:34
#: tickets/templates/tickets/ticket_list.html:103 users/forms/group.py:15 #: tickets/templates/tickets/ticket_list.html:103 users/forms/group.py:15
#: users/models/user.py:143 users/models/user.py:159 users/models/user.py:583 #: users/models/user.py:143 users/models/user.py:159 users/models/user.py:588
#: users/serializers/group.py:20 #: users/serializers/group.py:20
#: users/templates/users/user_asset_permission.html:38 #: users/templates/users/user_asset_permission.html:38
#: users/templates/users/user_asset_permission.html:64 #: users/templates/users/user_asset_permission.html:64
@ -1396,7 +1399,7 @@ msgstr "手动登录"
#: assets/views/platform.py:58 assets/views/platform.py:74 #: assets/views/platform.py:58 assets/views/platform.py:74
#: assets/views/system_user.py:30 assets/views/system_user.py:47 #: assets/views/system_user.py:30 assets/views/system_user.py:47
#: assets/views/system_user.py:64 assets/views/system_user.py:80 #: assets/views/system_user.py:64 assets/views/system_user.py:80
#: templates/_nav.html:39 xpack/plugins/change_auth_plan/models.py:52 #: templates/_nav.html:39 xpack/plugins/change_auth_plan/models.py:50
msgid "Assets" msgid "Assets"
msgstr "资产管理" msgstr "资产管理"
@ -1512,7 +1515,7 @@ msgstr "组织名称"
msgid "Connectivity" msgid "Connectivity"
msgstr "连接" msgstr "连接"
#: assets/serializers/asset_user.py:45 #: assets/serializers/asset_user.py:44
#: assets/templates/assets/_node_detail_modal.html:18 #: assets/templates/assets/_node_detail_modal.html:18
#: audits/templates/audits/login_log_list.html:56 #: audits/templates/audits/login_log_list.html:56
#: authentication/templates/authentication/_access_key_modal.html:30 #: authentication/templates/authentication/_access_key_modal.html:30
@ -1525,11 +1528,11 @@ msgstr "连接"
msgid "ID" msgid "ID"
msgstr "ID" msgstr "ID"
#: assets/serializers/asset_user.py:49 #: assets/serializers/asset_user.py:48
msgid "Backend" msgid "Backend"
msgstr "后端" msgstr "后端"
#: assets/serializers/asset_user.py:76 users/forms/profile.py:148 #: assets/serializers/asset_user.py:75 users/forms/profile.py:148
#: users/models/user.py:470 users/templates/users/first_login.html:42 #: users/models/user.py:470 users/templates/users/first_login.html:42
#: users/templates/users/user_password_update.html:49 #: users/templates/users/user_password_update.html:49
#: users/templates/users/user_profile.html:69 #: users/templates/users/user_profile.html:69
@ -1724,7 +1727,7 @@ msgstr "资产列表"
#: ops/templates/ops/command_execution_create.html:112 #: ops/templates/ops/command_execution_create.html:112
#: settings/templates/settings/_ldap_list_users_modal.html:41 #: settings/templates/settings/_ldap_list_users_modal.html:41
#: users/templates/users/_granted_assets.html:7 #: users/templates/users/_granted_assets.html:7
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:62 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:65
msgid "Loading" msgid "Loading"
msgstr "加载中" msgstr "加载中"
@ -1884,7 +1887,7 @@ msgstr "自动生成密钥"
#: perms/templates/perms/remote_app_permission_create_update.html:51 #: perms/templates/perms/remote_app_permission_create_update.html:51
#: terminal/templates/terminal/terminal_update.html:38 #: terminal/templates/terminal/terminal_update.html:38
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:61 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:61
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:44 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:47
#: xpack/plugins/gathered_user/templates/gathered_user/task_create_update.html:35 #: xpack/plugins/gathered_user/templates/gathered_user/task_create_update.html:35
msgid "Other" msgid "Other"
msgstr "其它" msgstr "其它"
@ -1953,7 +1956,7 @@ msgstr "选择节点"
#: users/templates/users/user_list.html:184 #: users/templates/users/user_list.html:184
#: users/templates/users/user_password_verify.html:20 #: users/templates/users/user_password_verify.html:20
#: xpack/plugins/cloud/templates/cloud/account_create_update.html:30 #: xpack/plugins/cloud/templates/cloud/account_create_update.html:30
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:50 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:53
#: xpack/plugins/gathered_user/templates/gathered_user/task_create_update.html:41 #: xpack/plugins/gathered_user/templates/gathered_user/task_create_update.html:41
#: xpack/plugins/interface/templates/interface/interface.html:103 #: xpack/plugins/interface/templates/interface/interface.html:103
#: xpack/plugins/orgs/templates/orgs/org_create_update.html:30 #: xpack/plugins/orgs/templates/orgs/org_create_update.html:30
@ -1993,7 +1996,7 @@ msgstr "资产用户"
#: users/templates/users/user_detail.html:126 #: users/templates/users/user_detail.html:126
#: users/templates/users/user_profile.html:150 #: users/templates/users/user_profile.html:150
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:126 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:126
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:129 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:139
#: xpack/plugins/license/templates/license/license_detail.html:80 #: xpack/plugins/license/templates/license/license_detail.html:80
msgid "Quick modify" msgid "Quick modify"
msgstr "快速修改" msgstr "快速修改"
@ -2526,7 +2529,7 @@ msgstr "启用"
msgid "-" msgid "-"
msgstr "" msgstr ""
#: audits/models.py:78 xpack/plugins/cloud/models.py:201 #: audits/models.py:78 xpack/plugins/cloud/models.py:204
msgid "Failed" msgid "Failed"
msgstr "失败" msgstr "失败"
@ -2557,9 +2560,9 @@ msgid "MFA"
msgstr "多因子认证" msgstr "多因子认证"
#: audits/models.py:87 audits/templates/audits/login_log_list.html:63 #: audits/models.py:87 audits/templates/audits/login_log_list.html:63
#: xpack/plugins/change_auth_plan/models.py:287 #: xpack/plugins/change_auth_plan/models.py:286
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:15 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:15
#: xpack/plugins/cloud/models.py:214 #: xpack/plugins/cloud/models.py:217
msgid "Reason" msgid "Reason"
msgstr "原因" msgstr "原因"
@ -2567,7 +2570,7 @@ msgstr "原因"
#: tickets/templates/tickets/ticket_detail.html:34 #: tickets/templates/tickets/ticket_detail.html:34
#: tickets/templates/tickets/ticket_list.html:36 #: tickets/templates/tickets/ticket_list.html:36
#: tickets/templates/tickets/ticket_list.html:104 #: tickets/templates/tickets/ticket_list.html:104
#: xpack/plugins/cloud/models.py:211 xpack/plugins/cloud/models.py:269 #: xpack/plugins/cloud/models.py:214 xpack/plugins/cloud/models.py:272
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:50 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:50
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:48 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:48
msgid "Status" msgid "Status"
@ -2587,8 +2590,8 @@ msgstr "登录日期"
#: perms/templates/perms/remote_app_permission_detail.html:73 #: perms/templates/perms/remote_app_permission_detail.html:73
#: terminal/models.py:199 terminal/templates/terminal/session_detail.html:72 #: terminal/models.py:199 terminal/templates/terminal/session_detail.html:72
#: terminal/templates/terminal/session_list.html:32 #: terminal/templates/terminal/session_list.html:32
#: xpack/plugins/change_auth_plan/models.py:169 #: xpack/plugins/change_auth_plan/models.py:167
#: xpack/plugins/change_auth_plan/models.py:291 #: xpack/plugins/change_auth_plan/models.py:290
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:59 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:59
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:17 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:17
#: xpack/plugins/gathered_user/models.py:76 #: xpack/plugins/gathered_user/models.py:76
@ -3003,7 +3006,7 @@ msgstr "字段必须唯一"
msgid "<h1>Flow service unavailable, check it</h1>" msgid "<h1>Flow service unavailable, check it</h1>"
msgstr "" msgstr ""
#: jumpserver/views/index.py:244 templates/_nav.html:7 #: jumpserver/views/index.py:257 templates/_nav.html:7
msgid "Dashboard" msgid "Dashboard"
msgstr "仪表盘" msgstr "仪表盘"
@ -3040,13 +3043,13 @@ msgstr "没有该主机 {} 权限"
#: ops/mixin.py:29 ops/mixin.py:92 ops/mixin.py:162 #: ops/mixin.py:29 ops/mixin.py:92 ops/mixin.py:162
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:98 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:98
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:88 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:98
msgid "Cycle perform" msgid "Cycle perform"
msgstr "周期执行" msgstr "周期执行"
#: ops/mixin.py:33 ops/mixin.py:90 ops/mixin.py:111 ops/mixin.py:150 #: ops/mixin.py:33 ops/mixin.py:90 ops/mixin.py:111 ops/mixin.py:150
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:90 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:90
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:80 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:90
msgid "Regularly perform" msgid "Regularly perform"
msgstr "定期执行" msgstr "定期执行"
@ -3054,8 +3057,8 @@ msgstr "定期执行"
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:54 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:54
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:79 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:79
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:17 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:17
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:37 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:40
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:69 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:79
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:16 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:16
#: xpack/plugins/gathered_user/templates/gathered_user/task_create_update.html:28 #: xpack/plugins/gathered_user/templates/gathered_user/task_create_update.html:28
msgid "Periodic perform" msgid "Periodic perform"
@ -3138,8 +3141,8 @@ msgstr "完成时间"
#: ops/models/adhoc.py:238 ops/templates/ops/adhoc_history.html:55 #: ops/models/adhoc.py:238 ops/templates/ops/adhoc_history.html:55
#: ops/templates/ops/task_history.html:61 ops/templates/ops/task_list.html:16 #: ops/templates/ops/task_history.html:61 ops/templates/ops/task_list.html:16
#: xpack/plugins/change_auth_plan/models.py:172 #: xpack/plugins/change_auth_plan/models.py:170
#: xpack/plugins/change_auth_plan/models.py:294 #: xpack/plugins/change_auth_plan/models.py:293
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:58 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:58
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:16 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:16
#: xpack/plugins/gathered_user/models.py:79 #: xpack/plugins/gathered_user/models.py:79
@ -3166,17 +3169,17 @@ msgstr "结果"
msgid "Adhoc result summary" msgid "Adhoc result summary"
msgstr "汇总" msgstr "汇总"
#: ops/models/adhoc.py:282 xpack/plugins/change_auth_plan/utils.py:89 #: ops/models/adhoc.py:282 xpack/plugins/change_auth_plan/utils.py:137
msgid "{} Start task: {}" msgid "{} Start task: {}"
msgstr "{} 任务开始: {}" msgstr "{} 任务开始: {}"
#: ops/models/adhoc.py:291 xpack/plugins/change_auth_plan/utils.py:101 #: ops/models/adhoc.py:291 xpack/plugins/change_auth_plan/utils.py:149
msgid "{} Task finish" msgid "{} Task finish"
msgstr "{} 任务结束" msgstr "{} 任务结束"
#: ops/models/command.py:24 #: ops/models/command.py:24
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:56 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:56
#: xpack/plugins/cloud/models.py:209 #: xpack/plugins/cloud/models.py:212
msgid "Result" msgid "Result"
msgstr "结果" msgstr "结果"
@ -3354,7 +3357,7 @@ msgid "Pending"
msgstr "等待" msgstr "等待"
#: ops/templates/ops/command_execution_list.html:70 #: ops/templates/ops/command_execution_list.html:70
#: xpack/plugins/change_auth_plan/models.py:259 #: xpack/plugins/change_auth_plan/models.py:257
msgid "Finished" msgid "Finished"
msgstr "结束" msgstr "结束"
@ -3394,7 +3397,7 @@ msgstr "内容"
#: ops/templates/ops/task_list.html:73 #: ops/templates/ops/task_list.html:73
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:135 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:135
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:54 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:54
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:138 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:148
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:58 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:58
#: xpack/plugins/gathered_user/templates/gathered_user/task_list.html:44 #: xpack/plugins/gathered_user/templates/gathered_user/task_list.html:44
msgid "Run" msgid "Run"
@ -3579,6 +3582,7 @@ msgid "Add node to this permission"
msgstr "添加节点" msgstr "添加节点"
#: perms/templates/perms/asset_permission_asset.html:105 #: perms/templates/perms/asset_permission_asset.html:105
#: terminal/templates/terminal/session_list.html:149
#: users/templates/users/user_detail.html:226 #: users/templates/users/user_detail.html:226
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:101 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_asset_list.html:101
msgid "Join" msgid "Join"
@ -4252,8 +4256,8 @@ msgid "The port is not the port of the LDAP service: {}"
msgstr "端口不是LDAP服务端口: {}" msgstr "端口不是LDAP服务端口: {}"
#: settings/utils/ldap.py:393 #: settings/utils/ldap.py:393
msgid "Please enter the certificate: {}" msgid "Please add certificate: {}"
msgstr "" msgstr "请添加证书"
#: settings/utils/ldap.py:395 settings/utils/ldap.py:422 #: settings/utils/ldap.py:395 settings/utils/ldap.py:422
#: settings/utils/ldap.py:452 settings/utils/ldap.py:480 #: settings/utils/ldap.py:452 settings/utils/ldap.py:480
@ -4761,6 +4765,22 @@ msgstr "月未登录主机"
msgid "Filters" msgid "Filters"
msgstr "过滤" msgstr "过滤"
#: terminal/api/session.py:142
msgid "Session does not exist: {}"
msgstr "会话不存在: {}"
#: terminal/api/session.py:145
msgid "Session is finished or the protocol not supported"
msgstr "会话已经完成或协议不支持"
#: terminal/api/session.py:150
msgid "User does not exist: {}"
msgstr "用户不存在: {}"
#: terminal/api/session.py:154
msgid "User does not have permission"
msgstr "用户没有权限"
#: terminal/api/storage.py:24 #: terminal/api/storage.py:24
msgid "Deleting the default storage is not allowed" msgid "Deleting the default storage is not allowed"
msgstr "不允许删除默认存储配置" msgstr "不允许删除默认存储配置"
@ -4779,13 +4799,13 @@ msgstr "测试失败: 账户无效"
#: terminal/backends/command/models.py:14 #: terminal/backends/command/models.py:14
#: terminal/templates/terminal/command_list.html:110 #: terminal/templates/terminal/command_list.html:110
#: terminal/templates/terminal/command_list.html:194 #: terminal/templates/terminal/command_list.html:205
msgid "Ordinary" msgid "Ordinary"
msgstr "普通" msgstr "普通"
#: terminal/backends/command/models.py:15 #: terminal/backends/command/models.py:15
#: terminal/templates/terminal/command_list.html:111 #: terminal/templates/terminal/command_list.html:111
#: terminal/templates/terminal/command_list.html:191 #: terminal/templates/terminal/command_list.html:202
msgid "Dangerous" msgid "Dangerous"
msgstr "危险" msgstr "危险"
@ -4860,9 +4880,9 @@ msgid ""
" " " "
msgstr "" msgstr ""
#: terminal/forms/storage.py:136 xpack/plugins/cloud/models.py:263 #: terminal/forms/storage.py:136 xpack/plugins/cloud/models.py:266
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:29 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:29
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:106 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:112
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:46 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:46
msgid "Region" msgid "Region"
msgstr "地域" msgstr "地域"
@ -4953,7 +4973,7 @@ msgstr "回放"
msgid "Date end" msgid "Date end"
msgstr "结束日期" msgstr "结束日期"
#: terminal/models.py:335 #: terminal/models.py:342
msgid "Args" msgid "Args"
msgstr "参数" msgstr "参数"
@ -4961,7 +4981,7 @@ msgstr "参数"
msgid "Export command" msgid "Export command"
msgstr "导出命令" msgstr "导出命令"
#: terminal/templates/terminal/command_list.html:199 #: terminal/templates/terminal/command_list.html:210
msgid "Goto" msgid "Goto"
msgstr "转到" msgstr "转到"
@ -5040,11 +5060,11 @@ msgstr "终断任务已发送,请等待"
msgid "Terminate" msgid "Terminate"
msgstr "终断" msgstr "终断"
#: terminal/templates/terminal/session_list.html:174 #: terminal/templates/terminal/session_list.html:179
msgid "Finish session success" msgid "Finish session success"
msgstr "标记会话完成成功" msgstr "标记会话完成成功"
#: terminal/templates/terminal/session_list.html:242 #: terminal/templates/terminal/session_list.html:247
msgid "Visit doc for replay play offline: " msgid "Visit doc for replay play offline: "
msgstr "访问文档查看如何离线播放: " msgstr "访问文档查看如何离线播放: "
@ -5276,7 +5296,7 @@ msgstr "工单列表"
msgid "Ticket detail" msgid "Ticket detail"
msgstr "工单详情" msgstr "工单详情"
#: users/api/user.py:177 #: users/api/user.py:116
msgid "Could not reset self otp, use profile reset instead" msgid "Could not reset self otp, use profile reset instead"
msgstr "不能在该页面重置多因子认证, 请去个人信息页面重置" msgstr "不能在该页面重置多因子认证, 请去个人信息页面重置"
@ -5350,7 +5370,7 @@ msgid "Public key should not be the same as your old one."
msgstr "不能和原来的密钥相同" msgstr "不能和原来的密钥相同"
#: users/forms/profile.py:137 users/forms/user.py:90 #: users/forms/profile.py:137 users/forms/user.py:90
#: users/serializers/user.py:131 #: users/serializers/user.py:138
msgid "Not a valid ssh public key" msgid "Not a valid ssh public key"
msgstr "ssh密钥不合法" msgstr "ssh密钥不合法"
@ -5390,7 +5410,7 @@ msgstr "生成重置密码链接,通过邮件发送给用户"
msgid "Set password" msgid "Set password"
msgstr "设置密码" msgstr "设置密码"
#: users/forms/user.py:132 xpack/plugins/change_auth_plan/models.py:61 #: users/forms/user.py:132 xpack/plugins/change_auth_plan/models.py:59
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:45 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_create_update.html:45
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:67 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:67
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:57 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:57
@ -5398,7 +5418,7 @@ msgstr "设置密码"
msgid "Password strategy" msgid "Password strategy"
msgstr "密码策略" msgstr "密码策略"
#: users/models/user.py:142 users/models/user.py:591 #: users/models/user.py:142 users/models/user.py:596
msgid "Administrator" msgid "Administrator"
msgstr "管理员" msgstr "管理员"
@ -5435,7 +5455,7 @@ msgstr "微信"
msgid "Date password last updated" msgid "Date password last updated"
msgstr "最后更新密码日期" msgstr "最后更新密码日期"
#: users/models/user.py:594 #: users/models/user.py:599
msgid "Administrator is the super user of system" msgid "Administrator is the super user of system"
msgstr "Administrator是初始的超级管理员" msgstr "Administrator是初始的超级管理员"
@ -5443,39 +5463,39 @@ msgstr "Administrator是初始的超级管理员"
msgid "Auditors cannot be join in the user group" msgid "Auditors cannot be join in the user group"
msgstr "审计员不能被加入到用户组" msgstr "审计员不能被加入到用户组"
#: users/serializers/user.py:35 #: users/serializers/user.py:42
msgid "Is first login" msgid "Is first login"
msgstr "首次登录" msgstr "首次登录"
#: users/serializers/user.py:36 #: users/serializers/user.py:43
msgid "Is valid" msgid "Is valid"
msgstr "账户是否有效" msgstr "账户是否有效"
#: users/serializers/user.py:37 #: users/serializers/user.py:44
msgid "Is expired" msgid "Is expired"
msgstr " 是否过期" msgstr " 是否过期"
#: users/serializers/user.py:38 #: users/serializers/user.py:45
msgid "Avatar url" msgid "Avatar url"
msgstr "头像路径" msgstr "头像路径"
#: users/serializers/user.py:46 #: users/serializers/user.py:53
msgid "Role limit to {}" msgid "Role limit to {}"
msgstr "角色只能为 {}" msgstr "角色只能为 {}"
#: users/serializers/user.py:58 #: users/serializers/user.py:65
msgid "Password does not match security rules" msgid "Password does not match security rules"
msgstr "密码不满足安全规则" msgstr "密码不满足安全规则"
#: users/serializers/user.py:116 #: users/serializers/user.py:123
msgid "Groups name" msgid "Groups name"
msgstr "用户组名" msgstr "用户组名"
#: users/serializers/user.py:117 #: users/serializers/user.py:124
msgid "Source name" msgid "Source name"
msgstr "用户来源名" msgstr "用户来源名"
#: users/serializers/user.py:118 #: users/serializers/user.py:125
msgid "Role name" msgid "Role name"
msgstr "角色名" msgstr "角色名"
@ -6209,8 +6229,8 @@ msgstr ""
"用户不存在,则创建用户。" "用户不存在,则创建用户。"
#: xpack/plugins/change_auth_plan/meta.py:9 #: xpack/plugins/change_auth_plan/meta.py:9
#: xpack/plugins/change_auth_plan/models.py:89 #: xpack/plugins/change_auth_plan/models.py:87
#: xpack/plugins/change_auth_plan/models.py:176 #: xpack/plugins/change_auth_plan/models.py:174
#: xpack/plugins/change_auth_plan/views.py:33 #: xpack/plugins/change_auth_plan/views.py:33
#: xpack/plugins/change_auth_plan/views.py:50 #: xpack/plugins/change_auth_plan/views.py:50
#: xpack/plugins/change_auth_plan/views.py:74 #: xpack/plugins/change_auth_plan/views.py:74
@ -6221,64 +6241,60 @@ msgstr ""
msgid "Change auth plan" msgid "Change auth plan"
msgstr "改密计划" msgstr "改密计划"
#: xpack/plugins/change_auth_plan/models.py:41 #: xpack/plugins/change_auth_plan/models.py:39
msgid "Custom password" msgid "Custom password"
msgstr "自定义密码" msgstr "自定义密码"
#: xpack/plugins/change_auth_plan/models.py:42 #: xpack/plugins/change_auth_plan/models.py:40
msgid "All assets use the same random password" msgid "All assets use the same random password"
msgstr "所有资产使用相同的随机密码" msgstr "所有资产使用相同的随机密码"
#: xpack/plugins/change_auth_plan/models.py:43 #: xpack/plugins/change_auth_plan/models.py:41
msgid "All assets use different random password" msgid "All assets use different random password"
msgstr "所有资产使用不同的随机密码" msgstr "所有资产使用不同的随机密码"
#: xpack/plugins/change_auth_plan/models.py:65 #: xpack/plugins/change_auth_plan/models.py:63
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:72 #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:72
msgid "Password rules" msgid "Password rules"
msgstr "密码规则" msgstr "密码规则"
#: xpack/plugins/change_auth_plan/models.py:180 #: xpack/plugins/change_auth_plan/models.py:178
msgid "Change auth plan snapshot" msgid "Change auth plan snapshot"
msgstr "改密计划快照" msgstr "改密计划快照"
#: xpack/plugins/change_auth_plan/models.py:195 #: xpack/plugins/change_auth_plan/models.py:193
#: xpack/plugins/change_auth_plan/models.py:281 #: xpack/plugins/change_auth_plan/models.py:279
msgid "Change auth plan execution" msgid "Change auth plan execution"
msgstr "改密计划执行" msgstr "改密计划执行"
#: xpack/plugins/change_auth_plan/models.py:254 #: xpack/plugins/change_auth_plan/models.py:252
msgid "Ready" msgid "Ready"
msgstr "" msgstr ""
#: xpack/plugins/change_auth_plan/models.py:255 #: xpack/plugins/change_auth_plan/models.py:253
msgid "check_condition" msgid "Preflight check"
msgstr "" msgstr ""
#: xpack/plugins/change_auth_plan/models.py:256 #: xpack/plugins/change_auth_plan/models.py:254
msgid "Change auth" msgid "Change auth"
msgstr "" msgstr ""
#: xpack/plugins/change_auth_plan/models.py:257 #: xpack/plugins/change_auth_plan/models.py:255
msgid "Verify auth" msgid "Verify auth"
msgstr "" msgstr ""
#: xpack/plugins/change_auth_plan/models.py:258 #: xpack/plugins/change_auth_plan/models.py:256
msgid "Save auth" msgid "Keep auth"
msgstr "" msgstr ""
#: xpack/plugins/change_auth_plan/models.py:284 #: xpack/plugins/change_auth_plan/models.py:283
msgid "Step" msgid "Step"
msgstr "步骤" msgstr "步骤"
#: xpack/plugins/change_auth_plan/models.py:301 #: xpack/plugins/change_auth_plan/models.py:300
msgid "Change auth plan task" msgid "Change auth plan task"
msgstr "改密计划任务" msgstr "改密计划任务"
#: xpack/plugins/change_auth_plan/serializers.py:58
msgid "* For security, do not change {}'s password"
msgstr "* 为了安全,不能修改 {} 的密码"
#: xpack/plugins/change_auth_plan/serializers.py:68 #: xpack/plugins/change_auth_plan/serializers.py:68
msgid "* Please enter custom password" msgid "* Please enter custom password"
msgstr "* 请输入自定义密码" msgstr "* 请输入自定义密码"
@ -6348,13 +6364,17 @@ msgstr "执行失败"
msgid "Create plan" msgid "Create plan"
msgstr "创建计划" msgstr "创建计划"
#: xpack/plugins/change_auth_plan/utils.py:262 #: xpack/plugins/change_auth_plan/utils.py:437
msgid "Failed to connect asset" msgid "Invalid/incorrect password"
msgstr "连接资产失败" msgstr "无效/错误 密码"
#: xpack/plugins/change_auth_plan/utils.py:264 #: xpack/plugins/change_auth_plan/utils.py:439
msgid "Incorrect password" msgid "Failed to connect to the host"
msgstr "密码错误" msgstr "连接主机失败"
#: xpack/plugins/change_auth_plan/utils.py:441
msgid "Data could not be sent to remote"
msgstr "无法将数据发送到远程"
#: xpack/plugins/change_auth_plan/views.py:34 #: xpack/plugins/change_auth_plan/views.py:34
msgid "Plan list" msgid "Plan list"
@ -6396,6 +6416,10 @@ msgstr "选择节点"
msgid "Select admins" msgid "Select admins"
msgstr "选择管理员" msgstr "选择管理员"
#: xpack/plugins/cloud/forms.py:85
msgid "Tips: The asset information is always covered"
msgstr ""
#: xpack/plugins/cloud/meta.py:9 xpack/plugins/cloud/views.py:27 #: xpack/plugins/cloud/meta.py:9 xpack/plugins/cloud/views.py:27
#: xpack/plugins/cloud/views.py:44 xpack/plugins/cloud/views.py:62 #: xpack/plugins/cloud/views.py:44 xpack/plugins/cloud/views.py:62
#: xpack/plugins/cloud/views.py:78 xpack/plugins/cloud/views.py:92 #: xpack/plugins/cloud/views.py:78 xpack/plugins/cloud/views.py:92
@ -6440,48 +6464,52 @@ msgstr "地域"
msgid "Instances" msgid "Instances"
msgstr "实例" msgstr "实例"
#: xpack/plugins/cloud/models.py:139 #: xpack/plugins/cloud/models.py:136
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:94 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:69
msgid "Covered always"
msgstr "总是覆盖"
#: xpack/plugins/cloud/models.py:142
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:104
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:17 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:17
msgid "Date last sync" msgid "Date last sync"
msgstr "最后同步日期" msgstr "最后同步日期"
#: xpack/plugins/cloud/models.py:150 xpack/plugins/cloud/models.py:207 #: xpack/plugins/cloud/models.py:153 xpack/plugins/cloud/models.py:210
msgid "Sync instance task" msgid "Sync instance task"
msgstr "同步实例任务" msgstr "同步实例任务"
#: xpack/plugins/cloud/models.py:202 #: xpack/plugins/cloud/models.py:205
msgid "Succeed" msgid "Succeed"
msgstr "成功" msgstr "成功"
#: xpack/plugins/cloud/models.py:217 xpack/plugins/cloud/models.py:272 #: xpack/plugins/cloud/models.py:220 xpack/plugins/cloud/models.py:275
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:51 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:51
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:49 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:49
msgid "Date sync" msgid "Date sync"
msgstr "同步日期" msgstr "同步日期"
#: xpack/plugins/cloud/models.py:245 #: xpack/plugins/cloud/models.py:248
msgid "Unsync" msgid "Unsync"
msgstr "未同步" msgstr "未同步"
#: xpack/plugins/cloud/models.py:246 xpack/plugins/cloud/models.py:247 #: xpack/plugins/cloud/models.py:249 xpack/plugins/cloud/models.py:250
msgid "Synced" msgid "Synced"
msgstr "已同步" msgstr "已同步"
#: xpack/plugins/cloud/models.py:248 #: xpack/plugins/cloud/models.py:251
msgid "Released" msgid "Released"
msgstr "已释放" msgstr "已释放"
#: xpack/plugins/cloud/models.py:253 #: xpack/plugins/cloud/models.py:256
msgid "Sync task" msgid "Sync task"
msgstr "同步任务" msgstr "同步任务"
#: xpack/plugins/cloud/models.py:257 #: xpack/plugins/cloud/models.py:260
msgid "Sync instance task history" msgid "Sync instance task history"
msgstr "同步实例任务历史" msgstr "同步实例任务历史"
#: xpack/plugins/cloud/models.py:260 #: xpack/plugins/cloud/models.py:263
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:114
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:45 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:45
msgid "Instance" msgid "Instance"
msgstr "实例" msgstr "实例"
@ -6560,7 +6588,7 @@ msgstr "创建账户"
msgid "Node & AdminUser" msgid "Node & AdminUser"
msgstr "节点 & 管理用户" msgstr "节点 & 管理用户"
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:63 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_create_update.html:66
msgid "Load failed" msgid "Load failed"
msgstr "加载失败" msgstr "加载失败"
@ -6585,11 +6613,11 @@ msgstr "同步历史列表"
msgid "Sync instance list" msgid "Sync instance list"
msgstr "同步实例列表" msgstr "同步实例列表"
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:135 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:145
msgid "Run task manually" msgid "Run task manually"
msgstr "手动执行任务" msgstr "手动执行任务"
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:178 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:188
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:102 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:102
msgid "Sync success" msgid "Sync success"
msgstr "同步成功" msgstr "同步成功"
@ -6626,7 +6654,7 @@ msgstr "执行次数"
msgid "Instance count" msgid "Instance count"
msgstr "实例个数" msgstr "实例个数"
#: xpack/plugins/cloud/utils.py:37 #: xpack/plugins/cloud/utils.py:38
msgid "Account unavailable" msgid "Account unavailable"
msgstr "账户无效" msgstr "账户无效"
@ -6920,6 +6948,9 @@ msgstr "密码匣子"
msgid "vault create" msgid "vault create"
msgstr "创建" msgstr "创建"
#~ msgid "* For security, do not change {}'s password"
#~ msgstr "* 为了安全,不能修改 {} 的密码"
#~ msgid "Assets is empty, please add the asset" #~ msgid "Assets is empty, please add the asset"
#~ msgstr "资产为空,请添加资产" #~ msgstr "资产为空,请添加资产"
@ -7294,9 +7325,6 @@ msgstr "创建"
#~ msgid "Loading..." #~ msgid "Loading..."
#~ msgstr "加载中..." #~ msgstr "加载中..."
#~ msgid "You do not have permission."
#~ msgstr "你没有权限"
#~ msgid "Interface" #~ msgid "Interface"
#~ msgstr "界面" #~ msgstr "界面"
@ -7321,9 +7349,6 @@ msgstr "创建"
#~ msgid "Reachable assets" #~ msgid "Reachable assets"
#~ msgstr "可连接资产" #~ msgstr "可连接资产"
#~ msgid "User does not exist"
#~ msgstr "用户不存在"
#~ msgid "Restore default successfully" #~ msgid "Restore default successfully"
#~ msgstr "恢复默认成功!" #~ msgstr "恢复默认成功!"

View File

@ -11,10 +11,9 @@ from .models import Organization
def get_org_from_request(request): def get_org_from_request(request):
oid = request.session.get("oid") oid = request.META.get("HTTP_X_JMS_ORG")
if not oid: if not oid:
oid = request.META.get("HTTP_X_JMS_ORG") oid = request.session.get("oid")
request_params_oid = request.GET.get("oid") request_params_oid = request.GET.get("oid")
if request_params_oid: if request_params_oid:
oid = request.GET.get("oid") oid = request.GET.get("oid")

View File

@ -390,7 +390,7 @@ class LDAPTestUtil(object):
except LDAPSessionTerminatedByServerError as e: except LDAPSessionTerminatedByServerError as e:
error = _('The port is not the port of the LDAP service: {}'.format(e)) error = _('The port is not the port of the LDAP service: {}'.format(e))
except LDAPSocketReceiveError as e: except LDAPSocketReceiveError as e:
error = _('Please enter the certificate: {}'.format(e)) error = _('Please add certificate: {}'.format(e))
except Exception as e: except Exception as e:
error = _('Unknown error: {}'.format(e)) error = _('Unknown error: {}'.format(e))
else: else:

View File

@ -1256,7 +1256,8 @@ function toSafeDateISOStr(s) {
function toSafeLocalDateStr(d) { function toSafeLocalDateStr(d) {
var date = safeDate(d); var date = safeDate(d);
var date_s = date.toLocaleString(getUserLang(), {hour12: false}); // var date_s = date.toLocaleString(getUserLang(), {hour12: false});
var date_s = date.toLocaleString(getUserLang(), {hourCycle: "h23"});
return date_s.split("/").join('-') return date_s.split("/").join('-')
} }

View File

@ -7,7 +7,7 @@
<script src="{% static "js/plugins/toastr/toastr.min.js" %}"></script> <script src="{% static "js/plugins/toastr/toastr.min.js" %}"></script>
<script src="{% static "js/inspinia.js" %}"></script> <script src="{% static "js/inspinia.js" %}"></script>
<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script> <script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
<script src="{% static "js/jumpserver.js" %}?v=7"></script> <script src="{% static "js/jumpserver.js" %}?v=8"></script>
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script> <script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
<script src="{% static 'js/plugins/select2/i18n/zh-CN.js' %}"></script> <script src="{% static 'js/plugins/select2/i18n/zh-CN.js' %}"></script>
<script> <script>

View File

@ -1,22 +1,27 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
from django.utils.translation import ugettext as _
from django.shortcuts import get_object_or_404, reverse from django.shortcuts import get_object_or_404, reverse
from django.core.files.storage import default_storage from django.core.files.storage import default_storage
from rest_framework import viewsets from rest_framework import viewsets, views
from rest_framework.response import Response from rest_framework.response import Response
from common.utils import is_uuid, get_logger from common.utils import is_uuid, get_logger, get_object_or_none
from common.mixins.api import AsyncApiMixin from common.mixins.api import AsyncApiMixin
from common.permissions import IsOrgAdminOrAppUser, IsOrgAuditor from common.permissions import IsOrgAdminOrAppUser, IsOrgAuditor, IsAppUser
from common.drf.filters import DatetimeRangeFilter from common.drf.filters import DatetimeRangeFilter
from orgs.mixins.api import OrgBulkModelViewSet from orgs.mixins.api import OrgBulkModelViewSet
from orgs.utils import tmp_to_root_org, tmp_to_org
from users.models import User
from ..utils import find_session_replay_local, download_session_replay from ..utils import find_session_replay_local, download_session_replay
from ..hands import SystemUser from ..hands import SystemUser
from ..models import Session from ..models import Session
from .. import serializers from .. import serializers
__all__ = ['SessionViewSet', 'SessionReplayViewSet',] __all__ = [
'SessionViewSet', 'SessionReplayViewSet', 'SessionJoinValidateAPI'
]
logger = get_logger(__name__) logger = get_logger(__name__)
@ -117,3 +122,36 @@ class SessionReplayViewSet(AsyncApiMixin, viewsets.ViewSet):
return Response({"error": url}) return Response({"error": url})
data = self.get_replay_data(session, url) data = self.get_replay_data(session, url)
return Response(data) return Response(data)
class SessionJoinValidateAPI(views.APIView):
permission_classes = (IsAppUser, )
serializer_class = serializers.SessionJoinValidateSerializer
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data)
if not serializer.is_valid():
msg = str(serializer.errors)
return Response({'ok': False, 'msg': msg}, status=401)
user_id = serializer.validated_data['user_id']
session_id = serializer.validated_data['session_id']
with tmp_to_root_org():
session = get_object_or_none(Session, pk=session_id)
if not session:
msg = _('Session does not exist: {}'.format(session_id))
return Response({'ok': False, 'msg': msg}, status=401)
if not session.can_join():
msg = _('Session is finished or the protocol not supported')
return Response({'ok': False, 'msg': msg}, status=401)
user = get_object_or_none(User, pk=user_id)
if not user:
msg = _('User does not exist: {}'.format(user_id))
return Response({'ok': False, 'msg': msg}, status=401)
with tmp_to_org(session.org):
if not user.admin_or_audit_orgs:
msg = _('User does not have permission')
return Response({'ok': False, 'msg': msg}, status=401)
return Response({'ok': True, 'msg': ''}, status=200)

View File

@ -243,6 +243,13 @@ class Session(OrgModelMixin):
return True return True
return False return False
def can_join(self):
if self.is_finished:
return False
if self.protocol not in ['ssh', 'telnet', 'mysql']:
return False
return True
def save_to_storage(self, f): def save_to_storage(self, f):
local_path = self.get_local_path() local_path = self.get_local_path()
try: try:

View File

@ -6,7 +6,7 @@ from ..models import Session
__all__ = [ __all__ = [
'SessionSerializer', 'SessionDisplaySerializer', 'SessionSerializer', 'SessionDisplaySerializer',
'ReplaySerializer', 'ReplaySerializer', 'SessionJoinValidateSerializer',
] ]
@ -21,7 +21,7 @@ class SessionSerializer(BulkOrgResourceModelSerializer):
"user_id", "asset_id", "system_user_id", "user_id", "asset_id", "system_user_id",
"login_from", "login_from_display", "remote_addr", "login_from", "login_from_display", "remote_addr",
"is_success", "is_finished", "has_replay", "can_replay", "is_success", "is_finished", "has_replay", "can_replay",
"protocol", "date_start", "date_end", "can_join", "protocol", "date_start", "date_end",
"terminal", "terminal",
] ]
@ -35,3 +35,8 @@ class SessionDisplaySerializer(SessionSerializer):
class ReplaySerializer(serializers.Serializer): class ReplaySerializer(serializers.Serializer):
file = serializers.FileField(allow_empty_file=True) file = serializers.FileField(allow_empty_file=True)
class SessionJoinValidateSerializer(serializers.Serializer):
user_id = serializers.UUIDField()
session_id = serializers.UUIDField()

View File

@ -117,6 +117,17 @@ $(document).ready(function () {
.on('click', '#btn_bulk_update', function(){ .on('click', '#btn_bulk_update', function(){
// var action = $('#slct_bulk_update').val(); // var action = $('#slct_bulk_update').val();
var params = getUrlParams(table.ajax.url()); var params = getUrlParams(table.ajax.url());
var searchParams = '';
var searchValue = $('input[type=search]').val();
var searchMap = parseTableFilter(searchValue);
if (Object.keys(searchMap).length === 0) {
searchParams = searchValue;
} else {
$.each(searchMap, function (k, v) {
searchParams += k + '=' + v + '&'
})
}
params += '&' + searchParams;
var exportPath = "{% url 'api-terminal:command-export' %}"; var exportPath = "{% url 'api-terminal:command-export' %}";
var url = exportPath + "?" + params; var url = exportPath + "?" + params;

View File

@ -146,10 +146,15 @@ function initTable() {
.replace("sessionID", cellData) .replace("sessionID", cellData)
.replace("terminalID", rowData.terminal) .replace("terminalID", rowData.terminal)
} }
var joinBtn = ' <a disabled data-session="sessionID" class="btn btn-xs btn-info btn-join" >{% trans "Join" %}</a>';
joinBtn = joinBtn.replace("sessionID", rowData.id);
if (rowData.can_join){
joinBtn = joinBtn.replace("disabled", "")
}
if (rowData.is_finished) { if (rowData.is_finished) {
btnGroup += replayBtn + downloadBtn btnGroup += replayBtn + downloadBtn
} else { } else {
btnGroup += termBtn; btnGroup += termBtn + joinBtn;
} }
$(td).html(btnGroup); $(td).html(btnGroup);
}}, }},
@ -246,6 +251,11 @@ $(document).ready(function() {
} }
window.open(downloadUrl) window.open(downloadUrl)
}) })
.on('click', '.btn-join', function () {
var sessionID = $(this).data("session");
var joinUrl = "/luna/join/?shareroom=" + sessionID;
window.open(joinUrl, "height=600, width=800, top=400, left=400, toolbar=no, menubar=no, scrollbars=no, location=no, status=no");
})
.on("click", '#session_table_filter input', function (e) { .on("click", '#session_table_filter input', function (e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();

View File

@ -22,6 +22,7 @@ router.register(r'replay-storages', api.ReplayStorageViewSet, 'replay-storage')
router.register(r'command-storages', api.CommandStorageViewSet, 'command-storage') router.register(r'command-storages', api.CommandStorageViewSet, 'command-storage')
urlpatterns = [ urlpatterns = [
path('sessions/join/validate/', api.SessionJoinValidateAPI.as_view(), name='join-session-validate'),
path('sessions/<uuid:pk>/replay/', path('sessions/<uuid:pk>/replay/',
api.SessionReplayViewSet.as_view({'get': 'retrieve', 'post': 'create'}), api.SessionReplayViewSet.as_view({'get': 'retrieve', 'post': 'create'}),
name='session-replay'), name='session-replay'),

View File

@ -3,4 +3,5 @@
from .user import * from .user import *
from .group import * from .group import *
from .profile import *
from .relation import * from .relation import *

9
apps/users/api/mixins.py Normal file
View File

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
#
from .. import utils
class UserQuerysetMixin:
def get_queryset(self):
queryset = utils.get_current_org_members()
return queryset

68
apps/users/api/profile.py Normal file
View File

@ -0,0 +1,68 @@
# ~*~ coding: utf-8 ~*~
import uuid
from rest_framework import generics
from rest_framework.permissions import IsAuthenticated
from common.permissions import (
IsCurrentUserOrReadOnly
)
from .. import serializers
from ..models import User
from .mixins import UserQuerysetMixin
__all__ = [
'UserResetPasswordApi', 'UserResetPKApi',
'UserProfileApi', 'UserUpdatePKApi',
]
class UserResetPasswordApi(UserQuerysetMixin, generics.UpdateAPIView):
queryset = User.objects.all()
serializer_class = serializers.UserSerializer
permission_classes = (IsAuthenticated,)
def perform_update(self, serializer):
# Note: we are not updating the user object here.
# We just do the reset-password stuff.
from ..utils import send_reset_password_mail
user = self.get_object()
user.password_raw = str(uuid.uuid4())
user.save()
send_reset_password_mail(user)
class UserResetPKApi(UserQuerysetMixin, generics.UpdateAPIView):
serializer_class = serializers.UserSerializer
permission_classes = (IsAuthenticated,)
def perform_update(self, serializer):
from ..utils import send_reset_ssh_key_mail
user = self.get_object()
user.public_key = None
user.save()
send_reset_ssh_key_mail(user)
# 废弃
class UserUpdatePKApi(UserQuerysetMixin, generics.UpdateAPIView):
serializer_class = serializers.UserPKUpdateSerializer
permission_classes = (IsCurrentUserOrReadOnly,)
def perform_update(self, serializer):
user = self.get_object()
user.public_key = serializer.validated_data['public_key']
user.save()
class UserProfileApi(generics.RetrieveAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = serializers.UserSerializer
def get_object(self):
return self.request.user
def retrieve(self, request, *args, **kwargs):
age = request.session.get_expiry_age()
request.session.set_expiry(age)
return super().retrieve(request, *args, **kwargs)

View File

@ -1,23 +1,20 @@
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
import uuid
from django.core.cache import cache from django.core.cache import cache
from django.contrib.auth import logout
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from rest_framework import generics from rest_framework import generics
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework_bulk import BulkModelViewSet from rest_framework_bulk import BulkModelViewSet
from common.permissions import ( from common.permissions import (
IsOrgAdmin, IsCurrentUserOrReadOnly, IsOrgAdminOrAppUser, IsOrgAdmin, IsOrgAdminOrAppUser,
CanUpdateDeleteUser, IsSuperUser CanUpdateDeleteUser, IsSuperUser
) )
from common.mixins import CommonApiMixin from common.mixins import CommonApiMixin
from common.utils import get_logger from common.utils import get_logger
from orgs.utils import current_org from orgs.utils import current_org
from .. import serializers, utils from .. import serializers
from .mixins import UserQuerysetMixin
from ..models import User from ..models import User
from ..signals import post_user_create from ..signals import post_user_create
@ -25,17 +22,10 @@ from ..signals import post_user_create
logger = get_logger(__name__) logger = get_logger(__name__)
__all__ = [ __all__ = [
'UserViewSet', 'UserChangePasswordApi', 'UserViewSet', 'UserChangePasswordApi',
'UserResetPasswordApi', 'UserResetPKApi', 'UserUpdatePKApi', 'UserUnblockPKApi', 'UserResetOTPApi',
'UserUnblockPKApi', 'UserProfileApi', 'UserResetOTPApi',
] ]
class UserQuerysetMixin:
def get_queryset(self):
queryset = utils.get_current_org_members()
return queryset
class UserViewSet(CommonApiMixin, UserQuerysetMixin, BulkModelViewSet): class UserViewSet(CommonApiMixin, UserQuerysetMixin, BulkModelViewSet):
filter_fields = ('username', 'email', 'name', 'id') filter_fields = ('username', 'email', 'name', 'id')
search_fields = filter_fields search_fields = filter_fields
@ -101,44 +91,6 @@ class UserChangePasswordApi(UserQuerysetMixin, generics.RetrieveUpdateAPIView):
user.save() user.save()
class UserResetPasswordApi(UserQuerysetMixin, generics.UpdateAPIView):
queryset = User.objects.all()
serializer_class = serializers.UserSerializer
permission_classes = (IsAuthenticated,)
def perform_update(self, serializer):
# Note: we are not updating the user object here.
# We just do the reset-password stuff.
from ..utils import send_reset_password_mail
user = self.get_object()
user.password_raw = str(uuid.uuid4())
user.save()
send_reset_password_mail(user)
class UserResetPKApi(UserQuerysetMixin, generics.UpdateAPIView):
serializer_class = serializers.UserSerializer
permission_classes = (IsAuthenticated,)
def perform_update(self, serializer):
from ..utils import send_reset_ssh_key_mail
user = self.get_object()
user.public_key = None
user.save()
send_reset_ssh_key_mail(user)
# 废弃
class UserUpdatePKApi(UserQuerysetMixin, generics.UpdateAPIView):
serializer_class = serializers.UserPKUpdateSerializer
permission_classes = (IsCurrentUserOrReadOnly,)
def perform_update(self, serializer):
user = self.get_object()
user.public_key = serializer.validated_data['public_key']
user.save()
class UserUnblockPKApi(UserQuerysetMixin, generics.UpdateAPIView): class UserUnblockPKApi(UserQuerysetMixin, generics.UpdateAPIView):
permission_classes = (IsOrgAdmin,) permission_classes = (IsOrgAdmin,)
serializer_class = serializers.UserSerializer serializer_class = serializers.UserSerializer
@ -154,19 +106,6 @@ class UserUnblockPKApi(UserQuerysetMixin, generics.UpdateAPIView):
cache.delete(key_block) cache.delete(key_block)
class UserProfileApi(generics.RetrieveAPIView):
permission_classes = (IsAuthenticated,)
serializer_class = serializers.UserSerializer
def get_object(self):
return self.request.user
def retrieve(self, request, *args, **kwargs):
age = request.session.get_expiry_age()
request.session.set_expiry(age)
return super().retrieve(request, *args, **kwargs)
class UserResetOTPApi(UserQuerysetMixin, generics.RetrieveAPIView): class UserResetOTPApi(UserQuerysetMixin, generics.RetrieveAPIView):
permission_classes = (IsOrgAdmin,) permission_classes = (IsOrgAdmin,)
serializer_class = serializers.ResetOTPSerializer serializer_class = serializers.ResetOTPSerializer

View File

@ -563,6 +563,11 @@ class User(AuthMixin, TokenMixin, RoleMixin, MFAMixin, AbstractUser):
user_default = settings.STATIC_URL + "img/avatar/user.png" user_default = settings.STATIC_URL + "img/avatar/user.png"
return user_default return user_default
def admin_orgs(self):
from orgs.models import Organization
orgs = Organization.get_user_admin_or_audit_orgs(self)
return orgs
def avatar_url(self): def avatar_url(self):
admin_default = settings.STATIC_URL + "img/avatar/admin.png" admin_default = settings.STATIC_URL + "img/avatar/admin.png"
user_default = settings.STATIC_URL + "img/avatar/user.png" user_default = settings.STATIC_URL + "img/avatar/user.png"

View File

@ -17,7 +17,13 @@ __all__ = [
] ]
class UserOrgSerializer(serializers.Serializer):
id = serializers.CharField()
name = serializers.CharField()
class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer): class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
admin_orgs = UserOrgSerializer(many=True, read_only=True)
class Meta: class Meta:
model = User model = User
@ -27,7 +33,8 @@ class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
'groups', 'role', 'wechat', 'phone', 'mfa_level', 'groups', 'role', 'wechat', 'phone', 'mfa_level',
'comment', 'source', 'is_valid', 'is_expired', 'comment', 'source', 'is_valid', 'is_expired',
'is_active', 'created_by', 'is_first_login', 'is_active', 'created_by', 'is_first_login',
'date_password_last_updated', 'date_expired', 'avatar_url', 'date_password_last_updated', 'date_expired',
'avatar_url', 'admin_orgs',
] ]
extra_kwargs = { extra_kwargs = {
'password': {'write_only': True, 'required': False, 'allow_null': True, 'allow_blank': True}, 'password': {'write_only': True, 'required': False, 'allow_null': True, 'allow_blank': True},