From b017e68a563975124049f4892fe1fa6087d918e3 Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" <32935519+BaiJiangJie@users.noreply.github.com> Date: Thu, 10 Mar 2022 11:25:33 +0800 Subject: [PATCH] =?UTF-8?q?Perf:=20=E4=BC=98=E5=8C=96RBAC=E6=9D=83?= =?UTF-8?q?=E9=99=90=E6=A0=91=20(#7782)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 优化权限树(1) * fix: 优化权限树(2) * fix: 优化权限树(3) * fix: 优化权限树(4) * fix: 优化权限树(5) * fix: 优化权限树(添加迁移文件) * fix: 优化权限树(6) * fix: 优化权限树(7) * fix: 优化权限树(8) * fix: 优化权限树(9) --- ...019_databaseapp_kubernetesapp_remoteapp.py | 49 + apps/applications/models/application.py | 18 + .../migrations/0089_auto_20220310_0616.py | 29 + apps/assets/models/asset.py | 2 + apps/assets/models/authbook.py | 1 + apps/assets/models/domain.py | 3 + apps/assets/models/user.py | 3 + .../migrations/0009_auto_20220310_0616.py | 17 + apps/authentication/models.py | 3 + apps/jumpserver/api.py | 2 +- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 884 ++++++++++++------ .../migrations/0026_auto_20220307_1500.py | 13 - .../migrations/0027_auto_20220310_0616.py | 78 ++ apps/perms/models/application_permission.py | 42 +- apps/perms/models/asset_permission.py | 4 + apps/rbac/migrations/0001_initial.py | 2 +- .../migrations/0005_auto_20220307_1524.py | 2 +- .../migrations/0007_auto_20220310_0616.py | 17 + apps/rbac/models/menu.py | 8 +- apps/rbac/models/permission.py | 29 +- apps/rbac/ztree/__init__.py | 0 apps/rbac/ztree/permissions.py | 259 +++++ apps/rbac/ztree/tree.py | 207 ++++ apps/rbac/ztree/tree_nodes.py | 308 ++++++ .../migrations/0005_auto_20220310_0616.py | 17 + apps/settings/models.py | 10 + apps/users/models/user.py | 2 +- 28 files changed, 1672 insertions(+), 341 deletions(-) create mode 100644 apps/applications/migrations/0019_databaseapp_kubernetesapp_remoteapp.py create mode 100644 apps/assets/migrations/0089_auto_20220310_0616.py create mode 100644 apps/authentication/migrations/0009_auto_20220310_0616.py create mode 100644 apps/perms/migrations/0027_auto_20220310_0616.py create mode 100644 apps/rbac/migrations/0007_auto_20220310_0616.py create mode 100644 apps/rbac/ztree/__init__.py create mode 100644 apps/rbac/ztree/permissions.py create mode 100644 apps/rbac/ztree/tree.py create mode 100644 apps/rbac/ztree/tree_nodes.py create mode 100644 apps/settings/migrations/0005_auto_20220310_0616.py diff --git a/apps/applications/migrations/0019_databaseapp_kubernetesapp_remoteapp.py b/apps/applications/migrations/0019_databaseapp_kubernetesapp_remoteapp.py new file mode 100644 index 000000000..ae70ef606 --- /dev/null +++ b/apps/applications/migrations/0019_databaseapp_kubernetesapp_remoteapp.py @@ -0,0 +1,49 @@ +# Generated by Django 3.1.14 on 2022-03-09 22:16 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('applications', '0018_auto_20220223_1539'), + ] + + operations = [ + migrations.CreateModel( + name='DatabaseApp', + fields=[ + ], + options={ + 'verbose_name': 'Database application', + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=('applications.application',), + ), + migrations.CreateModel( + name='KubernetesApp', + fields=[ + ], + options={ + 'verbose_name': 'Kubernetes', + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=('applications.application',), + ), + migrations.CreateModel( + name='RemoteApp', + fields=[ + ], + options={ + 'verbose_name': 'Remote application', + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=('applications.application',), + ), + ] diff --git a/apps/applications/models/application.py b/apps/applications/models/application.py index fcde3bdef..b4c190452 100644 --- a/apps/applications/models/application.py +++ b/apps/applications/models/application.py @@ -266,3 +266,21 @@ class ApplicationUser(SystemUser): class Meta: proxy = True verbose_name = _('Application user') + + +class RemoteApp(Application): + class Meta: + proxy = True + verbose_name = _('Remote application') + + +class DatabaseApp(Application): + class Meta: + proxy = True + verbose_name = _('Database application') + + +class KubernetesApp(Application): + class Meta: + proxy = True + verbose_name = _('Kubernetes') diff --git a/apps/assets/migrations/0089_auto_20220310_0616.py b/apps/assets/migrations/0089_auto_20220310_0616.py new file mode 100644 index 000000000..342c3d887 --- /dev/null +++ b/apps/assets/migrations/0089_auto_20220310_0616.py @@ -0,0 +1,29 @@ +# Generated by Django 3.1.14 on 2022-03-09 22:16 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0088_auto_20220303_1612'), + ] + + operations = [ + migrations.AlterModelOptions( + name='authbook', + options={'permissions': [('test_authbook', 'Can test asset account connectivity'), ('view_assetaccountsecret', 'Can view asset account secret'), ('change_assetaccountsecret', 'Can change asset account secret')], 'verbose_name': 'AuthBook'}, + ), + migrations.AlterModelOptions( + name='systemuser', + options={'ordering': ['name'], 'permissions': [('view_systemuserasset', 'Can view system user asset'), ('add_systemuserasset', 'Can add asset to system user'), ('remove_systemuserasset', 'Can remove system user asset'), ('match_systemuser', 'Can match system user')], 'verbose_name': 'System user'}, + ), + migrations.AlterModelOptions( + name='asset', + options={'ordering': ['hostname'], 'permissions': [('refresh_assethardwareinfo', 'Can refresh asset hardware info'), ('test_assetconnectivity', 'Can test asset connectivity'), ('push_assetsystemuser', 'Can push system user to asset'), ('match_asset', 'Can match asset'), ('add_assettonode', 'Add asset to node'), ('move_assettonode', 'Move asset to node')], 'verbose_name': 'Asset'}, + ), + migrations.AlterModelOptions( + name='gateway', + options={'permissions': [('test_gateway', 'Test gateway')], 'verbose_name': 'Gateway'}, + ), + ] diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py index f693febc5..d846c6ce4 100644 --- a/apps/assets/models/asset.py +++ b/apps/assets/models/asset.py @@ -359,4 +359,6 @@ class Asset(AbsConnectivity, AbsHardwareInfo, ProtocolsMixin, NodesRelationMixin ('test_assetconnectivity', _('Can test asset connectivity')), ('push_assetsystemuser', _('Can push system user to asset')), ('match_asset', _('Can match asset')), + ('add_assettonode', _('Add asset to node')), + ('move_assettonode', _('Move asset to node')), ] diff --git a/apps/assets/models/authbook.py b/apps/assets/models/authbook.py index c3164faba..53766d2b7 100644 --- a/apps/assets/models/authbook.py +++ b/apps/assets/models/authbook.py @@ -27,6 +27,7 @@ class AuthBook(BaseUser, AbsConnectivity): verbose_name = _('AuthBook') unique_together = [('username', 'asset', 'systemuser')] permissions = [ + ('test_authbook', _('Can test asset account connectivity')), ('view_assetaccountsecret', _('Can view asset account secret')), ('change_assetaccountsecret', _('Can change asset account secret')) ] diff --git a/apps/assets/models/domain.py b/apps/assets/models/domain.py index 2d6e8a1bc..ba3b069f5 100644 --- a/apps/assets/models/domain.py +++ b/apps/assets/models/domain.py @@ -70,6 +70,9 @@ class Gateway(BaseUser): class Meta: unique_together = [('name', 'org_id')] verbose_name = _("Gateway") + permissions = [ + ('test_gateway', _('Test gateway')) + ] def set_unconnective(self): unconnective_key = self.UNCONNECTIVE_KEY_TMPL.format(self.id) diff --git a/apps/assets/models/user.py b/apps/assets/models/user.py index 678e5f8cf..6ae0fa825 100644 --- a/apps/assets/models/user.py +++ b/apps/assets/models/user.py @@ -324,6 +324,9 @@ class SystemUser(ProtocolMixin, AuthMixin, BaseUser): unique_together = [('name', 'org_id')] verbose_name = _("System user") permissions = [ + ('view_systemuserasset', _('Can view system user asset')), + ('add_systemuserasset', _('Can add asset to system user')), + ('remove_systemuserasset', _('Can remove system user asset')), ('match_systemuser', _('Can match system user')), ] diff --git a/apps/authentication/migrations/0009_auto_20220310_0616.py b/apps/authentication/migrations/0009_auto_20220310_0616.py new file mode 100644 index 000000000..652aa2ea4 --- /dev/null +++ b/apps/authentication/migrations/0009_auto_20220310_0616.py @@ -0,0 +1,17 @@ +# Generated by Django 3.1.14 on 2022-03-09 22:16 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('authentication', '0008_superconnectiontoken'), + ] + + operations = [ + migrations.AlterModelOptions( + name='connectiontoken', + options={'permissions': [('view_connectiontokensecret', 'Can view connection token secret')], 'verbose_name': 'Connection token'}, + ), + ] diff --git a/apps/authentication/models.py b/apps/authentication/models.py index 7e407a1dd..1b353f737 100644 --- a/apps/authentication/models.py +++ b/apps/authentication/models.py @@ -59,6 +59,9 @@ class ConnectionToken(models.JMSBaseModel): class Meta: verbose_name = _('Connection token') + permissions = [ + ('view_connectiontokensecret', _('Can view connection token secret')) + ] class SuperConnectionToken(ConnectionToken): diff --git a/apps/jumpserver/api.py b/apps/jumpserver/api.py index e142a9c7b..eb09f7214 100644 --- a/apps/jumpserver/api.py +++ b/apps/jumpserver/api.py @@ -214,7 +214,7 @@ class DatesLoginMetricMixin: class IndexApi(DatesLoginMetricMixin, APIView): http_method_names = ['get'] rbac_perms = { - 'GET': 'rbac.view_resourcestatistics' + 'GET': 'rbac.view_dashboard' } def get(self, request, *args, **kwargs): diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 64432e35d..a831dfe88 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:819f2eb404c90465d945987436e236488653e031c46e90fb23defae28ca57c19 -size 102615 +oid sha256:a5f51e35576a9fd77db6f5267ccaffe74c453828ec36abc5dbea9734c8ac6a01 +size 107878 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index a0d45fa4c..dbec8d00b 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-03-07 18:41+0800\n" +"POT-Creation-Date: 2022-03-10 10:33+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -30,7 +30,7 @@ msgstr "访问控制" #: settings/models.py:29 settings/serializers/sms.py:6 #: 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:550 +#: users/models/group.py:15 users/models/user.py:567 #: users/templates/users/_select_user_modal.html:13 #: users/templates/users/user_asset_permission.html:37 #: users/templates/users/user_asset_permission.html:154 @@ -66,9 +66,9 @@ msgstr "激活中" #: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34 #: 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:587 +#: users/models/group.py:16 users/models/user.py:604 #: xpack/plugins/change_auth_plan/models/base.py:44 -#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:113 +#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:116 #: xpack/plugins/gathered_user/models.py:26 msgid "Comment" msgstr "备注" @@ -90,12 +90,12 @@ msgstr "登录复核" #: assets/models/cmd_filter.py:30 assets/models/label.py:15 audits/models.py:37 #: audits/models.py:60 audits/models.py:85 audits/serializers.py:100 #: authentication/models.py:50 orgs/models.py:196 perms/models/base.py:84 -#: rbac/builtin.py:99 rbac/models/rolebinding.py:35 templates/index.html:78 +#: rbac/builtin.py:103 rbac/models/rolebinding.py:35 templates/index.html:78 #: terminal/backends/command/models.py:19 #: terminal/backends/command/serializers.py:12 terminal/models/session.py:42 #: terminal/notifications.py:88 terminal/notifications.py:136 -#: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:769 -#: users/models/user.py:800 users/serializers/group.py:19 +#: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:786 +#: users/models/user.py:817 users/serializers/group.py:19 #: users/templates/users/user_asset_permission.html:38 #: users/templates/users/user_asset_permission.html:64 #: users/templates/users/user_database_app_permission.html:37 @@ -146,7 +146,7 @@ msgstr "系统用户" #: users/templates/users/user_asset_permission.html:70 #: xpack/plugins/change_auth_plan/models/asset.py:199 #: xpack/plugins/change_auth_plan/serializers/asset.py:180 -#: xpack/plugins/cloud/models.py:220 +#: xpack/plugins/cloud/models.py:223 msgid "Asset" msgstr "资产" @@ -168,7 +168,7 @@ msgstr "格式为逗号分隔的字符串, * 表示匹配所有. " #: authentication/forms.py:15 authentication/forms.py:17 #: authentication/templates/authentication/_msg_different_city.html:9 #: authentication/templates/authentication/_msg_oauth_bind.html:9 -#: ops/models/adhoc.py:159 users/forms/profile.py:31 users/models/user.py:548 +#: ops/models/adhoc.py:159 users/forms/profile.py:31 users/models/user.py:565 #: users/templates/users/_msg_user_created.html:12 #: users/templates/users/_select_user_modal.html:14 #: xpack/plugins/change_auth_plan/models/asset.py:34 @@ -301,7 +301,7 @@ msgstr "系统用户" msgid "Version" msgstr "版本" -#: applications/models/account.py:23 +#: applications/models/account.py:23 rbac/ztree/tree_nodes.py:147 msgid "Application account" msgstr "应用账号" @@ -344,6 +344,22 @@ msgstr "属性" msgid "Application user" msgstr "应用用户" +#: applications/models/application.py:274 rbac/ztree/tree_nodes.py:135 +msgid "Remote application" +msgstr "远程应用" + +#: applications/models/application.py:280 +#: perms/models/application_permission.py:134 rbac/ztree/tree_nodes.py:138 +#: rbac/ztree/tree_nodes.py:192 +msgid "Database application" +msgstr "数据库应用" + +#: applications/models/application.py:286 +#: perms/models/application_permission.py:145 rbac/ztree/tree_nodes.py:141 +#: rbac/ztree/tree_nodes.py:195 +msgid "Kubernetes" +msgstr "" + #: applications/serializers/application.py:70 #: applications/serializers/application.py:100 assets/serializers/label.py:13 #: perms/serializers/application/permission.py:18 @@ -368,8 +384,8 @@ msgstr "类型名称" #: assets/serializers/account.py:18 common/db/models.py:113 #: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30 #: orgs/models.py:14 orgs/models.py:199 perms/models/base.py:92 -#: users/models/group.py:18 users/models/user.py:801 -#: xpack/plugins/cloud/models.py:122 +#: users/models/group.py:18 users/models/user.py:818 +#: xpack/plugins/cloud/models.py:125 msgid "Date created" msgstr "创建日期" @@ -481,15 +497,15 @@ msgstr "Vmware 密码" msgid "Number required" msgstr "需要为数字" -#: assets/api/node.py:61 +#: assets/api/node.py:62 msgid "You can't update the root node name" msgstr "不能修改根节点名称" -#: assets/api/node.py:68 +#: assets/api/node.py:69 msgid "You can't delete the root node ({})" msgstr "不能删除根节点 ({})" -#: assets/api/node.py:71 +#: assets/api/node.py:72 msgid "Deletion failed and the node contains assets" msgstr "删除失败,节点包含资产" @@ -578,7 +594,7 @@ msgstr "主机名原始" #: assets/models/asset.py:215 assets/serializers/account.py:16 #: assets/serializers/asset.py:65 perms/serializers/asset/user_permission.py:41 -#: xpack/plugins/cloud/models.py:104 xpack/plugins/cloud/serializers/task.py:42 +#: xpack/plugins/cloud/models.py:107 xpack/plugins/cloud/serializers/task.py:42 msgid "Protocols" msgstr "协议组" @@ -595,7 +611,7 @@ msgid "Is active" msgstr "激活" #: assets/models/asset.py:222 assets/models/cluster.py:19 -#: assets/models/user.py:222 assets/models/user.py:377 +#: assets/models/user.py:222 assets/models/user.py:380 msgid "Admin user" msgstr "特权用户" @@ -615,10 +631,10 @@ msgstr "标签管理" #: assets/models/cluster.py:28 assets/models/cmd_filter.py:52 #: assets/models/cmd_filter.py:99 assets/models/group.py:21 #: common/db/models.py:111 common/mixins/models.py:49 orgs/models.py:13 -#: orgs/models.py:201 perms/models/base.py:91 users/models/user.py:595 +#: orgs/models.py:201 perms/models/base.py:91 users/models/user.py:612 #: users/serializers/group.py:33 #: xpack/plugins/change_auth_plan/models/base.py:48 -#: xpack/plugins/cloud/models.py:119 xpack/plugins/gathered_user/models.py:30 +#: xpack/plugins/cloud/models.py:122 xpack/plugins/gathered_user/models.py:30 msgid "Created by" msgstr "创建者" @@ -638,15 +654,27 @@ msgstr "可以推送系统用户到资产" msgid "Can match asset" msgstr "可以匹配资产" +#: assets/models/asset.py:362 +msgid "Add asset to node" +msgstr "添加资产到节点" + +#: assets/models/asset.py:363 +msgid "Move asset to node" +msgstr "移动资产到节点" + #: assets/models/authbook.py:27 msgid "AuthBook" msgstr "资产账号" #: assets/models/authbook.py:30 +msgid "Can test asset account connectivity" +msgstr "可以测试资产账号连接性" + +#: assets/models/authbook.py:31 msgid "Can view asset account secret" msgstr "可以查看资产账号密码" -#: assets/models/authbook.py:31 +#: assets/models/authbook.py:32 msgid "Can change asset account secret" msgstr "可以更改资产账号密码" @@ -710,7 +738,7 @@ msgstr "触发模式" #: xpack/plugins/change_auth_plan/models/base.py:201 #: xpack/plugins/change_auth_plan/serializers/app.py:66 #: xpack/plugins/change_auth_plan/serializers/asset.py:179 -#: xpack/plugins/cloud/models.py:176 +#: xpack/plugins/cloud/models.py:179 msgid "Reason" msgstr "原因" @@ -784,7 +812,7 @@ msgstr "带宽" msgid "Contact" msgstr "联系人" -#: assets/models/cluster.py:22 users/models/user.py:570 +#: assets/models/cluster.py:22 users/models/user.py:587 msgid "Phone" msgstr "手机" @@ -810,7 +838,7 @@ msgid "Default" msgstr "默认" #: assets/models/cluster.py:36 assets/models/label.py:14 rbac/const.py:6 -#: users/models/user.py:786 +#: users/models/user.py:803 msgid "System" msgstr "系统" @@ -819,8 +847,8 @@ msgid "Default Cluster" msgstr "默认Cluster" #: assets/models/cmd_filter.py:34 perms/models/base.py:86 -#: users/models/group.py:31 users/models/user.py:556 -#: users/templates/users/_select_user_modal.html:16 +#: rbac/ztree/tree_nodes.py:84 users/models/group.py:31 +#: users/models/user.py:573 users/templates/users/_select_user_modal.html:16 #: users/templates/users/user_asset_permission.html:39 #: users/templates/users/user_asset_permission.html:67 #: users/templates/users/user_database_app_permission.html:38 @@ -829,6 +857,7 @@ msgid "User group" msgstr "用户组" #: assets/models/cmd_filter.py:60 assets/serializers/system_user.py:54 +#: rbac/ztree/tree_nodes.py:123 msgid "Command filter" msgstr "命令过滤器" @@ -868,7 +897,7 @@ msgstr "每行一个命令" msgid "Ignore case" msgstr "忽略大小写" -#: assets/models/cmd_filter.py:103 +#: assets/models/cmd_filter.py:103 rbac/ztree/tree_nodes.py:126 msgid "Command filter rule" msgstr "命令过滤规则" @@ -884,16 +913,20 @@ msgstr "命令复核" msgid "Gateway" msgstr "网关" -#: assets/models/domain.py:127 +#: assets/models/domain.py:74 +msgid "Test gateway" +msgstr "测试网关" + +#: assets/models/domain.py:130 #, python-brace-format msgid "Unable to connect to port {port} on {ip}" msgstr "无法连接到 {ip} 上的端口 {port}" -#: assets/models/domain.py:130 +#: assets/models/domain.py:133 msgid "Authentication failed" msgstr "认证失败" -#: assets/models/domain.py:132 assets/models/domain.py:154 +#: assets/models/domain.py:135 assets/models/domain.py:157 msgid "Connect failed" msgstr "连接失败" @@ -937,7 +970,7 @@ msgstr "新节点" msgid "empty" msgstr "空" -#: assets/models/node.py:545 perms/models/asset_permission.py:99 +#: assets/models/node.py:545 perms/models/asset_permission.py:103 msgid "Key" msgstr "键" @@ -945,7 +978,7 @@ msgstr "键" msgid "Full value" msgstr "全称" -#: assets/models/node.py:550 perms/models/asset_permission.py:100 +#: assets/models/node.py:550 perms/models/asset_permission.py:104 msgid "Parent key" msgstr "ssh私钥" @@ -953,7 +986,7 @@ msgstr "ssh私钥" #: users/templates/users/user_asset_permission.html:41 #: users/templates/users/user_asset_permission.html:73 #: users/templates/users/user_asset_permission.html:158 -#: xpack/plugins/cloud/models.py:93 xpack/plugins/cloud/serializers/task.py:69 +#: xpack/plugins/cloud/models.py:96 xpack/plugins/cloud/serializers/task.py:69 msgid "Node" msgstr "节点" @@ -1032,6 +1065,18 @@ msgid "Switch from" msgstr "切换自" #: assets/models/user.py:327 +msgid "Can view system user asset" +msgstr "可以查看系统用户资产列表" + +#: assets/models/user.py:328 +msgid "Can add asset to system user" +msgstr "可以添加资产到系统用户" + +#: assets/models/user.py:329 +msgid "Can remove system user asset" +msgstr "可以移除系统用户资产" + +#: assets/models/user.py:330 msgid "Can match system user" msgstr "可以匹配系统用户" @@ -1343,7 +1388,8 @@ msgstr "日志审计" #: audits/models.py:27 audits/models.py:57 #: authentication/templates/authentication/_access_key_modal.html:65 -#: rbac/tree.py:317 users/templates/users/user_asset_permission.html:128 +#: rbac/tree.py:226 rbac/ztree/tree.py:156 +#: users/templates/users/user_asset_permission.html:128 #: users/templates/users/user_database_app_permission.html:111 msgid "Delete" msgstr "删除" @@ -1397,12 +1443,12 @@ msgstr "文件管理" #: audits/models.py:55 #: authentication/templates/authentication/_access_key_modal.html:22 -#: rbac/tree.py:314 +#: rbac/tree.py:223 rbac/ztree/tree.py:153 msgid "Create" msgstr "创建" -#: audits/models.py:56 rbac/tree.py:316 templates/_csv_import_export.html:18 -#: templates/_csv_update_modal.html:6 +#: audits/models.py:56 rbac/tree.py:225 rbac/ztree/tree.py:155 +#: templates/_csv_import_export.html:18 templates/_csv_update_modal.html:6 #: users/templates/users/user_asset_permission.html:127 #: users/templates/users/user_database_app_permission.html:110 msgid "Update" @@ -1465,14 +1511,14 @@ msgstr "用户代理" #: audits/models.py:124 #: authentication/templates/authentication/_mfa_confirm_modal.html:14 -#: users/forms/profile.py:64 users/models/user.py:573 +#: users/forms/profile.py:64 users/models/user.py:590 #: users/serializers/profile.py:121 msgid "MFA" msgstr "MFA" #: audits/models.py:126 terminal/models/status.py:33 -#: tickets/models/ticket.py:140 xpack/plugins/cloud/models.py:172 -#: xpack/plugins/cloud/models.py:224 +#: tickets/models/ticket.py:140 xpack/plugins/cloud/models.py:175 +#: xpack/plugins/cloud/models.py:227 msgid "Status" msgstr "状态" @@ -1509,7 +1555,7 @@ msgid "Hosts display" msgstr "主机名称" #: audits/serializers.py:96 ops/models/command.py:27 -#: xpack/plugins/cloud/models.py:170 +#: xpack/plugins/cloud/models.py:173 msgid "Result" msgstr "结果" @@ -1543,13 +1589,13 @@ msgstr "认证令牌" #: audits/signal_handlers.py:71 authentication/notifications.py:73 #: authentication/views/login.py:164 authentication/views/wecom.py:158 -#: notifications/backends/__init__.py:11 users/models/user.py:609 +#: notifications/backends/__init__.py:11 users/models/user.py:626 msgid "WeCom" msgstr "企业微信" #: audits/signal_handlers.py:72 authentication/views/dingtalk.py:160 #: authentication/views/login.py:170 notifications/backends/__init__.py:12 -#: users/models/user.py:610 +#: users/models/user.py:627 msgid "DingTalk" msgstr "钉钉" @@ -1624,6 +1670,7 @@ msgid "{AssetPermission} REMOVE {UserGroup}" msgstr "{AssetPermission} 移除 {UserGroup}" #: audits/signal_handlers.py:131 perms/models/asset_permission.py:29 +#: rbac/ztree/tree_nodes.py:27 rbac/ztree/tree_nodes.py:171 #: users/templates/users/_user_detail_nav_header.html:31 msgid "Asset permission" msgstr "资产授权" @@ -1695,6 +1742,7 @@ msgid "{ApplicationPermission} REMOVE {UserGroup}" msgstr "{ApplicationPermission} 移除 {UserGroup}" #: audits/signal_handlers.py:156 perms/models/application_permission.py:38 +#: rbac/ztree/tree_nodes.py:90 rbac/ztree/tree_nodes.py:174 msgid "Application permission" msgstr "应用授权" @@ -2029,11 +2077,15 @@ msgstr "" #: authentication/models.py:61 msgid "Connection token" -msgstr "连接Token" +msgstr "连接令牌" -#: authentication/models.py:67 +#: authentication/models.py:63 +msgid "Can view connection token secret" +msgstr "可以查看连接令牌密文" + +#: authentication/models.py:70 msgid "Super connection token" -msgstr "超级连接Token" +msgstr "超级连接令牌" #: authentication/notifications.py:19 msgid "Different city login reminder" @@ -2076,14 +2128,14 @@ msgid "Show" msgstr "显示" #: authentication/templates/authentication/_access_key_modal.html:66 -#: settings/serializers/security.py:39 users/models/user.py:445 +#: settings/serializers/security.py:39 users/models/user.py:462 #: users/serializers/profile.py:111 users/templates/users/mfa_setting.html:60 #: users/templates/users/user_verify_mfa.html:36 msgid "Disable" msgstr "禁用" #: authentication/templates/authentication/_access_key_modal.html:67 -#: users/models/user.py:446 users/serializers/profile.py:112 +#: users/models/user.py:463 users/serializers/profile.py:112 #: users/templates/users/mfa_setting.html:26 #: users/templates/users/mfa_setting.html:67 msgid "Enable" @@ -2332,7 +2384,7 @@ msgid "The FeiShu is already bound to another user" msgstr "该飞书已经绑定其他用户" #: authentication/views/feishu.py:148 authentication/views/login.py:176 -#: notifications/backends/__init__.py:14 users/models/user.py:611 +#: notifications/backends/__init__.py:14 users/models/user.py:628 msgid "FeiShu" msgstr "飞书" @@ -2627,11 +2679,11 @@ msgid "Notifications" msgstr "通知" #: notifications/backends/__init__.py:10 users/forms/profile.py:101 -#: users/models/user.py:552 +#: users/models/user.py:569 msgid "Email" msgstr "邮件" -#: notifications/backends/__init__.py:13 +#: notifications/backends/__init__.py:13 rbac/ztree/tree_nodes.py:257 msgid "Site message" msgstr "站内信" @@ -2834,7 +2886,7 @@ msgstr "当前组织 ({}) 不能被删除" msgid "The organization have resource ({}) cannot be deleted" msgstr "组织存在资源 ({}) 不能被删除" -#: orgs/apps.py:7 rbac/tree.py:185 +#: orgs/apps.py:7 rbac/tree.py:97 msgid "App organizations" msgstr "组织管理" @@ -2853,7 +2905,7 @@ msgid "Can view root org" msgstr "可以查看全局组织" #: orgs/models.py:198 rbac/models/role.py:46 rbac/models/rolebinding.py:38 -#: users/models/user.py:560 users/templates/users/_select_user_modal.html:15 +#: users/models/user.py:577 users/templates/users/_select_user_modal.html:15 msgid "Role" msgstr "角色" @@ -2869,51 +2921,83 @@ msgstr "管理员正在修改授权,请稍等" msgid "The authorization cannot be revoked for the time being" msgstr "该授权暂时不能撤销" -#: perms/models/application_permission.py:110 -msgid "Permed app" -msgstr "授权的应用" +#: perms/models/application_permission.py:40 +msgid "Can view application of permission to user" +msgstr "可以查看授权给用户的应用" #: perms/models/application_permission.py:112 -msgid "Can view my apps" -msgstr "可以查看我的应用" +msgid "Permed application" +msgstr "授权的应用" -#: perms/models/application_permission.py:113 -msgid "Can connect my apps" -msgstr "可以我的应用" - -#: perms/models/application_permission.py:114 +#: perms/models/application_permission.py:115 msgid "Can view user apps" msgstr "可以查看用户授权的应用" -#: perms/models/application_permission.py:115 +#: perms/models/application_permission.py:116 msgid "Can view usergroup apps" msgstr "可以查看用户组授权的应用" -#: perms/models/asset_permission.py:132 +#: perms/models/application_permission.py:123 +msgid "Permed remote application" +msgstr "授权的远程应用" + +#: perms/models/application_permission.py:126 +msgid "Can view my remoteapp" +msgstr "可以查看我的应用" + +#: perms/models/application_permission.py:127 +msgid "Can connect my remoteapp" +msgstr "可以连接我的远程应用" + +#: perms/models/application_permission.py:137 +msgid "Can view my database application" +msgstr "可以查看我的数据库应用" + +#: perms/models/application_permission.py:138 +msgid "Can connect my database application" +msgstr "可以连接我的数据库应用" + +#: perms/models/application_permission.py:148 +msgid "Can view my kubernetes application" +msgstr "可以查看我的Kubernetes" + +#: perms/models/application_permission.py:149 +msgid "Can connect my kubernetes application" +msgstr "可以连接我的Kubernetes" + +#: perms/models/asset_permission.py:32 +msgid "Can view asset of permission to user" +msgstr "可以查看授权给用户的资产" + +#: perms/models/asset_permission.py:33 +msgid "Can view asset of permission to user group" +msgstr "可以查看授权给用户组的资产" + +#: perms/models/asset_permission.py:136 msgid "Ungrouped" msgstr "未分组" -#: perms/models/asset_permission.py:134 +#: perms/models/asset_permission.py:138 msgid "Favorite" msgstr "收藏夹" -#: perms/models/asset_permission.py:181 +#: perms/models/asset_permission.py:185 msgid "Permed asset" msgstr "授权的资产" -#: perms/models/asset_permission.py:183 +#: perms/models/asset_permission.py:187 msgid "Can view my assets" -msgstr "可以查看资产" +msgstr "可以查看我的资产" -#: perms/models/asset_permission.py:184 +#: perms/models/asset_permission.py:188 msgid "Can connect my assets" -msgstr "可以连接资产" +msgstr "可以连接我的资产" -#: perms/models/asset_permission.py:185 +#: perms/models/asset_permission.py:189 msgid "Can view user assets" msgstr "可以查看用户授权的资产" -#: perms/models/asset_permission.py:186 +#: perms/models/asset_permission.py:190 msgid "Can view usergroup assets" msgstr "可以查看用户组授权的资产" @@ -2948,7 +3032,7 @@ msgstr "剪贴板复制粘贴" #: perms/models/base.py:90 #: tickets/serializers/ticket/meta/ticket_type/apply_application.py:58 #: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:60 -#: users/models/user.py:592 +#: users/models/user.py:609 msgid "Date expired" msgstr "失效日期" @@ -2991,15 +3075,15 @@ msgstr "组织 ({}) 的应用授权" #: perms/serializers/application/permission.py:20 #: perms/serializers/application/permission.py:41 #: perms/serializers/asset/permission.py:19 -#: perms/serializers/asset/permission.py:45 users/serializers/user.py:135 +#: perms/serializers/asset/permission.py:45 users/serializers/user.py:139 msgid "Is valid" msgstr "账号是否有效" #: perms/serializers/application/permission.py:21 #: perms/serializers/application/permission.py:40 #: perms/serializers/asset/permission.py:20 -#: perms/serializers/asset/permission.py:44 users/serializers/user.py:84 -#: users/serializers/user.py:137 +#: perms/serializers/asset/permission.py:44 users/serializers/user.py:85 +#: users/serializers/user.py:141 msgid "Is expired" msgstr "已过期" @@ -3061,15 +3145,15 @@ msgstr "" msgid "If you have any question, please contact the administrator" msgstr "如果有疑问或需求,请联系系统管理员" -#: rbac/api/role.py:31 +#: rbac/api/role.py:32 msgid "Internal role, can't be destroy" msgstr "" -#: rbac/api/role.py:34 +#: rbac/api/role.py:36 msgid "The role has been bound to users, can't be destroy" msgstr "" -#: rbac/api/role.py:41 +#: rbac/api/role.py:43 msgid "Internal role, can't be update" msgstr "" @@ -3081,27 +3165,27 @@ msgstr "{} 至少有一个系统角色" msgid "RBAC" msgstr "RBAC" -#: rbac/builtin.py:90 +#: rbac/builtin.py:94 msgid "SystemAdmin" msgstr "系统管理员" -#: rbac/builtin.py:93 +#: rbac/builtin.py:97 msgid "SystemAuditor" msgstr "系统审计员" -#: rbac/builtin.py:96 +#: rbac/builtin.py:100 msgid "SystemComponent" msgstr "系统组件" -#: rbac/builtin.py:102 +#: rbac/builtin.py:106 msgid "OrgAdmin" msgstr "组织管理员" -#: rbac/builtin.py:105 +#: rbac/builtin.py:109 msgid "OrgAuditor" msgstr "组织审计员" -#: rbac/builtin.py:108 +#: rbac/builtin.py:112 msgid "OrgUser" msgstr "组织用户" @@ -3110,29 +3194,29 @@ msgid "Menu permission" msgstr "菜单授权" #: rbac/models/menu.py:15 -msgid "Can view resource statistics" -msgstr "可以查看资源统计" +msgid "Can view console view" +msgstr "可以显示控制台" #: rbac/models/menu.py:16 -msgid "Can view console view" -msgstr "可以查看控制台" +msgid "Can view audit view" +msgstr "可以显示审计台" #: rbac/models/menu.py:17 -msgid "Can view audit view" -msgstr "可以查看审计台" +msgid "Can view workspace view" +msgstr "可以显示工作台" #: rbac/models/menu.py:18 -msgid "Can view workspace view" -msgstr "可以查看工作台" - -#: rbac/models/menu.py:19 msgid "Can view web terminal" msgstr "Web终端" -#: rbac/models/menu.py:20 +#: rbac/models/menu.py:19 msgid "Can view file manager" msgstr "文件管理" +#: rbac/models/menu.py:20 +msgid "Can view dashboard" +msgstr "仪表盘" + #: rbac/models/permission.py:22 msgid "Permission" msgstr "授权" @@ -3149,11 +3233,11 @@ msgstr "授权" msgid "Built-in" msgstr "内置" -#: rbac/models/role.py:127 +#: rbac/models/role.py:127 rbac/ztree/tree_nodes.py:230 msgid "System role" msgstr "系统角色" -#: rbac/models/role.py:135 +#: rbac/models/role.py:135 rbac/ztree/tree_nodes.py:227 msgid "Organization role" msgstr "组织角色" @@ -3195,78 +3279,356 @@ msgstr "角色显示" msgid "Has bound this role" msgstr "已经绑定" -#: rbac/tree.py:17 rbac/tree.py:18 +#: rbac/tree.py:17 rbac/tree.py:18 rbac/ztree/tree_nodes.py:6 msgid "All permissions" msgstr "所有权限" -#: rbac/tree.py:26 +#: rbac/tree.py:24 rbac/ztree/tree_nodes.py:12 msgid "Console view" msgstr "控制台" -#: rbac/tree.py:30 +#: rbac/tree.py:25 rbac/ztree/tree_nodes.py:21 msgid "Workspace view" msgstr "工作台" -#: rbac/tree.py:34 +#: rbac/tree.py:26 rbac/ztree/tree_nodes.py:24 msgid "Audit view" msgstr "审计台" -#: rbac/tree.py:38 settings/models.py:140 +#: rbac/tree.py:27 rbac/ztree/tree_nodes.py:51 settings/models.py:140 msgid "System setting" msgstr "系统设置" -#: rbac/tree.py:42 +#: rbac/tree.py:28 msgid "Other" msgstr "其它" -#: rbac/tree.py:62 +#: rbac/tree.py:36 msgid "Accounts" msgstr "账号管理" -#: rbac/tree.py:79 +#: rbac/tree.py:40 rbac/ztree/tree_nodes.py:30 msgid "Session audits" msgstr "会话审计" -#: rbac/tree.py:108 +#: rbac/tree.py:50 msgid "Cloud import" msgstr "云同步" -#: rbac/tree.py:113 +#: rbac/tree.py:51 msgid "Backup account" msgstr "备份账号" -#: rbac/tree.py:118 +#: rbac/tree.py:52 msgid "Gather account" msgstr "收集账号" -#: rbac/tree.py:123 +#: rbac/tree.py:53 msgid "App change auth" msgstr "应用改密" -#: rbac/tree.py:128 +#: rbac/tree.py:54 msgid "Asset change auth" msgstr "资产改密" -#: rbac/tree.py:133 +#: rbac/tree.py:55 rbac/ztree/tree_nodes.py:198 msgid "Terminal setting" msgstr "终端设置" -#: rbac/tree.py:138 +#: rbac/tree.py:56 rbac/ztree/tree_nodes.py:42 msgid "My assets" msgstr "我的资产" -#: rbac/tree.py:143 +#: rbac/tree.py:57 msgid "My apps" msgstr "我的应用" -#: rbac/tree.py:186 +#: rbac/tree.py:98 msgid "Ticket comment" msgstr "工单评论" -#: rbac/tree.py:315 +#: rbac/tree.py:224 rbac/ztree/tree.py:154 msgid "View" msgstr "查看" +#: rbac/ztree/tree.py:99 rbac/ztree/tree_nodes.py:96 +msgid "Detail" +msgstr "详情" + +#: rbac/ztree/tree_nodes.py:9 +msgid "View menu" +msgstr "视图菜单" + +#: rbac/ztree/tree_nodes.py:15 +msgid "User management" +msgstr "用户管理" + +#: rbac/ztree/tree_nodes.py:18 +msgid "User list" +msgstr "用户列表" + +#: rbac/ztree/tree_nodes.py:33 +msgid "Online/Offline Session record" +msgstr "在线/离线会话记录" + +#: rbac/ztree/tree_nodes.py:36 +msgid "Asset management" +msgstr "资产管理" + +#: rbac/ztree/tree_nodes.py:39 rbac/ztree/tree_nodes.py:117 +msgid "Asset list" +msgstr "资产列表" + +#: rbac/ztree/tree_nodes.py:45 +msgid "My application" +msgstr "我的应用" + +#: rbac/ztree/tree_nodes.py:48 rbac/ztree/tree_nodes.py:254 +msgid "Bulk command" +msgstr "批量命令" + +#: rbac/ztree/tree_nodes.py:54 +msgid "Ticket system" +msgstr "工单系统" + +#: rbac/ztree/tree_nodes.py:57 templates/_header_bar.html:12 +msgid "Help" +msgstr "帮助" + +#: rbac/ztree/tree_nodes.py:60 +msgid "API permission" +msgstr "API权限" + +#: rbac/ztree/tree_nodes.py:63 +msgid "Application management" +msgstr "应用管理" + +#: rbac/ztree/tree_nodes.py:66 +msgid "Account management" +msgstr "账号管理" + +#: rbac/ztree/tree_nodes.py:69 +msgid "Permission management" +msgstr "权限管理" + +#: rbac/ztree/tree_nodes.py:72 +msgid "Access control" +msgstr "访问控制" + +#: rbac/ztree/tree_nodes.py:75 +msgid "Job center" +msgstr "作业中心" + +#: rbac/ztree/tree_nodes.py:78 +msgid "Session audit" +msgstr "会话审计" + +#: rbac/ztree/tree_nodes.py:81 +msgid "Log audit" +msgstr "日志审计" + +#: rbac/ztree/tree_nodes.py:87 +msgid "Role list" +msgstr "角色列表" + +#: rbac/ztree/tree_nodes.py:93 +msgid "User login acl" +msgstr "用户登录规则" + +#: rbac/ztree/tree_nodes.py:99 +msgid "Permission list" +msgstr "权限列表" + +#: rbac/ztree/tree_nodes.py:102 +msgid "Node tree" +msgstr "节点树" + +#: rbac/ztree/tree_nodes.py:105 +msgid "Cloud sync" +msgstr "云同步" + +#: rbac/ztree/tree_nodes.py:108 +msgid "Sync instance task list" +msgstr "同步实例任务列表" + +#: rbac/ztree/tree_nodes.py:111 rbac/ztree/tree_nodes.py:120 +msgid "Account list" +msgstr "账号列表" + +#: rbac/ztree/tree_nodes.py:114 +msgid "Common/Admin User" +msgstr "普通/特权用户" + +#: rbac/ztree/tree_nodes.py:129 +msgid "Platform list" +msgstr "平台列表" + +#: rbac/ztree/tree_nodes.py:132 +msgid "Label management" +msgstr "标签管理" + +#: rbac/ztree/tree_nodes.py:144 +msgid "Asset account" +msgstr "资产账号" + +#: rbac/ztree/tree_nodes.py:150 xpack/plugins/gathered_user/meta.py:11 +msgid "Gathered user" +msgstr "收集用户" + +#: rbac/ztree/tree_nodes.py:153 +msgid "Gathered user list" +msgstr "收集用户列表" + +#: rbac/ztree/tree_nodes.py:156 +msgid "Gathered user task list" +msgstr "收集用户任务列表" + +#: rbac/ztree/tree_nodes.py:159 xpack/plugins/change_auth_plan/meta.py:9 +#: xpack/plugins/change_auth_plan/models/asset.py:123 +msgid "Change auth plan" +msgstr "改密计划" + +#: rbac/ztree/tree_nodes.py:162 +#: xpack/plugins/change_auth_plan/models/asset.py:67 +msgid "Asset change auth plan" +msgstr "资产改密计划" + +#: rbac/ztree/tree_nodes.py:165 xpack/plugins/change_auth_plan/models/app.py:46 +#: xpack/plugins/change_auth_plan/models/app.py:95 +msgid "Application change auth plan" +msgstr "应用改密计划" + +#: rbac/ztree/tree_nodes.py:168 +msgid "Account backup" +msgstr "账号备份" + +#: rbac/ztree/tree_nodes.py:177 +msgid "Asset login" +msgstr "资产登录" + +#: rbac/ztree/tree_nodes.py:180 +msgid "Task list" +msgstr "任务列表" + +#: rbac/ztree/tree_nodes.py:183 terminal/models/command.py:24 +msgid "Command record" +msgstr "命令记录" + +#: rbac/ztree/tree_nodes.py:186 +msgid "File transfer" +msgstr "文件传输" + +#: rbac/ztree/tree_nodes.py:189 +msgid "Remote App" +msgstr "远程应用" + +#: rbac/ztree/tree_nodes.py:201 +msgid "Terminal management" +msgstr "终端管理" + +#: rbac/ztree/tree_nodes.py:204 terminal/models/storage.py:113 +#: terminal/models/terminal.py:108 +msgid "Command storage" +msgstr "命令存储" + +#: rbac/ztree/tree_nodes.py:207 terminal/models/storage.py:173 +#: terminal/models/terminal.py:109 +msgid "Replay storage" +msgstr "录像存储" + +#: rbac/ztree/tree_nodes.py:210 +msgid "Organization management" +msgstr "组织管理" + +#: rbac/ztree/tree_nodes.py:213 xpack/plugins/license/meta.py:11 +#: xpack/plugins/license/models.py:127 +msgid "License" +msgstr "许可证" + +#: rbac/ztree/tree_nodes.py:218 +msgid "View all permission" +msgstr "查看所有权限" + +#: rbac/ztree/tree_nodes.py:221 +msgid "Domain list" +msgstr "网域列表" + +#: rbac/ztree/tree_nodes.py:224 +msgid "Gateway list" +msgstr "网关列表" + +#: rbac/ztree/tree_nodes.py:233 +msgid "Run gather user task" +msgstr "执行收集用户任务" + +#: rbac/ztree/tree_nodes.py:236 +msgid "Run asset change auth plan" +msgstr "执行资产改密计划" + +#: rbac/ztree/tree_nodes.py:239 +msgid "Run application change auth plan" +msgstr "执行应用改密计划" + +#: rbac/ztree/tree_nodes.py:242 +msgid "Run account backup plan" +msgstr "执行账号备份计划" + +#: rbac/ztree/tree_nodes.py:245 +msgid "Run task" +msgstr "运行任务" + +#: rbac/ztree/tree_nodes.py:248 +msgid "View task version" +msgstr "查看任务版本" + +#: rbac/ztree/tree_nodes.py:251 +msgid "View execution history" +msgstr "查看执行历史" + +#: rbac/ztree/tree_nodes.py:260 +msgid "Message subscription" +msgstr "消息订阅" + +#: rbac/ztree/tree_nodes.py:263 +msgid "Component monitor" +msgstr "组件监控" + +#: rbac/ztree/tree_nodes.py:266 +msgid "View my/assigned ticket" +msgstr "查看我的/待审批工单" + +#: rbac/ztree/tree_nodes.py:269 +msgid "Create asset/application ticket" +msgstr "创建资产/应用申请工单" + +#: rbac/ztree/tree_nodes.py:272 +msgid "Change/close ticket" +msgstr "更新/关闭工单" + +#: rbac/ztree/tree_nodes.py:275 +msgid "View some of the assets searched" +msgstr "查看搜索的部分资产" + +#: rbac/ztree/tree_nodes.py:282 +msgid "Overview" +msgstr "概览" + +#: rbac/ztree/tree_nodes.py:287 rbac/ztree/tree_nodes.py:296 +msgid "View permission user" +msgstr "查看授权用户" + +#: rbac/ztree/tree_nodes.py:290 rbac/ztree/tree_nodes.py:299 +msgid "Add user to role" +msgstr "添加用户到角色" + +#: rbac/ztree/tree_nodes.py:293 rbac/ztree/tree_nodes.py:302 +msgid "Remove user from role" +msgstr "从角色移除用户" + +#: rbac/ztree/tree_nodes.py:305 +msgid "Run sync instance task" +msgstr "执行同步实例任务" + #: settings/api/alibaba_sms.py:31 settings/api/tencent_sms.py:35 msgid "test_phone is required" msgstr "测试手机号 该字段是必填项。" @@ -3305,6 +3667,38 @@ msgstr "成功导入 {} 个用户 ( 组织: {} )" msgid "Settings" msgstr "系统设置" +#: settings/models.py:142 +msgid "Can change basic setting" +msgstr "基本设置" + +#: settings/models.py:143 +msgid "Can change email setting" +msgstr "邮件设置" + +#: settings/models.py:144 +msgid "Can change auth setting" +msgstr "认证设置" + +#: settings/models.py:145 +msgid "Can change sms setting" +msgstr "短信设置" + +#: settings/models.py:146 +msgid "Can change security setting" +msgstr "安全设置" + +#: settings/models.py:147 +msgid "Can change clean setting" +msgstr "定期清理" + +#: settings/models.py:148 +msgid "Can change other setting" +msgstr "其他设置" + +#: settings/models.py:149 +msgid "Can change terminal basic setting" +msgstr "基本设置" + #: settings/serializers/auth/base.py:10 msgid "CAS Auth" msgstr "CAS 认证" @@ -4262,10 +4656,6 @@ msgstr "下载更新的模板或使用导出的csv格式" msgid "Download the update template" msgstr "下载更新模版" -#: templates/_header_bar.html:12 -msgid "Help" -msgstr "帮助" - #: templates/_header_bar.html:19 msgid "Docs" msgstr "文档" @@ -4608,31 +4998,31 @@ msgstr "用户没有权限" msgid "Secure session sharing settings is disabled" msgstr "未开启会话共享" -#: terminal/api/storage.py:29 +#: terminal/api/storage.py:28 msgid "Deleting the default storage is not allowed" msgstr "不允许删除默认存储配置" -#: terminal/api/storage.py:32 +#: terminal/api/storage.py:31 msgid "Cannot delete storage that is being used" msgstr "不允许删除正在使用的存储配置" -#: terminal/api/storage.py:73 terminal/api/storage.py:74 +#: terminal/api/storage.py:72 terminal/api/storage.py:73 msgid "Command storages" msgstr "命令存储" -#: terminal/api/storage.py:80 +#: terminal/api/storage.py:79 msgid "Invalid" msgstr "无效" -#: terminal/api/storage.py:120 +#: terminal/api/storage.py:119 msgid "Test failure: {}" msgstr "测试失败: {}" -#: terminal/api/storage.py:123 +#: terminal/api/storage.py:122 msgid "Test successful" msgstr "测试成功" -#: terminal/api/storage.py:125 +#: terminal/api/storage.py:124 msgid "Test failure: Account invalid" msgstr "测试失败: 账号无效" @@ -4717,10 +5107,6 @@ msgstr "不支持批量创建" msgid "Storage is invalid" msgstr "存储无效" -#: terminal/models/command.py:24 -msgid "Command record" -msgstr "命令记录" - #: terminal/models/replay.py:12 msgid "Session replay" msgstr "会话录像" @@ -4747,7 +5133,7 @@ msgstr "结束日期" #: terminal/models/session.py:242 msgid "Session record" -msgstr "会话" +msgstr "会话记录" #: terminal/models/session.py:244 msgid "Can monitor session" @@ -4759,7 +5145,7 @@ msgstr "可以分享会话" #: terminal/models/session.py:246 msgid "Can terminate session" -msgstr "可以中断会话" +msgstr "可以终断会话" #: terminal/models/session.py:247 msgid "Can validate session action perm" @@ -4850,14 +5236,6 @@ msgstr "运行时间" msgid "Default storage" msgstr "默认存储" -#: terminal/models/storage.py:113 terminal/models/terminal.py:108 -msgid "Command storage" -msgstr "命令存储" - -#: terminal/models/storage.py:173 terminal/models/terminal.py:109 -msgid "Replay storage" -msgstr "录像存储" - #: terminal/models/task.py:17 msgid "Args" msgstr "参数" @@ -4938,7 +5316,7 @@ msgstr "端点无效: 移除路径 `{}`" msgid "Bucket" msgstr "桶名称" -#: terminal/serializers/storage.py:34 users/models/user.py:584 +#: terminal/serializers/storage.py:34 users/models/user.py:601 msgid "Secret key" msgstr "密钥" @@ -4948,7 +5326,7 @@ msgstr "密钥" msgid "Endpoint" msgstr "端点" -#: terminal/serializers/storage.py:66 xpack/plugins/cloud/models.py:217 +#: terminal/serializers/storage.py:66 xpack/plugins/cloud/models.py:220 msgid "Region" msgstr "地域" @@ -5545,68 +5923,68 @@ msgstr "不能和原来的密钥相同" msgid "Not a valid ssh public key" msgstr "SSH密钥不合法" -#: users/forms/profile.py:160 users/models/user.py:581 +#: users/forms/profile.py:160 users/models/user.py:598 #: users/templates/users/user_password_update.html:48 msgid "Public key" msgstr "SSH公钥" -#: users/models/user.py:447 +#: users/models/user.py:464 msgid "Force enable" msgstr "强制启用" -#: users/models/user.py:514 +#: users/models/user.py:531 msgid "Local" msgstr "数据库" -#: users/models/user.py:562 users/serializers/user.py:136 +#: users/models/user.py:579 users/serializers/user.py:140 msgid "Is service account" msgstr "服务账号" -#: users/models/user.py:564 +#: users/models/user.py:581 msgid "Avatar" msgstr "头像" -#: users/models/user.py:567 +#: users/models/user.py:584 msgid "Wechat" msgstr "微信" -#: users/models/user.py:578 +#: users/models/user.py:595 msgid "Private key" msgstr "ssh私钥" -#: users/models/user.py:600 +#: users/models/user.py:617 msgid "Source" msgstr "来源" -#: users/models/user.py:604 +#: users/models/user.py:621 msgid "Date password last updated" msgstr "最后更新密码日期" -#: users/models/user.py:607 +#: users/models/user.py:624 msgid "Need update password" msgstr "需要更新密码" -#: users/models/user.py:771 +#: users/models/user.py:788 msgid "Can invite user" msgstr "可以邀请用户" -#: users/models/user.py:772 +#: users/models/user.py:789 msgid "Can remove user" msgstr "可以移除用户" -#: users/models/user.py:773 +#: users/models/user.py:790 msgid "Can match user" msgstr "可以匹配用户" -#: users/models/user.py:782 +#: users/models/user.py:799 msgid "Administrator" msgstr "管理员" -#: users/models/user.py:785 +#: users/models/user.py:802 msgid "Administrator is the super user of system" msgstr "Administrator是初始的超级管理员" -#: users/models/user.py:810 +#: users/models/user.py:827 msgid "User password history" msgstr "用户密码历史" @@ -5657,97 +6035,97 @@ msgstr "新密码不能是最近 {} 次的密码" msgid "The newly set password is inconsistent" msgstr "两次密码不一致" -#: users/serializers/profile.py:141 users/serializers/user.py:134 +#: users/serializers/profile.py:141 users/serializers/user.py:138 msgid "Is first login" msgstr "首次登录" -#: users/serializers/user.py:25 users/serializers/user.py:32 +#: users/serializers/user.py:26 users/serializers/user.py:33 msgid "System roles" msgstr "系统角色" -#: users/serializers/user.py:30 users/serializers/user.py:33 +#: users/serializers/user.py:31 users/serializers/user.py:34 msgid "Org roles" msgstr "组织角色" -#: users/serializers/user.py:76 +#: users/serializers/user.py:77 #: xpack/plugins/change_auth_plan/models/base.py:35 #: xpack/plugins/change_auth_plan/serializers/base.py:22 msgid "Password strategy" msgstr "密码策略" -#: users/serializers/user.py:78 +#: users/serializers/user.py:79 msgid "MFA enabled" msgstr "MFA" -#: users/serializers/user.py:79 +#: users/serializers/user.py:80 msgid "MFA force enabled" msgstr "强制 MFA" -#: users/serializers/user.py:81 +#: users/serializers/user.py:82 msgid "MFA level display" msgstr "MFA 等级名称" -#: users/serializers/user.py:83 +#: users/serializers/user.py:84 msgid "Login blocked" msgstr "登录被阻塞" -#: users/serializers/user.py:86 +#: users/serializers/user.py:87 msgid "Can public key authentication" msgstr "能否公钥认证" -#: users/serializers/user.py:138 +#: users/serializers/user.py:142 msgid "Avatar url" msgstr "头像路径" -#: users/serializers/user.py:140 +#: users/serializers/user.py:144 msgid "Groups name" msgstr "用户组名" -#: users/serializers/user.py:141 +#: users/serializers/user.py:145 msgid "Source name" msgstr "用户来源名" -#: users/serializers/user.py:142 +#: users/serializers/user.py:146 msgid "Organization role name" msgstr "组织角色名称" -#: users/serializers/user.py:143 +#: users/serializers/user.py:147 msgid "Super role name" msgstr "超级角色名称" -#: users/serializers/user.py:144 +#: users/serializers/user.py:148 msgid "Total role name" msgstr "汇总角色名称" -#: users/serializers/user.py:146 +#: users/serializers/user.py:150 msgid "Is wecom bound" msgstr "是否绑定了企业微信" -#: users/serializers/user.py:147 +#: users/serializers/user.py:151 msgid "Is dingtalk bound" msgstr "是否绑定了钉钉" -#: users/serializers/user.py:148 +#: users/serializers/user.py:152 msgid "Is feishu bound" msgstr "是否绑定了飞书" -#: users/serializers/user.py:149 +#: users/serializers/user.py:153 msgid "Is OTP bound" msgstr "是否绑定了虚拟 MFA" -#: users/serializers/user.py:151 +#: users/serializers/user.py:155 msgid "System role name" msgstr "系统角色名称" -#: users/serializers/user.py:236 +#: users/serializers/user.py:247 msgid "Select users" msgstr "选择用户" -#: users/serializers/user.py:237 +#: users/serializers/user.py:248 msgid "For security, only list several users" msgstr "为了安全,仅列出几个用户" -#: users/serializers/user.py:270 +#: users/serializers/user.py:281 msgid "name not unique" msgstr "名称重复" @@ -6094,16 +6472,6 @@ msgstr "" msgid "The parameter 'action' must be [{}]" msgstr "参数 'action' 必须是 [{}]" -#: xpack/plugins/change_auth_plan/meta.py:9 -#: xpack/plugins/change_auth_plan/models/asset.py:123 -msgid "Change auth plan" -msgstr "改密计划" - -#: xpack/plugins/change_auth_plan/models/app.py:46 -#: xpack/plugins/change_auth_plan/models/app.py:95 -msgid "Application change auth plan" -msgstr "应用改密计划" - #: xpack/plugins/change_auth_plan/models/app.py:99 #: xpack/plugins/change_auth_plan/models/app.py:151 msgid "Application change auth plan execution" @@ -6140,10 +6508,6 @@ msgstr "替换 (由 JumpServer 生成的密钥)" msgid "SSH Key strategy" msgstr "SSH 密钥策略" -#: xpack/plugins/change_auth_plan/models/asset.py:67 -msgid "Asset change auth plan" -msgstr "资产改密计划" - #: xpack/plugins/change_auth_plan/models/asset.py:134 msgid "Asset change auth plan execution" msgstr "资产改密计划执行" @@ -6360,64 +6724,71 @@ msgstr "云管中心" msgid "Provider" msgstr "云服务商" -#: xpack/plugins/cloud/models.py:39 xpack/plugins/cloud/models.py:82 -#: xpack/plugins/cloud/serializers/task.py:66 +#: xpack/plugins/cloud/models.py:39 +msgid "Cloud account" +msgstr "云账号" + +#: xpack/plugins/cloud/models.py:41 +msgid "Test cloud account" +msgstr "测试云账号" + +#: xpack/plugins/cloud/models.py:85 xpack/plugins/cloud/serializers/task.py:66 msgid "Account" msgstr "账号" -#: xpack/plugins/cloud/models.py:85 xpack/plugins/cloud/serializers/task.py:37 +#: xpack/plugins/cloud/models.py:88 xpack/plugins/cloud/serializers/task.py:37 msgid "Regions" msgstr "地域" -#: xpack/plugins/cloud/models.py:88 +#: xpack/plugins/cloud/models.py:91 msgid "Hostname strategy" msgstr "主机名策略" -#: xpack/plugins/cloud/models.py:97 xpack/plugins/cloud/serializers/task.py:67 +#: xpack/plugins/cloud/models.py:100 xpack/plugins/cloud/serializers/task.py:67 msgid "Unix admin user" msgstr "Unix 管理员" -#: xpack/plugins/cloud/models.py:101 xpack/plugins/cloud/serializers/task.py:68 +#: xpack/plugins/cloud/models.py:104 xpack/plugins/cloud/serializers/task.py:68 msgid "Windows admin user" msgstr "Windows 管理员" -#: xpack/plugins/cloud/models.py:107 xpack/plugins/cloud/serializers/task.py:45 +#: xpack/plugins/cloud/models.py:110 xpack/plugins/cloud/serializers/task.py:45 msgid "IP network segment group" msgstr "IP网段组" -#: xpack/plugins/cloud/models.py:110 xpack/plugins/cloud/serializers/task.py:71 +#: xpack/plugins/cloud/models.py:113 xpack/plugins/cloud/serializers/task.py:71 msgid "Always update" msgstr "总是更新" -#: xpack/plugins/cloud/models.py:116 +#: xpack/plugins/cloud/models.py:119 msgid "Date last sync" msgstr "最后同步日期" -#: xpack/plugins/cloud/models.py:127 xpack/plugins/cloud/models.py:168 +#: xpack/plugins/cloud/models.py:130 xpack/plugins/cloud/models.py:171 msgid "Sync instance task" msgstr "同步实例任务" -#: xpack/plugins/cloud/models.py:179 xpack/plugins/cloud/models.py:227 +#: xpack/plugins/cloud/models.py:182 xpack/plugins/cloud/models.py:230 msgid "Date sync" msgstr "同步日期" -#: xpack/plugins/cloud/models.py:183 +#: xpack/plugins/cloud/models.py:186 msgid "Sync instance task execution" msgstr "同步实例任务执行" -#: xpack/plugins/cloud/models.py:207 +#: xpack/plugins/cloud/models.py:210 msgid "Sync task" msgstr "同步任务" -#: xpack/plugins/cloud/models.py:211 +#: xpack/plugins/cloud/models.py:214 msgid "Sync instance task history" msgstr "同步实例任务历史" -#: xpack/plugins/cloud/models.py:214 +#: xpack/plugins/cloud/models.py:217 msgid "Instance" msgstr "实例" -#: xpack/plugins/cloud/models.py:231 +#: xpack/plugins/cloud/models.py:234 msgid "Sync instance detail" msgstr "同步实例详情" @@ -6656,10 +7027,6 @@ msgstr "定时执行" msgid "Account unavailable" msgstr "账号无效" -#: xpack/plugins/gathered_user/meta.py:11 -msgid "Gathered user" -msgstr "收集用户" - #: xpack/plugins/gathered_user/models.py:39 msgid "Gather user task" msgstr "收集用户任务" @@ -6720,10 +7087,6 @@ msgstr "许可证导入成功" msgid "License is invalid" msgstr "无效的许可证" -#: xpack/plugins/license/meta.py:11 xpack/plugins/license/models.py:127 -msgid "License" -msgstr "许可证" - #: xpack/plugins/license/models.py:71 msgid "Standard edition" msgstr "标准版" @@ -6740,82 +7103,5 @@ msgstr "旗舰版" msgid "Community edition" msgstr "社区版" -#~ msgid "Common permission" -#~ msgstr "通用权限" - -#~ msgid "Can view connect token secret" -#~ msgstr "可以查看 连接Token 密文" - -#~ msgid "AppAsset" -#~ msgstr "资产管理" - -#~ msgid "User and Organization" -#~ msgstr "用户与组织" - -#, python-brace-format -#~ msgid "{User} JOINED {Organization}" -#~ msgstr "{User} 加入 {Organization}" - -#, python-brace-format -#~ msgid "{User} LEFT {Organization}" -#~ msgstr "{User} 离开 {Organization}" - -#~ msgid "Dashboard" -#~ msgstr "仪表盘" - -#~ msgid "User list" -#~ msgstr "用户列表" - -#~ msgid "Asset list" -#~ msgstr "资产列表" - -#~ msgid "Domain list" -#~ msgstr "网域列表" - -#~ msgid "Command filters" -#~ msgstr "命令过滤" - -#~ msgid "Platform list" -#~ msgstr "平台列表" - -#~ msgid "RemoteApp" -#~ msgstr "远程应用" - -#~ msgid "Session offline" -#~ msgstr "历史会话" - -#~ msgid "Commands" -#~ msgstr "命令记录" - -#~ msgid "Job Center" -#~ msgstr "作业中心" - -#~ msgid "Task list" -#~ msgstr "任务列表" - -#~ msgid "Batch command" -#~ msgstr "批量命令" - -#~ msgid "FTP log" -#~ msgstr "FTP日志" - -#~ msgid "XPack" -#~ msgstr "XPack" - -#~ msgid "Account list" -#~ msgstr "账号列表" - -#~ msgid "Sync instance" -#~ msgstr "同步实例" - -#~ msgid "Can update" -#~ msgstr "是否可更新" - -#~ msgid "Can delete" -#~ msgstr "是否可删除" - -#~ msgid "Role limit to {}" -#~ msgstr "角色只能为 {}" - -#~ msgid "Public key update" -#~ msgstr "密钥更新" +#~ msgid "Can view resource statistics" +#~ msgstr "可以查看资源统计" diff --git a/apps/perms/migrations/0026_auto_20220307_1500.py b/apps/perms/migrations/0026_auto_20220307_1500.py index a86365b5f..efb4a1795 100644 --- a/apps/perms/migrations/0026_auto_20220307_1500.py +++ b/apps/perms/migrations/0026_auto_20220307_1500.py @@ -12,19 +12,6 @@ class Migration(migrations.Migration): ] operations = [ - migrations.CreateModel( - name='PermedApplication', - fields=[ - ], - options={ - 'verbose_name': 'Permed app', - 'permissions': [('view_myapps', 'Can view my apps'), ('connect_myapps', 'Can connect my apps'), ('view_userapps', 'Can view user apps'), ('view_usergroupapps', 'Can view usergroup apps')], - 'proxy': True, - 'indexes': [], - 'constraints': [], - }, - bases=('applications.application',), - ), migrations.CreateModel( name='PermedAsset', fields=[ diff --git a/apps/perms/migrations/0027_auto_20220310_0616.py b/apps/perms/migrations/0027_auto_20220310_0616.py new file mode 100644 index 000000000..74a57690a --- /dev/null +++ b/apps/perms/migrations/0027_auto_20220310_0616.py @@ -0,0 +1,78 @@ +# Generated by Django 3.1.14 on 2022-03-09 22:16 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('applications', '0019_databaseapp_kubernetesapp_remoteapp'), + ('perms', '0026_auto_20220307_1500'), + ] + + operations = [ + migrations.CreateModel( + name='PermedApplication', + fields=[ + ], + options={ + 'verbose_name': 'Permed application', + 'permissions': [('view_userapps', 'Can view user apps'), ('view_usergroupapps', 'Can view usergroup apps')], + 'proxy': True, + 'default_permissions': [], + 'indexes': [], + 'constraints': [], + }, + bases=('applications.application',), + ), + migrations.CreateModel( + name='PermedDatabaseApp', + fields=[ + ], + options={ + 'verbose_name': 'Database application', + 'permissions': [('view_mydatabaseapp', 'Can view my database application'), ('connect_mydatabaseapp', 'Can connect my database application')], + 'proxy': True, + 'default_permissions': [], + 'indexes': [], + 'constraints': [], + }, + bases=('applications.application',), + ), + migrations.CreateModel( + name='PermedKubernetesApp', + fields=[ + ], + options={ + 'verbose_name': 'Kubernetes', + 'permissions': [('view_mykubernetesapp', 'Can view my kubernetes application'), ('connect_mykubernetesapp', 'Can connect my kubernetes application')], + 'proxy': True, + 'default_permissions': [], + 'indexes': [], + 'constraints': [], + }, + bases=('applications.application',), + ), + migrations.CreateModel( + name='PermedRemoteApp', + fields=[ + ], + options={ + 'verbose_name': 'Permed remote application', + 'permissions': [('view_myremoteapp', 'Can view my remoteapp'), ('connect_myremoteapp', 'Can connect my remoteapp')], + 'proxy': True, + 'default_permissions': [], + 'indexes': [], + 'constraints': [], + }, + bases=('applications.application',), + ), + migrations.AlterModelOptions( + name='applicationpermission', + options={'ordering': ('name',), 'permissions': [('view_permuserapplication', 'Can view application of permission to user')], 'verbose_name': 'Application permission'}, + ), + migrations.AlterModelOptions( + name='assetpermission', + options={'ordering': ('name',), 'permissions': [('view_permuserasset', 'Can view asset of permission to user'), ('view_permusergroupasset', 'Can view asset of permission to user group')], 'verbose_name': 'Asset permission'}, + ), + ] diff --git a/apps/perms/models/application_permission.py b/apps/perms/models/application_permission.py index f391bdc06..e2e77279a 100644 --- a/apps/perms/models/application_permission.py +++ b/apps/perms/models/application_permission.py @@ -36,9 +36,11 @@ class ApplicationPermission(BasePermission): class Meta: unique_together = [('org_id', 'name')] verbose_name = _('Application permission') + permissions = [ + ('view_permuserapplication', _('Can view application of permission to user')) + ] ordering = ('name',) - @property def category_remote_app(self): return self.category == AppCategory.remote_app.value @@ -107,10 +109,42 @@ class ApplicationPermission(BasePermission): class PermedApplication(Application): class Meta: proxy = True - verbose_name = _("Permed app") + verbose_name = _('Permed application') + default_permissions = [] permissions = [ - ('view_myapps', _('Can view my apps')), - ('connect_myapps', _('Can connect my apps')), ('view_userapps', _('Can view user apps')), ('view_usergroupapps', _('Can view usergroup apps')), ] + + +class PermedRemoteApp(Application): + class Meta: + proxy = True + verbose_name = _('Permed remote application') + default_permissions = [] + permissions = [ + ('view_myremoteapp', _('Can view my remoteapp')), + ('connect_myremoteapp', _('Can connect my remoteapp')), + ] + + +class PermedDatabaseApp(Application): + class Meta: + proxy = True + verbose_name = _('Database application') + default_permissions = [] + permissions = [ + ('view_mydatabaseapp', _('Can view my database application')), + ('connect_mydatabaseapp', _('Can connect my database application')), + ] + + +class PermedKubernetesApp(Application): + class Meta: + proxy = True + verbose_name = _('Kubernetes') + default_permissions = [] + permissions = [ + ('view_mykubernetesapp', _('Can view my kubernetes application')), + ('connect_mykubernetesapp', _('Can connect my kubernetes application')), + ] diff --git a/apps/perms/models/asset_permission.py b/apps/perms/models/asset_permission.py index f0f222ee9..0834e704a 100644 --- a/apps/perms/models/asset_permission.py +++ b/apps/perms/models/asset_permission.py @@ -28,6 +28,10 @@ class AssetPermission(BasePermission): unique_together = [('org_id', 'name')] verbose_name = _("Asset permission") ordering = ('name',) + permissions = [ + ('view_permuserasset', _('Can view asset of permission to user')), + ('view_permusergroupasset', _('Can view asset of permission to user group')) + ] @lazyproperty def users_amount(self): diff --git a/apps/rbac/migrations/0001_initial.py b/apps/rbac/migrations/0001_initial.py index ce67374a0..5687bf574 100644 --- a/apps/rbac/migrations/0001_initial.py +++ b/apps/rbac/migrations/0001_initial.py @@ -27,7 +27,7 @@ class Migration(migrations.Migration): ], options={ 'verbose_name': 'Menu permission', - 'permissions': [('view_adminview', 'Can view console view'), ('view_auditview', 'Can view audit view'), ('view_userview', 'Can view workspace view')], + 'permissions': [('view_console', 'Can view console view'), ('view_audit', 'Can view audit view'), ('view_workspace', 'Can view workspace view')], 'default_permissions': [], }, ), diff --git a/apps/rbac/migrations/0005_auto_20220307_1524.py b/apps/rbac/migrations/0005_auto_20220307_1524.py index fb97ac9c5..88b9a0f91 100644 --- a/apps/rbac/migrations/0005_auto_20220307_1524.py +++ b/apps/rbac/migrations/0005_auto_20220307_1524.py @@ -12,6 +12,6 @@ class Migration(migrations.Migration): operations = [ migrations.AlterModelOptions( name='menupermission', - options={'default_permissions': [], 'permissions': [('view_resourcestatistics', 'Can view resource statistics'), ('view_adminview', 'Can view console view'), ('view_auditview', 'Can view audit view'), ('view_userview', 'Can view workspace view'), ('view_webterminal', 'Can view web terminal'), ('view_filemanager', 'Can view file manager')], 'verbose_name': 'Menu permission'}, + options={'default_permissions': [], 'permissions': [('view_dashboard', 'Can view resource statistics'), ('view_console', 'Can view console view'), ('view_audit', 'Can view audit view'), ('view_workspace', 'Can view workspace view'), ('view_webterminal', 'Can view web terminal'), ('view_filemanager', 'Can view file manager')], 'verbose_name': 'Menu permission'}, ), ] diff --git a/apps/rbac/migrations/0007_auto_20220310_0616.py b/apps/rbac/migrations/0007_auto_20220310_0616.py new file mode 100644 index 000000000..684ae9962 --- /dev/null +++ b/apps/rbac/migrations/0007_auto_20220310_0616.py @@ -0,0 +1,17 @@ +# Generated by Django 3.1.14 on 2022-03-09 22:16 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('rbac', '0006_auto_20220307_1558'), + ] + + operations = [ + migrations.AlterModelOptions( + name='menupermission', + options={'default_permissions': [], 'permissions': [('view_console', 'Can view console view'), ('view_audit', 'Can view audit view'), ('view_workspace', 'Can view workspace view'), ('view_webterminal', 'Can view web terminal'), ('view_filemanager', 'Can view file manager'), ('view_dashboard', 'Can view dashboard')], 'verbose_name': 'Menu permission'}, + ), + ] diff --git a/apps/rbac/models/menu.py b/apps/rbac/models/menu.py index 0990f7109..b13c3d99e 100644 --- a/apps/rbac/models/menu.py +++ b/apps/rbac/models/menu.py @@ -12,10 +12,10 @@ class MenuPermission(models.Model): default_permissions = [] verbose_name = _('Menu permission') permissions = [ - ('view_resourcestatistics', _('Can view resource statistics')), - ('view_adminview', _('Can view console view')), - ('view_auditview', _('Can view audit view')), - ('view_userview', _('Can view workspace view')), + ('view_console', _('Can view console view')), + ('view_audit', _('Can view audit view')), + ('view_workspace', _('Can view workspace view')), ('view_webterminal', _('Can view web terminal')), ('view_filemanager', _('Can view file manager')), + ('view_dashboard', _('Can view dashboard')), ] diff --git a/apps/rbac/models/permission.py b/apps/rbac/models/permission.py index 4b506168b..a15eb17a0 100644 --- a/apps/rbac/models/permission.py +++ b/apps/rbac/models/permission.py @@ -64,22 +64,12 @@ class Permission(DjangoPermission): q |= Q(**kwargs) return q - @classmethod - def clean_permissions(cls, permissions, scope=Scope.system): - if scope == Scope.org: - excludes = const.org_exclude_permissions - else: - excludes = const.system_exclude_permissions - q = cls.get_define_permissions_q(excludes) - if q: - permissions = permissions.exclude(q) - return permissions - @staticmethod def create_tree_nodes(permissions, scope, check_disabled=False): - from ..tree import PermissionTreeUtil - util = PermissionTreeUtil(permissions, scope, check_disabled) - return util.create_tree_nodes() + from ..ztree.tree import ZTree + ztree = ZTree(permissions, scope, check_disabled) + tree_nodes = ztree.get_tree_nodes() + return tree_nodes @classmethod def get_permissions(cls, scope): @@ -87,4 +77,13 @@ class Permission(DjangoPermission): permissions = cls.clean_permissions(permissions, scope=scope) return permissions - + @classmethod + def clean_permissions(cls, permissions, scope=Scope.system): + from ..ztree.tree import ZTree + perms_app_label_codename = ZTree.get_permissions_app_label_codename(scope) + q = Q() + for app_label_codename in perms_app_label_codename: + app_label, codename = app_label_codename.split('.') + q |= Q(**{'content_type__app_label': app_label, 'codename': codename}) + permissions = permissions.filter(q) + return permissions diff --git a/apps/rbac/ztree/__init__.py b/apps/rbac/ztree/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/rbac/ztree/permissions.py b/apps/rbac/ztree/permissions.py new file mode 100644 index 000000000..5c5a7a37b --- /dev/null +++ b/apps/rbac/ztree/permissions.py @@ -0,0 +1,259 @@ +# @ 分割符 $ 企业版 # ! 系统级别 # # 组织级别 # 控制台 +flag_sep = '@' +flag_license_required = '$' +flag_scope_system = '!' +# flag_scop_org = '#' + +permission_paths = [ + # format: 权限树路径 / app.codename @ 企业版、系统级别 + '/root/view/view_console/rbac.view_console', + '/root/view/view_console/rbac.view_dashboard', + '/root/view/view_console/user_management/user_list/users.view_user', + '/root/view/view_console/user_management/user_list/users.add_user', + '/root/view/view_console/user_management/user_list/users.change_user', + '/root/view/view_console/user_management/user_list/users.delete_user', + f'/root/view/view_console/user_management/user_list/users.invite_user{flag_sep}{flag_license_required}', + f'/root/view/view_console/user_management/user_list/users.remove_user{flag_sep}{flag_license_required}', + '/root/view/view_console/user_management/user_list/user_detail/perms.view_userassets', + '/root/view/view_console/user_management/user_list/user_detail/asset_perm/perms.view_assetpermission', + '/root/view/view_console/user_management/user_list/user_detail/asset_perm/perms.change_assetpermission', + '/root/view/view_console/user_management/user_list/user_detail/asset_perm/perms.delete_assetpermission', + '/root/view/view_console/user_management/user_list/user_detail/perms.view_userapps', + '/root/view/view_console/user_management/user_list/user_detail/app_perm/perms.view_applicationpermission', + '/root/view/view_console/user_management/user_list/user_detail/app_perm/perms.change_applicationpermission', + '/root/view/view_console/user_management/user_list/user_detail/app_perm/perms.delete_applicationpermission', + '/root/view/view_console/user_management/user_list/user_detail/user_login_acl/acls.view_loginacl', + '/root/view/view_console/user_management/user_list/user_detail/user_login_acl/acls.add_loginacl', + '/root/view/view_console/user_management/user_list/user_detail/user_login_acl/acls.change_loginacl', + '/root/view/view_console/user_management/user_list/user_detail/user_login_acl/acls.delete_loginacl', + '/root/view/view_console/user_management/user_group_list/users.view_usergroup', + '/root/view/view_console/user_management/user_group_list/users.add_usergroup', + '/root/view/view_console/user_management/user_group_list/users.change_usergroup', + '/root/view/view_console/user_management/user_group_list/users.delete_usergroup', + '/root/view/view_console/user_management/user_group_list/user_group_detail/perms.view_permusergroupasset', + '/root/view/view_console/user_management/role_list/permission_list/rbac.view_permission', + '/root/view/view_console/user_management/role_list/org_role/rbac.view_orgrole', + '/root/view/view_console/user_management/role_list/org_role/rbac.add_orgrole', + '/root/view/view_console/user_management/role_list/org_role/rbac.change_orgrole', + '/root/view/view_console/user_management/role_list/org_role/rbac.delete_orgrole', + '/root/view/view_console/user_management/role_list/org_role/org_role_detail/rbac.view_orgrolebinding', + '/root/view/view_console/user_management/role_list/org_role/org_role_detail/rbac.add_orgrolebinding', + '/root/view/view_console/user_management/role_list/org_role/org_role_detail/rbac.delete_orgrolebinding', + '/root/view/view_console/user_management/role_list/system_role/rbac.view_systemrole', + '/root/view/view_console/user_management/role_list/system_role/rbac.add_systemrole', + '/root/view/view_console/user_management/role_list/system_role/rbac.change_systemrole', + '/root/view/view_console/user_management/role_list/system_role/rbac.delete_systemrole', + '/root/view/view_console/user_management/role_list/system_role/system_role_detail/rbac.view_systemrolebinding', + '/root/view/view_console/user_management/role_list/system_role/system_role_detail/rbac.add_systemrolebinding', + '/root/view/view_console/user_management/role_list/system_role/system_role_detail/rbac.delete_systemrolebinding', + + '/root/view/view_console/asset_management/asset_list/assets.view_asset', + '/root/view/view_console/asset_management/asset_list/assets.add_asset', + '/root/view/view_console/asset_management/asset_list/assets.change_asset', + '/root/view/view_console/asset_management/asset_list/assets.delete_asset', + '/root/view/view_console/asset_management/asset_list/assets.test_assetconnectivity', + '/root/view/view_console/asset_management/asset_list/assets.refresh_assethardwareinfo', + '/root/view/view_console/asset_management/asset_list/assets.push_assetsystemuser', + '/root/view/view_console/asset_management/asset_list/assets.match_asset', + '/root/view/view_console/asset_management/asset_list/node_tree/assets.view_node', + '/root/view/view_console/asset_management/asset_list/node_tree/assets.add_node', + '/root/view/view_console/asset_management/asset_list/node_tree/assets.change_node', + '/root/view/view_console/asset_management/asset_list/node_tree/assets.delete_node', + '/root/view/view_console/asset_management/asset_list/node_tree/assets.add_assettonode', + '/root/view/view_console/asset_management/asset_list/node_tree/assets.move_assettonode', + f'/root/view/view_console/asset_management/asset_list/cloud_sync/sync_instance_task_list/xpack.view_syncinstancetask{flag_sep}{flag_license_required}', + f'/root/view/view_console/asset_management/asset_list/cloud_sync/sync_instance_task_list/xpack.add_syncinstancetask{flag_sep}{flag_license_required}', + f'/root/view/view_console/asset_management/asset_list/cloud_sync/sync_instance_task_list/xpack.change_syncinstancetask{flag_sep}{flag_license_required}', + f'/root/view/view_console/asset_management/asset_list/cloud_sync/sync_instance_task_list/xpack.delete_syncinstancetask{flag_sep}{flag_license_required}', + f'/root/view/view_console/asset_management/asset_list/cloud_sync/sync_instance_task_list/xpack.add_syncinstancetaskexecution{flag_sep}{flag_license_required}', + f'/root/view/view_console/asset_management/asset_list/cloud_sync/sync_instance_task_list/sync_instance_task_detail/xpack.view_syncinstancetaskexecution{flag_sep}{flag_license_required}', + f'/root/view/view_console/asset_management/asset_list/cloud_sync/sync_instance_task_list/sync_instance_task_detail/xpack.view_syncinstancedetail{flag_sep}{flag_license_required}', + f'/root/view/view_console/asset_management/asset_list/cloud_sync/account_list/xpack.view_account{flag_sep}{flag_license_required}', + f'/root/view/view_console/asset_management/asset_list/cloud_sync/account_list/xpack.add_account{flag_sep}{flag_license_required}', + f'/root/view/view_console/asset_management/asset_list/cloud_sync/account_list/xpack.change_account{flag_sep}{flag_license_required}', + f'/root/view/view_console/asset_management/asset_list/cloud_sync/account_list/xpack.delete_account{flag_sep}{flag_license_required}', + f'/root/view/view_console/asset_management/asset_list/cloud_sync/account_list/xpack.test_account{flag_sep}{flag_license_required}', + '/root/view/view_console/asset_management/domain_list/assets.view_domain', + '/root/view/view_console/asset_management/domain_list/assets.add_domain', + '/root/view/view_console/asset_management/domain_list/assets.change_domain', + '/root/view/view_console/asset_management/domain_list/assets.delete_domain', + '/root/view/view_console/asset_management/domain_list/gateway_list/assets.view_gateway', + '/root/view/view_console/asset_management/domain_list/gateway_list/assets.add_gateway', + '/root/view/view_console/asset_management/domain_list/gateway_list/assets.change_gateway', + '/root/view/view_console/asset_management/domain_list/gateway_list/assets.delete_gateway', + '/root/view/view_console/asset_management/domain_list/gateway_list/assets.test_gateway', + '/root/view/view_console/asset_management/system_user/assets.view_systemuser', + '/root/view/view_console/asset_management/system_user/assets.add_systemuser', + '/root/view/view_console/asset_management/system_user/assets.change_systemuser', + '/root/view/view_console/asset_management/system_user/assets.delete_systemuser', + '/root/view/view_console/asset_management/system_user/assets.test_assetconnectivity', + '/root/view/view_console/asset_management/system_user/assets.push_assetsystemuser', + '/root/view/view_console/asset_management/system_user/system_user_detail/system_user_asset_list/assets.view_systemuserasset', + '/root/view/view_console/asset_management/system_user/system_user_detail/system_user_asset_list/assets.add_systemuserasset', + '/root/view/view_console/asset_management/system_user/system_user_detail/system_user_asset_list/assets.remove_systemuserasset', + '/root/view/view_console/asset_management/system_user/system_user_detail/system_user_account_list/assets.view_authbook', + '/root/view/view_console/asset_management/system_user/system_user_detail/system_user_account_list/assets.change_authbook', + '/root/view/view_console/asset_management/system_user/system_user_detail/system_user_account_list/assets.delete_authbook', + '/root/view/view_console/asset_management/system_user/system_user_detail/system_user_account_list/assets.test_authbook', + '/root/view/view_console/asset_management/command_filter/assets.view_commandfilter', + '/root/view/view_console/asset_management/command_filter/assets.add_commandfilter', + '/root/view/view_console/asset_management/command_filter/assets.change_commandfilter', + '/root/view/view_console/asset_management/command_filter/assets.delete_commandfilter', + '/root/view/view_console/asset_management/command_filter/command_filter_rule/assets.view_commandfilterrule', + '/root/view/view_console/asset_management/command_filter/command_filter_rule/assets.add_commandfilterrule', + '/root/view/view_console/asset_management/command_filter/command_filter_rule/assets.change_commandfilterrule', + '/root/view/view_console/asset_management/command_filter/command_filter_rule/assets.delete_commandfilterrule', + '/root/view/view_console/asset_management/platform_list/assets.view_platform', + '/root/view/view_console/asset_management/platform_list/assets.add_platform', + '/root/view/view_console/asset_management/platform_list/assets.change_platform', + '/root/view/view_console/asset_management/platform_list/assets.delete_platform', + '/root/view/view_console/asset_management/label_management/assets.view_label', + '/root/view/view_console/asset_management/label_management/assets.add_label', + '/root/view/view_console/asset_management/label_management/assets.change_label', + '/root/view/view_console/asset_management/label_management/assets.delete_label', + + '/root/view/view_console/app_management/remote_app/applications.view_remoteapp', + '/root/view/view_console/app_management/remote_app/applications.add_remoteapp', + '/root/view/view_console/app_management/remote_app/applications.change_remoteapp', + '/root/view/view_console/app_management/remote_app/applications.delete_remoteapp', + '/root/view/view_console/app_management/db_app/applications.view_databaseapp', + '/root/view/view_console/app_management/db_app/applications.add_databaseapp', + '/root/view/view_console/app_management/db_app/applications.change_databaseapp', + '/root/view/view_console/app_management/db_app/applications.delete_databaseapp', + '/root/view/view_console/app_management/k8s_app/applications.view_kubernetesapp', + '/root/view/view_console/app_management/k8s_app/applications.add_kubernetesapp', + '/root/view/view_console/app_management/k8s_app/applications.change_kubernetesapp', + '/root/view/view_console/app_management/k8s_app/applications.delete_kubernetesapp', + + '/root/view/view_console/account_management/asset_account/assets.view_authbook', + '/root/view/view_console/account_management/asset_account/assets.add_authbook', + '/root/view/view_console/account_management/asset_account/assets.change_authbook', + '/root/view/view_console/account_management/asset_account/assets.delete_authbook', + '/root/view/view_console/account_management/asset_account/assets.test_authbook', + '/root/view/view_console/account_management/application_account/applications.view_account', + '/root/view/view_console/account_management/application_account/applications.add_account', + '/root/view/view_console/account_management/application_account/applications.change_account', + '/root/view/view_console/account_management/application_account/applications.delete_account', + '/root/view/view_console/account_management/gather_user/gather_user_list/assets.view_gathereduser', + '/root/view/view_console/account_management/gather_user/gather_user_task_list/xpack.view_gatherusertask', + '/root/view/view_console/account_management/gather_user/gather_user_task_list/xpack.add_gatherusertask', + '/root/view/view_console/account_management/gather_user/gather_user_task_list/xpack.change_gatherusertask', + '/root/view/view_console/account_management/gather_user/gather_user_task_list/xpack.delete_gatherusertask', + '/root/view/view_console/account_management/gather_user/gather_user_task_list/xpack.add_gatherusertaskexecution', + '/root/view/view_console/account_management/gather_user/gather_user_task_list/xpack.view_gatherusertaskexecution', + '/root/view/view_console/account_management/change_auth_plan/asset_change_auth_plan/xpack.view_changeauthplan', + '/root/view/view_console/account_management/change_auth_plan/asset_change_auth_plan/xpack.add_changeauthplan', + '/root/view/view_console/account_management/change_auth_plan/asset_change_auth_plan/xpack.change_changeauthplan', + '/root/view/view_console/account_management/change_auth_plan/asset_change_auth_plan/xpack.delete_changeauthplan', + '/root/view/view_console/account_management/change_auth_plan/asset_change_auth_plan/xpack.add_changeauthplanexecution', + '/root/view/view_console/account_management/change_auth_plan/asset_change_auth_plan/xpack.view_changeauthplanexecution', + '/root/view/view_console/account_management/change_auth_plan/app_change_auth_plan/xpack.view_applicationchangeauthplan', + '/root/view/view_console/account_management/change_auth_plan/app_change_auth_plan/xpack.add_applicationchangeauthplan', + '/root/view/view_console/account_management/change_auth_plan/app_change_auth_plan/xpack.change_applicationchangeauthplan', + '/root/view/view_console/account_management/change_auth_plan/app_change_auth_plan/xpack.delete_applicationchangeauthplan', + '/root/view/view_console/account_management/change_auth_plan/app_change_auth_plan/xpack.add_applicationchangeauthplanexecution', + '/root/view/view_console/account_management/change_auth_plan/app_change_auth_plan/xpack.view_applicationchangeauthplanexecution', + '/root/view/view_console/account_management/account_backup/assets.view_accountbackupplan', + '/root/view/view_console/account_management/account_backup/assets.add_accountbackupplan', + '/root/view/view_console/account_management/account_backup/assets.change_accountbackupplan', + '/root/view/view_console/account_management/account_backup/assets.delete_accountbackupplan', + '/root/view/view_console/account_management/account_backup/assets.add_accountbackupplanexecution', + '/root/view/view_console/account_management/account_backup/assets.view_accountbackupplanexecution', + + '/root/view/view_console/perm_management/asset_permission/perms.view_assetpermission', + '/root/view/view_console/perm_management/asset_permission/perms.add_assetpermission', + '/root/view/view_console/perm_management/asset_permission/perms.change_assetpermission', + '/root/view/view_console/perm_management/asset_permission/perms.delete_assetpermission', + '/root/view/view_console/perm_management/app_permission/perms.view_applicationpermission', + '/root/view/view_console/perm_management/app_permission/perms.add_applicationpermission', + '/root/view/view_console/perm_management/app_permission/perms.change_applicationpermission', + '/root/view/view_console/perm_management/app_permission/perms.delete_applicationpermission', + + '/root/view/view_console/access_control/asset_login/acls.view_loginassetacl', + '/root/view/view_console/access_control/asset_login/acls.add_loginassetacl', + '/root/view/view_console/access_control/asset_login/acls.change_loginassetacl', + '/root/view/view_console/access_control/asset_login/acls.delete_loginassetacl', + + '/root/view/view_console/job_center/task_list/ops.view_task', + '/root/view/view_console/job_center/task_list/ops.delete_task', + '/root/view/view_console/job_center/task_list/ops.add_adhocexecution', + '/root/view/view_console/job_center/task_list/task_list_detail/ops.view_adhoc', + '/root/view/view_console/job_center/task_list/task_list_detail/ops.view_adhocexecution', + '/root/view/view_console/job_center/ops.view_taskmonitor', + + '/root/view/view_audit/rbac.view_audit', + '/root/view/view_audit/rbac.view_dashboard', + '/root/view/view_audit/session_audit/session_record/terminal.view_session', + '/root/view/view_audit/session_audit/session_record/terminal.terminate_session', + '/root/view/view_audit/session_audit/session_record/terminal.monitor_session', + '/root/view/view_audit/session_audit/session_record/session_detail/terminal.view_command', + '/root/view/view_audit/session_audit/session_record/session_detail/terminal.view_sessionjoinrecord', + '/root/view/view_audit/session_audit/command_record/terminal.view_command', + '/root/view/view_audit/session_audit/command_record/terminal.view_commandstorage', + '/root/view/view_audit/session_audit/file_transfer/audits.view_ftplog', + '/root/view/view_audit/log_audit/audits.view_userloginlog', + '/root/view/view_audit/log_audit/audits.view_operatelog', + '/root/view/view_audit/log_audit/audits.view_passwordchangelog', + '/root/view/view_audit/log_audit/ops.view_commandexecution', + + '/root/view/view_workspace/rbac.view_workspace', + '/root/view/view_workspace/rbac.view_overview', + '/root/view/view_workspace/my_asset/perms.view_myassets', + '/root/view/view_workspace/my_asset/perms.connect_myassets', + '/root/view/view_workspace/my_app/my_remote_app/perms.view_myremoteapp', + '/root/view/view_workspace/my_app/my_remote_app/perms.connect_myremoteapp', + '/root/view/view_workspace/my_app/my_db_app/perms.view_mydatabaseapp', + '/root/view/view_workspace/my_app/my_db_app/perms.connect_mydatabaseapp', + '/root/view/view_workspace/my_app/my_k8s_app/perms.view_mykubernetesapp', + '/root/view/view_workspace/my_app/my_k8s_app/perms.connect_mykubernetesapp', + '/root/view/view_workspace/ops.add_commandexecution', + '/root/view/view_workspace/rbac.view_webterminal', + '/root/view/view_workspace/rbac.view_filemanager', + + '/root/notifications.view_sitemessage', + '/root/rbac.view_webterminal', + + f'/root/system_setting/settings.change_basic{flag_sep}{flag_scope_system}', + f'/root/system_setting/settings.change_email{flag_sep}{flag_scope_system}', + f'/root/system_setting/settings.change_auth{flag_sep}{flag_scope_system}', + f'/root/system_setting/notifications.change_systemmsgsubscription{flag_sep}{flag_scope_system}', + f'/root/system_setting/settings.change_sms{flag_sep}{flag_scope_system}{flag_license_required}', + f'/root/system_setting/terminal_setting/settings.change_terminal_basic_setting{flag_sep}{flag_scope_system}', + f'/root/system_setting/terminal_setting/terminal_management/terminal.view_terminal{flag_sep}{flag_scope_system}', + f'/root/system_setting/terminal_setting/terminal_management/terminal.change_terminal{flag_sep}{flag_scope_system}', + f'/root/system_setting/terminal_setting/terminal_management/terminal.delete_terminal{flag_sep}{flag_scope_system}', + f'/root/system_setting/terminal_setting/replay_storage/terminal.view_replaystorage{flag_sep}{flag_scope_system}', + f'/root/system_setting/terminal_setting/replay_storage/terminal.add_replaystorage{flag_sep}{flag_scope_system}', + f'/root/system_setting/terminal_setting/replay_storage/terminal.change_replaystorage{flag_sep}{flag_scope_system}', + f'/root/system_setting/terminal_setting/replay_storage/terminal.delete_replaystorage{flag_sep}{flag_scope_system}', + f'/root/system_setting/terminal_setting/command_storage/terminal.view_commandstorage{flag_sep}{flag_scope_system}', + f'/root/system_setting/terminal_setting/command_storage/terminal.add_commandstorage{flag_sep}{flag_scope_system}', + f'/root/system_setting/terminal_setting/command_storage/terminal.change_commandstorage{flag_sep}{flag_scope_system}', + f'/root/system_setting/terminal_setting/command_storage/terminal.delete_commandstorage{flag_sep}{flag_scope_system}', + f'/root/system_setting/terminal_setting/terminal.view_status{flag_sep}{flag_scope_system}', + f'/root/system_setting/settings.change_security{flag_sep}{flag_scope_system}', + f'/root/system_setting/settings.change_clean{flag_sep}{flag_scope_system}{flag_license_required}', + f'/root/system_setting/org_management/orgs.view_rootorg{flag_sep}{flag_scope_system}{flag_license_required}', + f'/root/system_setting/org_management/orgs.view_organization{flag_sep}{flag_scope_system}{flag_license_required}', + f'/root/system_setting/org_management/orgs.add_organization{flag_sep}{flag_scope_system}{flag_license_required}', + f'/root/system_setting/org_management/orgs.change_organization{flag_sep}{flag_scope_system}{flag_license_required}', + f'/root/system_setting/org_management/orgs.delete_organization{flag_sep}{flag_scope_system}{flag_license_required}', + f'/root/system_setting/settings.change_other{flag_sep}{flag_scope_system}', + f'/root/system_setting/license/xpack.view_license{flag_sep}{flag_scope_system}', + f'/root/system_setting/license/xpack.add_license{flag_sep}{flag_scope_system}', + + f'/root/ticket/tickets.view_ticket{flag_sep}{flag_license_required}', + f'/root/ticket/tickets.add_ticket{flag_sep}{flag_license_required}', + f'/root/ticket/ticket_detail/tickets.change_ticket{flag_sep}{flag_license_required}', + f'/root/ticket/ticket_detail/tickets.add_comment{flag_sep}{flag_license_required}', + f'/root/ticket/ticket_detail/tickets.view_comment{flag_sep}{flag_license_required}', + f'/root/ticket/ticket_detail/tickets.view_ticketsession{flag_sep}{flag_license_required}', + + # '/root/rbac.view_help', + f'/root/api_permission/terminal.add_session', + '/root/api_permission/terminal.add_command', + f'/root/api_permission/tickets.add_superticket{flag_sep}{flag_license_required}', + '/root/api_permission/authentication.add_superconnectiontoken', + '/root/api_permission/authentication.view_connectiontokensecret', + # ... +] diff --git a/apps/rbac/ztree/tree.py b/apps/rbac/ztree/tree.py new file mode 100644 index 000000000..2279135e8 --- /dev/null +++ b/apps/rbac/ztree/tree.py @@ -0,0 +1,207 @@ +import random +from collections import defaultdict +from django.utils.translation import ugettext +from common.tree import TreeNode as RawTreeNode +from django.utils.translation import gettext_lazy as _, gettext +from rbac.models import Permission, ContentType +from django.db.models import F, Count +from .permissions import permission_paths, flag_license_required, flag_sep, flag_scope_system +from .tree_nodes import permission_tree_nodes +from ..const import Scope +from jumpserver.utils import has_valid_xpack_license +from django.conf import settings + + +class TreeNode(RawTreeNode): + total_count = 0 + checked_count = 0 + app_label_codename = '' + + def mark_checked_if_need(self): + if self.isParent: + self.checked = self.total_count == self.checked_count + + def refresh_name_if_need(self): + if self.isParent: + self.name = str(self.name) + f'({self.checked_count}/{self.total_count})' + elif settings.DEBUG: + self.name = str(self.name) + f'({self.app_label_codename})' + + +class TreeNodes: + + def __init__(self): + self.tree_nodes = defaultdict(TreeNode) + + def add_node(self, data): + tree_node = self.add(data) + tree_node.total_count += 1 + + def add_leaf(self, data): + tree_node = self.add(data) + if not data['checked']: + return + + parent_node = self.tree_nodes.get(tree_node.pId) + while parent_node: + parent_node.checked_count += 1 + parent_node = self.tree_nodes.get(parent_node.pId) + + def add(self, data): + _id = data['id'] + data['name'] = data.get('name') or data['id'] + tree_node = self.tree_nodes.get(_id, TreeNode(**data)) + self.tree_nodes[tree_node.id] = tree_node + return tree_node + + def get(self): + tree_nodes = list(self.tree_nodes.values()) + for tree_node in tree_nodes: + tree_node.mark_checked_if_need() + tree_node.refresh_name_if_need() + return tree_nodes + + +class ZTree(object): + + has_valid_license = has_valid_xpack_license() + + def __init__(self, checked_permission, scope, check_disabled=False): + self.scope = scope + self.checked_permission = self.prefetch_permissions( + checked_permission + ) + self.checked_permissions_mapper = {p.id: p for p in self.checked_permission} + self.permissions = self.prefetch_permissions( + Permission.get_permissions(scope) + ) + self.permissions_mapper = {p.app_label_codename: p for p in self.permissions} + self.content_types_name_mapper = {ct.model: ct.name for ct in ContentType.objects.all()} + self.check_disabled = check_disabled + self.tree_nodes = TreeNodes() + self.show_node_level = 3 + + @staticmethod + def prefetch_permissions(permissions): + return permissions.select_related('content_type') \ + .annotate(app=F('content_type__app_label')) \ + .annotate(model=F('content_type__model')) + + def get_tree_nodes(self): + perm_paths = self.__class__.get_permission_paths(self.scope) + for perm_path in perm_paths: + self.generate_tree_nodes_by_path(perm_path) + return self.tree_nodes.get() + + def generate_tree_nodes_by_path(self, perm_path): + path, perm_app_label_codename = perm_path.rsplit('/', 1) + + # add path + path_list = path.lstrip('/').split('/') + pid = '' + for level, tree_node_id in enumerate(path_list, start=1): + name = _('Detail') if 'detail' in tree_node_id else tree_node_id + data = dict({ + 'id': tree_node_id, + 'name': name, + 'title': name, + 'pId': pid, + 'isParent': True, + 'chkDisabled': self.check_disabled, + 'open': level < self.show_node_level, + 'meta': { + 'type': 'perm', + } + }) + _data = permission_tree_nodes.get(tree_node_id, {}) + data.update(_data) + pid = data['id'] + self.tree_nodes.add_node(data) + + # add perm + if not perm_app_label_codename: + return + perm = self.permissions_mapper.get(perm_app_label_codename) + if perm: + # 解决同一个权限不能在多个节点的问题 + _id = f'{pid}#{perm.id}' + name = self._get_permission_name(perm) + checked = perm.id in self.checked_permissions_mapper + else: + # 最终不应该走这里,所有权限都要在数据库里 + _id = perm_app_label_codename + name = perm_app_label_codename + checked = False + + data = { + 'id': _id, + 'pId': pid, + 'name': name, + 'title': perm_app_label_codename, + 'chkDisabled': self.check_disabled, + 'app_label_codename': perm_app_label_codename, + 'isParent': False, + 'iconSkin': 'file', + 'open': False, + 'checked': checked, + 'meta': { + 'type': 'perm', + } + } + _data = permission_tree_nodes.get(perm_app_label_codename, {}) + data.update(_data) + self.tree_nodes.add_leaf(data) + + def _get_permission_name(self, p): + code_name = p.codename + action_mapper = { + 'add': ugettext('Create'), + 'view': ugettext('View'), + 'change': ugettext('Update'), + 'delete': ugettext('Delete') + } + name = '' + ct = '' + if 'add_' in p.codename: + name = action_mapper['add'] + ct = code_name.replace('add_', '') + elif 'view_' in p.codename: + name = action_mapper['view'] + ct = code_name.replace('view_', '') + elif 'change_' in p.codename: + name = action_mapper['change'] + ct = code_name.replace('change_', '') + elif 'delete' in code_name: + name = action_mapper['delete'] + ct = code_name.replace('delete_', '') + + if ct in self.content_types_name_mapper: + name += self.content_types_name_mapper[ct] + else: + name = gettext(p.name) + name = name.replace('Can ', '').replace('可以', '') + return name + + @classmethod + def get_permissions_app_label_codename(cls, scope): + perm_paths = cls.get_permission_paths(scope) + perms = [] + for path in perm_paths: + path, app_label_code_name = path.rsplit('/', 1) + if not app_label_code_name: + continue + perms.append(app_label_code_name) + return perms + + @classmethod + def get_permission_paths(cls, scope): + perm_paths = [] + for path in permission_paths: + if flag_sep in path: + path, flags = path.split(flag_sep) + if flag_scope_system in flags and scope == Scope.org: + continue + if flag_license_required in flags and not cls.has_valid_license: + continue + perm_paths.append(path) + return perm_paths diff --git a/apps/rbac/ztree/tree_nodes.py b/apps/rbac/ztree/tree_nodes.py new file mode 100644 index 000000000..3d1dacb1e --- /dev/null +++ b/apps/rbac/ztree/tree_nodes.py @@ -0,0 +1,308 @@ +from django.utils.translation import gettext_lazy as _ + +permission_tree_nodes = { + # 节点 + 'root': { + 'name': _('All permissions'), + }, + 'view': { + 'name': _("View menu") + }, + 'view_console': { + 'name': _('Console view'), + }, + 'user_management': { + 'name': _('User management') + }, + 'user_list': { + 'name': _('User list') + }, + 'view_workspace': { + 'name': _('Workspace view') + }, + 'view_audit': { + 'name': _("Audit view") + }, + 'asset_perm': { + 'name': _('Asset permission') + }, + 'session_audits': { + 'name': _('Session audits') + }, + 'session_record': { + 'name': _('Online/Offline Session record') + }, + 'asset_management': { + 'name': _('Asset management') + }, + 'asset_list': { + 'name': _('Asset list') + }, + 'my_asset': { + 'name': _('My assets') + }, + 'my_app': { + 'name': _('My application') + }, + 'bulk_command': { + 'name': _('Bulk command') + }, + 'system_setting': { + 'name': _('System setting') + }, + 'ticket': { + 'name': _('Ticket system') + }, + 'help': { + 'name': _('Help') + }, + 'api_permission': { + 'name': _('API permission') + }, + 'app_management': { + 'name': _('Application management') + }, + 'account_management': { + 'name': _('Account management'), + }, + 'perm_management': { + 'name': _('Permission management'), + }, + 'access_control': { + 'name': _('Access control'), + }, + 'job_center': { + 'name': _('Job center'), + }, + 'session_audit': { + 'name': _('Session audit') + }, + 'log_audit': { + 'name': _('Log audit') + }, + 'user_group_list': { + 'name': _('User group') + }, + 'role_list': { + 'name': _('Role list') + }, + 'app_perm': { + 'name': _('Application permission') + }, + 'user_login_acl': { + 'name': _('User login acl') + }, + 'user_group_detail': { + 'name': _('Detail') + }, + 'permission_list': { + 'name': _('Permission list') + }, + 'node_tree': { + 'name': _('Node tree') + }, + 'cloud_sync': { + 'name': _('Cloud sync') + }, + 'sync_instance_task_list': { + 'name': _('Sync instance task list') + }, + 'account_list': { + 'name': _('Account list') + }, + 'system_user': { + 'name': _('Common/Admin User') + }, + 'system_user_asset_list': { + 'name': _('Asset list'), + }, + 'system_user_account_list': { + 'name': _('Account list') + }, + 'command_filter': { + 'name': _('Command filter') + }, + 'command_filter_rule': { + 'name': _('Command filter rule') + }, + 'platform_list': { + 'name': _('Platform list') + }, + 'label_management': { + 'name': _('Label management') + }, + 'remote_app': { + 'name': _('Remote application') + }, + 'db_app': { + 'name': _('Database application') + }, + 'k8s_app': { + 'name': _('Kubernetes') + }, + 'asset_account': { + 'name': _('Asset account') + }, + 'application_account': { + 'name': _('Application account') + }, + 'gather_user': { + 'name': _('Gathered user') + }, + 'gather_user_list': { + 'name': _('Gathered user list') + }, + 'gather_user_task_list': { + 'name': _('Gathered user task list') + }, + 'change_auth_plan': { + 'name': _('Change auth plan') + }, + 'asset_change_auth_plan': { + 'name': _('Asset change auth plan') + }, + 'app_change_auth_plan': { + 'name': _('Application change auth plan') + }, + 'account_backup': { + 'name': _('Account backup') + }, + 'asset_permission': { + 'name': _('Asset permission') + }, + 'app_permission': { + 'name': _('Application permission') + }, + 'asset_login': { + 'name': _('Asset login') + }, + 'task_list': { + 'name': _('Task list') + }, + 'command_record': { + 'name': _('Command record') + }, + 'file_transfer': { + 'name': _('File transfer') + }, + 'my_remote_app': { + 'name': _('Remote App') + }, + 'my_db_app': { + 'name': _('Database application') + }, + 'my_k8s_app': { + 'name': _('Kubernetes') + }, + 'terminal_setting': { + 'name': _('Terminal setting') + }, + 'terminal_management': { + 'name': _('Terminal management') + }, + 'command_storage': { + 'name': _('Command storage') + }, + 'replay_storage': { + 'name': _('Replay storage') + }, + 'org_management': { + 'name': _('Organization management') + }, + 'license': { + 'name': _('License') + }, + + # 权限 + 'rbac.view_permission': { + 'name': _('View all permission') + }, + 'domain_list': { + 'name': _('Domain list') + }, + 'gateway_list': { + 'name': _('Gateway list') + }, + 'org_role': { + 'name': _('Organization role') + }, + 'system_role': { + 'name': _('System role') + }, + 'xpack.add_gatherusertaskexecution': { + 'name': _('Run gather user task') + }, + 'xpack.add_changeauthplanexecution': { + 'name': _('Run asset change auth plan') + }, + 'xpack.add_applicationchangeauthplanexecution': { + 'name': _('Run application change auth plan') + }, + 'assets.add_accountbackupplanexecution': { + 'name': _('Run account backup plan') + }, + 'ops.add_adhocexecution': { + 'name': _('Run task') + }, + 'ops.view_adhoc': { + 'name': _('View task version') + }, + 'ops.view_adhocexecution': { + 'name': _('View execution history') + }, + 'ops.add_commandexecution': { + 'name': _('Bulk command') + }, + 'notifications.view_sitemessage': { + 'name': _('Site message') + }, + 'notifications.change_systemmsgsubscription': { + 'name': _('Message subscription') + }, + 'terminal.view_status': { + 'name': _('Component monitor') + }, + 'tickets.view_ticket': { + 'name': _('View my/assigned ticket') + }, + 'tickets.add_ticket': { + 'name': _('Create asset/application ticket') + }, + 'tickets.change_ticket': { + 'name': _('Change/close ticket') + }, + 'assets.match_asset': { + 'name': _('View some of the assets searched') + }, + 'rbac.view_workspace': { + 'checked': True, + 'chkDisabled': True, + }, + 'rbac.view_overview': { + 'name': _('Overview'), + 'checked': True, + 'chkDisabled': True, + }, + 'rbac.view_orgrolebinding': { + 'name': _('View permission user') + }, + 'rbac.add_orgrolebinding': { + 'name': _('Add user to role') + }, + 'rbac.delete_orgrolebinding': { + 'name': _('Remove user from role') + }, + 'rbac.view_systemrolebinding': { + 'name': _('View permission user') + }, + 'rbac.add_systemrolebinding': { + 'name': _('Add user to role') + }, + 'rbac.delete_systemrolebinding': { + 'name': _('Remove user from role') + }, + 'xpack.add_syncinstancetaskexecution': { + 'name': _('Run sync instance task') + } + +} diff --git a/apps/settings/migrations/0005_auto_20220310_0616.py b/apps/settings/migrations/0005_auto_20220310_0616.py new file mode 100644 index 000000000..f29f017c5 --- /dev/null +++ b/apps/settings/migrations/0005_auto_20220310_0616.py @@ -0,0 +1,17 @@ +# Generated by Django 3.1.14 on 2022-03-09 22:16 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('settings', '0004_auto_20220211_1401'), + ] + + operations = [ + migrations.AlterModelOptions( + name='setting', + options={'permissions': [('change_basic', 'Can change basic setting'), ('change_email', 'Can change email setting'), ('change_auth', 'Can change auth setting'), ('change_sms', 'Can change sms setting'), ('change_security', 'Can change security setting'), ('change_clean', 'Can change clean setting'), ('change_other', 'Can change other setting'), ('change_terminal_basic_setting', 'Can change terminal basic setting')], 'verbose_name': 'System setting'}, + ), + ] diff --git a/apps/settings/models.py b/apps/settings/models.py index c89f5e81b..6f87c2325 100644 --- a/apps/settings/models.py +++ b/apps/settings/models.py @@ -138,3 +138,13 @@ class Setting(models.Model): class Meta: db_table = "settings_setting" verbose_name = _("System setting") + permissions = [ + ('change_basic', _('Can change basic setting')), + ('change_email', _('Can change email setting')), + ('change_auth', _('Can change auth setting')), + ('change_sms', _('Can change sms setting')), + ('change_security', _('Can change security setting')), + ('change_clean', _('Can change clean setting')), + ('change_other', _('Can change other setting')), + ('change_terminal_basic_setting', _('Can change terminal basic setting')), + ] diff --git a/apps/users/models/user.py b/apps/users/models/user.py index 600672847..d071b9f66 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -274,7 +274,7 @@ class RoleMixin: def perms(self): key = self.PERM_CACHE_KEY.format(self.id, current_org.id) perms = cache.get(key) - if not perms: + if not perms or settings.DEBUG: perms = self.get_all_permissions() cache.set(key, perms, 3600) return perms