mirror of https://github.com/jumpserver/jumpserver
commit
8080d36d90
|
@ -17,7 +17,7 @@ class ApplicationViewSet(SuggestionMixin, OrgBulkModelViewSet):
|
||||||
model = Application
|
model = Application
|
||||||
filterset_fields = {
|
filterset_fields = {
|
||||||
'name': ['exact'],
|
'name': ['exact'],
|
||||||
'category': ['exact'],
|
'category': ['exact', 'in'],
|
||||||
'type': ['exact', 'in'],
|
'type': ['exact', 'in'],
|
||||||
}
|
}
|
||||||
search_fields = ('name', 'type', 'category')
|
search_fields = ('name', 'type', 'category')
|
||||||
|
|
|
@ -65,7 +65,7 @@ class AccountViewSet(OrgBulkModelViewSet):
|
||||||
}
|
}
|
||||||
rbac_perms = {
|
rbac_perms = {
|
||||||
'verify_account': 'assets.test_authbook',
|
'verify_account': 'assets.test_authbook',
|
||||||
'PATCH': 'assets.change_assetaccountsecret'
|
'partial_update': 'assets.change_assetaccountsecret',
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
|
|
@ -40,7 +40,7 @@ class GatewayTestConnectionApi(SingleObjectMixin, APIView):
|
||||||
queryset = Gateway.objects.all()
|
queryset = Gateway.objects.all()
|
||||||
object = None
|
object = None
|
||||||
rbac_perms = {
|
rbac_perms = {
|
||||||
'POST': 'assets.change_gateway'
|
'POST': 'assets.test_gateway'
|
||||||
}
|
}
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
|
|
@ -16,7 +16,7 @@ class Migration(migrations.Migration):
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='systemuser',
|
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'},
|
options={'ordering': ['name'], 'permissions': [('match_systemuser', 'Can match system user')], 'verbose_name': 'System user'},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='asset',
|
name='asset',
|
||||||
|
|
|
@ -324,9 +324,6 @@ class SystemUser(ProtocolMixin, AuthMixin, BaseUser):
|
||||||
unique_together = [('name', 'org_id')]
|
unique_together = [('name', 'org_id')]
|
||||||
verbose_name = _("System user")
|
verbose_name = _("System user")
|
||||||
permissions = [
|
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')),
|
('match_systemuser', _('Can match system user')),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -12,13 +12,11 @@ from terminal.models import Session
|
||||||
|
|
||||||
|
|
||||||
class CommandFilterSerializer(BulkOrgResourceModelSerializer):
|
class CommandFilterSerializer(BulkOrgResourceModelSerializer):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CommandFilter
|
model = CommandFilter
|
||||||
fields_mini = ['id', 'name']
|
fields_mini = ['id', 'name']
|
||||||
fields_small = fields_mini + [
|
fields_small = fields_mini + [
|
||||||
'org_id', 'org_name',
|
'org_id', 'org_name', 'is_active',
|
||||||
'is_active',
|
|
||||||
'date_created', 'date_updated',
|
'date_created', 'date_updated',
|
||||||
'comment', 'created_by',
|
'comment', 'created_by',
|
||||||
]
|
]
|
||||||
|
@ -26,7 +24,9 @@ class CommandFilterSerializer(BulkOrgResourceModelSerializer):
|
||||||
fields_m2m = ['users', 'user_groups', 'system_users', 'assets', 'applications']
|
fields_m2m = ['users', 'user_groups', 'system_users', 'assets', 'applications']
|
||||||
fields = fields_small + fields_fk + fields_m2m
|
fields = fields_small + fields_fk + fields_m2m
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
'rules': {'read_only': True}
|
'rules': {'read_only': True},
|
||||||
|
'date_created': {'label': _("Date created")},
|
||||||
|
'date_updated': {'label': _("Date updated")},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,6 +45,11 @@ class CommandFilterRuleSerializer(BulkOrgResourceModelSerializer):
|
||||||
]
|
]
|
||||||
fields_fk = ['filter']
|
fields_fk = ['filter']
|
||||||
fields = fields_small + fields_fk
|
fields = fields_small + fields_fk
|
||||||
|
extra_kwargs = {
|
||||||
|
'date_created': {'label': _("Date created")},
|
||||||
|
'date_updated': {'label': _("Date updated")},
|
||||||
|
'action_display': {'label': _("Action display")}
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
|
@ -132,7 +132,8 @@ class CommandExecutionHostRelationViewSet(OrgRelationMixin, OrgBulkModelViewSet)
|
||||||
search_fields = ('asset__hostname', )
|
search_fields = ('asset__hostname', )
|
||||||
http_method_names = ['options', 'get']
|
http_method_names = ['options', 'get']
|
||||||
rbac_perms = {
|
rbac_perms = {
|
||||||
'GET': 'ops.view_commandexecution'
|
'GET': 'ops.view_commandexecution',
|
||||||
|
'list': 'ops.view_commandexecution',
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
|
|
@ -18,7 +18,7 @@ from .signals import post_auth_success, post_auth_failed
|
||||||
@receiver(user_logged_in)
|
@receiver(user_logged_in)
|
||||||
def on_user_auth_login_success(sender, user, request, **kwargs):
|
def on_user_auth_login_success(sender, user, request, **kwargs):
|
||||||
# 失效 perms 缓存
|
# 失效 perms 缓存
|
||||||
user.expire_perms_cache()
|
user.expire_rbac_perms_cache()
|
||||||
|
|
||||||
# 开启了 MFA,且没有校验过, 可以全局校验, middleware 中可以全局管理 oidc 等第三方认证的 MFA
|
# 开启了 MFA,且没有校验过, 可以全局校验, middleware 中可以全局管理 oidc 等第三方认证的 MFA
|
||||||
if settings.SECURITY_MFA_AUTH_ENABLED_FOR_THIRD_PARTY \
|
if settings.SECURITY_MFA_AUTH_ENABLED_FOR_THIRD_PARTY \
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:f529bbca004aeba7532d9faf50f6f8ab5532b19bf0afd650f8360f418c03c15c
|
oid sha256:43b38f824f3e62af12575cc853ec0ad7f9b0ac935e1d99116ebe3ddb6c93485c
|
||||||
size 104629
|
size 104599
|
||||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: JumpServer 0.3.3\n"
|
"Project-Id-Version: JumpServer 0.3.3\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2022-03-16 20:38+0800\n"
|
"POT-Creation-Date: 2022-03-17 15:19+0800\n"
|
||||||
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
|
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
|
||||||
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
||||||
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
||||||
|
@ -30,7 +30,7 @@ msgstr "访问控制"
|
||||||
#: settings/models.py:29 settings/serializers/sms.py:6
|
#: settings/models.py:29 settings/serializers/sms.py:6
|
||||||
#: terminal/models/storage.py:23 terminal/models/task.py:16
|
#: terminal/models/storage.py:23 terminal/models/task.py:16
|
||||||
#: terminal/models/terminal.py:100 users/forms/profile.py:32
|
#: terminal/models/terminal.py:100 users/forms/profile.py:32
|
||||||
#: users/models/group.py:15 users/models/user.py:574
|
#: users/models/group.py:15 users/models/user.py:584
|
||||||
#: users/templates/users/_select_user_modal.html:13
|
#: users/templates/users/_select_user_modal.html:13
|
||||||
#: users/templates/users/user_asset_permission.html:37
|
#: users/templates/users/user_asset_permission.html:37
|
||||||
#: users/templates/users/user_asset_permission.html:154
|
#: users/templates/users/user_asset_permission.html:154
|
||||||
|
@ -66,7 +66,7 @@ msgstr "激活中"
|
||||||
#: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34
|
#: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34
|
||||||
#: terminal/models/storage.py:26 terminal/models/terminal.py:114
|
#: terminal/models/storage.py:26 terminal/models/terminal.py:114
|
||||||
#: tickets/models/comment.py:24 tickets/models/ticket.py:154
|
#: tickets/models/comment.py:24 tickets/models/ticket.py:154
|
||||||
#: users/models/group.py:16 users/models/user.py:611
|
#: users/models/group.py:16 users/models/user.py:621
|
||||||
#: xpack/plugins/change_auth_plan/models/base.py:44
|
#: xpack/plugins/change_auth_plan/models/base.py:44
|
||||||
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:116
|
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:116
|
||||||
#: xpack/plugins/gathered_user/models.py:26
|
#: xpack/plugins/gathered_user/models.py:26
|
||||||
|
@ -90,12 +90,12 @@ msgstr "登录复核"
|
||||||
#: assets/models/cmd_filter.py:30 assets/models/label.py:15 audits/models.py:37
|
#: 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
|
#: audits/models.py:60 audits/models.py:85 audits/serializers.py:100
|
||||||
#: authentication/models.py:50 orgs/models.py:214 perms/models/base.py:84
|
#: authentication/models.py:50 orgs/models.py:214 perms/models/base.py:84
|
||||||
#: rbac/builtin.py:97 rbac/models/rolebinding.py:39 templates/index.html:78
|
#: rbac/builtin.py:101 rbac/models/rolebinding.py:39 templates/index.html:78
|
||||||
#: terminal/backends/command/models.py:19
|
#: terminal/backends/command/models.py:19
|
||||||
#: terminal/backends/command/serializers.py:12 terminal/models/session.py:42
|
#: terminal/backends/command/serializers.py:12 terminal/models/session.py:42
|
||||||
#: terminal/notifications.py:88 terminal/notifications.py:136
|
#: terminal/notifications.py:91 terminal/notifications.py:139
|
||||||
#: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:795
|
#: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:809
|
||||||
#: users/models/user.py:826 users/serializers/group.py:19
|
#: users/models/user.py:840 users/serializers/group.py:19
|
||||||
#: users/templates/users/user_asset_permission.html:38
|
#: users/templates/users/user_asset_permission.html:38
|
||||||
#: users/templates/users/user_asset_permission.html:64
|
#: users/templates/users/user_asset_permission.html:64
|
||||||
#: users/templates/users/user_database_app_permission.html:37
|
#: users/templates/users/user_database_app_permission.html:37
|
||||||
|
@ -141,7 +141,7 @@ msgstr "系统用户"
|
||||||
#: audits/models.py:39 perms/models/asset_permission.py:23
|
#: audits/models.py:39 perms/models/asset_permission.py:23
|
||||||
#: templates/index.html:82 terminal/backends/command/models.py:20
|
#: templates/index.html:82 terminal/backends/command/models.py:20
|
||||||
#: terminal/backends/command/serializers.py:13 terminal/models/session.py:44
|
#: terminal/backends/command/serializers.py:13 terminal/models/session.py:44
|
||||||
#: terminal/notifications.py:87
|
#: terminal/notifications.py:90
|
||||||
#: users/templates/users/user_asset_permission.html:40
|
#: users/templates/users/user_asset_permission.html:40
|
||||||
#: users/templates/users/user_asset_permission.html:70
|
#: users/templates/users/user_asset_permission.html:70
|
||||||
#: xpack/plugins/change_auth_plan/models/asset.py:199
|
#: xpack/plugins/change_auth_plan/models/asset.py:199
|
||||||
|
@ -168,7 +168,7 @@ msgstr "格式为逗号分隔的字符串, * 表示匹配所有. "
|
||||||
#: authentication/forms.py:15 authentication/forms.py:17
|
#: authentication/forms.py:15 authentication/forms.py:17
|
||||||
#: authentication/templates/authentication/_msg_different_city.html:9
|
#: authentication/templates/authentication/_msg_different_city.html:9
|
||||||
#: authentication/templates/authentication/_msg_oauth_bind.html:9
|
#: authentication/templates/authentication/_msg_oauth_bind.html:9
|
||||||
#: ops/models/adhoc.py:159 users/forms/profile.py:31 users/models/user.py:572
|
#: ops/models/adhoc.py:159 users/forms/profile.py:31 users/models/user.py:582
|
||||||
#: users/templates/users/_msg_user_created.html:12
|
#: users/templates/users/_msg_user_created.html:12
|
||||||
#: users/templates/users/_select_user_modal.html:14
|
#: users/templates/users/_select_user_modal.html:14
|
||||||
#: xpack/plugins/change_auth_plan/models/asset.py:34
|
#: xpack/plugins/change_auth_plan/models/asset.py:34
|
||||||
|
@ -341,6 +341,7 @@ msgid "Domain"
|
||||||
msgstr "网域"
|
msgstr "网域"
|
||||||
|
|
||||||
#: applications/models/application.py:220 xpack/plugins/cloud/models.py:33
|
#: applications/models/application.py:220 xpack/plugins/cloud/models.py:33
|
||||||
|
#: xpack/plugins/cloud/serializers/account.py:57
|
||||||
msgid "Attrs"
|
msgid "Attrs"
|
||||||
msgstr "属性"
|
msgstr "属性"
|
||||||
|
|
||||||
|
@ -373,16 +374,18 @@ msgstr "类型名称"
|
||||||
#: assets/models/base.py:181 assets/models/cluster.py:26
|
#: assets/models/base.py:181 assets/models/cluster.py:26
|
||||||
#: assets/models/domain.py:26 assets/models/gathered_user.py:19
|
#: assets/models/domain.py:26 assets/models/gathered_user.py:19
|
||||||
#: assets/models/group.py:22 assets/models/label.py:25
|
#: assets/models/group.py:22 assets/models/label.py:25
|
||||||
#: assets/serializers/account.py:18 common/db/models.py:113
|
#: assets/serializers/account.py:18 assets/serializers/cmd_filter.py:28
|
||||||
|
#: assets/serializers/cmd_filter.py:49 common/db/models.py:113
|
||||||
#: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30
|
#: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30
|
||||||
#: orgs/models.py:67 orgs/models.py:217 perms/models/base.py:92
|
#: orgs/models.py:67 orgs/models.py:217 perms/models/base.py:92
|
||||||
#: users/models/group.py:18 users/models/user.py:827
|
#: users/models/group.py:18 users/models/user.py:841
|
||||||
#: xpack/plugins/cloud/models.py:125
|
#: xpack/plugins/cloud/models.py:125
|
||||||
msgid "Date created"
|
msgid "Date created"
|
||||||
msgstr "创建日期"
|
msgstr "创建日期"
|
||||||
|
|
||||||
#: applications/serializers/application.py:104 assets/models/base.py:182
|
#: applications/serializers/application.py:104 assets/models/base.py:182
|
||||||
#: assets/models/gathered_user.py:20 assets/serializers/account.py:21
|
#: assets/models/gathered_user.py:20 assets/serializers/account.py:21
|
||||||
|
#: assets/serializers/cmd_filter.py:29 assets/serializers/cmd_filter.py:50
|
||||||
#: common/db/models.py:114 common/mixins/models.py:51 ops/models/adhoc.py:40
|
#: common/db/models.py:114 common/mixins/models.py:51 ops/models/adhoc.py:40
|
||||||
#: orgs/models.py:218
|
#: orgs/models.py:218
|
||||||
msgid "Date updated"
|
msgid "Date updated"
|
||||||
|
@ -607,7 +610,7 @@ msgid "Is active"
|
||||||
msgstr "激活"
|
msgstr "激活"
|
||||||
|
|
||||||
#: assets/models/asset.py:222 assets/models/cluster.py:19
|
#: assets/models/asset.py:222 assets/models/cluster.py:19
|
||||||
#: assets/models/user.py:222 assets/models/user.py:380
|
#: assets/models/user.py:222 assets/models/user.py:377
|
||||||
msgid "Admin user"
|
msgid "Admin user"
|
||||||
msgstr "特权用户"
|
msgstr "特权用户"
|
||||||
|
|
||||||
|
@ -627,7 +630,7 @@ msgstr "标签管理"
|
||||||
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:52
|
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:52
|
||||||
#: assets/models/cmd_filter.py:99 assets/models/group.py:21
|
#: assets/models/cmd_filter.py:99 assets/models/group.py:21
|
||||||
#: common/db/models.py:111 common/mixins/models.py:49 orgs/models.py:66
|
#: common/db/models.py:111 common/mixins/models.py:49 orgs/models.py:66
|
||||||
#: orgs/models.py:219 perms/models/base.py:91 users/models/user.py:619
|
#: orgs/models.py:219 perms/models/base.py:91 users/models/user.py:629
|
||||||
#: users/serializers/group.py:33
|
#: users/serializers/group.py:33
|
||||||
#: xpack/plugins/change_auth_plan/models/base.py:48
|
#: xpack/plugins/change_auth_plan/models/base.py:48
|
||||||
#: xpack/plugins/cloud/models.py:122 xpack/plugins/gathered_user/models.py:30
|
#: xpack/plugins/cloud/models.py:122 xpack/plugins/gathered_user/models.py:30
|
||||||
|
@ -808,7 +811,7 @@ msgstr "带宽"
|
||||||
msgid "Contact"
|
msgid "Contact"
|
||||||
msgstr "联系人"
|
msgstr "联系人"
|
||||||
|
|
||||||
#: assets/models/cluster.py:22 users/models/user.py:594
|
#: assets/models/cluster.py:22 users/models/user.py:604
|
||||||
msgid "Phone"
|
msgid "Phone"
|
||||||
msgstr "手机"
|
msgstr "手机"
|
||||||
|
|
||||||
|
@ -834,7 +837,7 @@ msgid "Default"
|
||||||
msgstr "默认"
|
msgstr "默认"
|
||||||
|
|
||||||
#: assets/models/cluster.py:36 assets/models/label.py:14 rbac/const.py:6
|
#: assets/models/cluster.py:36 assets/models/label.py:14 rbac/const.py:6
|
||||||
#: users/models/user.py:812
|
#: users/models/user.py:826
|
||||||
msgid "System"
|
msgid "System"
|
||||||
msgstr "系统"
|
msgstr "系统"
|
||||||
|
|
||||||
|
@ -843,7 +846,7 @@ msgid "Default Cluster"
|
||||||
msgstr "默认Cluster"
|
msgstr "默认Cluster"
|
||||||
|
|
||||||
#: assets/models/cmd_filter.py:34 perms/models/base.py:86
|
#: assets/models/cmd_filter.py:34 perms/models/base.py:86
|
||||||
#: users/models/group.py:31 users/models/user.py:580
|
#: users/models/group.py:31 users/models/user.py:590
|
||||||
#: users/templates/users/_select_user_modal.html:16
|
#: users/templates/users/_select_user_modal.html:16
|
||||||
#: users/templates/users/user_asset_permission.html:39
|
#: users/templates/users/user_asset_permission.html:39
|
||||||
#: users/templates/users/user_asset_permission.html:67
|
#: users/templates/users/user_asset_permission.html:67
|
||||||
|
@ -1060,18 +1063,6 @@ msgid "Switch from"
|
||||||
msgstr "切换自"
|
msgstr "切换自"
|
||||||
|
|
||||||
#: assets/models/user.py:327
|
#: 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"
|
msgid "Can match system user"
|
||||||
msgstr "可以匹配系统用户"
|
msgstr "可以匹配系统用户"
|
||||||
|
|
||||||
|
@ -1162,6 +1153,12 @@ msgstr "密钥密码"
|
||||||
msgid "private key invalid or passphrase error"
|
msgid "private key invalid or passphrase error"
|
||||||
msgstr "密钥不合法或密钥密码错误"
|
msgstr "密钥不合法或密钥密码错误"
|
||||||
|
|
||||||
|
#: assets/serializers/cmd_filter.py:51
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Application display"
|
||||||
|
msgid "Action display"
|
||||||
|
msgstr "应用名称"
|
||||||
|
|
||||||
#: assets/serializers/domain.py:13 assets/serializers/label.py:12
|
#: assets/serializers/domain.py:13 assets/serializers/label.py:12
|
||||||
#: assets/serializers/system_user.py:59
|
#: assets/serializers/system_user.py:59
|
||||||
#: perms/serializers/asset/permission.py:49
|
#: perms/serializers/asset/permission.py:49
|
||||||
|
@ -1384,7 +1381,7 @@ msgstr "日志审计"
|
||||||
|
|
||||||
#: audits/models.py:27 audits/models.py:57
|
#: audits/models.py:27 audits/models.py:57
|
||||||
#: authentication/templates/authentication/_access_key_modal.html:65
|
#: authentication/templates/authentication/_access_key_modal.html:65
|
||||||
#: rbac/tree.py:162 users/templates/users/user_asset_permission.html:128
|
#: rbac/tree.py:167 users/templates/users/user_asset_permission.html:128
|
||||||
#: users/templates/users/user_database_app_permission.html:111
|
#: users/templates/users/user_database_app_permission.html:111
|
||||||
msgid "Delete"
|
msgid "Delete"
|
||||||
msgstr "删除"
|
msgstr "删除"
|
||||||
|
@ -1438,11 +1435,11 @@ msgstr "文件管理"
|
||||||
|
|
||||||
#: audits/models.py:55
|
#: audits/models.py:55
|
||||||
#: authentication/templates/authentication/_access_key_modal.html:22
|
#: authentication/templates/authentication/_access_key_modal.html:22
|
||||||
#: rbac/tree.py:159
|
#: rbac/tree.py:164
|
||||||
msgid "Create"
|
msgid "Create"
|
||||||
msgstr "创建"
|
msgstr "创建"
|
||||||
|
|
||||||
#: audits/models.py:56 rbac/tree.py:161 templates/_csv_import_export.html:18
|
#: audits/models.py:56 rbac/tree.py:166 templates/_csv_import_export.html:18
|
||||||
#: templates/_csv_update_modal.html:6
|
#: templates/_csv_update_modal.html:6
|
||||||
#: users/templates/users/user_asset_permission.html:127
|
#: users/templates/users/user_asset_permission.html:127
|
||||||
#: users/templates/users/user_database_app_permission.html:110
|
#: users/templates/users/user_database_app_permission.html:110
|
||||||
|
@ -1506,7 +1503,7 @@ msgstr "用户代理"
|
||||||
|
|
||||||
#: audits/models.py:124
|
#: audits/models.py:124
|
||||||
#: authentication/templates/authentication/_mfa_confirm_modal.html:14
|
#: authentication/templates/authentication/_mfa_confirm_modal.html:14
|
||||||
#: users/forms/profile.py:64 users/models/user.py:597
|
#: users/forms/profile.py:64 users/models/user.py:607
|
||||||
#: users/serializers/profile.py:121
|
#: users/serializers/profile.py:121
|
||||||
msgid "MFA"
|
msgid "MFA"
|
||||||
msgstr "MFA"
|
msgstr "MFA"
|
||||||
|
@ -1584,13 +1581,13 @@ msgstr "认证令牌"
|
||||||
|
|
||||||
#: audits/signal_handlers.py:71 authentication/notifications.py:73
|
#: audits/signal_handlers.py:71 authentication/notifications.py:73
|
||||||
#: authentication/views/login.py:164 authentication/views/wecom.py:158
|
#: authentication/views/login.py:164 authentication/views/wecom.py:158
|
||||||
#: notifications/backends/__init__.py:11 users/models/user.py:633
|
#: notifications/backends/__init__.py:11 users/models/user.py:643
|
||||||
msgid "WeCom"
|
msgid "WeCom"
|
||||||
msgstr "企业微信"
|
msgstr "企业微信"
|
||||||
|
|
||||||
#: audits/signal_handlers.py:72 authentication/views/dingtalk.py:160
|
#: audits/signal_handlers.py:72 authentication/views/dingtalk.py:160
|
||||||
#: authentication/views/login.py:170 notifications/backends/__init__.py:12
|
#: authentication/views/login.py:170 notifications/backends/__init__.py:12
|
||||||
#: users/models/user.py:634
|
#: users/models/user.py:644
|
||||||
msgid "DingTalk"
|
msgid "DingTalk"
|
||||||
msgstr "钉钉"
|
msgstr "钉钉"
|
||||||
|
|
||||||
|
@ -2111,7 +2108,7 @@ msgid "Secret"
|
||||||
msgstr "密钥"
|
msgstr "密钥"
|
||||||
|
|
||||||
#: authentication/templates/authentication/_access_key_modal.html:33
|
#: authentication/templates/authentication/_access_key_modal.html:33
|
||||||
#: terminal/notifications.py:90 terminal/notifications.py:138
|
#: terminal/notifications.py:93 terminal/notifications.py:141
|
||||||
msgid "Date"
|
msgid "Date"
|
||||||
msgstr "日期"
|
msgstr "日期"
|
||||||
|
|
||||||
|
@ -2121,14 +2118,14 @@ msgid "Show"
|
||||||
msgstr "显示"
|
msgstr "显示"
|
||||||
|
|
||||||
#: authentication/templates/authentication/_access_key_modal.html:66
|
#: authentication/templates/authentication/_access_key_modal.html:66
|
||||||
#: settings/serializers/security.py:39 users/models/user.py:469
|
#: settings/serializers/security.py:39 users/models/user.py:479
|
||||||
#: users/serializers/profile.py:111 users/templates/users/mfa_setting.html:61
|
#: users/serializers/profile.py:111 users/templates/users/mfa_setting.html:61
|
||||||
#: users/templates/users/user_verify_mfa.html:36
|
#: users/templates/users/user_verify_mfa.html:36
|
||||||
msgid "Disable"
|
msgid "Disable"
|
||||||
msgstr "禁用"
|
msgstr "禁用"
|
||||||
|
|
||||||
#: authentication/templates/authentication/_access_key_modal.html:67
|
#: authentication/templates/authentication/_access_key_modal.html:67
|
||||||
#: users/models/user.py:470 users/serializers/profile.py:112
|
#: users/models/user.py:480 users/serializers/profile.py:112
|
||||||
#: users/templates/users/mfa_setting.html:26
|
#: users/templates/users/mfa_setting.html:26
|
||||||
#: users/templates/users/mfa_setting.html:68
|
#: users/templates/users/mfa_setting.html:68
|
||||||
msgid "Enable"
|
msgid "Enable"
|
||||||
|
@ -2377,7 +2374,7 @@ msgid "The FeiShu is already bound to another user"
|
||||||
msgstr "该飞书已经绑定其他用户"
|
msgstr "该飞书已经绑定其他用户"
|
||||||
|
|
||||||
#: authentication/views/feishu.py:148 authentication/views/login.py:176
|
#: authentication/views/feishu.py:148 authentication/views/login.py:176
|
||||||
#: notifications/backends/__init__.py:14 users/models/user.py:635
|
#: notifications/backends/__init__.py:14 users/models/user.py:645
|
||||||
msgid "FeiShu"
|
msgid "FeiShu"
|
||||||
msgstr "飞书"
|
msgstr "飞书"
|
||||||
|
|
||||||
|
@ -2672,7 +2669,7 @@ msgid "Notifications"
|
||||||
msgstr "通知"
|
msgstr "通知"
|
||||||
|
|
||||||
#: notifications/backends/__init__.py:10 users/forms/profile.py:101
|
#: notifications/backends/__init__.py:10 users/forms/profile.py:101
|
||||||
#: users/models/user.py:576
|
#: users/models/user.py:586
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr "邮件"
|
msgstr "邮件"
|
||||||
|
|
||||||
|
@ -2879,7 +2876,7 @@ msgstr "当前组织 ({}) 不能被删除"
|
||||||
msgid "The organization have resource ({}) cannot be deleted"
|
msgid "The organization have resource ({}) cannot be deleted"
|
||||||
msgstr "组织存在资源 ({}) 不能被删除"
|
msgstr "组织存在资源 ({}) 不能被删除"
|
||||||
|
|
||||||
#: orgs/apps.py:7 rbac/tree.py:110
|
#: orgs/apps.py:7 rbac/tree.py:113
|
||||||
msgid "App organizations"
|
msgid "App organizations"
|
||||||
msgstr "组织管理"
|
msgstr "组织管理"
|
||||||
|
|
||||||
|
@ -2898,7 +2895,7 @@ msgid "Can view root org"
|
||||||
msgstr "可以查看全局组织"
|
msgstr "可以查看全局组织"
|
||||||
|
|
||||||
#: orgs/models.py:216 rbac/models/role.py:46 rbac/models/rolebinding.py:42
|
#: orgs/models.py:216 rbac/models/role.py:46 rbac/models/rolebinding.py:42
|
||||||
#: users/models/user.py:584 users/templates/users/_select_user_modal.html:15
|
#: users/models/user.py:594 users/templates/users/_select_user_modal.html:15
|
||||||
msgid "Role"
|
msgid "Role"
|
||||||
msgstr "角色"
|
msgstr "角色"
|
||||||
|
|
||||||
|
@ -2997,7 +2994,7 @@ msgstr "剪贴板复制粘贴"
|
||||||
#: perms/models/base.py:90
|
#: perms/models/base.py:90
|
||||||
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:58
|
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:58
|
||||||
#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:60
|
#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:60
|
||||||
#: users/models/user.py:616
|
#: users/models/user.py:626
|
||||||
msgid "Date expired"
|
msgid "Date expired"
|
||||||
msgstr "失效日期"
|
msgstr "失效日期"
|
||||||
|
|
||||||
|
@ -3040,15 +3037,15 @@ msgstr "组织 ({}) 的应用授权"
|
||||||
#: perms/serializers/application/permission.py:20
|
#: perms/serializers/application/permission.py:20
|
||||||
#: perms/serializers/application/permission.py:41
|
#: perms/serializers/application/permission.py:41
|
||||||
#: perms/serializers/asset/permission.py:19
|
#: perms/serializers/asset/permission.py:19
|
||||||
#: perms/serializers/asset/permission.py:45 users/serializers/user.py:139
|
#: perms/serializers/asset/permission.py:45 users/serializers/user.py:137
|
||||||
msgid "Is valid"
|
msgid "Is valid"
|
||||||
msgstr "账号是否有效"
|
msgstr "账号是否有效"
|
||||||
|
|
||||||
#: perms/serializers/application/permission.py:21
|
#: perms/serializers/application/permission.py:21
|
||||||
#: perms/serializers/application/permission.py:40
|
#: perms/serializers/application/permission.py:40
|
||||||
#: perms/serializers/asset/permission.py:20
|
#: perms/serializers/asset/permission.py:20
|
||||||
#: perms/serializers/asset/permission.py:44 users/serializers/user.py:85
|
#: perms/serializers/asset/permission.py:44 users/serializers/user.py:83
|
||||||
#: users/serializers/user.py:141
|
#: users/serializers/user.py:139
|
||||||
msgid "Is expired"
|
msgid "Is expired"
|
||||||
msgstr "已过期"
|
msgstr "已过期"
|
||||||
|
|
||||||
|
@ -3130,27 +3127,27 @@ msgstr "{} 至少有一个系统角色"
|
||||||
msgid "RBAC"
|
msgid "RBAC"
|
||||||
msgstr "RBAC"
|
msgstr "RBAC"
|
||||||
|
|
||||||
#: rbac/builtin.py:89
|
#: rbac/builtin.py:92
|
||||||
msgid "SystemAdmin"
|
msgid "SystemAdmin"
|
||||||
msgstr "系统管理员"
|
msgstr "系统管理员"
|
||||||
|
|
||||||
#: rbac/builtin.py:92
|
#: rbac/builtin.py:95
|
||||||
msgid "SystemAuditor"
|
msgid "SystemAuditor"
|
||||||
msgstr "系统审计员"
|
msgstr "系统审计员"
|
||||||
|
|
||||||
#: rbac/builtin.py:95
|
#: rbac/builtin.py:98
|
||||||
msgid "SystemComponent"
|
msgid "SystemComponent"
|
||||||
msgstr "系统组件"
|
msgstr "系统组件"
|
||||||
|
|
||||||
#: rbac/builtin.py:101
|
#: rbac/builtin.py:104
|
||||||
msgid "OrgAdmin"
|
msgid "OrgAdmin"
|
||||||
msgstr "组织管理员"
|
msgstr "组织管理员"
|
||||||
|
|
||||||
#: rbac/builtin.py:104
|
#: rbac/builtin.py:107
|
||||||
msgid "OrgAuditor"
|
msgid "OrgAuditor"
|
||||||
msgstr "组织审计员"
|
msgstr "组织审计员"
|
||||||
|
|
||||||
#: rbac/builtin.py:107
|
#: rbac/builtin.py:110
|
||||||
msgid "OrgUser"
|
msgid "OrgUser"
|
||||||
msgstr "组织用户"
|
msgstr "组织用户"
|
||||||
|
|
||||||
|
@ -3220,7 +3217,7 @@ msgstr "组织角色绑定"
|
||||||
msgid "System role binding"
|
msgid "System role binding"
|
||||||
msgstr "系统角色绑定"
|
msgstr "系统角色绑定"
|
||||||
|
|
||||||
#: rbac/serializers/permission.py:26 users/serializers/profile.py:125
|
#: rbac/serializers/permission.py:26 users/serializers/profile.py:126
|
||||||
msgid "Perms"
|
msgid "Perms"
|
||||||
msgstr "权限"
|
msgstr "权限"
|
||||||
|
|
||||||
|
@ -3240,91 +3237,91 @@ msgstr "角色显示"
|
||||||
msgid "Has bound this role"
|
msgid "Has bound this role"
|
||||||
msgstr "已经绑定"
|
msgstr "已经绑定"
|
||||||
|
|
||||||
#: rbac/tree.py:16 rbac/tree.py:17
|
#: rbac/tree.py:19 rbac/tree.py:20
|
||||||
msgid "All permissions"
|
msgid "All permissions"
|
||||||
msgstr "所有权限"
|
msgstr "所有权限"
|
||||||
|
|
||||||
#: rbac/tree.py:23
|
#: rbac/tree.py:26
|
||||||
msgid "Console view"
|
msgid "Console view"
|
||||||
msgstr "控制台"
|
msgstr "控制台"
|
||||||
|
|
||||||
#: rbac/tree.py:24
|
#: rbac/tree.py:27
|
||||||
msgid "Workspace view"
|
msgid "Workspace view"
|
||||||
msgstr "工作台"
|
msgstr "工作台"
|
||||||
|
|
||||||
#: rbac/tree.py:25
|
#: rbac/tree.py:28
|
||||||
msgid "Audit view"
|
msgid "Audit view"
|
||||||
msgstr "审计台"
|
msgstr "审计台"
|
||||||
|
|
||||||
#: rbac/tree.py:26 settings/models.py:140
|
#: rbac/tree.py:29 settings/models.py:140
|
||||||
msgid "System setting"
|
msgid "System setting"
|
||||||
msgstr "系统设置"
|
msgstr "系统设置"
|
||||||
|
|
||||||
#: rbac/tree.py:27
|
#: rbac/tree.py:30
|
||||||
msgid "Other"
|
msgid "Other"
|
||||||
msgstr "其它"
|
msgstr "其它"
|
||||||
|
|
||||||
#: rbac/tree.py:35
|
#: rbac/tree.py:38
|
||||||
msgid "Accounts"
|
msgid "Accounts"
|
||||||
msgstr "账号管理"
|
msgstr "账号管理"
|
||||||
|
|
||||||
#: rbac/tree.py:39
|
#: rbac/tree.py:42
|
||||||
msgid "Session audits"
|
msgid "Session audits"
|
||||||
msgstr "会话审计"
|
msgstr "会话审计"
|
||||||
|
|
||||||
#: rbac/tree.py:49
|
#: rbac/tree.py:52
|
||||||
msgid "Cloud import"
|
msgid "Cloud import"
|
||||||
msgstr "云同步"
|
msgstr "云同步"
|
||||||
|
|
||||||
#: rbac/tree.py:50
|
#: rbac/tree.py:53
|
||||||
msgid "Backup account"
|
msgid "Backup account"
|
||||||
msgstr "备份账号"
|
msgstr "备份账号"
|
||||||
|
|
||||||
#: rbac/tree.py:51
|
#: rbac/tree.py:54
|
||||||
msgid "Gather account"
|
msgid "Gather account"
|
||||||
msgstr "收集账号"
|
msgstr "收集账号"
|
||||||
|
|
||||||
#: rbac/tree.py:52
|
#: rbac/tree.py:55
|
||||||
msgid "App change auth"
|
msgid "App change auth"
|
||||||
msgstr "应用改密"
|
msgstr "应用改密"
|
||||||
|
|
||||||
#: rbac/tree.py:53
|
#: rbac/tree.py:56
|
||||||
msgid "Asset change auth"
|
msgid "Asset change auth"
|
||||||
msgstr "资产改密"
|
msgstr "资产改密"
|
||||||
|
|
||||||
#: rbac/tree.py:54
|
#: rbac/tree.py:57
|
||||||
msgid "Terminal setting"
|
msgid "Terminal setting"
|
||||||
msgstr "终端设置"
|
msgstr "终端设置"
|
||||||
|
|
||||||
#: rbac/tree.py:55
|
#: rbac/tree.py:58
|
||||||
msgid "My assets"
|
msgid "My assets"
|
||||||
msgstr "我的资产"
|
msgstr "我的资产"
|
||||||
|
|
||||||
#: rbac/tree.py:56
|
#: rbac/tree.py:59
|
||||||
msgid "My apps"
|
msgid "My apps"
|
||||||
msgstr "我的应用"
|
msgstr "我的应用"
|
||||||
|
|
||||||
#: rbac/tree.py:111
|
#: rbac/tree.py:114
|
||||||
msgid "Ticket comment"
|
msgid "Ticket comment"
|
||||||
msgstr "工单评论"
|
msgstr "工单评论"
|
||||||
|
|
||||||
#: rbac/tree.py:112 tickets/models/ticket.py:163
|
#: rbac/tree.py:115 tickets/models/ticket.py:163
|
||||||
msgid "Ticket"
|
msgid "Ticket"
|
||||||
msgstr "工单管理"
|
msgstr "工单管理"
|
||||||
|
|
||||||
#: rbac/tree.py:113
|
#: rbac/tree.py:116
|
||||||
msgid "Common setting"
|
msgid "Common setting"
|
||||||
msgstr "一般设置"
|
msgstr "一般设置"
|
||||||
|
|
||||||
#: rbac/tree.py:115
|
#: rbac/tree.py:117
|
||||||
msgid "View permission tree"
|
msgid "View permission tree"
|
||||||
msgstr "查看授权树"
|
msgstr "查看授权树"
|
||||||
|
|
||||||
#: rbac/tree.py:116
|
#: rbac/tree.py:118
|
||||||
msgid "Execute batch command"
|
msgid "Execute batch command"
|
||||||
msgstr "执行批量命令"
|
msgstr "执行批量命令"
|
||||||
|
|
||||||
#: rbac/tree.py:160
|
#: rbac/tree.py:165
|
||||||
msgid "View"
|
msgid "View"
|
||||||
msgstr "查看"
|
msgstr "查看"
|
||||||
|
|
||||||
|
@ -4991,11 +4988,11 @@ msgstr "会话管理"
|
||||||
msgid "Danger command alert"
|
msgid "Danger command alert"
|
||||||
msgstr "危险命令告警"
|
msgstr "危险命令告警"
|
||||||
|
|
||||||
#: terminal/notifications.py:89 terminal/notifications.py:137
|
#: terminal/notifications.py:92 terminal/notifications.py:140
|
||||||
msgid "Level"
|
msgid "Level"
|
||||||
msgstr "级别"
|
msgstr "级别"
|
||||||
|
|
||||||
#: terminal/notifications.py:107
|
#: terminal/notifications.py:110
|
||||||
msgid "Batch danger command alert"
|
msgid "Batch danger command alert"
|
||||||
msgstr "批量危险命令告警"
|
msgstr "批量危险命令告警"
|
||||||
|
|
||||||
|
@ -5039,7 +5036,7 @@ msgstr "端点无效: 移除路径 `{}`"
|
||||||
msgid "Bucket"
|
msgid "Bucket"
|
||||||
msgstr "桶名称"
|
msgstr "桶名称"
|
||||||
|
|
||||||
#: terminal/serializers/storage.py:34 users/models/user.py:608
|
#: terminal/serializers/storage.py:34 users/models/user.py:618
|
||||||
msgid "Secret key"
|
msgid "Secret key"
|
||||||
msgstr "密钥"
|
msgstr "密钥"
|
||||||
|
|
||||||
|
@ -5384,19 +5381,19 @@ msgstr "请再次尝试"
|
||||||
msgid "Super ticket"
|
msgid "Super ticket"
|
||||||
msgstr "超级工单"
|
msgstr "超级工单"
|
||||||
|
|
||||||
#: tickets/notifications.py:57
|
#: tickets/notifications.py:63
|
||||||
msgid "Your has a new ticket, applicant - {}"
|
msgid "Your has a new ticket, applicant - {}"
|
||||||
msgstr "你有一个新的工单, 申请人 - {}"
|
msgstr "你有一个新的工单, 申请人 - {}"
|
||||||
|
|
||||||
#: tickets/notifications.py:63
|
#: tickets/notifications.py:69
|
||||||
msgid "New Ticket - {} ({})"
|
msgid "New Ticket - {} ({})"
|
||||||
msgstr "新工单 - {} ({})"
|
msgstr "新工单 - {} ({})"
|
||||||
|
|
||||||
#: tickets/notifications.py:85
|
#: tickets/notifications.py:91
|
||||||
msgid "Your ticket has been processed, processor - {}"
|
msgid "Your ticket has been processed, processor - {}"
|
||||||
msgstr "你的工单已被处理, 处理人 - {}"
|
msgstr "你的工单已被处理, 处理人 - {}"
|
||||||
|
|
||||||
#: tickets/notifications.py:89
|
#: tickets/notifications.py:95
|
||||||
msgid "Ticket has processed - {} ({})"
|
msgid "Ticket has processed - {} ({})"
|
||||||
msgstr "你的工单已被处理, 处理人 - {} ({})"
|
msgstr "你的工单已被处理, 处理人 - {} ({})"
|
||||||
|
|
||||||
|
@ -5535,7 +5532,7 @@ msgstr "当前组织已存在该类型"
|
||||||
msgid "Click here to review"
|
msgid "Click here to review"
|
||||||
msgstr "点击查看"
|
msgstr "点击查看"
|
||||||
|
|
||||||
#: users/api/user.py:175
|
#: users/api/user.py:180
|
||||||
msgid "Could not reset self otp, use profile reset instead"
|
msgid "Could not reset self otp, use profile reset instead"
|
||||||
msgstr "不能在该页面重置 MFA 多因子认证, 请去个人信息页面重置"
|
msgstr "不能在该页面重置 MFA 多因子认证, 请去个人信息页面重置"
|
||||||
|
|
||||||
|
@ -5638,72 +5635,72 @@ msgid "Public key should not be the same as your old one."
|
||||||
msgstr "不能和原来的密钥相同"
|
msgstr "不能和原来的密钥相同"
|
||||||
|
|
||||||
#: users/forms/profile.py:149 users/serializers/profile.py:95
|
#: users/forms/profile.py:149 users/serializers/profile.py:95
|
||||||
#: users/serializers/profile.py:175 users/serializers/profile.py:202
|
#: users/serializers/profile.py:176 users/serializers/profile.py:203
|
||||||
msgid "Not a valid ssh public key"
|
msgid "Not a valid ssh public key"
|
||||||
msgstr "SSH密钥不合法"
|
msgstr "SSH密钥不合法"
|
||||||
|
|
||||||
#: users/forms/profile.py:160 users/models/user.py:605
|
#: users/forms/profile.py:160 users/models/user.py:615
|
||||||
#: users/templates/users/user_password_update.html:48
|
#: users/templates/users/user_password_update.html:48
|
||||||
msgid "Public key"
|
msgid "Public key"
|
||||||
msgstr "SSH公钥"
|
msgstr "SSH公钥"
|
||||||
|
|
||||||
#: users/models/user.py:471
|
#: users/models/user.py:481
|
||||||
msgid "Force enable"
|
msgid "Force enable"
|
||||||
msgstr "强制启用"
|
msgstr "强制启用"
|
||||||
|
|
||||||
#: users/models/user.py:538
|
#: users/models/user.py:548
|
||||||
msgid "Local"
|
msgid "Local"
|
||||||
msgstr "数据库"
|
msgstr "数据库"
|
||||||
|
|
||||||
#: users/models/user.py:586 users/serializers/user.py:140
|
#: users/models/user.py:596 users/serializers/user.py:138
|
||||||
msgid "Is service account"
|
msgid "Is service account"
|
||||||
msgstr "服务账号"
|
msgstr "服务账号"
|
||||||
|
|
||||||
#: users/models/user.py:588
|
#: users/models/user.py:598
|
||||||
msgid "Avatar"
|
msgid "Avatar"
|
||||||
msgstr "头像"
|
msgstr "头像"
|
||||||
|
|
||||||
#: users/models/user.py:591
|
#: users/models/user.py:601
|
||||||
msgid "Wechat"
|
msgid "Wechat"
|
||||||
msgstr "微信"
|
msgstr "微信"
|
||||||
|
|
||||||
#: users/models/user.py:602
|
#: users/models/user.py:612
|
||||||
msgid "Private key"
|
msgid "Private key"
|
||||||
msgstr "ssh私钥"
|
msgstr "ssh私钥"
|
||||||
|
|
||||||
#: users/models/user.py:624
|
#: users/models/user.py:634
|
||||||
msgid "Source"
|
msgid "Source"
|
||||||
msgstr "来源"
|
msgstr "来源"
|
||||||
|
|
||||||
#: users/models/user.py:628
|
#: users/models/user.py:638
|
||||||
msgid "Date password last updated"
|
msgid "Date password last updated"
|
||||||
msgstr "最后更新密码日期"
|
msgstr "最后更新密码日期"
|
||||||
|
|
||||||
#: users/models/user.py:631
|
#: users/models/user.py:641
|
||||||
msgid "Need update password"
|
msgid "Need update password"
|
||||||
msgstr "需要更新密码"
|
msgstr "需要更新密码"
|
||||||
|
|
||||||
#: users/models/user.py:797
|
#: users/models/user.py:811
|
||||||
msgid "Can invite user"
|
msgid "Can invite user"
|
||||||
msgstr "可以邀请用户"
|
msgstr "可以邀请用户"
|
||||||
|
|
||||||
#: users/models/user.py:798
|
#: users/models/user.py:812
|
||||||
msgid "Can remove user"
|
msgid "Can remove user"
|
||||||
msgstr "可以移除用户"
|
msgstr "可以移除用户"
|
||||||
|
|
||||||
#: users/models/user.py:799
|
#: users/models/user.py:813
|
||||||
msgid "Can match user"
|
msgid "Can match user"
|
||||||
msgstr "可以匹配用户"
|
msgstr "可以匹配用户"
|
||||||
|
|
||||||
#: users/models/user.py:808
|
#: users/models/user.py:822
|
||||||
msgid "Administrator"
|
msgid "Administrator"
|
||||||
msgstr "管理员"
|
msgstr "管理员"
|
||||||
|
|
||||||
#: users/models/user.py:811
|
#: users/models/user.py:825
|
||||||
msgid "Administrator is the super user of system"
|
msgid "Administrator is the super user of system"
|
||||||
msgstr "Administrator是初始的超级管理员"
|
msgstr "Administrator是初始的超级管理员"
|
||||||
|
|
||||||
#: users/models/user.py:836
|
#: users/models/user.py:850
|
||||||
msgid "User password history"
|
msgid "User password history"
|
||||||
msgstr "用户密码历史"
|
msgstr "用户密码历史"
|
||||||
|
|
||||||
|
@ -5742,7 +5739,7 @@ msgstr "重置 MFA"
|
||||||
msgid "The old password is incorrect"
|
msgid "The old password is incorrect"
|
||||||
msgstr "旧密码错误"
|
msgstr "旧密码错误"
|
||||||
|
|
||||||
#: users/serializers/profile.py:36 users/serializers/profile.py:189
|
#: users/serializers/profile.py:36 users/serializers/profile.py:190
|
||||||
msgid "Password does not match security rules"
|
msgid "Password does not match security rules"
|
||||||
msgstr "密码不满足安全规则"
|
msgstr "密码不满足安全规则"
|
||||||
|
|
||||||
|
@ -5754,97 +5751,97 @@ msgstr "新密码不能是最近 {} 次的密码"
|
||||||
msgid "The newly set password is inconsistent"
|
msgid "The newly set password is inconsistent"
|
||||||
msgstr "两次密码不一致"
|
msgstr "两次密码不一致"
|
||||||
|
|
||||||
#: users/serializers/profile.py:141 users/serializers/user.py:138
|
#: users/serializers/profile.py:142 users/serializers/user.py:136
|
||||||
msgid "Is first login"
|
msgid "Is first login"
|
||||||
msgstr "首次登录"
|
msgstr "首次登录"
|
||||||
|
|
||||||
#: users/serializers/user.py:26 users/serializers/user.py:33
|
#: users/serializers/user.py:24 users/serializers/user.py:31
|
||||||
msgid "System roles"
|
msgid "System roles"
|
||||||
msgstr "系统角色"
|
msgstr "系统角色"
|
||||||
|
|
||||||
#: users/serializers/user.py:31 users/serializers/user.py:34
|
#: users/serializers/user.py:29 users/serializers/user.py:32
|
||||||
msgid "Org roles"
|
msgid "Org roles"
|
||||||
msgstr "组织角色"
|
msgstr "组织角色"
|
||||||
|
|
||||||
#: users/serializers/user.py:77
|
#: users/serializers/user.py:75
|
||||||
#: xpack/plugins/change_auth_plan/models/base.py:35
|
#: xpack/plugins/change_auth_plan/models/base.py:35
|
||||||
#: xpack/plugins/change_auth_plan/serializers/base.py:22
|
#: xpack/plugins/change_auth_plan/serializers/base.py:22
|
||||||
msgid "Password strategy"
|
msgid "Password strategy"
|
||||||
msgstr "密码策略"
|
msgstr "密码策略"
|
||||||
|
|
||||||
#: users/serializers/user.py:79
|
#: users/serializers/user.py:77
|
||||||
msgid "MFA enabled"
|
msgid "MFA enabled"
|
||||||
msgstr "MFA"
|
msgstr "MFA"
|
||||||
|
|
||||||
#: users/serializers/user.py:80
|
#: users/serializers/user.py:78
|
||||||
msgid "MFA force enabled"
|
msgid "MFA force enabled"
|
||||||
msgstr "强制 MFA"
|
msgstr "强制 MFA"
|
||||||
|
|
||||||
#: users/serializers/user.py:82
|
#: users/serializers/user.py:80
|
||||||
msgid "MFA level display"
|
msgid "MFA level display"
|
||||||
msgstr "MFA 等级名称"
|
msgstr "MFA 等级名称"
|
||||||
|
|
||||||
#: users/serializers/user.py:84
|
#: users/serializers/user.py:82
|
||||||
msgid "Login blocked"
|
msgid "Login blocked"
|
||||||
msgstr "登录被阻塞"
|
msgstr "登录被阻塞"
|
||||||
|
|
||||||
#: users/serializers/user.py:87
|
#: users/serializers/user.py:85
|
||||||
msgid "Can public key authentication"
|
msgid "Can public key authentication"
|
||||||
msgstr "能否公钥认证"
|
msgstr "能否公钥认证"
|
||||||
|
|
||||||
#: users/serializers/user.py:142
|
#: users/serializers/user.py:140
|
||||||
msgid "Avatar url"
|
msgid "Avatar url"
|
||||||
msgstr "头像路径"
|
msgstr "头像路径"
|
||||||
|
|
||||||
#: users/serializers/user.py:144
|
#: users/serializers/user.py:142
|
||||||
msgid "Groups name"
|
msgid "Groups name"
|
||||||
msgstr "用户组名"
|
msgstr "用户组名"
|
||||||
|
|
||||||
#: users/serializers/user.py:145
|
#: users/serializers/user.py:143
|
||||||
msgid "Source name"
|
msgid "Source name"
|
||||||
msgstr "用户来源名"
|
msgstr "用户来源名"
|
||||||
|
|
||||||
#: users/serializers/user.py:146
|
#: users/serializers/user.py:144
|
||||||
msgid "Organization role name"
|
msgid "Organization role name"
|
||||||
msgstr "组织角色名称"
|
msgstr "组织角色名称"
|
||||||
|
|
||||||
#: users/serializers/user.py:147
|
#: users/serializers/user.py:145
|
||||||
msgid "Super role name"
|
msgid "Super role name"
|
||||||
msgstr "超级角色名称"
|
msgstr "超级角色名称"
|
||||||
|
|
||||||
#: users/serializers/user.py:148
|
#: users/serializers/user.py:146
|
||||||
msgid "Total role name"
|
msgid "Total role name"
|
||||||
msgstr "汇总角色名称"
|
msgstr "汇总角色名称"
|
||||||
|
|
||||||
#: users/serializers/user.py:150
|
#: users/serializers/user.py:148
|
||||||
msgid "Is wecom bound"
|
msgid "Is wecom bound"
|
||||||
msgstr "是否绑定了企业微信"
|
msgstr "是否绑定了企业微信"
|
||||||
|
|
||||||
#: users/serializers/user.py:151
|
#: users/serializers/user.py:149
|
||||||
msgid "Is dingtalk bound"
|
msgid "Is dingtalk bound"
|
||||||
msgstr "是否绑定了钉钉"
|
msgstr "是否绑定了钉钉"
|
||||||
|
|
||||||
#: users/serializers/user.py:152
|
#: users/serializers/user.py:150
|
||||||
msgid "Is feishu bound"
|
msgid "Is feishu bound"
|
||||||
msgstr "是否绑定了飞书"
|
msgstr "是否绑定了飞书"
|
||||||
|
|
||||||
#: users/serializers/user.py:153
|
#: users/serializers/user.py:151
|
||||||
msgid "Is OTP bound"
|
msgid "Is OTP bound"
|
||||||
msgstr "是否绑定了虚拟 MFA"
|
msgstr "是否绑定了虚拟 MFA"
|
||||||
|
|
||||||
#: users/serializers/user.py:155
|
#: users/serializers/user.py:153
|
||||||
msgid "System role name"
|
msgid "System role name"
|
||||||
msgstr "系统角色名称"
|
msgstr "系统角色名称"
|
||||||
|
|
||||||
#: users/serializers/user.py:247
|
#: users/serializers/user.py:245
|
||||||
msgid "Select users"
|
msgid "Select users"
|
||||||
msgstr "选择用户"
|
msgstr "选择用户"
|
||||||
|
|
||||||
#: users/serializers/user.py:248
|
#: users/serializers/user.py:246
|
||||||
msgid "For security, only list several users"
|
msgid "For security, only list several users"
|
||||||
msgstr "为了安全,仅列出几个用户"
|
msgstr "为了安全,仅列出几个用户"
|
||||||
|
|
||||||
#: users/serializers/user.py:281
|
#: users/serializers/user.py:279
|
||||||
msgid "name not unique"
|
msgid "name not unique"
|
||||||
msgstr "名称重复"
|
msgstr "名称重复"
|
||||||
|
|
||||||
|
@ -6685,6 +6682,14 @@ msgstr "华北-乌兰察布一"
|
||||||
msgid "CN South-Guangzhou-InvitationOnly"
|
msgid "CN South-Guangzhou-InvitationOnly"
|
||||||
msgstr "华南-广州-友好用户环境"
|
msgstr "华南-广州-友好用户环境"
|
||||||
|
|
||||||
|
#: xpack/plugins/cloud/serializers/account.py:58
|
||||||
|
msgid "Validity display"
|
||||||
|
msgstr "有效显示"
|
||||||
|
|
||||||
|
#: xpack/plugins/cloud/serializers/account.py:59
|
||||||
|
msgid "Provider display"
|
||||||
|
msgstr "服务商名称"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/serializers/account_attrs.py:13
|
#: xpack/plugins/cloud/serializers/account_attrs.py:13
|
||||||
msgid "AccessKey ID"
|
msgid "AccessKey ID"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -6844,6 +6849,25 @@ msgstr "旗舰版"
|
||||||
msgid "Community edition"
|
msgid "Community edition"
|
||||||
msgstr "社区版"
|
msgstr "社区版"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
|
#~| msgid "Date created"
|
||||||
|
#~ msgid "date created"
|
||||||
|
#~ msgstr "创建日期"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
|
#~| msgid "Date updated"
|
||||||
|
#~ msgid "date updated"
|
||||||
|
#~ msgstr "更新日期"
|
||||||
|
|
||||||
|
#~ msgid "Can view system user asset"
|
||||||
|
#~ msgstr "可以查看系统用户资产列表"
|
||||||
|
|
||||||
|
#~ msgid "Can add asset to system user"
|
||||||
|
#~ msgstr "可以添加资产到系统用户"
|
||||||
|
|
||||||
|
#~ msgid "Can remove system user asset"
|
||||||
|
#~ msgstr "可以移除系统用户资产"
|
||||||
|
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#~| msgid "Create"
|
#~| msgid "Create"
|
||||||
#~ msgid "create"
|
#~ msgid "create"
|
||||||
|
|
|
@ -55,6 +55,10 @@ class CommandExecution(OrgModelMixin):
|
||||||
def user_display(self):
|
def user_display(self):
|
||||||
return str(self.user)
|
return str(self.user)
|
||||||
|
|
||||||
|
@lazyproperty
|
||||||
|
def hosts_display(self):
|
||||||
|
return ','.join(self.hosts.all().values_list('hostname', flat=True))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def result(self):
|
def result(self):
|
||||||
if self._result:
|
if self._result:
|
||||||
|
|
|
@ -136,8 +136,7 @@ class CommandExecutionSerializer(serializers.ModelSerializer):
|
||||||
fields_mini = ['id']
|
fields_mini = ['id']
|
||||||
fields_small = fields_mini + [
|
fields_small = fields_mini + [
|
||||||
'command', 'result', 'log_url',
|
'command', 'result', 'log_url',
|
||||||
'is_finished',
|
'is_finished', 'date_created', 'date_finished'
|
||||||
'date_created', 'date_finished'
|
|
||||||
]
|
]
|
||||||
fields_fk = ['run_as']
|
fields_fk = ['run_as']
|
||||||
fields_m2m = ['hosts']
|
fields_m2m = ['hosts']
|
||||||
|
|
|
@ -27,10 +27,10 @@ class Migration(migrations.Migration):
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='applicationpermission',
|
name='applicationpermission',
|
||||||
options={'ordering': ('name',), 'permissions': [('view_permuserapplication', 'Can view application of permission to user')], 'verbose_name': 'Application permission'},
|
options={'ordering': ('name',), 'permissions': [], 'verbose_name': 'Application permission'},
|
||||||
),
|
),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
name='assetpermission',
|
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'},
|
options={'ordering': ('name',), 'permissions': [], 'verbose_name': 'Asset permission'},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -37,7 +37,6 @@ class ApplicationPermission(BasePermission):
|
||||||
unique_together = [('org_id', 'name')]
|
unique_together = [('org_id', 'name')]
|
||||||
verbose_name = _('Application permission')
|
verbose_name = _('Application permission')
|
||||||
permissions = [
|
permissions = [
|
||||||
('view_permuserapplication', _('Can view application of permission to user'))
|
|
||||||
]
|
]
|
||||||
ordering = ('name',)
|
ordering = ('name',)
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,6 @@ class AssetPermission(BasePermission):
|
||||||
verbose_name = _("Asset permission")
|
verbose_name = _("Asset permission")
|
||||||
ordering = ('name',)
|
ordering = ('name',)
|
||||||
permissions = [
|
permissions = [
|
||||||
('view_permuserasset', _('Can view asset of permission to user')),
|
|
||||||
('view_permusergroupasset', _('Can view asset of permission to user group'))
|
|
||||||
]
|
]
|
||||||
|
|
||||||
@lazyproperty
|
@lazyproperty
|
||||||
|
|
|
@ -41,13 +41,3 @@ class PermissionViewSet(JMSModelViewSet):
|
||||||
queryset = Permission.get_permissions(self.scope)
|
queryset = Permission.get_permissions(self.scope)
|
||||||
queryset = queryset.prefetch_related('content_type')
|
queryset = queryset.prefetch_related('content_type')
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
# class UserPermsApi(ListAPIView):
|
|
||||||
# serializer_class = UserPermsSerializer
|
|
||||||
# permission_classes = (IsValidUser,)
|
|
||||||
#
|
|
||||||
# def list(self, request, *args, **kwargs):
|
|
||||||
# perms = RoleBinding.get_user_perms(request.user)
|
|
||||||
# serializer = super().get_serializer(data={'perms': perms})
|
|
||||||
# return Res
|
|
||||||
|
|
|
@ -2,6 +2,8 @@ from django.utils.translation import ugettext_noop
|
||||||
|
|
||||||
from .const import Scope, system_exclude_permissions, org_exclude_permissions
|
from .const import Scope, system_exclude_permissions, org_exclude_permissions
|
||||||
|
|
||||||
|
# Todo: 获取应该区分 系统用户,和组织用户的权限
|
||||||
|
# 工作台也区分组织后再考虑
|
||||||
user_perms = (
|
user_perms = (
|
||||||
('rbac', 'menupermission', 'view', 'workspace'),
|
('rbac', 'menupermission', 'view', 'workspace'),
|
||||||
('rbac', 'menupermission', 'view', 'webterminal'),
|
('rbac', 'menupermission', 'view', 'webterminal'),
|
||||||
|
@ -11,13 +13,14 @@ user_perms = (
|
||||||
('assets', 'asset', 'match', 'asset'),
|
('assets', 'asset', 'match', 'asset'),
|
||||||
('assets', 'systemuser', 'match', 'systemuser'),
|
('assets', 'systemuser', 'match', 'systemuser'),
|
||||||
('assets', 'node', 'match', 'node'),
|
('assets', 'node', 'match', 'node'),
|
||||||
|
('applications', 'application', 'match', 'application'),
|
||||||
('ops', 'commandexecution', 'add', 'commandexecution'),
|
('ops', 'commandexecution', 'add', 'commandexecution'),
|
||||||
('authentication', 'connectiontoken', 'add', 'connectiontoken'),
|
('authentication', 'connectiontoken', 'add', 'connectiontoken'),
|
||||||
|
('tickets', 'ticket', 'view', 'ticket'),
|
||||||
)
|
)
|
||||||
|
|
||||||
auditor_perms = user_perms + (
|
auditor_perms = user_perms + (
|
||||||
('rbac', 'menupermission', 'view', 'audit'),
|
('rbac', 'menupermission', 'view', 'audit'),
|
||||||
('rbac', 'menupermission', 'view', 'dashboard'),
|
|
||||||
('audits', '*', '*', '*'),
|
('audits', '*', '*', '*'),
|
||||||
('terminal', 'commandstorage', 'view', 'commandstorage'),
|
('terminal', 'commandstorage', 'view', 'commandstorage'),
|
||||||
('terminal', 'sessionreplay', 'view,download', 'sessionreplay'),
|
('terminal', 'sessionreplay', 'view,download', 'sessionreplay'),
|
||||||
|
@ -95,7 +98,7 @@ class BuiltinRole:
|
||||||
'4', ugettext_noop('SystemComponent'), Scope.system, app_exclude_perms, 'exclude'
|
'4', ugettext_noop('SystemComponent'), Scope.system, app_exclude_perms, 'exclude'
|
||||||
)
|
)
|
||||||
system_user = PredefineRole(
|
system_user = PredefineRole(
|
||||||
'3', ugettext_noop('User'), Scope.system, []
|
'3', ugettext_noop('User'), Scope.system, user_perms
|
||||||
)
|
)
|
||||||
org_admin = PredefineRole(
|
org_admin = PredefineRole(
|
||||||
'5', ugettext_noop('OrgAdmin'), Scope.org, []
|
'5', ugettext_noop('OrgAdmin'), Scope.org, []
|
||||||
|
|
|
@ -29,7 +29,8 @@ exclude_permissions = (
|
||||||
('users', 'userpasswordhistory', '*', '*'),
|
('users', 'userpasswordhistory', '*', '*'),
|
||||||
('applications', 'applicationuser', '*', '*'),
|
('applications', 'applicationuser', '*', '*'),
|
||||||
('applications', 'historicalaccount', '*', '*'),
|
('applications', 'historicalaccount', '*', '*'),
|
||||||
('applications', 'account', 'add,change', 'account'),
|
('applications', 'account', 'add,change,delete', 'account'),
|
||||||
|
('applications', 'account', 'change', 'appplicationaccountsecret'),
|
||||||
('assets', 'adminuser', '*', '*'),
|
('assets', 'adminuser', '*', '*'),
|
||||||
('assets', 'assetgroup', '*', '*'),
|
('assets', 'assetgroup', '*', '*'),
|
||||||
('assets', 'cluster', '*', '*'),
|
('assets', 'cluster', '*', '*'),
|
||||||
|
@ -78,6 +79,7 @@ exclude_permissions = (
|
||||||
('common', 'permission', 'add,delete,view,change', 'permission'),
|
('common', 'permission', 'add,delete,view,change', 'permission'),
|
||||||
('terminal', 'command', 'delete,change', 'command'),
|
('terminal', 'command', 'delete,change', 'command'),
|
||||||
('terminal', 'status', 'delete,change', 'status'),
|
('terminal', 'status', 'delete,change', 'status'),
|
||||||
|
('terminal', 'task', 'add,delete', 'task'),
|
||||||
('terminal', 'sessionjoinrecord', 'delete', 'sessionjoinrecord'),
|
('terminal', 'sessionjoinrecord', 'delete', 'sessionjoinrecord'),
|
||||||
('terminal', 'sessionreplay', 'add,change,delete', 'sessionreplay'),
|
('terminal', 'sessionreplay', 'add,change,delete', 'sessionreplay'),
|
||||||
('terminal', 'sessionsharing', 'view,add,change,delete', 'sessionsharing'),
|
('terminal', 'sessionsharing', 'view,add,change,delete', 'sessionsharing'),
|
||||||
|
|
|
@ -66,8 +66,10 @@ class RBACPermission(permissions.DjangoModelPermissions):
|
||||||
perms = {}
|
perms = {}
|
||||||
if hasattr(view, 'rbac_perms'):
|
if hasattr(view, 'rbac_perms'):
|
||||||
perms.update(dict(view.rbac_perms))
|
perms.update(dict(view.rbac_perms))
|
||||||
|
default_perms = self.get_default_action_perms(model_cls)
|
||||||
if '*' not in perms:
|
if '*' not in perms:
|
||||||
perms.update(self.get_default_action_perms(model_cls))
|
for k, v in default_perms.items():
|
||||||
|
perms.setdefault(k, v)
|
||||||
return perms
|
return perms
|
||||||
|
|
||||||
def _get_action_perms(self, action, model_cls, view):
|
def _get_action_perms(self, action, model_cls, view):
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.db.models.signals import post_migrate
|
from django.db.models.signals import post_migrate, post_save
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
|
|
||||||
|
from .models import SystemRole, OrgRole
|
||||||
from .builtin import BuiltinRole
|
from .builtin import BuiltinRole
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,3 +13,15 @@ def after_migrate_update_builtin_role_permissions(sender, app_config, **kwargs):
|
||||||
if app_config.name == last_app.name:
|
if app_config.name == last_app.name:
|
||||||
print("After migration, update builtin role permissions")
|
print("After migration, update builtin role permissions")
|
||||||
BuiltinRole.sync_to_db()
|
BuiltinRole.sync_to_db()
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(post_save, sender=SystemRole)
|
||||||
|
def on_system_role_update(sender, instance, created, **kwargs):
|
||||||
|
from users.models import User
|
||||||
|
User.expire_users_rbac_perms_cache()
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(post_save, sender=OrgRole)
|
||||||
|
def on_org_role_update(sender, instance, created, **kwargs):
|
||||||
|
from users.models import User
|
||||||
|
User.expire_users_rbac_perms_cache()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
import os
|
||||||
|
|
||||||
from django.utils.translation import gettext_lazy as _, gettext, get_language
|
from django.utils.translation import gettext_lazy as _, gettext, get_language
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -10,6 +11,8 @@ from django.db.models import F, Count
|
||||||
from common.tree import TreeNode
|
from common.tree import TreeNode
|
||||||
from .models import Permission, ContentType
|
from .models import Permission, ContentType
|
||||||
|
|
||||||
|
DEBUG_DB = os.environ.get('DEBUG_DB', '0') == '1'
|
||||||
|
|
||||||
# 根节点
|
# 根节点
|
||||||
root_node_data = {
|
root_node_data = {
|
||||||
'id': '$ROOT$',
|
'id': '$ROOT$',
|
||||||
|
@ -116,11 +119,14 @@ verbose_name_mapper = {
|
||||||
}
|
}
|
||||||
|
|
||||||
xpack_nodes = [
|
xpack_nodes = [
|
||||||
'xpack', 'tickets', 'applications.remoteapp',
|
'xpack', 'tickets', 'gather_account_node',
|
||||||
"assets.accountbackupplan", "assets.accountbackupplanexecution",
|
'applications.remoteapp', "assets.accountbackupplan",
|
||||||
|
"assets.accountbackupplanexecution",
|
||||||
"rbac.orgrole", "rbac.orgrolebinding",
|
"rbac.orgrole", "rbac.orgrolebinding",
|
||||||
"settings.change_interface", 'assets.gathereduser',
|
'assets.gathereduser',
|
||||||
'gather_account_node'
|
|
||||||
|
'settings.change_interface', 'settings.change_sms',
|
||||||
|
'users.invite_user', 'users.remove_user',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -313,12 +319,15 @@ class PermissionTreeUtil:
|
||||||
model_id = f'{p.app}.{p.model}'
|
model_id = f'{p.app}.{p.model}'
|
||||||
if not self._check_model_xpack(model_id):
|
if not self._check_model_xpack(model_id):
|
||||||
continue
|
continue
|
||||||
|
title = p.app_label_codename
|
||||||
|
if not settings.XPACK_ENABLED and title in xpack_nodes:
|
||||||
|
continue
|
||||||
|
|
||||||
# name 要特殊处理,解决 i18n 问题
|
# name 要特殊处理,解决 i18n 问题
|
||||||
name, icon = self._get_permission_name_icon(p, content_types_name_mapper)
|
name, icon = self._get_permission_name_icon(p, content_types_name_mapper)
|
||||||
if settings.DEBUG:
|
if DEBUG_DB:
|
||||||
name += '[{}]'.format(p.app_label_codename)
|
name += '[{}]'.format(p.app_label_codename)
|
||||||
|
|
||||||
title = p.app_label_codename
|
|
||||||
pid = model_id
|
pid = model_id
|
||||||
# perm node 的特殊设置用的是 title,因为 id 是数字,不一致
|
# perm node 的特殊设置用的是 title,因为 id 是数字,不一致
|
||||||
if title in special_pid_mapper:
|
if title in special_pid_mapper:
|
||||||
|
@ -366,9 +375,9 @@ class PermissionTreeUtil:
|
||||||
}
|
}
|
||||||
node_data['title'] = node_data['id']
|
node_data['title'] = node_data['id']
|
||||||
node = TreeNode(**node_data)
|
node = TreeNode(**node_data)
|
||||||
if settings.DEBUG:
|
if DEBUG_DB:
|
||||||
node.name += ('[' + node.id + ']')
|
node.name += ('[' + node.id + ']')
|
||||||
if settings.DEBUG:
|
if DEBUG_DB:
|
||||||
node.name += ('-' + node.id)
|
node.name += ('-' + node.id)
|
||||||
node.name += f'({checked_count}/{total_count})'
|
node.name += f'({checked_count}/{total_count})'
|
||||||
return node
|
return node
|
||||||
|
|
|
@ -105,6 +105,7 @@ class CommandViewSet(JMSBulkModelViewSet):
|
||||||
command_store = get_command_storage()
|
command_store = get_command_storage()
|
||||||
serializer_class = SessionCommandSerializer
|
serializer_class = SessionCommandSerializer
|
||||||
filterset_class = CommandFilter
|
filterset_class = CommandFilter
|
||||||
|
search_fields = ('input',)
|
||||||
model = Command
|
model = Command
|
||||||
ordering_fields = ('timestamp', )
|
ordering_fields = ('timestamp', )
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,9 @@ class CommandAlertMessage(CommandAlertMixin, SystemMessage):
|
||||||
'api-terminal:session-detail', kwargs={'pk': command['session']},
|
'api-terminal:session-detail', kwargs={'pk': command['session']},
|
||||||
external=True, api_to_ui=True
|
external=True, api_to_ui=True
|
||||||
) + '?oid={}'.format(self.command['org_id'])
|
) + '?oid={}'.format(self.command['org_id'])
|
||||||
|
session_detail_url = session_detail_url.replace(
|
||||||
|
'/terminal/sessions/', '/audit/sessions/sessions/'
|
||||||
|
)
|
||||||
level = Command.get_risk_level_str(command['risk_level'])
|
level = Command.get_risk_level_str(command['risk_level'])
|
||||||
items = {
|
items = {
|
||||||
_("Asset"): command['asset'],
|
_("Asset"): command['asset'],
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from django.db.models import TextChoices, IntegerChoices
|
from django.db.models import TextChoices, IntegerChoices
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
TICKET_DETAIL_URL = '/ui/#/tickets/tickets/{id}'
|
TICKET_DETAIL_URL = '/ui/#/tickets/tickets/{id}?type={type}'
|
||||||
|
|
||||||
|
|
||||||
class TicketType(TextChoices):
|
class TicketType(TextChoices):
|
||||||
|
|
|
@ -20,7 +20,13 @@ class BaseTicketMessage(UserMessage):
|
||||||
@property
|
@property
|
||||||
def ticket_detail_url(self):
|
def ticket_detail_url(self):
|
||||||
tp = self.ticket.type
|
tp = self.ticket.type
|
||||||
return urljoin(settings.SITE_URL, const.TICKET_DETAIL_URL.format(id=str(self.ticket.id)))
|
return urljoin(
|
||||||
|
settings.SITE_URL,
|
||||||
|
const.TICKET_DETAIL_URL.format(
|
||||||
|
id=str(self.ticket.id),
|
||||||
|
type=tp
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def content_title(self):
|
def content_title(self):
|
||||||
|
|
|
@ -10,7 +10,7 @@ from rest_framework_bulk import BulkModelViewSet
|
||||||
from common.mixins import CommonApiMixin
|
from common.mixins import CommonApiMixin
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
from common.mixins.api import SuggestionMixin
|
from common.mixins.api import SuggestionMixin
|
||||||
from orgs.utils import current_org
|
from orgs.utils import current_org, tmp_to_root_org
|
||||||
from rbac.models import Role, RoleBinding
|
from rbac.models import Role, RoleBinding
|
||||||
from users.utils import LoginBlockUtil, MFABlockUtils
|
from users.utils import LoginBlockUtil, MFABlockUtils
|
||||||
from .mixins import UserQuerysetMixin
|
from .mixins import UserQuerysetMixin
|
||||||
|
@ -61,6 +61,11 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, SuggestionMixin, BulkModelV
|
||||||
self.set_users_roles_for_cache(queryset)
|
self.set_users_roles_for_cache(queryset)
|
||||||
return page
|
return page
|
||||||
|
|
||||||
|
@action(methods=['get'], detail=False, url_path='suggestions')
|
||||||
|
def match(self, request, *args, **kwargs):
|
||||||
|
with tmp_to_root_org():
|
||||||
|
return super().match(request, *args, **kwargs)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def set_users_roles_for_cache(queryset):
|
def set_users_roles_for_cache(queryset):
|
||||||
# Todo: 未来有机会用 SQL 实现
|
# Todo: 未来有机会用 SQL 实现
|
||||||
|
|
|
@ -279,10 +279,15 @@ class RoleMixin:
|
||||||
cache.set(key, perms, 3600)
|
cache.set(key, perms, 3600)
|
||||||
return perms
|
return perms
|
||||||
|
|
||||||
def expire_perms_cache(self):
|
def expire_rbac_perms_cache(self):
|
||||||
key = self.PERM_CACHE_KEY.format(self.id, '*')
|
key = self.PERM_CACHE_KEY.format(self.id, '*')
|
||||||
cache.delete_pattern(key)
|
cache.delete_pattern(key)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def expire_users_rbac_perms_cache(cls):
|
||||||
|
key = cls.PERM_CACHE_KEY.format('*', '*')
|
||||||
|
cache.delete_pattern(key)
|
||||||
|
|
||||||
@lazyproperty
|
@lazyproperty
|
||||||
def is_superuser(self):
|
def is_superuser(self):
|
||||||
"""
|
"""
|
||||||
|
@ -377,6 +382,11 @@ class RoleMixin:
|
||||||
perms = RoleBinding.get_user_perms(self)
|
perms = RoleBinding.get_user_perms(self)
|
||||||
return perms
|
return perms
|
||||||
|
|
||||||
|
def set_default_system_role(self):
|
||||||
|
from rbac.builtin import BuiltinRole
|
||||||
|
role_user = BuiltinRole.system_user.get_role()
|
||||||
|
self.system_roles.add(role_user)
|
||||||
|
|
||||||
|
|
||||||
class TokenMixin:
|
class TokenMixin:
|
||||||
CACHE_KEY_USER_RESET_PASSWORD_PREFIX = "_KEY_USER_RESET_PASSWORD_{}"
|
CACHE_KEY_USER_RESET_PASSWORD_PREFIX = "_KEY_USER_RESET_PASSWORD_{}"
|
||||||
|
|
|
@ -6,13 +6,11 @@ from rest_framework import serializers
|
||||||
|
|
||||||
from common.mixins import CommonBulkSerializerMixin
|
from common.mixins import CommonBulkSerializerMixin
|
||||||
from common.validators import PhoneValidator
|
from common.validators import PhoneValidator
|
||||||
from rbac.models import Role
|
|
||||||
from rbac.builtin import BuiltinRole
|
from rbac.builtin import BuiltinRole
|
||||||
from rbac.permissions import RBACPermission
|
from rbac.permissions import RBACPermission
|
||||||
from rbac.models import OrgRoleBinding, SystemRoleBinding
|
from rbac.models import OrgRoleBinding, SystemRoleBinding, Role
|
||||||
from ..models import User
|
from ..models import User
|
||||||
from ..const import PasswordStrategy
|
from ..const import PasswordStrategy
|
||||||
from rbac.models import Role
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'UserSerializer', 'MiniUserSerializer',
|
'UserSerializer', 'MiniUserSerializer',
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django_auth_ldap.backend import populate_user
|
from django_auth_ldap.backend import populate_user
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -9,9 +8,9 @@ from django_cas_ng.signals import cas_user_authenticated
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
|
|
||||||
from authentication.backends.oidc.signals import openid_create_or_update_user
|
from authentication.backends.oidc.signals import openid_create_or_update_user
|
||||||
|
|
||||||
from authentication.backends.saml2.signals import saml2_create_or_update_user
|
from authentication.backends.saml2.signals import saml2_create_or_update_user
|
||||||
from common.utils import get_logger
|
from common.utils import get_logger
|
||||||
|
from common.decorator import on_transaction_commit
|
||||||
from .signals import post_user_create
|
from .signals import post_user_create
|
||||||
from .models import User, UserPasswordHistory
|
from .models import User, UserPasswordHistory
|
||||||
|
|
||||||
|
@ -26,7 +25,8 @@ def user_authenticated_handle(user, created, source, attrs=None, **kwargs):
|
||||||
if created:
|
if created:
|
||||||
user.source = source
|
user.source = source
|
||||||
user.save()
|
user.save()
|
||||||
elif not created and settings.AUTH_SAML2_ALWAYS_UPDATE_USER:
|
|
||||||
|
if not created and settings.AUTH_SAML2_ALWAYS_UPDATE_USER:
|
||||||
attr_whitelist = ('user', 'username', 'email', 'phone', 'comment')
|
attr_whitelist = ('user', 'username', 'email', 'phone', 'comment')
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Receive saml2 user updated signal: {}, "
|
"Receive saml2 user updated signal: {}, "
|
||||||
|
@ -34,16 +34,18 @@ def user_authenticated_handle(user, created, source, attrs=None, **kwargs):
|
||||||
"(Update only properties in the whitelist. [{}])"
|
"(Update only properties in the whitelist. [{}])"
|
||||||
"".format(user, str(attrs), ','.join(attr_whitelist))
|
"".format(user, str(attrs), ','.join(attr_whitelist))
|
||||||
)
|
)
|
||||||
if attrs is not None:
|
if not attrs:
|
||||||
for key, value in attrs.items():
|
return
|
||||||
if key in attr_whitelist and value:
|
for key, value in attrs.items():
|
||||||
setattr(user, key, value)
|
if key in attr_whitelist and value:
|
||||||
user.save()
|
setattr(user, key, value)
|
||||||
|
user.save()
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=User)
|
@receiver(post_save, sender=User)
|
||||||
def save_passwd_change(sender, instance: User, **kwargs):
|
def save_passwd_change(sender, instance: User, **kwargs):
|
||||||
passwords = UserPasswordHistory.objects.filter(user=instance) \
|
passwords = UserPasswordHistory.objects\
|
||||||
|
.filter(user=instance) \
|
||||||
.order_by('-date_created')\
|
.order_by('-date_created')\
|
||||||
.values_list('password', flat=True)
|
.values_list('password', flat=True)
|
||||||
passwords = passwords[:int(settings.OLD_PASSWORD_HISTORY_LIMIT_COUNT)]
|
passwords = passwords[:int(settings.OLD_PASSWORD_HISTORY_LIMIT_COUNT)]
|
||||||
|
@ -58,6 +60,17 @@ def save_passwd_change(sender, instance: User, **kwargs):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(post_save, sender=User)
|
||||||
|
@on_transaction_commit
|
||||||
|
def on_user_create_set_default_system_role(sender, instance, created, **kwargs):
|
||||||
|
if not created:
|
||||||
|
return
|
||||||
|
has_system_role = instance.system_roles.all().exists()
|
||||||
|
if not has_system_role:
|
||||||
|
logger.debug("Receive user create signal, set default role")
|
||||||
|
instance.set_default_system_role()
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_user_create)
|
@receiver(post_user_create)
|
||||||
def on_user_create(sender, user=None, **kwargs):
|
def on_user_create(sender, user=None, **kwargs):
|
||||||
logger.debug("Receive user `{}` create signal".format(user.name))
|
logger.debug("Receive user `{}` create signal".format(user.name))
|
||||||
|
|
|
@ -55,6 +55,9 @@ def clean_db_content_types():
|
||||||
('perms', 'permedkubernetesapp', 'view_mykubernetesapp'),
|
('perms', 'permedkubernetesapp', 'view_mykubernetesapp'),
|
||||||
('perms', 'permedremoteapp', 'connect_myremoteapp'),
|
('perms', 'permedremoteapp', 'connect_myremoteapp'),
|
||||||
('perms', 'permedremoteapp', 'view_myremoteapp'),
|
('perms', 'permedremoteapp', 'view_myremoteapp'),
|
||||||
|
('perms', 'applicationpermission', 'view_permuserapplication'),
|
||||||
|
('perms', 'assetpermission', 'view_permuserasset'),
|
||||||
|
('perms', 'assetpermission', 'view_permusergroupasset'),
|
||||||
|
|
||||||
('applications', 'databaseapp', 'add_databaseapp'),
|
('applications', 'databaseapp', 'add_databaseapp'),
|
||||||
('applications', 'databaseapp', 'change_databaseapp'),
|
('applications', 'databaseapp', 'change_databaseapp'),
|
||||||
|
@ -79,6 +82,9 @@ def clean_db_content_types():
|
||||||
('rbac', 'menupermission', 'view_userview'),
|
('rbac', 'menupermission', 'view_userview'),
|
||||||
('rbac', 'menupermission', 'view_adminview'),
|
('rbac', 'menupermission', 'view_adminview'),
|
||||||
('rbac', 'menupermission', 'view_auditview'),
|
('rbac', 'menupermission', 'view_auditview'),
|
||||||
|
('assets', 'systemuser', 'view_systemuserasset'),
|
||||||
|
('assets', 'systemuser', 'add_systemuserasset'),
|
||||||
|
('assets', 'systemuser', 'remove_systemuserasset'),
|
||||||
]
|
]
|
||||||
for app, model, codename in permissions_delete_required:
|
for app, model, codename in permissions_delete_required:
|
||||||
print('delete {}.{} ({})'.format(app, codename, model))
|
print('delete {}.{} ({})'.format(app, codename, model))
|
||||||
|
|
Loading…
Reference in New Issue