perf: 优化一些 rbac 权限位,着重 connection token 的

pull/10985/head
ibuler 2023-07-13 16:00:24 +08:00 committed by Bryan
parent bedc83bd3a
commit a1ded0c737
12 changed files with 209 additions and 159 deletions

View File

@ -8,7 +8,7 @@ from django.http import HttpResponse
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from rest_framework import status from rest_framework import status, serializers
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied, ValidationError from rest_framework.exceptions import PermissionDenied, ValidationError
from rest_framework.request import Request from rest_framework.request import Request
@ -28,7 +28,7 @@ from ..models import ConnectionToken, date_expired_default
from ..serializers import ( from ..serializers import (
ConnectionTokenSerializer, ConnectionTokenSecretSerializer, ConnectionTokenSerializer, ConnectionTokenSecretSerializer,
SuperConnectionTokenSerializer, ConnectTokenAppletOptionSerializer, SuperConnectionTokenSerializer, ConnectTokenAppletOptionSerializer,
ConnectionTokenUpdateSerializer ConnectionTokenReusableSerializer,
) )
__all__ = ['ConnectionTokenViewSet', 'SuperConnectionTokenViewSet'] __all__ = ['ConnectionTokenViewSet', 'SuperConnectionTokenViewSet']
@ -212,6 +212,17 @@ class ExtraActionApiMixin(RDPFileClientProtocolURLMixin):
instance.expire() instance.expire()
return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_204_NO_CONTENT)
@action(methods=['PATCH'], detail=True, url_path='reuse')
def reuse(self, request, *args, **kwargs):
instance = self.get_object()
if not settings.CONNECTION_TOKEN_REUSABLE:
raise serializers.ValidationError(_('Reusable connection token is not allowed, global setting not enabled'))
serializer = self.get_serializer(instance, data=request.data, partial=True)
serializer.is_valid(raise_exception=True)
is_reusable = serializer.validated_data.get('is_reusable', False)
instance.set_reusable(is_reusable)
return Response(data=serializer.data)
@action(methods=['POST'], detail=False) @action(methods=['POST'], detail=False)
def exchange(self, request, *args, **kwargs): def exchange(self, request, *args, **kwargs):
pk = request.data.get('id', None) or request.data.get('pk', None) pk = request.data.get('id', None) or request.data.get('pk', None)
@ -232,17 +243,16 @@ class ConnectionTokenViewSet(ExtraActionApiMixin, RootOrgViewMixin, JMSModelView
search_fields = filterset_fields search_fields = filterset_fields
serializer_classes = { serializer_classes = {
'default': ConnectionTokenSerializer, 'default': ConnectionTokenSerializer,
'update': ConnectionTokenUpdateSerializer, 'reuse': ConnectionTokenReusableSerializer,
'partial_update': ConnectionTokenUpdateSerializer,
} }
http_method_names = ['get', 'post', 'patch', 'head', 'options', 'trace'] http_method_names = ['get', 'post', 'patch', 'head', 'options', 'trace']
rbac_perms = { rbac_perms = {
'list': 'authentication.view_connectiontoken', 'list': 'authentication.view_connectiontoken',
'retrieve': 'authentication.view_connectiontoken', 'retrieve': 'authentication.view_connectiontoken',
'update': 'authentication.change_connectiontoken',
'create': 'authentication.add_connectiontoken', 'create': 'authentication.add_connectiontoken',
'exchange': 'authentication.add_connectiontoken', 'exchange': 'authentication.add_connectiontoken',
'expire': 'authentication.change_connectiontoken', 'reuse': 'authentication.reuse_connectiontoken',
'expire': 'authentication.expire_connectiontoken',
'get_rdp_file': 'authentication.add_connectiontoken', 'get_rdp_file': 'authentication.add_connectiontoken',
'get_client_protocol_url': 'authentication.add_connectiontoken', 'get_client_protocol_url': 'authentication.add_connectiontoken',
} }
@ -346,7 +356,7 @@ class SuperConnectionTokenViewSet(ConnectionTokenViewSet):
rbac_perms = { rbac_perms = {
'create': 'authentication.add_superconnectiontoken', 'create': 'authentication.add_superconnectiontoken',
'renewal': 'authentication.add_superconnectiontoken', 'renewal': 'authentication.add_superconnectiontoken',
'get_secret_detail': 'authentication.view_connectiontokensecret', 'get_secret_detail': 'authentication.view_superconnectiontokensecret',
'get_applet_info': 'authentication.view_superconnectiontoken', 'get_applet_info': 'authentication.view_superconnectiontoken',
'release_applet_account': 'authentication.view_superconnectiontoken', 'release_applet_account': 'authentication.view_superconnectiontoken',
} }
@ -376,7 +386,7 @@ class SuperConnectionTokenViewSet(ConnectionTokenViewSet):
@action(methods=['POST'], detail=False, url_path='secret') @action(methods=['POST'], detail=False, url_path='secret')
def get_secret_detail(self, request, *args, **kwargs): def get_secret_detail(self, request, *args, **kwargs):
""" 非常重要的 api, 在逻辑层再判断一下 rbac 权限, 双重保险 """ """ 非常重要的 api, 在逻辑层再判断一下 rbac 权限, 双重保险 """
rbac_perm = 'authentication.view_connectiontokensecret' rbac_perm = 'authentication.view_superconnectiontokensecret'
if not request.user.has_perm(rbac_perm): if not request.user.has_perm(rbac_perm):
raise PermissionDenied('Not allow to view secret') raise PermissionDenied('Not allow to view secret')

View File

@ -0,0 +1,24 @@
# Generated by Django 3.2.19 on 2023-07-13 06:59
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('authentication', '0020_connectiontoken_connect_options'),
]
operations = [
migrations.AlterModelOptions(
name='connectiontoken',
options={'ordering': ('-date_expired',),
'permissions': [('expire_connectiontoken', 'Can expire connection token'),
('reuse_connectiontoken', 'Can reuse connection token')],
'verbose_name': 'Connection token'},
),
migrations.AlterModelOptions(
name='superconnectiontoken',
options={'permissions': [('view_superconnectiontokensecret', 'Can view super connection token secret')],
'verbose_name': 'Super connection token'},
),
]

