mirror of https://github.com/jumpserver/jumpserver
commit
e83d676712
|
@ -156,10 +156,7 @@ class AccountBackupHandler:
|
|||
logger.info('步骤完成: 用时 {}s'.format(timedelta))
|
||||
return files
|
||||
|
||||
def send_backup_mail(self, files):
|
||||
recipients = self.execution.plan_snapshot.get('recipients')
|
||||
if not recipients:
|
||||
return
|
||||
def send_backup_mail(self, files, recipients):
|
||||
if not files:
|
||||
return
|
||||
recipients = User.objects.filter(id__in=list(recipients))
|
||||
|
@ -198,8 +195,16 @@ class AccountBackupHandler:
|
|||
is_success = False
|
||||
error = '-'
|
||||
try:
|
||||
recipients = self.execution.plan_snapshot.get('recipients')
|
||||
if not recipients:
|
||||
logger.info(
|
||||
'\n'
|
||||
'\033[32m>>> 该备份任务未分配收件人\033[0m'
|
||||
''
|
||||
)
|
||||
else:
|
||||
files = self.create_excel()
|
||||
self.send_backup_mail(files)
|
||||
self.send_backup_mail(files, recipients)
|
||||
except Exception as e:
|
||||
self.is_frozen = True
|
||||
logger.error('任务执行被异常中断')
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4e6962699271d0f5402223321e65211f1c7ad0b7a9b43524f3a0fac7ea2541d9
|
||||
size 125623
|
||||
oid sha256:f2c88ade4bfae213bdcdafad656af73f764e3b1b3f2b0c59aa39626e967730ca
|
||||
size 125911
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-04-19 15:57+0800\n"
|
||||
"POT-Creation-Date: 2022-04-20 16:35+0800\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -29,7 +29,7 @@ msgstr "Acls"
|
|||
#: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24
|
||||
#: orgs/models.py:65 perms/models/base.py:83 rbac/models/role.py:29
|
||||
#: settings/models.py:29 settings/serializers/sms.py:6
|
||||
#: terminal/models/endpoint.py:10 terminal/models/endpoint.py:55
|
||||
#: terminal/models/endpoint.py:10 terminal/models/endpoint.py:58
|
||||
#: terminal/models/storage.py:23 terminal/models/task.py:16
|
||||
#: terminal/models/terminal.py:100 users/forms/profile.py:32
|
||||
#: users/models/group.py:15 users/models/user.py:661
|
||||
|
@ -38,12 +38,12 @@ msgid "Name"
|
|||
msgstr "名前"
|
||||
|
||||
#: acls/models/base.py:27 assets/models/cmd_filter.py:84
|
||||
#: assets/models/user.py:247 terminal/models/endpoint.py:58
|
||||
#: assets/models/user.py:247 terminal/models/endpoint.py:61
|
||||
msgid "Priority"
|
||||
msgstr "優先順位"
|
||||
|
||||
#: acls/models/base.py:28 assets/models/cmd_filter.py:84
|
||||
#: assets/models/user.py:247 terminal/models/endpoint.py:59
|
||||
#: assets/models/user.py:247 terminal/models/endpoint.py:62
|
||||
msgid "1-100, the lower the value will be match first"
|
||||
msgstr "1-100、低い値は最初に一致します"
|
||||
|
||||
|
@ -61,7 +61,7 @@ msgstr "アクティブ"
|
|||
#: assets/models/domain.py:64 assets/models/group.py:23
|
||||
#: assets/models/label.py:23 ops/models/adhoc.py:38 orgs/models.py:68
|
||||
#: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34
|
||||
#: terminal/models/endpoint.py:20 terminal/models/endpoint.py:65
|
||||
#: terminal/models/endpoint.py:20 terminal/models/endpoint.py:68
|
||||
#: terminal/models/storage.py:26 terminal/models/terminal.py:114
|
||||
#: tickets/models/comment.py:24 tickets/models/ticket.py:154
|
||||
#: users/models/group.py:16 users/models/user.py:698
|
||||
|
@ -1360,7 +1360,7 @@ msgstr "監査"
|
|||
|
||||
#: audits/models.py:27 audits/models.py:57
|
||||
#: authentication/templates/authentication/_access_key_modal.html:65
|
||||
#: rbac/tree.py:166
|
||||
#: rbac/tree.py:168
|
||||
msgid "Delete"
|
||||
msgstr "削除"
|
||||
|
||||
|
@ -1413,11 +1413,11 @@ msgstr "ファイル転送ログ"
|
|||
|
||||
#: audits/models.py:55
|
||||
#: authentication/templates/authentication/_access_key_modal.html:22
|
||||
#: rbac/tree.py:163
|
||||
#: rbac/tree.py:165
|
||||
msgid "Create"
|
||||
msgstr "作成"
|
||||
|
||||
#: audits/models.py:56 rbac/tree.py:165 templates/_csv_import_export.html:18
|
||||
#: audits/models.py:56 rbac/tree.py:167 templates/_csv_import_export.html:18
|
||||
#: templates/_csv_update_modal.html:6
|
||||
msgid "Update"
|
||||
msgstr "更新"
|
||||
|
@ -2886,15 +2886,22 @@ msgstr "タスクログ"
|
|||
msgid "Update task content: {}"
|
||||
msgstr "タスク内容の更新: {}"
|
||||
|
||||
#: orgs/api.py:68
|
||||
#: orgs/api.py:69
|
||||
msgid "The current organization ({}) cannot be deleted"
|
||||
msgstr "現在の組織 ({}) は削除できません"
|
||||
|
||||
#: orgs/api.py:76
|
||||
#: orgs/api.py:74
|
||||
msgid ""
|
||||
"LDAP synchronization is set to the current organization. Please switch to "
|
||||
"another organization before deleting"
|
||||
msgstr ""
|
||||
"LDAP 同期は現在の組織に設定されます。削除する前に別の組織に切り替えてください"
|
||||
|
||||
#: orgs/api.py:83
|
||||
msgid "The organization have resource ({}) cannot be deleted"
|
||||
msgstr "組織のリソース ({}) は削除できません"
|
||||
|
||||
#: orgs/apps.py:7 rbac/tree.py:112
|
||||
#: orgs/apps.py:7 rbac/tree.py:114
|
||||
msgid "App organizations"
|
||||
msgstr "アプリ組織"
|
||||
|
||||
|
@ -3202,18 +3209,18 @@ msgstr "組織の役割"
|
|||
msgid "Role binding"
|
||||
msgstr "ロールバインディング"
|
||||
|
||||
#: rbac/models/rolebinding.py:150
|
||||
#: rbac/models/rolebinding.py:151
|
||||
msgid ""
|
||||
"User last role in org, can not be delete, you can remove user from org "
|
||||
"instead"
|
||||
msgstr ""
|
||||
"ユーザーの最後のロールは削除できません。ユーザーを組織から削除できます。"
|
||||
|
||||
#: rbac/models/rolebinding.py:157
|
||||
#: rbac/models/rolebinding.py:158
|
||||
msgid "Organization role binding"
|
||||
msgstr "組織の役割バインディング"
|
||||
|
||||
#: rbac/models/rolebinding.py:172
|
||||
#: rbac/models/rolebinding.py:173
|
||||
msgid "System role binding"
|
||||
msgstr "システムロールバインディング"
|
||||
|
||||
|
@ -3301,27 +3308,27 @@ msgstr "私の資産"
|
|||
msgid "My apps"
|
||||
msgstr "マイアプリ"
|
||||
|
||||
#: rbac/tree.py:113
|
||||
#: rbac/tree.py:115
|
||||
msgid "Ticket comment"
|
||||
msgstr "チケットコメント"
|
||||
|
||||
#: rbac/tree.py:114 tickets/models/ticket.py:163
|
||||
#: rbac/tree.py:116 tickets/models/ticket.py:163
|
||||
msgid "Ticket"
|
||||
msgstr "チケット"
|
||||
|
||||
#: rbac/tree.py:115
|
||||
#: rbac/tree.py:117
|
||||
msgid "Common setting"
|
||||
msgstr "共通設定"
|
||||
|
||||
#: rbac/tree.py:116
|
||||
#: rbac/tree.py:118
|
||||
msgid "View permission tree"
|
||||
msgstr "権限ツリーの表示"
|
||||
|
||||
#: rbac/tree.py:117
|
||||
#: rbac/tree.py:119
|
||||
msgid "Execute batch command"
|
||||
msgstr "バッチ実行コマンド"
|
||||
|
||||
#: rbac/tree.py:164
|
||||
#: rbac/tree.py:166
|
||||
msgid "View"
|
||||
msgstr "表示"
|
||||
|
||||
|
@ -4228,8 +4235,8 @@ msgid ""
|
|||
"Tips: The login success message varies with devices. if you cannot log in to "
|
||||
"the device through Telnet, set this parameter"
|
||||
msgstr ""
|
||||
"ヒント: ログイン成功メッセージはデバイスによって異なります。Telnet経由でデバイスにロ"
|
||||
"グインできない場合は、このパラメーターを設定します。"
|
||||
"ヒント: ログイン成功メッセージはデバイスによって異なります。Telnet経由でデバ"
|
||||
"イスにログインできない場合は、このパラメーターを設定します。"
|
||||
|
||||
#: settings/serializers/terminal.py:36
|
||||
msgid "Enable database proxy"
|
||||
|
@ -4243,104 +4250,104 @@ msgstr "XRDPの有効化"
|
|||
msgid "Enable KoKo SSH"
|
||||
msgstr "KoKo SSHの有効化"
|
||||
|
||||
#: settings/utils/ldap.py:417
|
||||
#: settings/utils/ldap.py:419
|
||||
msgid "ldap:// or ldaps:// protocol is used."
|
||||
msgstr "ldap:// または ldaps:// プロトコルが使用されます。"
|
||||
|
||||
#: settings/utils/ldap.py:428
|
||||
#: settings/utils/ldap.py:430
|
||||
msgid "Host or port is disconnected: {}"
|
||||
msgstr "ホストまたはポートが切断されました: {}"
|
||||
|
||||
#: settings/utils/ldap.py:430
|
||||
#: settings/utils/ldap.py:432
|
||||
msgid "The port is not the port of the LDAP service: {}"
|
||||
msgstr "ポートはLDAPサービスのポートではありません: {}"
|
||||
|
||||
#: settings/utils/ldap.py:432
|
||||
#: settings/utils/ldap.py:434
|
||||
msgid "Please add certificate: {}"
|
||||
msgstr "証明書を追加してください: {}"
|
||||
|
||||
#: settings/utils/ldap.py:436 settings/utils/ldap.py:463
|
||||
#: settings/utils/ldap.py:493 settings/utils/ldap.py:521
|
||||
#: settings/utils/ldap.py:438 settings/utils/ldap.py:465
|
||||
#: settings/utils/ldap.py:495 settings/utils/ldap.py:523
|
||||
msgid "Unknown error: {}"
|
||||
msgstr "不明なエラー: {}"
|
||||
|
||||
#: settings/utils/ldap.py:450
|
||||
#: settings/utils/ldap.py:452
|
||||
msgid "Bind DN or Password incorrect"
|
||||
msgstr "DNまたはパスワードのバインドが正しくありません"
|
||||
|
||||
#: settings/utils/ldap.py:457
|
||||
#: settings/utils/ldap.py:459
|
||||
msgid "Please enter Bind DN: {}"
|
||||
msgstr "バインドDN: {} を入力してください"
|
||||
|
||||
#: settings/utils/ldap.py:459
|
||||
#: settings/utils/ldap.py:461
|
||||
msgid "Please enter Password: {}"
|
||||
msgstr "パスワードを入力してください: {}"
|
||||
|
||||
#: settings/utils/ldap.py:461
|
||||
#: settings/utils/ldap.py:463
|
||||
msgid "Please enter correct Bind DN and Password: {}"
|
||||
msgstr "正しいバインドDNとパスワードを入力してください: {}"
|
||||
|
||||
#: settings/utils/ldap.py:479
|
||||
#: settings/utils/ldap.py:481
|
||||
msgid "Invalid User OU or User search filter: {}"
|
||||
msgstr "無効なユーザー OU またはユーザー検索フィルター: {}"
|
||||
|
||||
#: settings/utils/ldap.py:510
|
||||
#: settings/utils/ldap.py:512
|
||||
msgid "LDAP User attr map not include: {}"
|
||||
msgstr "LDAP ユーザーattrマップは含まれません: {}"
|
||||
|
||||
#: settings/utils/ldap.py:517
|
||||
#: settings/utils/ldap.py:519
|
||||
msgid "LDAP User attr map is not dict"
|
||||
msgstr "LDAPユーザーattrマップはdictではありません"
|
||||
|
||||
#: settings/utils/ldap.py:536
|
||||
#: settings/utils/ldap.py:538
|
||||
msgid "LDAP authentication is not enabled"
|
||||
msgstr "LDAP 認証が有効になっていない"
|
||||
|
||||
#: settings/utils/ldap.py:554
|
||||
#: settings/utils/ldap.py:556
|
||||
msgid "Error (Invalid LDAP server): {}"
|
||||
msgstr "エラー (LDAPサーバーが無効): {}"
|
||||
|
||||
#: settings/utils/ldap.py:556
|
||||
#: settings/utils/ldap.py:558
|
||||
msgid "Error (Invalid Bind DN): {}"
|
||||
msgstr "エラー (DNのバインドが無効): {}"
|
||||
|
||||
#: settings/utils/ldap.py:558
|
||||
#: settings/utils/ldap.py:560
|
||||
msgid "Error (Invalid LDAP User attr map): {}"
|
||||
msgstr "エラー (LDAPユーザーattrマップが無効): {}"
|
||||
|
||||
#: settings/utils/ldap.py:560
|
||||
#: settings/utils/ldap.py:562
|
||||
msgid "Error (Invalid User OU or User search filter): {}"
|
||||
msgstr "エラー (ユーザーOUまたはユーザー検索フィルターが無効): {}"
|
||||
|
||||
#: settings/utils/ldap.py:562
|
||||
#: settings/utils/ldap.py:564
|
||||
msgid "Error (Not enabled LDAP authentication): {}"
|
||||
msgstr "エラー (LDAP認証が有効化されていません): {}"
|
||||
|
||||
#: settings/utils/ldap.py:564
|
||||
#: settings/utils/ldap.py:566
|
||||
msgid "Error (Unknown): {}"
|
||||
msgstr "エラー (不明): {}"
|
||||
|
||||
#: settings/utils/ldap.py:567
|
||||
#: settings/utils/ldap.py:569
|
||||
msgid "Succeed: Match {} s user"
|
||||
msgstr "成功: {} 人のユーザーに一致"
|
||||
|
||||
#: settings/utils/ldap.py:600
|
||||
#: settings/utils/ldap.py:602
|
||||
msgid "Authentication failed (configuration incorrect): {}"
|
||||
msgstr "認証に失敗しました (設定が正しくありません): {}"
|
||||
|
||||
#: settings/utils/ldap.py:602
|
||||
#: settings/utils/ldap.py:604
|
||||
msgid "Authentication failed (before login check failed): {}"
|
||||
msgstr "認証に失敗しました (ログインチェックが失敗する前): {}"
|
||||
|
||||
#: settings/utils/ldap.py:604
|
||||
#: settings/utils/ldap.py:606
|
||||
msgid "Authentication failed (username or password incorrect): {}"
|
||||
msgstr "認証に失敗しました (ユーザー名またはパスワードが正しくありません): {}"
|
||||
|
||||
#: settings/utils/ldap.py:606
|
||||
#: settings/utils/ldap.py:608
|
||||
msgid "Authentication failed (Unknown): {}"
|
||||
msgstr "認証に失敗しました (不明): {}"
|
||||
|
||||
#: settings/utils/ldap.py:609
|
||||
#: settings/utils/ldap.py:611
|
||||
msgid "Authentication success: {}"
|
||||
msgstr "認証成功: {}"
|
||||
|
||||
|
@ -4725,18 +4732,18 @@ msgstr "MariaDB ポート"
|
|||
msgid "PostgreSQL Port"
|
||||
msgstr "PostgreSQL ポート"
|
||||
|
||||
#: terminal/models/endpoint.py:25 terminal/models/endpoint.py:63
|
||||
#: terminal/models/endpoint.py:25 terminal/models/endpoint.py:66
|
||||
#: terminal/serializers/endpoint.py:40 terminal/serializers/storage.py:37
|
||||
#: terminal/serializers/storage.py:49 terminal/serializers/storage.py:79
|
||||
#: terminal/serializers/storage.py:89 terminal/serializers/storage.py:97
|
||||
msgid "Endpoint"
|
||||
msgstr "エンドポイント"
|
||||
|
||||
#: terminal/models/endpoint.py:56
|
||||
#: terminal/models/endpoint.py:59
|
||||
msgid "IP group"
|
||||
msgstr "IP グループ"
|
||||
|
||||
#: terminal/models/endpoint.py:68
|
||||
#: terminal/models/endpoint.py:71
|
||||
msgid "Endpoint rule"
|
||||
msgstr "エンドポイントルール"
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3462a9a3eef8f372bf341f2066a33d85e1f01aca5a8fe506528a1cd0a37e98b4
|
||||
size 103951
|
||||
oid sha256:c75e0a1f2a047dac1374916c630bc0e8ef5ad5eea7518ffc21e93f747fc1235e
|
||||
size 104165
|
||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: JumpServer 0.3.3\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-04-19 15:57+0800\n"
|
||||
"POT-Creation-Date: 2022-04-20 16:35+0800\n"
|
||||
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
|
||||
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
||||
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
||||
|
@ -28,7 +28,7 @@ msgstr "访问控制"
|
|||
#: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24
|
||||
#: orgs/models.py:65 perms/models/base.py:83 rbac/models/role.py:29
|
||||
#: settings/models.py:29 settings/serializers/sms.py:6
|
||||
#: terminal/models/endpoint.py:10 terminal/models/endpoint.py:55
|
||||
#: terminal/models/endpoint.py:10 terminal/models/endpoint.py:58
|
||||
#: terminal/models/storage.py:23 terminal/models/task.py:16
|
||||
#: terminal/models/terminal.py:100 users/forms/profile.py:32
|
||||
#: users/models/group.py:15 users/models/user.py:661
|
||||
|
@ -37,12 +37,12 @@ msgid "Name"
|
|||
msgstr "名称"
|
||||
|
||||
#: acls/models/base.py:27 assets/models/cmd_filter.py:84
|
||||
#: assets/models/user.py:247 terminal/models/endpoint.py:58
|
||||
#: assets/models/user.py:247 terminal/models/endpoint.py:61
|
||||
msgid "Priority"
|
||||
msgstr "优先级"
|
||||
|
||||
#: acls/models/base.py:28 assets/models/cmd_filter.py:84
|
||||
#: assets/models/user.py:247 terminal/models/endpoint.py:59
|
||||
#: assets/models/user.py:247 terminal/models/endpoint.py:62
|
||||
msgid "1-100, the lower the value will be match first"
|
||||
msgstr "优先级可选范围为 1-100 (数值越小越优先)"
|
||||
|
||||
|
@ -60,7 +60,7 @@ msgstr "激活中"
|
|||
#: assets/models/domain.py:64 assets/models/group.py:23
|
||||
#: assets/models/label.py:23 ops/models/adhoc.py:38 orgs/models.py:68
|
||||
#: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34
|
||||
#: terminal/models/endpoint.py:20 terminal/models/endpoint.py:65
|
||||
#: terminal/models/endpoint.py:20 terminal/models/endpoint.py:68
|
||||
#: terminal/models/storage.py:26 terminal/models/terminal.py:114
|
||||
#: tickets/models/comment.py:24 tickets/models/ticket.py:154
|
||||
#: users/models/group.py:16 users/models/user.py:698
|
||||
|
@ -1348,7 +1348,7 @@ msgstr "日志审计"
|
|||
|
||||
#: audits/models.py:27 audits/models.py:57
|
||||
#: authentication/templates/authentication/_access_key_modal.html:65
|
||||
#: rbac/tree.py:166
|
||||
#: rbac/tree.py:168
|
||||
msgid "Delete"
|
||||
msgstr "删除"
|
||||
|
||||
|
@ -1401,11 +1401,11 @@ msgstr "文件管理"
|
|||
|
||||
#: audits/models.py:55
|
||||
#: authentication/templates/authentication/_access_key_modal.html:22
|
||||
#: rbac/tree.py:163
|
||||
#: rbac/tree.py:165
|
||||
msgid "Create"
|
||||
msgstr "创建"
|
||||
|
||||
#: audits/models.py:56 rbac/tree.py:165 templates/_csv_import_export.html:18
|
||||
#: audits/models.py:56 rbac/tree.py:167 templates/_csv_import_export.html:18
|
||||
#: templates/_csv_update_modal.html:6
|
||||
msgid "Update"
|
||||
msgstr "更新"
|
||||
|
@ -2851,15 +2851,21 @@ msgstr "任务列表"
|
|||
msgid "Update task content: {}"
|
||||
msgstr "更新任务内容: {}"
|
||||
|
||||
#: orgs/api.py:68
|
||||
#: orgs/api.py:69
|
||||
msgid "The current organization ({}) cannot be deleted"
|
||||
msgstr "当前组织 ({}) 不能被删除"
|
||||
|
||||
#: orgs/api.py:76
|
||||
#: orgs/api.py:74
|
||||
msgid ""
|
||||
"LDAP synchronization is set to the current organization. Please switch to "
|
||||
"another organization before deleting"
|
||||
msgstr "LDAP 同步设置组织为当前组织,请切换其他组织后再进行删除操作"
|
||||
|
||||
#: orgs/api.py:83
|
||||
msgid "The organization have resource ({}) cannot be deleted"
|
||||
msgstr "组织存在资源 ({}) 不能被删除"
|
||||
|
||||
#: orgs/apps.py:7 rbac/tree.py:112
|
||||
#: orgs/apps.py:7 rbac/tree.py:114
|
||||
msgid "App organizations"
|
||||
msgstr "组织管理"
|
||||
|
||||
|
@ -3165,17 +3171,17 @@ msgstr "组织角色"
|
|||
msgid "Role binding"
|
||||
msgstr "角色绑定"
|
||||
|
||||
#: rbac/models/rolebinding.py:150
|
||||
#: rbac/models/rolebinding.py:151
|
||||
msgid ""
|
||||
"User last role in org, can not be delete, you can remove user from org "
|
||||
"instead"
|
||||
msgstr "用户最后一个角色,不能删除,你可以将用户从组织移除"
|
||||
|
||||
#: rbac/models/rolebinding.py:157
|
||||
#: rbac/models/rolebinding.py:158
|
||||
msgid "Organization role binding"
|
||||
msgstr "组织角色绑定"
|
||||
|
||||
#: rbac/models/rolebinding.py:172
|
||||
#: rbac/models/rolebinding.py:173
|
||||
msgid "System role binding"
|
||||
msgstr "系统角色绑定"
|
||||
|
||||
|
@ -3263,27 +3269,27 @@ msgstr "我的资产"
|
|||
msgid "My apps"
|
||||
msgstr "我的应用"
|
||||
|
||||
#: rbac/tree.py:113
|
||||
#: rbac/tree.py:115
|
||||
msgid "Ticket comment"
|
||||
msgstr "工单评论"
|
||||
|
||||
#: rbac/tree.py:114 tickets/models/ticket.py:163
|
||||
#: rbac/tree.py:116 tickets/models/ticket.py:163
|
||||
msgid "Ticket"
|
||||
msgstr "工单管理"
|
||||
|
||||
#: rbac/tree.py:115
|
||||
#: rbac/tree.py:117
|
||||
msgid "Common setting"
|
||||
msgstr "一般设置"
|
||||
|
||||
#: rbac/tree.py:116
|
||||
#: rbac/tree.py:118
|
||||
msgid "View permission tree"
|
||||
msgstr "查看授权树"
|
||||
|
||||
#: rbac/tree.py:117
|
||||
#: rbac/tree.py:119
|
||||
msgid "Execute batch command"
|
||||
msgstr "执行批量命令"
|
||||
|
||||
#: rbac/tree.py:164
|
||||
#: rbac/tree.py:166
|
||||
msgid "View"
|
||||
msgstr "查看"
|
||||
|
||||
|
@ -4167,7 +4173,8 @@ msgstr "Telnet 成功正则表达式"
|
|||
msgid ""
|
||||
"Tips: The login success message varies with devices. if you cannot log in to "
|
||||
"the device through Telnet, set this parameter"
|
||||
msgstr "提示: 不同设备登录成功提示不一样,所以如果 telnet 不能正常登录,可以这里设置"
|
||||
msgstr ""
|
||||
"提示: 不同设备登录成功提示不一样,所以如果 telnet 不能正常登录,可以这里设置"
|
||||
|
||||
#: settings/serializers/terminal.py:36
|
||||
msgid "Enable database proxy"
|
||||
|
@ -4181,104 +4188,104 @@ msgstr "启用 XRDP 服务"
|
|||
msgid "Enable KoKo SSH"
|
||||
msgstr "启用 KoKo SSH"
|
||||
|
||||
#: settings/utils/ldap.py:417
|
||||
#: settings/utils/ldap.py:419
|
||||
msgid "ldap:// or ldaps:// protocol is used."
|
||||
msgstr "使用 ldap:// 或 ldaps:// 协议"
|
||||
|
||||
#: settings/utils/ldap.py:428
|
||||
#: settings/utils/ldap.py:430
|
||||
msgid "Host or port is disconnected: {}"
|
||||
msgstr "主机或端口不可连接: {}"
|
||||
|
||||
#: settings/utils/ldap.py:430
|
||||
#: settings/utils/ldap.py:432
|
||||
msgid "The port is not the port of the LDAP service: {}"
|
||||
msgstr "端口不是LDAP服务端口: {}"
|
||||
|
||||
#: settings/utils/ldap.py:432
|
||||
#: settings/utils/ldap.py:434
|
||||
msgid "Please add certificate: {}"
|
||||
msgstr "请添加证书"
|
||||
|
||||
#: settings/utils/ldap.py:436 settings/utils/ldap.py:463
|
||||
#: settings/utils/ldap.py:493 settings/utils/ldap.py:521
|
||||
#: settings/utils/ldap.py:438 settings/utils/ldap.py:465
|
||||
#: settings/utils/ldap.py:495 settings/utils/ldap.py:523
|
||||
msgid "Unknown error: {}"
|
||||
msgstr "未知错误: {}"
|
||||
|
||||
#: settings/utils/ldap.py:450
|
||||
#: settings/utils/ldap.py:452
|
||||
msgid "Bind DN or Password incorrect"
|
||||
msgstr "绑定DN或密码错误"
|
||||
|
||||
#: settings/utils/ldap.py:457
|
||||
#: settings/utils/ldap.py:459
|
||||
msgid "Please enter Bind DN: {}"
|
||||
msgstr "请输入绑定DN: {}"
|
||||
|
||||
#: settings/utils/ldap.py:459
|
||||
#: settings/utils/ldap.py:461
|
||||
msgid "Please enter Password: {}"
|
||||
msgstr "请输入密码: {}"
|
||||
|
||||
#: settings/utils/ldap.py:461
|
||||
#: settings/utils/ldap.py:463
|
||||
msgid "Please enter correct Bind DN and Password: {}"
|
||||
msgstr "请输入正确的绑定DN和密码: {}"
|
||||
|
||||
#: settings/utils/ldap.py:479
|
||||
#: settings/utils/ldap.py:481
|
||||
msgid "Invalid User OU or User search filter: {}"
|
||||
msgstr "不合法的用户OU或用户过滤器: {}"
|
||||
|
||||
#: settings/utils/ldap.py:510
|
||||
#: settings/utils/ldap.py:512
|
||||
msgid "LDAP User attr map not include: {}"
|
||||
msgstr "LDAP属性映射没有包含: {}"
|
||||
|
||||
#: settings/utils/ldap.py:517
|
||||
#: settings/utils/ldap.py:519
|
||||
msgid "LDAP User attr map is not dict"
|
||||
msgstr "LDAP属性映射不合法"
|
||||
|
||||
#: settings/utils/ldap.py:536
|
||||
#: settings/utils/ldap.py:538
|
||||
msgid "LDAP authentication is not enabled"
|
||||
msgstr "LDAP认证没有启用"
|
||||
|
||||
#: settings/utils/ldap.py:554
|
||||
#: settings/utils/ldap.py:556
|
||||
msgid "Error (Invalid LDAP server): {}"
|
||||
msgstr "错误 (不合法的LDAP服务器地址): {}"
|
||||
|
||||
#: settings/utils/ldap.py:556
|
||||
#: settings/utils/ldap.py:558
|
||||
msgid "Error (Invalid Bind DN): {}"
|
||||
msgstr "错误(不合法的绑定DN): {}"
|
||||
|
||||
#: settings/utils/ldap.py:558
|
||||
#: settings/utils/ldap.py:560
|
||||
msgid "Error (Invalid LDAP User attr map): {}"
|
||||
msgstr "错误(不合法的LDAP属性映射): {}"
|
||||
|
||||
#: settings/utils/ldap.py:560
|
||||
#: settings/utils/ldap.py:562
|
||||
msgid "Error (Invalid User OU or User search filter): {}"
|
||||
msgstr "错误(不合法的用户OU或用户过滤器): {}"
|
||||
|
||||
#: settings/utils/ldap.py:562
|
||||
#: settings/utils/ldap.py:564
|
||||
msgid "Error (Not enabled LDAP authentication): {}"
|
||||
msgstr "错误(没有启用LDAP认证): {}"
|
||||
|
||||
#: settings/utils/ldap.py:564
|
||||
#: settings/utils/ldap.py:566
|
||||
msgid "Error (Unknown): {}"
|
||||
msgstr "错误(未知): {}"
|
||||
|
||||
#: settings/utils/ldap.py:567
|
||||
#: settings/utils/ldap.py:569
|
||||
msgid "Succeed: Match {} s user"
|
||||
msgstr "成功匹配 {} 个用户"
|
||||
|
||||
#: settings/utils/ldap.py:600
|
||||
#: settings/utils/ldap.py:602
|
||||
msgid "Authentication failed (configuration incorrect): {}"
|
||||
msgstr "认证失败(配置错误): {}"
|
||||
|
||||
#: settings/utils/ldap.py:602
|
||||
#: settings/utils/ldap.py:604
|
||||
msgid "Authentication failed (before login check failed): {}"
|
||||
msgstr "认证失败(登录前检查失败): {}"
|
||||
|
||||
#: settings/utils/ldap.py:604
|
||||
#: settings/utils/ldap.py:606
|
||||
msgid "Authentication failed (username or password incorrect): {}"
|
||||
msgstr "认证失败 (用户名或密码不正确): {}"
|
||||
|
||||
#: settings/utils/ldap.py:606
|
||||
#: settings/utils/ldap.py:608
|
||||
msgid "Authentication failed (Unknown): {}"
|
||||
msgstr "认证失败: (未知): {}"
|
||||
|
||||
#: settings/utils/ldap.py:609
|
||||
#: settings/utils/ldap.py:611
|
||||
msgid "Authentication success: {}"
|
||||
msgstr "认证成功: {}"
|
||||
|
||||
|
@ -4651,18 +4658,18 @@ msgstr "MariaDB 端口"
|
|||
msgid "PostgreSQL Port"
|
||||
msgstr "PostgreSQL 端口"
|
||||
|
||||
#: terminal/models/endpoint.py:25 terminal/models/endpoint.py:63
|
||||
#: terminal/models/endpoint.py:25 terminal/models/endpoint.py:66
|
||||
#: terminal/serializers/endpoint.py:40 terminal/serializers/storage.py:37
|
||||
#: terminal/serializers/storage.py:49 terminal/serializers/storage.py:79
|
||||
#: terminal/serializers/storage.py:89 terminal/serializers/storage.py:97
|
||||
msgid "Endpoint"
|
||||
msgstr "端点"
|
||||
|
||||
#: terminal/models/endpoint.py:56
|
||||
#: terminal/models/endpoint.py:59
|
||||
msgid "IP group"
|
||||
msgstr "IP 组"
|
||||
|
||||
#: terminal/models/endpoint.py:68
|
||||
#: terminal/models/endpoint.py:71
|
||||
msgid "Endpoint rule"
|
||||
msgstr "端点规则"
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.conf import settings
|
||||
from rest_framework_bulk import BulkModelViewSet
|
||||
from rest_framework.generics import RetrieveAPIView
|
||||
from rest_framework.exceptions import PermissionDenied
|
||||
|
@ -68,6 +69,12 @@ class OrgViewSet(BulkModelViewSet):
|
|||
msg = _('The current organization ({}) cannot be deleted').format(current_org)
|
||||
raise PermissionDenied(detail=msg)
|
||||
|
||||
if str(instance.id) == settings.AUTH_LDAP_SYNC_ORG_ID:
|
||||
msg = _(
|
||||
'LDAP synchronization is set to the current organization. Please switch to another organization before deleting'
|
||||
)
|
||||
raise PermissionDenied(detail=msg)
|
||||
|
||||
for model in org_related_models:
|
||||
data = self.get_data_from_model(instance, model)
|
||||
if not data:
|
||||
|
|
|
@ -90,7 +90,7 @@ class SystemRolePermissionsViewSet(BaseRolePermissionsViewSet):
|
|||
role_pk = 'system_role_pk'
|
||||
model = SystemRole
|
||||
rbac_perms = (
|
||||
('get_tree', 'rbac.view_systemrole'),
|
||||
('get_tree', 'rbac.view_permission'),
|
||||
)
|
||||
|
||||
|
||||
|
@ -99,6 +99,6 @@ class OrgRolePermissionsViewSet(BaseRolePermissionsViewSet):
|
|||
role_pk = 'org_role_pk'
|
||||
model = OrgRole
|
||||
rbac_perms = (
|
||||
('get_tree', 'rbac.view_orgrole'),
|
||||
('get_tree', 'rbac.view_permission'),
|
||||
)
|
||||
|
||||
|
|
|
@ -2,15 +2,10 @@ from django.utils.translation import ugettext_noop
|
|||
|
||||
from .const import Scope, system_exclude_permissions, org_exclude_permissions
|
||||
|
||||
system_user_perms = (
|
||||
('authentication', 'connectiontoken', 'add', 'connectiontoken'),
|
||||
('authentication', 'temptoken', 'add,change,view', 'temptoken'),
|
||||
('authentication', 'accesskey', '*', '*'),
|
||||
('tickets', 'ticket', 'view', 'ticket'),
|
||||
_view_root_perms = (
|
||||
('orgs', 'organization', 'view', 'rootorg'),
|
||||
)
|
||||
|
||||
# Todo: 获取应该区分 系统用户,和组织用户的权限
|
||||
# 工作台也区分组织后再考虑
|
||||
user_perms = (
|
||||
('rbac', 'menupermission', 'view', 'workbench'),
|
||||
|
@ -25,16 +20,28 @@ user_perms = (
|
|||
('ops', 'commandexecution', 'add', 'commandexecution'),
|
||||
)
|
||||
|
||||
auditor_perms = user_perms + (
|
||||
system_user_perms = (
|
||||
('authentication', 'connectiontoken', 'add', 'connectiontoken'),
|
||||
('authentication', 'temptoken', 'add,change,view', 'temptoken'),
|
||||
('authentication', 'accesskey', '*', '*'),
|
||||
('tickets', 'ticket', 'view', 'ticket'),
|
||||
) + user_perms
|
||||
|
||||
_auditor_perms = (
|
||||
('rbac', 'menupermission', 'view', 'audit'),
|
||||
('audits', '*', '*', '*'),
|
||||
('terminal', 'commandstorage', 'view', 'commandstorage'),
|
||||
('terminal', 'sessionreplay', 'view,download', 'sessionreplay'),
|
||||
('terminal', 'session', '*', '*'),
|
||||
('terminal', 'command', '*', '*'),
|
||||
('ops', 'commandexecution', 'view', 'commandexecution')
|
||||
('ops', 'commandexecution', 'view', 'commandexecution'),
|
||||
)
|
||||
|
||||
auditor_perms = user_perms + _auditor_perms
|
||||
|
||||
system_auditor_perms = system_user_perms + _auditor_perms + _view_root_perms
|
||||
|
||||
|
||||
app_exclude_perms = [
|
||||
('users', 'user', 'add,delete', 'user'),
|
||||
('orgs', 'org', 'add,delete,change', 'org'),
|
||||
|
@ -102,7 +109,7 @@ class BuiltinRole:
|
|||
'1', ugettext_noop('SystemAdmin'), Scope.system, []
|
||||
)
|
||||
system_auditor = PredefineRole(
|
||||
'2', ugettext_noop('SystemAuditor'), Scope.system, auditor_perms
|
||||
'2', ugettext_noop('SystemAuditor'), Scope.system, system_auditor_perms
|
||||
)
|
||||
system_component = PredefineRole(
|
||||
'4', ugettext_noop('SystemComponent'), Scope.system, app_exclude_perms, 'exclude'
|
||||
|
|
|
@ -108,8 +108,11 @@ only_system_permissions = (
|
|||
('terminal', 'replaystorage', '*', '*'),
|
||||
('terminal', 'status', '*', '*'),
|
||||
('terminal', 'task', '*', '*'),
|
||||
('terminal', 'endpoint', '*', '*'),
|
||||
('terminal', 'endpointrule', '*', '*'),
|
||||
('authentication', '*', '*', '*'),
|
||||
('tickets', '*', '*', '*'),
|
||||
('orgs', 'organization', 'view', 'rootorg'),
|
||||
)
|
||||
|
||||
only_org_permissions = (
|
||||
|
|
|
@ -6,7 +6,7 @@ from rest_framework.serializers import ValidationError
|
|||
|
||||
from common.db.models import JMSModel
|
||||
from common.utils import lazyproperty
|
||||
from orgs.utils import current_org
|
||||
from orgs.utils import current_org, tmp_to_root_org
|
||||
from .role import Role
|
||||
from ..const import Scope
|
||||
|
||||
|
@ -105,20 +105,25 @@ class RoleBinding(JMSModel):
|
|||
from orgs.models import Organization
|
||||
|
||||
roles = Role.get_roles_by_perm(perm)
|
||||
with tmp_to_root_org():
|
||||
bindings = list(cls.objects.root_all().filter(role__in=roles, user=user))
|
||||
system_bindings = [b for b in bindings if b.scope == Role.Scope.system.value]
|
||||
|
||||
system_bindings = [b for b in bindings if b.scope == Role.Scope.system.value]
|
||||
# 工作台仅限于自己加入的组织
|
||||
if perm == 'rbac.view_workbench':
|
||||
all_orgs = user.orgs.all()
|
||||
else:
|
||||
all_orgs = Organization.objects.all()
|
||||
|
||||
# 有系统级别的绑定,就代表在所有组织有这个权限
|
||||
if system_bindings:
|
||||
orgs = all_orgs
|
||||
else:
|
||||
org_ids = [b.org.id for b in bindings if b.org]
|
||||
orgs = all_orgs.filter(id__in=org_ids)
|
||||
if orgs and user.has_perm('orgs.view_rootorg'):
|
||||
|
||||
# 全局组织
|
||||
if orgs and perm != 'rbac.view_workbench' and user.has_perm('orgs.view_rootorg'):
|
||||
orgs = [Organization.root(), *list(orgs)]
|
||||
return orgs
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#!/usr/bin/python
|
||||
import os
|
||||
from collections import defaultdict
|
||||
from typing import Callable
|
||||
from treelib import Tree
|
||||
from treelib.exceptions import NodeIDAbsentError
|
||||
|
||||
from django.utils.translation import gettext_lazy as _, gettext, get_language
|
||||
from django.conf import settings
|
||||
|
@ -159,6 +160,65 @@ def sort_nodes(node):
|
|||
return value
|
||||
|
||||
|
||||
class CounterTree(Tree):
|
||||
def get_total_count(self, node):
|
||||
count = getattr(node, '_total_count', None)
|
||||
if count is not None:
|
||||
return count
|
||||
|
||||
if not node.data.isParent:
|
||||
return 1
|
||||
|
||||
count = 0
|
||||
children = self.children(node.identifier)
|
||||
for child in children:
|
||||
if child.data.isParent:
|
||||
count += self.get_total_count(child)
|
||||
else:
|
||||
count += 1
|
||||
node._total_count = count
|
||||
return count
|
||||
|
||||
def get_checked_count(self, node):
|
||||
count = getattr(node, '_checked_count', None)
|
||||
if count is not None:
|
||||
return count
|
||||
|
||||
if not node.data.isParent:
|
||||
if node.data.checked:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
count = 0
|
||||
children = self.children(node.identifier)
|
||||
for child in children:
|
||||
if child.data.isParent:
|
||||
count += self.get_checked_count(child)
|
||||
else:
|
||||
if child.data.checked:
|
||||
count += 1
|
||||
node._checked_count = count
|
||||
return count
|
||||
|
||||
def add_nodes_to_tree(self, ztree_nodes, retry=0):
|
||||
failed = []
|
||||
for node in ztree_nodes:
|
||||
pid = node.pId
|
||||
if retry == 2:
|
||||
pid = '$ROOT$'
|
||||
|
||||
try:
|
||||
self.create_node(node.name, node.id, pid, data=node)
|
||||
except NodeIDAbsentError:
|
||||
failed.append(node)
|
||||
if retry > 2:
|
||||
return
|
||||
if failed:
|
||||
retry += 1
|
||||
return self.add_nodes_to_tree(failed, retry)
|
||||
|
||||
|
||||
class PermissionTreeUtil:
|
||||
get_permissions: Callable
|
||||
action_mapper = {
|
||||
|
@ -183,8 +243,6 @@ class PermissionTreeUtil:
|
|||
Permission.get_permissions(scope)
|
||||
)
|
||||
self.check_disabled = check_disabled
|
||||
self.total_counts = defaultdict(int)
|
||||
self.checked_counts = defaultdict(int)
|
||||
self.lang = get_language()
|
||||
|
||||
@staticmethod
|
||||
|
@ -211,38 +269,10 @@ class PermissionTreeUtil:
|
|||
'name': name,
|
||||
'pId': view,
|
||||
}
|
||||
total_count = self.total_counts[app]
|
||||
checked_count = self.checked_counts[app]
|
||||
if total_count == 0:
|
||||
continue
|
||||
self.total_counts[view] += total_count
|
||||
self.checked_counts[view] += checked_count
|
||||
node = self._create_node(
|
||||
app_data, total_count, checked_count,
|
||||
'app', is_open=False
|
||||
)
|
||||
node = self._create_node(app_data, 'app', is_open=False)
|
||||
nodes.append(node)
|
||||
return nodes
|
||||
|
||||
def _get_model_counts_mapper(self):
|
||||
model_counts = self.all_permissions \
|
||||
.values('model', 'app', 'content_type') \
|
||||
.order_by('content_type') \
|
||||
.annotate(count=Count('content_type'))
|
||||
model_check_counts = self.permissions \
|
||||
.values('content_type', 'model') \
|
||||
.order_by('content_type') \
|
||||
.annotate(count=Count('content_type'))
|
||||
model_counts_mapper = {
|
||||
i['content_type']: i['count']
|
||||
for i in model_counts
|
||||
}
|
||||
model_check_counts_mapper = {
|
||||
i['content_type']: i['count']
|
||||
for i in model_check_counts
|
||||
}
|
||||
return model_counts_mapper, model_check_counts_mapper
|
||||
|
||||
@staticmethod
|
||||
def _check_model_xpack(model_id):
|
||||
app, model = model_id.split('.', 2)
|
||||
|
@ -263,17 +293,10 @@ class PermissionTreeUtil:
|
|||
if not self._check_model_xpack(model_id):
|
||||
continue
|
||||
|
||||
total_count = self.total_counts[model_id]
|
||||
checked_count = self.checked_counts[model_id]
|
||||
if total_count == 0:
|
||||
continue
|
||||
|
||||
# 获取 pid
|
||||
app = ct.app_label
|
||||
if model_id in special_pid_mapper:
|
||||
app = special_pid_mapper[model_id]
|
||||
self.total_counts[app] += total_count
|
||||
self.checked_counts[app] += checked_count
|
||||
|
||||
# 获取 name
|
||||
name = f'{ct.name}'
|
||||
|
@ -284,7 +307,7 @@ class PermissionTreeUtil:
|
|||
'id': model_id,
|
||||
'name': name,
|
||||
'pId': app,
|
||||
}, total_count, checked_count, 'model', is_open=False)
|
||||
}, 'model', is_open=False)
|
||||
nodes.append(node)
|
||||
return nodes
|
||||
|
||||
|
@ -334,10 +357,7 @@ class PermissionTreeUtil:
|
|||
if title in special_pid_mapper:
|
||||
pid = special_pid_mapper[title]
|
||||
|
||||
self.total_counts[pid] += 1
|
||||
checked = p.id in permissions_id
|
||||
if checked:
|
||||
self.checked_counts[pid] += 1
|
||||
|
||||
node = TreeNode(**{
|
||||
'id': p.id,
|
||||
|
@ -347,7 +367,7 @@ class PermissionTreeUtil:
|
|||
'isParent': False,
|
||||
'chkDisabled': self.check_disabled,
|
||||
'iconSkin': icon,
|
||||
'checked': p.id in permissions_id,
|
||||
'checked': checked,
|
||||
'open': False,
|
||||
'meta': {
|
||||
'type': 'perm',
|
||||
|
@ -356,13 +376,11 @@ class PermissionTreeUtil:
|
|||
nodes.append(node)
|
||||
return nodes
|
||||
|
||||
def _create_node(self, data, total_count, checked_count, tp,
|
||||
is_parent=True, is_open=True, icon='', checked=None):
|
||||
def _create_node(self, data, tp, is_parent=True, is_open=True, icon='', checked=None):
|
||||
assert data.get('id')
|
||||
assert data.get('name')
|
||||
assert data.get('pId') is not None
|
||||
if checked is None:
|
||||
checked = total_count == checked_count
|
||||
|
||||
node_data = {
|
||||
'isParent': is_parent,
|
||||
'iconSkin': icon,
|
||||
|
@ -380,46 +398,58 @@ class PermissionTreeUtil:
|
|||
node.name += ('[' + node.id + ']')
|
||||
if DEBUG_DB:
|
||||
node.name += ('-' + node.id)
|
||||
node.name += f'({checked_count}/{total_count})'
|
||||
return node
|
||||
|
||||
def _create_root_tree_node(self):
|
||||
total_count = self.all_permissions.count()
|
||||
checked_count = self.permissions.count()
|
||||
node = self._create_node(root_node_data, total_count, checked_count, 'root')
|
||||
node = self._create_node(root_node_data, 'root')
|
||||
return node
|
||||
|
||||
def _create_views_node(self):
|
||||
nodes = []
|
||||
for view_data in view_nodes_data:
|
||||
view = view_data['id']
|
||||
data = {
|
||||
**view_data,
|
||||
'pId': '$ROOT$',
|
||||
}
|
||||
total_count = self.total_counts[view]
|
||||
checked_count = self.checked_counts[view]
|
||||
if total_count == 0:
|
||||
continue
|
||||
node = self._create_node(data, total_count, checked_count, 'view', is_open=True)
|
||||
node = self._create_node(data, 'view', is_open=True)
|
||||
nodes.append(node)
|
||||
return nodes
|
||||
|
||||
def _create_extra_nodes(self):
|
||||
nodes = []
|
||||
for data in extra_nodes_data:
|
||||
i = data['id']
|
||||
pid = data['pId']
|
||||
checked_count = self.checked_counts[i]
|
||||
total_count = self.total_counts[i]
|
||||
node = self._create_node(data, 'extra', is_open=False)
|
||||
nodes.append(node)
|
||||
return nodes
|
||||
|
||||
@staticmethod
|
||||
def compute_nodes_count(ztree_nodes):
|
||||
tree = CounterTree()
|
||||
reverse_nodes = ztree_nodes[::-1]
|
||||
root = reverse_nodes[0]
|
||||
tree.create_node(root.name, root.id, data=root)
|
||||
tree.add_nodes_to_tree(reverse_nodes[1:])
|
||||
counter_nodes = tree.all_nodes()
|
||||
|
||||
node_counts = {}
|
||||
for n in counter_nodes:
|
||||
if not n:
|
||||
continue
|
||||
total_count = tree.get_total_count(n)
|
||||
checked_count = tree.get_checked_count(n)
|
||||
node_counts[n.identifier] = [checked_count, total_count]
|
||||
|
||||
nodes = []
|
||||
for node in ztree_nodes:
|
||||
counter = node_counts[node.id]
|
||||
if not counter:
|
||||
counter = [0, 0]
|
||||
checked_count, total_count = counter
|
||||
if total_count == 0:
|
||||
continue
|
||||
self.total_counts[pid] += total_count
|
||||
self.checked_counts[pid] += checked_count
|
||||
node = self._create_node(
|
||||
data, total_count, checked_count,
|
||||
'extra', is_open=False
|
||||
)
|
||||
node.name += '({}/{})'.format(checked_count, total_count)
|
||||
if checked_count != 0:
|
||||
node.checked = True
|
||||
nodes.append(node)
|
||||
return nodes
|
||||
|
||||
|
@ -431,5 +461,6 @@ class PermissionTreeUtil:
|
|||
nodes += self._create_views_node()
|
||||
nodes += [self._create_root_tree_node()]
|
||||
|
||||
nodes = self.compute_nodes_count(nodes)
|
||||
nodes.sort(key=sort_nodes)
|
||||
return nodes
|
||||
|
|
|
@ -376,7 +376,9 @@ class LDAPImportUtil(object):
|
|||
except Exception as e:
|
||||
errors.append({user['username']: str(e)})
|
||||
logger.error(e)
|
||||
if org and org.is_root():
|
||||
if not org:
|
||||
return
|
||||
if org.is_root():
|
||||
return
|
||||
for obj in objs:
|
||||
org.add_member(obj)
|
||||
|
|
|
@ -63,7 +63,7 @@ class SessionViewSet(OrgBulkModelViewSet):
|
|||
]
|
||||
extra_filter_backends = [DatetimeRangeFilter]
|
||||
rbac_perms = {
|
||||
'download': ['terminal.download_sessionreplay|terminal.view_sessionreplay']
|
||||
'download': ['terminal.download_sessionreplay']
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -81,8 +81,14 @@ def import_ldap_user():
|
|||
util_server = LDAPServerUtil()
|
||||
util_import = LDAPImportUtil()
|
||||
users = util_server.search()
|
||||
if settings.XPACK_ENABLED:
|
||||
org_id = settings.AUTH_LDAP_SYNC_ORG_ID
|
||||
org = Organization.get_instance(org_id)
|
||||
default_org = None
|
||||
else:
|
||||
# 社区版默认导入Default组织
|
||||
org_id = Organization.DEFAULT_ID
|
||||
default_org = Organization.default()
|
||||
org = Organization.get_instance(org_id, default=default_org)
|
||||
errors = util_import.perform_import(users, org)
|
||||
if errors:
|
||||
logger.error("Imported LDAP users errors: {}".format(errors))
|
||||
|
@ -106,6 +112,9 @@ def import_ldap_user_periodic():
|
|||
else:
|
||||
interval = None
|
||||
crontab = settings.AUTH_LDAP_SYNC_CRONTAB
|
||||
if crontab:
|
||||
# 优先使用 crontab
|
||||
interval = None
|
||||
tasks = {
|
||||
task_name: {
|
||||
'task': import_ldap_user.name,
|
||||
|
|
Loading…
Reference in New Issue