View File

@ -54,10 +54,11 @@ class ConnectionToken(JMSOrgBaseModel):
class Meta: class Meta:
ordering = ('-date_expired',) ordering = ('-date_expired',)
verbose_name = _('Connection token')
permissions = [ permissions = [
('view_connectiontokensecret', _('Can view connection token secret')) ('expire_connectiontoken', _('Can expire connection token')),
('reuse_connectiontoken', _('Can reuse connection token')),
] ]
verbose_name = _('Connection token')
@property @property
def is_expired(self): def is_expired(self):
@ -80,6 +81,15 @@ class ConnectionToken(JMSOrgBaseModel):
self.date_expired = timezone.now() self.date_expired = timezone.now()
self.save(update_fields=['date_expired']) self.save(update_fields=['date_expired'])
def set_reusable(self, is_reusable):
self.is_reusable = is_reusable
if self.is_reusable:
seconds = settings.CONNECTION_TOKEN_REUSABLE_EXPIRATION
else:
seconds = settings.CONNECTION_TOKEN_ONETIME_EXPIRATION
self.date_expired = timezone.now() + timedelta(seconds=seconds)
self.save(update_fields=['is_reusable', 'date_expired'])
def renewal(self): def renewal(self):
""" 续期 Token将来支持用户自定义创建 token 后,续期策略要修改 """ """ 续期 Token将来支持用户自定义创建 token 后,续期策略要修改 """
self.date_expired = date_expired_default() self.date_expired = date_expired_default()
@ -255,4 +265,7 @@ class ConnectionToken(JMSOrgBaseModel):
class SuperConnectionToken(ConnectionToken): class SuperConnectionToken(ConnectionToken):
class Meta: class Meta:
proxy = True proxy = True
permissions = [
('view_superconnectiontokensecret', _('Can view super connection token secret'))
]
verbose_name = _("Super connection token") verbose_name = _("Super connection token")

View File

@ -1,20 +1,18 @@
from django.conf import settings
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers from rest_framework import serializers
from common.serializers import CommonModelSerializer
from common.serializers.fields import EncryptedField from common.serializers.fields import EncryptedField
from orgs.mixins.serializers import OrgResourceModelSerializerMixin
from perms.serializers.permission import ActionChoicesField from perms.serializers.permission import ActionChoicesField
from ..models import ConnectionToken from ..models import ConnectionToken
__all__ = [ __all__ = [
'ConnectionTokenSerializer', 'SuperConnectionTokenSerializer', 'ConnectionTokenSerializer', 'SuperConnectionTokenSerializer',
'ConnectionTokenUpdateSerializer', 'ConnectionTokenReusableSerializer',
] ]
class ConnectionTokenSerializer(OrgResourceModelSerializerMixin): class ConnectionTokenSerializer(CommonModelSerializer):
expire_time = serializers.IntegerField(read_only=True, label=_('Expired time')) expire_time = serializers.IntegerField(read_only=True, label=_('Expired time'))
input_secret = EncryptedField( input_secret = EncryptedField(
label=_("Input secret"), max_length=40960, required=False, allow_blank=True label=_("Input secret"), max_length=40960, required=False, allow_blank=True
@ -60,30 +58,12 @@ class ConnectionTokenSerializer(OrgResourceModelSerializerMixin):
return info return info
class ConnectionTokenUpdateSerializer(ConnectionTokenSerializer): class ConnectionTokenReusableSerializer(CommonModelSerializer):
class Meta(ConnectionTokenSerializer.Meta): class Meta:
model = ConnectionToken
fields = ['id', 'date_expired', 'is_reusable']
can_update_fields = ['is_reusable'] can_update_fields = ['is_reusable']
read_only_fields = list(set(ConnectionTokenSerializer.Meta.fields) - set(can_update_fields)) read_only_fields = list(set(fields) - set(can_update_fields))
def _get_date_expired(self):
delta = self.instance.date_expired - self.instance.date_created
if delta.total_seconds() > 3600 * 24:
return self.instance.date_expired
seconds = settings.CONNECTION_TOKEN_REUSABLE_EXPIRATION
return timezone.now() + timezone.timedelta(seconds=seconds)
@staticmethod
def validate_is_reusable(value):
if value and not settings.CONNECTION_TOKEN_REUSABLE:
raise serializers.ValidationError(_('Reusable connection token is not allowed, global setting not enabled'))
return value
def validate(self, attrs):
reusable = attrs.get('is_reusable', False)
if reusable:
attrs['date_expired'] = self._get_date_expired()
return attrs
class SuperConnectionTokenSerializer(ConnectionTokenSerializer): class SuperConnectionTokenSerializer(ConnectionTokenSerializer):

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:3c01e373aea806f104ae77bb4dfbeab1a9c5d4af9ca5c421f62b40f00bbf4b33 oid sha256:a4463d66ad3eac6127e435d60759e1a6584f93842d959e6129c9b92d1a68de32
size 147721 size 148522

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-11 12:03+0800\n" "POT-Creation-Date: 2023-07-13 15:56+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -87,7 +87,7 @@ msgstr "テンプレート"
msgid "Skip" msgid "Skip"
msgstr "スキップ" msgstr "スキップ"
#: accounts/const/account.py:28 audits/const.py:24 rbac/tree.py:229 #: accounts/const/account.py:28 audits/const.py:24 rbac/tree.py:230
#: templates/_csv_import_export.html:18 templates/_csv_update_modal.html:6 #: templates/_csv_import_export.html:18 templates/_csv_update_modal.html:6
msgid "Update" msgid "Update"
msgstr "更新" msgstr "更新"
@ -652,7 +652,7 @@ msgstr "ID"
#: authentication/models/sso_token.py:16 #: authentication/models/sso_token.py:16
#: notifications/models/notification.py:12 #: notifications/models/notification.py:12
#: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58 #: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58
#: perms/serializers/permission.py:30 rbac/builtin.py:122 #: perms/serializers/permission.py:30 rbac/builtin.py:123
#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17 #: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17
#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32 #: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
#: terminal/notifications.py:135 terminal/notifications.py:183 #: terminal/notifications.py:135 terminal/notifications.py:183
@ -1023,7 +1023,7 @@ msgid "{} disabled"
msgstr "{} 無効" msgstr "{} 無効"
#: assets/automations/ping_gateway/manager.py:33 #: assets/automations/ping_gateway/manager.py:33
#: authentication/models/connection_token.py:118 #: authentication/models/connection_token.py:128
msgid "No account" msgid "No account"
msgstr "アカウントなし" msgstr "アカウントなし"
@ -1077,7 +1077,8 @@ msgstr "無効"
msgid "Basic" msgid "Basic"
msgstr "基本" msgstr "基本"
#: assets/const/base.py:35 assets/models/asset/web.py:13 #: assets/const/base.py:35 assets/const/protocol.py:193
#: assets/models/asset/web.py:13
msgid "Script" msgid "Script"
msgstr "脚本" msgstr "脚本"
@ -1185,23 +1186,28 @@ msgstr "AD ドメイン"
msgid "Use SSL" msgid "Use SSL"
msgstr "SSLの使用" msgstr "SSLの使用"
#: assets/const/protocol.py:145 #: assets/const/protocol.py:149
msgid "Auth username" msgid "Auth username"
msgstr "ユーザー名で認証する" msgstr "ユーザー名で認証する"
#: assets/const/protocol.py:173 assets/models/asset/web.py:10 #: assets/const/protocol.py:170 assets/models/asset/web.py:9
#: assets/serializers/asset/info/spec.py:16
msgid "Autofill"
msgstr "自動充填"
#: assets/const/protocol.py:178 assets/models/asset/web.py:10
msgid "Username selector" msgid "Username selector"
msgstr "ユーザー名ピッカー" msgstr "ユーザー名ピッカー"
#: assets/const/protocol.py:178 assets/models/asset/web.py:11 #: assets/const/protocol.py:183 assets/models/asset/web.py:11
msgid "Password selector" msgid "Password selector"
msgstr "パスワードセレクター" msgstr "パスワードセレクター"
#: assets/const/protocol.py:183 assets/models/asset/web.py:12 #: assets/const/protocol.py:188 assets/models/asset/web.py:12
msgid "Submit selector" msgid "Submit selector"
msgstr "ボタンセレクターを確認する" msgstr "ボタンセレクターを確認する"
#: assets/const/protocol.py:201 #: assets/const/protocol.py:211
msgid "API mode" msgid "API mode"
msgstr "APIモード" msgstr "APIモード"
@ -1408,10 +1414,6 @@ msgstr "証明書チェックを無視"
msgid "Proxy" msgid "Proxy"
msgstr "" msgstr ""
#: assets/models/asset/web.py:9 assets/serializers/asset/info/spec.py:16
msgid "Autofill"
msgstr "自動充填"
#: assets/models/automations/base.py:22 ops/models/job.py:187 #: assets/models/automations/base.py:22 ops/models/job.py:187
#: settings/serializers/auth/sms.py:99 #: settings/serializers/auth/sms.py:99
msgid "Parameters" msgid "Parameters"
@ -1963,7 +1965,7 @@ msgstr "Rmdir"
#: audits/const.py:14 audits/const.py:25 #: audits/const.py:14 audits/const.py:25
#: authentication/templates/authentication/_access_key_modal.html:65 #: authentication/templates/authentication/_access_key_modal.html:65
#: perms/const.py:17 rbac/tree.py:230 #: perms/const.py:17 rbac/tree.py:231
msgid "Delete" msgid "Delete"
msgstr "削除" msgstr "削除"
@ -1987,13 +1989,13 @@ msgstr "ダウンロード"
msgid "Rename dir" msgid "Rename dir"
msgstr "マップディレクトリ" msgstr "マップディレクトリ"
#: audits/const.py:23 rbac/tree.py:228 #: audits/const.py:23 rbac/tree.py:229
msgid "View" msgid "View"
msgstr "表示" msgstr "表示"
#: audits/const.py:26 #: audits/const.py:26
#: authentication/templates/authentication/_access_key_modal.html:22 #: authentication/templates/authentication/_access_key_modal.html:22
#: rbac/tree.py:227 #: rbac/tree.py:228
msgid "Create" msgid "Create"
msgstr "作成" msgstr "作成"
@ -2230,23 +2232,29 @@ msgstr "外部ストレージへのFTPファイルのアップロード"
msgid "This action require verify your MFA" msgid "This action require verify your MFA"
msgstr "この操作には、MFAを検証する必要があります" msgstr "この操作には、MFAを検証する必要があります"
#: authentication/api/connection_token.py:288 #: authentication/api/connection_token.py:219
msgid "Reusable connection token is not allowed, global setting not enabled"
msgstr ""
"再使用可能な接続トークンの使用は許可されていません。グローバル設定は有効に"
"なっていません"
#: authentication/api/connection_token.py:298
msgid "Anonymous account is not supported for this asset" msgid "Anonymous account is not supported for this asset"
msgstr "匿名アカウントはこのプロパティではサポートされていません" msgstr "匿名アカウントはこのプロパティではサポートされていません"
#: authentication/api/connection_token.py:310 #: authentication/api/connection_token.py:320
msgid "Account not found" msgid "Account not found"
msgstr "アカウントが見つかりません" msgstr "アカウントが見つかりません"
#: authentication/api/connection_token.py:313 #: authentication/api/connection_token.py:323
msgid "Permission expired" msgid "Permission expired"
msgstr "承認の有効期限が切れています" msgstr "承認の有効期限が切れています"
#: authentication/api/connection_token.py:327 #: authentication/api/connection_token.py:337
msgid "ACL action is reject: {}({})" msgid "ACL action is reject: {}({})"
msgstr "ACL アクションは拒否です: {}({})" msgstr "ACL アクションは拒否です: {}({})"
#: authentication/api/connection_token.py:331 #: authentication/api/connection_token.py:341
msgid "ACL action is review" msgid "ACL action is review"
msgstr "ACL アクションはレビューです" msgstr "ACL アクションはレビューです"
@ -2637,7 +2645,7 @@ msgid "Input username"
msgstr "カスタム ユーザー名" msgstr "カスタム ユーザー名"
#: authentication/models/connection_token.py:40 #: authentication/models/connection_token.py:40
#: authentication/serializers/connection_token.py:20 #: authentication/serializers/connection_token.py:18
msgid "Input secret" msgid "Input secret"
msgstr "カスタムパスワード" msgstr "カスタムパスワード"
@ -2674,31 +2682,39 @@ msgstr "期限切れの日付"
msgid "From ticket" msgid "From ticket"
msgstr "チケットから" msgstr "チケットから"
#: authentication/models/connection_token.py:57 #: authentication/models/connection_token.py:58
msgid "Can expire connection token"
msgstr "接続トークンの有効期限を設定できます"
#: authentication/models/connection_token.py:59
msgid "Can reuse connection token"
msgstr "接続トークンを再利用できます"
#: authentication/models/connection_token.py:61
msgid "Connection token" msgid "Connection token"
msgstr "接続トークン" msgstr "接続トークン"
#: authentication/models/connection_token.py:59 #: authentication/models/connection_token.py:116
msgid "Can view connection token secret"
msgstr "接続トークンの秘密を表示できます"
#: authentication/models/connection_token.py:106
msgid "Connection token inactive" msgid "Connection token inactive"
msgstr "接続トークンがアクティブ化されていません" msgstr "接続トークンがアクティブ化されていません"
#: authentication/models/connection_token.py:109 #: authentication/models/connection_token.py:119
msgid "Connection token expired at: {}" msgid "Connection token expired at: {}"
msgstr "接続トークンの有効期限: {}" msgstr "接続トークンの有効期限: {}"
#: authentication/models/connection_token.py:112 #: authentication/models/connection_token.py:122
msgid "No user or invalid user" msgid "No user or invalid user"
msgstr "ユーザーなしまたは期限切れのユーザー" msgstr "ユーザーなしまたは期限切れのユーザー"
#: authentication/models/connection_token.py:115 #: authentication/models/connection_token.py:125
msgid "No asset or inactive asset" msgid "No asset or inactive asset"
msgstr "アセットがないか、有効化されていないアセット" msgstr "アセットがないか、有効化されていないアセット"
#: authentication/models/connection_token.py:258 #: authentication/models/connection_token.py:269
msgid "Can view super connection token secret"
msgstr "スーパー接続トークンのシークレットを表示できます"
#: authentication/models/connection_token.py:271
msgid "Super connection token" msgid "Super connection token"
msgstr "スーパー接続トークン" msgstr "スーパー接続トークン"
@ -2742,15 +2758,15 @@ msgstr "コンポーネント"
msgid "Expired now" msgid "Expired now"
msgstr "すぐに期限切れ" msgstr "すぐに期限切れ"
#: authentication/serializers/connection_token.py:18 #: authentication/serializers/connection_token.py:16
msgid "Expired time" msgid "Expired time"
msgstr "期限切れ時間" msgstr "期限切れ時間"
#: authentication/serializers/connection_token.py:22 #: authentication/serializers/connection_token.py:20
msgid "Ticket info" msgid "Ticket info"
msgstr "作業指示情報" msgstr "作業指示情報"
#: authentication/serializers/connection_token.py:23 #: authentication/serializers/connection_token.py:21
#: perms/models/asset_permission.py:71 perms/serializers/permission.py:36 #: perms/models/asset_permission.py:71 perms/serializers/permission.py:36
#: perms/serializers/permission.py:56 #: perms/serializers/permission.py:56
#: tickets/models/ticket/apply_application.py:28 #: tickets/models/ticket/apply_application.py:28
@ -2758,18 +2774,12 @@ msgstr "作業指示情報"
msgid "Actions" msgid "Actions"
msgstr "アクション" msgstr "アクション"
#: authentication/serializers/connection_token.py:44 #: authentication/serializers/connection_token.py:42
#: perms/serializers/permission.py:38 perms/serializers/permission.py:57 #: perms/serializers/permission.py:38 perms/serializers/permission.py:57
#: users/serializers/user.py:96 users/serializers/user.py:172 #: users/serializers/user.py:96 users/serializers/user.py:172
msgid "Is expired" msgid "Is expired"
msgstr "期限切れです" msgstr "期限切れです"
#: authentication/serializers/connection_token.py:79
msgid "Reusable connection token is not allowed, global setting not enabled"
msgstr ""
"再使用可能な接続トークンの使用は許可されていません。グローバル設定は有効に"
"なっていません"
#: authentication/serializers/password_mfa.py:16 #: authentication/serializers/password_mfa.py:16
#: authentication/serializers/password_mfa.py:24 #: authentication/serializers/password_mfa.py:24
#: notifications/backends/__init__.py:10 settings/serializers/email.py:19 #: notifications/backends/__init__.py:10 settings/serializers/email.py:19
@ -3899,7 +3909,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:118 #: orgs/apps.py:7 rbac/tree.py:119
msgid "App organizations" msgid "App organizations"
msgstr "アプリ組織" msgstr "アプリ組織"
@ -4058,27 +4068,27 @@ msgstr "{} 少なくとも1つのシステムロール"
msgid "RBAC" msgid "RBAC"
msgstr "RBAC" msgstr "RBAC"
#: rbac/builtin.py:113 #: rbac/builtin.py:114
msgid "SystemAdmin" msgid "SystemAdmin"
msgstr "システム管理者" msgstr "システム管理者"
#: rbac/builtin.py:116 #: rbac/builtin.py:117
msgid "SystemAuditor" msgid "SystemAuditor"
msgstr "システム監査人" msgstr "システム監査人"
#: rbac/builtin.py:119 #: rbac/builtin.py:120
msgid "SystemComponent" msgid "SystemComponent"
msgstr "システムコンポーネント" msgstr "システムコンポーネント"
#: rbac/builtin.py:125 #: rbac/builtin.py:126
msgid "OrgAdmin" msgid "OrgAdmin"
msgstr "組織管理者" msgstr "組織管理者"
#: rbac/builtin.py:128 #: rbac/builtin.py:129
msgid "OrgAuditor" msgid "OrgAuditor"
msgstr "監査員を組織する" msgstr "監査員を組織する"
#: rbac/builtin.py:131 #: rbac/builtin.py:132
msgid "OrgUser" msgid "OrgUser"
msgstr "組織ユーザー" msgstr "組織ユーザー"
@ -4229,19 +4239,19 @@ msgstr "私の資産"
msgid "Applet" msgid "Applet"
msgstr "リモートアプリケーション" msgstr "リモートアプリケーション"
#: rbac/tree.py:119 #: rbac/tree.py:120
msgid "Ticket comment" msgid "Ticket comment"
msgstr "チケットコメント" msgstr "チケットコメント"
#: rbac/tree.py:120 tickets/models/ticket/general.py:307 #: rbac/tree.py:121 tickets/models/ticket/general.py:307
msgid "Ticket" msgid "Ticket"
msgstr "チケット" msgstr "チケット"
#: rbac/tree.py:121 #: rbac/tree.py:122
msgid "Common setting" msgid "Common setting"
msgstr "共通設定" msgstr "共通設定"
#: rbac/tree.py:122 #: rbac/tree.py:123
msgid "View permission tree" msgid "View permission tree"
msgstr "権限ツリーの表示" msgstr "権限ツリーの表示"
@ -5722,7 +5732,7 @@ msgstr "出力"
msgid "Risk level" msgid "Risk level"
msgstr "リスクレベル" msgstr "リスクレベル"
#: terminal/connect_methods.py:55 #: terminal/connect_methods.py:34
msgid "DB Client" msgid "DB Client"
msgstr "データベース クライアント" msgstr "データベース クライアント"

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:3d81d525d06bd1446780753e7627adbcc344144a3c0ed856d7953b9758913028 oid sha256:f5261baf86de7c7c1374041d450b51ead282b6f546738c4caffd6b4d4ea22a00
size 120819 size 121562

View File

@ -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: 2023-07-11 12:03+0800\n" "POT-Creation-Date: 2023-07-13 15:56+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"
@ -86,7 +86,7 @@ msgstr "模板"
msgid "Skip" msgid "Skip"
msgstr "跳过" msgstr "跳过"
#: accounts/const/account.py:28 audits/const.py:24 rbac/tree.py:229 #: accounts/const/account.py:28 audits/const.py:24 rbac/tree.py:230
#: templates/_csv_import_export.html:18 templates/_csv_update_modal.html:6 #: templates/_csv_import_export.html:18 templates/_csv_update_modal.html:6
msgid "Update" msgid "Update"
msgstr "更新" msgstr "更新"
@ -648,7 +648,7 @@ msgstr "ID"
#: authentication/models/sso_token.py:16 #: authentication/models/sso_token.py:16
#: notifications/models/notification.py:12 #: notifications/models/notification.py:12
#: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58 #: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:58
#: perms/serializers/permission.py:30 rbac/builtin.py:122 #: perms/serializers/permission.py:30 rbac/builtin.py:123
#: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17 #: rbac/models/rolebinding.py:49 terminal/backends/command/models.py:17
#: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32 #: terminal/models/session/session.py:29 terminal/models/session/sharing.py:32
#: terminal/notifications.py:135 terminal/notifications.py:183 #: terminal/notifications.py:135 terminal/notifications.py:183
@ -1016,7 +1016,7 @@ msgid "{} disabled"
msgstr "{} 已禁用" msgstr "{} 已禁用"
#: assets/automations/ping_gateway/manager.py:33 #: assets/automations/ping_gateway/manager.py:33
#: authentication/models/connection_token.py:118 #: authentication/models/connection_token.py:128
msgid "No account" msgid "No account"
msgstr "没有账号" msgstr "没有账号"
@ -1070,7 +1070,8 @@ msgstr "禁用"
msgid "Basic" msgid "Basic"
msgstr "基本" msgstr "基本"
#: assets/const/base.py:35 assets/models/asset/web.py:13 #: assets/const/base.py:35 assets/const/protocol.py:193
#: assets/models/asset/web.py:13
msgid "Script" msgid "Script"
msgstr "脚本" msgstr "脚本"
@ -1178,23 +1179,28 @@ msgstr "AD 网域"
msgid "Use SSL" msgid "Use SSL"
msgstr "使用 SSL" msgstr "使用 SSL"
#: assets/const/protocol.py:145 #: assets/const/protocol.py:149
msgid "Auth username" msgid "Auth username"
msgstr "使用用户名认证" msgstr "使用用户名认证"
#: assets/const/protocol.py:173 assets/models/asset/web.py:10 #: assets/const/protocol.py:170 assets/models/asset/web.py:9
#: assets/serializers/asset/info/spec.py:16
msgid "Autofill"
msgstr "自动代填"
#: assets/const/protocol.py:178 assets/models/asset/web.py:10
msgid "Username selector" msgid "Username selector"
msgstr "用户名选择器" msgstr "用户名选择器"
#: assets/const/protocol.py:178 assets/models/asset/web.py:11 #: assets/const/protocol.py:183 assets/models/asset/web.py:11
msgid "Password selector" msgid "Password selector"
msgstr "密码选择器" msgstr "密码选择器"
#: assets/const/protocol.py:183 assets/models/asset/web.py:12 #: assets/const/protocol.py:188 assets/models/asset/web.py:12
msgid "Submit selector" msgid "Submit selector"
msgstr "确认按钮选择器" msgstr "确认按钮选择器"
#: assets/const/protocol.py:201 #: assets/const/protocol.py:211
msgid "API mode" msgid "API mode"
msgstr "API 模式" msgstr "API 模式"
@ -1401,10 +1407,6 @@ msgstr "忽略证书校验"
msgid "Proxy" msgid "Proxy"
msgstr "代理" msgstr "代理"
#: assets/models/asset/web.py:9 assets/serializers/asset/info/spec.py:16
msgid "Autofill"
msgstr "自动代填"
#: assets/models/automations/base.py:22 ops/models/job.py:187 #: assets/models/automations/base.py:22 ops/models/job.py:187
#: settings/serializers/auth/sms.py:99 #: settings/serializers/auth/sms.py:99
msgid "Parameters" msgid "Parameters"
@ -1947,7 +1949,7 @@ msgstr "删除目录"
#: audits/const.py:14 audits/const.py:25 #: audits/const.py:14 audits/const.py:25
#: authentication/templates/authentication/_access_key_modal.html:65 #: authentication/templates/authentication/_access_key_modal.html:65
#: perms/const.py:17 rbac/tree.py:230 #: perms/const.py:17 rbac/tree.py:231
msgid "Delete" msgid "Delete"
msgstr "删除" msgstr "删除"
@ -1971,13 +1973,13 @@ msgstr "下载"
msgid "Rename dir" msgid "Rename dir"
msgstr "映射目录" msgstr "映射目录"
#: audits/const.py:23 rbac/tree.py:228 #: audits/const.py:23 rbac/tree.py:229
msgid "View" msgid "View"
msgstr "查看" msgstr "查看"
#: audits/const.py:26 #: audits/const.py:26
#: authentication/templates/authentication/_access_key_modal.html:22 #: authentication/templates/authentication/_access_key_modal.html:22
#: rbac/tree.py:227 #: rbac/tree.py:228
msgid "Create" msgid "Create"
msgstr "创建" msgstr "创建"
@ -2214,23 +2216,27 @@ msgstr "上传 FTP 文件到外部存储"
msgid "This action require verify your MFA" msgid "This action require verify your MFA"
msgstr "该操作需要验证您的 MFA, 请先开启并配置" msgstr "该操作需要验证您的 MFA, 请先开启并配置"
#: authentication/api/connection_token.py:288 #: authentication/api/connection_token.py:219
msgid "Reusable connection token is not allowed, global setting not enabled"
msgstr "不允许使用可重复使用的连接令牌,未启用全局设置"
#: authentication/api/connection_token.py:298
msgid "Anonymous account is not supported for this asset" msgid "Anonymous account is not supported for this asset"
msgstr "匿名账号不支持当前资产" msgstr "匿名账号不支持当前资产"
#: authentication/api/connection_token.py:310 #: authentication/api/connection_token.py:320
msgid "Account not found" msgid "Account not found"
msgstr "账号未找到" msgstr "账号未找到"
#: authentication/api/connection_token.py:313 #: authentication/api/connection_token.py:323
msgid "Permission expired" msgid "Permission expired"
msgstr "授权已过期" msgstr "授权已过期"
#: authentication/api/connection_token.py:327 #: authentication/api/connection_token.py:337
msgid "ACL action is reject: {}({})" msgid "ACL action is reject: {}({})"
msgstr "ACL 动作是拒绝: {}({})" msgstr "ACL 动作是拒绝: {}({})"
#: authentication/api/connection_token.py:331 #: authentication/api/connection_token.py:341
msgid "ACL action is review" msgid "ACL action is review"
msgstr "ACL 动作是复核" msgstr "ACL 动作是复核"
@ -2607,7 +2613,7 @@ msgid "Input username"
msgstr "自定义用户名" msgstr "自定义用户名"
#: authentication/models/connection_token.py:40 #: authentication/models/connection_token.py:40
#: authentication/serializers/connection_token.py:20 #: authentication/serializers/connection_token.py:18
msgid "Input secret" msgid "Input secret"
msgstr "自定义密码" msgstr "自定义密码"
@ -2644,31 +2650,39 @@ msgstr "失效日期"
msgid "From ticket" msgid "From ticket"
msgstr "来自工单" msgstr "来自工单"
#: authentication/models/connection_token.py:57 #: authentication/models/connection_token.py:58
msgid "Can expire connection token"
msgstr "可以失效连接令牌"
#: authentication/models/connection_token.py:59
msgid "Can reuse connection token"
msgstr "可以复用连接令牌"
#: authentication/models/connection_token.py:61
msgid "Connection token" msgid "Connection token"
msgstr "连接令牌" msgstr "连接令牌"
#: authentication/models/connection_token.py:59 #: authentication/models/connection_token.py:116
msgid "Can view connection token secret"
msgstr "可以查看连接令牌密文"
#: authentication/models/connection_token.py:106
msgid "Connection token inactive" msgid "Connection token inactive"
msgstr "连接令牌未激活" msgstr "连接令牌未激活"
#: authentication/models/connection_token.py:109 #: authentication/models/connection_token.py:119
msgid "Connection token expired at: {}" msgid "Connection token expired at: {}"
msgstr "连接令牌过期: {}" msgstr "连接令牌过期: {}"
#: authentication/models/connection_token.py:112 #: authentication/models/connection_token.py:122
msgid "No user or invalid user" msgid "No user or invalid user"
msgstr "没有用户或用户失效" msgstr "没有用户或用户失效"
#: authentication/models/connection_token.py:115 #: authentication/models/connection_token.py:125
msgid "No asset or inactive asset" msgid "No asset or inactive asset"
msgstr "没有资产或资产未激活" msgstr "没有资产或资产未激活"
#: authentication/models/connection_token.py:258 #: authentication/models/connection_token.py:269
msgid "Can view super connection token secret"
msgstr "可以查看超级连接令牌密文"
#: authentication/models/connection_token.py:271
msgid "Super connection token" msgid "Super connection token"
msgstr "超级连接令牌" msgstr "超级连接令牌"
@ -2712,15 +2726,15 @@ msgstr "组件"
msgid "Expired now" msgid "Expired now"
msgstr "立刻过期" msgstr "立刻过期"
#: authentication/serializers/connection_token.py:18 #: authentication/serializers/connection_token.py:16
msgid "Expired time" msgid "Expired time"
msgstr "过期时间" msgstr "过期时间"
#: authentication/serializers/connection_token.py:22 #: authentication/serializers/connection_token.py:20
msgid "Ticket info" msgid "Ticket info"
msgstr "工单信息" msgstr "工单信息"
#: authentication/serializers/connection_token.py:23 #: authentication/serializers/connection_token.py:21
#: perms/models/asset_permission.py:71 perms/serializers/permission.py:36 #: perms/models/asset_permission.py:71 perms/serializers/permission.py:36
#: perms/serializers/permission.py:56 #: perms/serializers/permission.py:56
#: tickets/models/ticket/apply_application.py:28 #: tickets/models/ticket/apply_application.py:28
@ -2728,16 +2742,12 @@ msgstr "工单信息"
msgid "Actions" msgid "Actions"
msgstr "动作" msgstr "动作"
#: authentication/serializers/connection_token.py:44 #: authentication/serializers/connection_token.py:42
#: perms/serializers/permission.py:38 perms/serializers/permission.py:57 #: perms/serializers/permission.py:38 perms/serializers/permission.py:57
#: users/serializers/user.py:96 users/serializers/user.py:172 #: users/serializers/user.py:96 users/serializers/user.py:172
msgid "Is expired" msgid "Is expired"
msgstr "已过期" msgstr "已过期"
#: authentication/serializers/connection_token.py:79
msgid "Reusable connection token is not allowed, global setting not enabled"
msgstr "不允许使用可重复使用的连接令牌,未启用全局设置"
#: authentication/serializers/password_mfa.py:16 #: authentication/serializers/password_mfa.py:16
#: authentication/serializers/password_mfa.py:24 #: authentication/serializers/password_mfa.py:24
#: notifications/backends/__init__.py:10 settings/serializers/email.py:19 #: notifications/backends/__init__.py:10 settings/serializers/email.py:19
@ -3851,7 +3861,7 @@ msgstr "LDAP 同步设置组织为当前组织,请切换其他组织后再进
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:118 #: orgs/apps.py:7 rbac/tree.py:119
msgid "App organizations" msgid "App organizations"
msgstr "组织管理" msgstr "组织管理"
@ -4010,27 +4020,27 @@ msgstr "{} 至少有一个系统角色"
msgid "RBAC" msgid "RBAC"
msgstr "RBAC" msgstr "RBAC"
#: rbac/builtin.py:113 #: rbac/builtin.py:114
msgid "SystemAdmin" msgid "SystemAdmin"
msgstr "系统管理员" msgstr "系统管理员"
#: rbac/builtin.py:116 #: rbac/builtin.py:117
msgid "SystemAuditor" msgid "SystemAuditor"
msgstr "系统审计员" msgstr "系统审计员"
#: rbac/builtin.py:119 #: rbac/builtin.py:120
msgid "SystemComponent" msgid "SystemComponent"
msgstr "系统组件" msgstr "系统组件"
#: rbac/builtin.py:125 #: rbac/builtin.py:126
msgid "OrgAdmin" msgid "OrgAdmin"
msgstr "组织管理员" msgstr "组织管理员"
#: rbac/builtin.py:128 #: rbac/builtin.py:129
msgid "OrgAuditor" msgid "OrgAuditor"
msgstr "组织审计员" msgstr "组织审计员"
#: rbac/builtin.py:131 #: rbac/builtin.py:132
msgid "OrgUser" msgid "OrgUser"
msgstr "组织用户" msgstr "组织用户"
@ -4180,19 +4190,19 @@ msgstr "我的资产"
msgid "Applet" msgid "Applet"
msgstr "远程应用" msgstr "远程应用"
#: rbac/tree.py:119 #: rbac/tree.py:120
msgid "Ticket comment" msgid "Ticket comment"
msgstr "工单评论" msgstr "工单评论"
#: rbac/tree.py:120 tickets/models/ticket/general.py:307 #: rbac/tree.py:121 tickets/models/ticket/general.py:307
msgid "Ticket" msgid "Ticket"
msgstr "工单管理" msgstr "工单管理"
#: rbac/tree.py:121 #: rbac/tree.py:122
msgid "Common setting" msgid "Common setting"
msgstr "一般设置" msgstr "一般设置"
#: rbac/tree.py:122 #: rbac/tree.py:123
msgid "View permission tree" msgid "View permission tree"
msgstr "查看授权树" msgstr "查看授权树"
@ -5635,7 +5645,7 @@ msgstr "输出"
msgid "Risk level" msgid "Risk level"
msgstr "风险等级" msgstr "风险等级"
#: terminal/connect_methods.py:55 #: terminal/connect_methods.py:34
msgid "DB Client" msgid "DB Client"
msgstr "数据库客户端" msgstr "数据库客户端"

View File

@ -26,11 +26,12 @@ user_perms = (
) )
system_user_perms = ( system_user_perms = (
('authentication', 'connectiontoken', 'add,change,view', 'connectiontoken'), ('authentication', 'connectiontoken', 'add,view,reuse,expire', 'connectiontoken'),
('authentication', 'temptoken', 'add,change,view', 'temptoken'), ('authentication', 'temptoken', 'add,change,view', 'temptoken'),
('authentication', 'accesskey', '*', '*'), ('authentication', 'accesskey', '*', '*'),
('tickets', 'ticket', 'view', 'ticket'), ('tickets', 'ticket', 'view', 'ticket'),
) + user_perms + _view_all_joined_org_perms )
system_user_perms += (user_perms + _view_all_joined_org_perms)
_auditor_perms = ( _auditor_perms = (
('rbac', 'menupermission', 'view', 'audit'), ('rbac', 'menupermission', 'view', 'audit'),

View File

@ -22,7 +22,8 @@ exclude_permissions = (
('common', 'setting', '*', '*'), ('common', 'setting', '*', '*'),
('authentication', 'privatetoken', '*', '*'), ('authentication', 'privatetoken', '*', '*'),
('authentication', 'connectiontoken', 'delete', 'connectiontoken'), ('authentication', 'connectiontoken', 'delete,change', 'connectiontoken'),
('authentication', 'connectiontoken', 'view', 'connectiontokensecret'),
('authentication', 'ssotoken', '*', '*'), ('authentication', 'ssotoken', '*', '*'),
('authentication', 'superconnectiontoken', 'change,delete', 'superconnectiontoken'), ('authentication', 'superconnectiontoken', 'change,delete', 'superconnectiontoken'),
('authentication', 'temptoken', 'delete', 'temptoken'), ('authentication', 'temptoken', 'delete', 'temptoken'),

View File

@ -65,6 +65,7 @@ special_pid_mapper = {
'acls.commandgroup': 'perms', 'acls.commandgroup': 'perms',
'acls.loginacl': 'perms', 'acls.loginacl': 'perms',
'acls.loginassetacl': 'perms', 'acls.loginassetacl': 'perms',
'acls.connectmethodacl': 'perms',
'xpack.account': 'cloud_import', 'xpack.account': 'cloud_import',
'xpack.syncinstancedetail': 'cloud_import', 'xpack.syncinstancedetail': 'cloud_import',
'xpack.syncinstancetask': 'cloud_import', 'xpack.syncinstancetask': 'cloud_import',

View File

@ -15,7 +15,7 @@ class Migration(migrations.Migration):
field=models.CharField( field=models.CharField(
choices=[('koko', 'KoKo'), ('guacamole', 'Guacamole'), ('omnidb', 'OmniDB'), ('xrdp', 'Xrdp'), choices=[('koko', 'KoKo'), ('guacamole', 'Guacamole'), ('omnidb', 'OmniDB'), ('xrdp', 'Xrdp'),
('lion', 'Lion'), ('core', 'Core'), ('celery', 'Celery'), ('magnus', 'Magnus'), ('lion', 'Lion'), ('core', 'Core'), ('celery', 'Celery'), ('magnus', 'Magnus'),
('razor', 'Razor'), ('tinker', 'Tinker'), ('video_worker', 'Video Worker'), ('chen', 'Chen')], ('razor', 'Razor'), ('tinker', 'Tinker'), ('video_worker', 'Video Worker'), ('chen', 'Chen'),
default='koko', max_length=64, verbose_name='type'), ('kael', 'Kael')], default='koko', max_length=64, verbose_name='type'),
), ),
] ]