perf: 修改冲突

pull/8683/head
Jiangjie.Bai 2022-07-28 18:27:19 +08:00 committed by 老广
parent c1cb211724
commit 306f078a09
7 changed files with 152 additions and 185 deletions

View File

@ -44,58 +44,29 @@ class LoginACL(BaseACL):
def __str__(self):
return self.name
@property
def action_reject(self):
return self.action == self.ActionChoices.reject
@property
def action_allow(self):
return self.action == self.ActionChoices.allow
def is_action(self, action):
return self.action == action
@classmethod
def filter_acl(cls, user):
return user.login_acls.all().valid().distinct()
@staticmethod
def allow_user_confirm_if_need(user, ip):
acl = LoginACL.filter_acl(user).filter(
action=LoginACL.ActionChoices.confirm
).first()
acl = acl if acl and acl.reviewers.exists() else None
if not acl:
return False, acl
ip_group = acl.rules.get('ip_group')
time_periods = acl.rules.get('time_period')
is_contain_ip = contains_ip(ip, ip_group)
is_contain_time_period = contains_time_period(time_periods)
return is_contain_ip and is_contain_time_period, acl
def match(user, ip):
acls = LoginACL.filter_acl(user)
if not acls:
return
@staticmethod
def allow_user_to_login(user, ip):
acl = LoginACL.filter_acl(user).exclude(
action=LoginACL.ActionChoices.confirm
).first()
if not acl:
return True, ''
ip_group = acl.rules.get('ip_group')
time_periods = acl.rules.get('time_period')
is_contain_ip = contains_ip(ip, ip_group)
is_contain_time_period = contains_time_period(time_periods)
reject_type = ''
if is_contain_ip and is_contain_time_period:
# 满足条件
allow = acl.action_allow
if not allow:
reject_type = 'ip' if is_contain_ip else 'time'
else:
# 不满足条件
# 如果acl本身允许那就拒绝如果本身拒绝那就允许
allow = not acl.action_allow
if not allow:
reject_type = 'ip' if not is_contain_ip else 'time'
return allow, reject_type
for acl in acls:
if acl.is_action(LoginACL.ActionChoices.confirm) and not acl.reviewers.exists():
continue
ip_group = acl.rules.get('ip_group')
time_periods = acl.rules.get('time_period')
is_contain_ip = contains_ip(ip, ip_group)
is_contain_time_period = contains_time_period(time_periods)
if is_contain_ip and is_contain_time_period:
# 满足条件,则返回
return acl
def create_confirm_ticket(self, request):
from tickets import const

View File

@ -138,18 +138,11 @@ class ACLError(AuthFailedNeedLogMixin, AuthFailedError):
}
class LoginIPNotAllowed(ACLError):
class LoginACLNotAllowed(ACLError):
def __init__(self, username, request, **kwargs):
self.username = username
self.request = request
super().__init__(_("IP is not allowed"), **kwargs)
class TimePeriodNotAllowed(ACLError):
def __init__(self, username, request, **kwargs):
self.username = username
self.request = request
super().__init__(_("Time Period is not allowed"), **kwargs)
super().__init__(_("ACL is not allowed"), **kwargs)
class MFACodeRequiredError(AuthFailedError):

View File

@ -328,13 +328,56 @@ class AuthACLMixin:
def _check_login_acl(self, user, ip):
# ACL 限制用户登录
is_allowed, limit_type = LoginACL.allow_user_to_login(user, ip)
if is_allowed:
acl = LoginACL.match(user, ip)
if not acl:
return
if limit_type == 'ip':
raise errors.LoginIPNotAllowed(username=user.username, request=self.request)
elif limit_type == 'time':
raise errors.TimePeriodNotAllowed(username=user.username, request=self.request)
acl: LoginACL
if acl.is_action(acl.ActionChoices.allow):
return
if acl.is_action(acl.ActionChoices.reject):
raise errors.LoginACLNotAllowed(username=user.username, request=self.request)
if acl.is_action(acl.ActionChoices.confirm):
self.request.session['auth_confirm_required'] = '1'
self.request.session['auth_acl_id'] = str(acl.id)
return
def check_user_login_confirm_if_need(self, user):
if not self.request.session.get("auth_confirm_required"):
return
acl_id = self.request.session.get('auth_acl_id')
logger.debug('Login confirm acl id: {}'.format(acl_id))
if not acl_id:
return
acl = LoginACL.filter_acl(user).filter(id=acl_id).first()
if not acl:
return
if not acl.is_action(acl.ActionChoices.confirm):
return
self.get_ticket_or_create(acl)
self.check_user_login_confirm()
def get_ticket_or_create(self, acl):
ticket = self.get_ticket()
if not ticket or ticket.is_state(ticket.State.closed):
ticket = acl.create_confirm_ticket(self.request)
self.request.session['auth_ticket_id'] = str(ticket.id)
return ticket
def check_user_login_confirm(self):
ticket = self.get_ticket()
if not ticket:
raise errors.LoginConfirmOtherError('', "Not found")
elif ticket.is_state(ticket.State.approved):
self.request.session["auth_confirm_required"] = ''
return
elif ticket.is_status(ticket.Status.open):
raise errors.LoginConfirmWaitError(ticket.id)
else:
# rejected, closed
raise errors.LoginConfirmOtherError(ticket.id, ticket.get_state_display())
def get_ticket(self):
from tickets.models import ApplyLoginTicket
@ -346,44 +389,6 @@ class AuthACLMixin:
ticket = ApplyLoginTicket.all().filter(id=ticket_id).first()
return ticket
def get_ticket_or_create(self, confirm_setting):
ticket = self.get_ticket()
if not ticket or ticket.is_status(ticket.Status.closed):
ticket = confirm_setting.create_confirm_ticket(self.request)
self.request.session['auth_ticket_id'] = str(ticket.id)
return ticket
def check_user_login_confirm(self):
ticket = self.get_ticket()
if not ticket:
raise errors.LoginConfirmOtherError('', "Not found")
if ticket.is_status(ticket.Status.open):
raise errors.LoginConfirmWaitError(ticket.id)
elif ticket.is_state(ticket.State.approved):
self.request.session["auth_confirm"] = "1"
return
elif ticket.is_state(ticket.State.rejected):
raise errors.LoginConfirmOtherError(
ticket.id, ticket.get_state_display()
)
elif ticket.is_state(ticket.State.closed):
raise errors.LoginConfirmOtherError(
ticket.id, ticket.get_state_display()
)
else:
raise errors.LoginConfirmOtherError(
ticket.id, ticket.get_status_display()
)
def check_user_login_confirm_if_need(self, user):
ip = self.get_request_ip()
is_allowed, confirm_setting = LoginACL.allow_user_confirm_if_need(user, ip)
if self.request.session.get('auth_confirm') or not is_allowed:
return
self.get_ticket_or_create(confirm_setting)
self.check_user_login_confirm()
class AuthMixin(CommonMixin, AuthPreCheckMixin, AuthACLMixin, MFAMixin, AuthPostCheckMixin):
request = None
@ -482,7 +487,9 @@ class AuthMixin(CommonMixin, AuthPreCheckMixin, AuthACLMixin, MFAMixin, AuthPost
return self.check_user_auth(valid_data)
def clear_auth_mark(self):
keys = ['auth_password', 'user_id', 'auth_confirm', 'auth_ticket_id']
keys = [
'auth_password', 'user_id', 'auth_confirm_required', 'auth_ticket_id', 'auth_acl_id'
]
for k in keys:
self.request.session.pop(k, '')

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0f2fdd3a7bd34a26d068fc6ce521d0ea9983c477b13536ba3f51700a554d4ae3
size 128706
oid sha256:3414a662f323c5d3b04780d67230ea4911127e2bceb040bded1b64292622ceed
size 128606

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-20 13:51+0800\n"
"POT-Creation-Date: 2022-07-29 11:26+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -27,7 +27,7 @@ msgstr "Acls"
#: assets/models/base.py:175 assets/models/cluster.py:18
#: assets/models/cmd_filter.py:27 assets/models/domain.py:23
#: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24
#: orgs/models.py:65 perms/models/base.py:83 rbac/models/role.py:29
#: orgs/models.py:70 perms/models/base.py:83 rbac/models/role.py:29
#: settings/models.py:29 settings/serializers/sms.py:6
#: terminal/models/endpoint.py:10 terminal/models/endpoint.py:86
#: terminal/models/storage.py:26 terminal/models/task.py:16
@ -59,7 +59,7 @@ msgstr "アクティブ"
#: assets/models/cluster.py:29 assets/models/cmd_filter.py:48
#: assets/models/cmd_filter.py:96 assets/models/domain.py:24
#: assets/models/domain.py:65 assets/models/group.py:23
#: assets/models/label.py:23 ops/models/adhoc.py:38 orgs/models.py:68
#: assets/models/label.py:23 ops/models/adhoc.py:38 orgs/models.py:73
#: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34
#: terminal/models/endpoint.py:23 terminal/models/endpoint.py:96
#: terminal/models/storage.py:29 terminal/models/terminal.py:114
@ -80,7 +80,7 @@ msgstr "拒否"
msgid "Allow"
msgstr "許可"
#: acls/models/login_acl.py:20 acls/models/login_acl.py:104
#: acls/models/login_acl.py:20 acls/models/login_acl.py:75
#: acls/models/login_asset_acl.py:17 tickets/const.py:9
msgid "Login confirm"
msgstr "ログイン確認"
@ -88,7 +88,7 @@ msgstr "ログイン確認"
#: acls/models/login_acl.py:24 acls/models/login_asset_acl.py:20
#: assets/models/cmd_filter.py:30 assets/models/label.py:15 audits/models.py:37
#: audits/models.py:62 audits/models.py:87 audits/serializers.py:100
#: authentication/models.py:54 authentication/models.py:78 orgs/models.py:215
#: authentication/models.py:54 authentication/models.py:78 orgs/models.py:220
#: perms/models/base.py:84 rbac/builtin.py:120 rbac/models/rolebinding.py:41
#: terminal/backends/command/models.py:20
#: terminal/backends/command/serializers.py:13 terminal/models/session.py:44
@ -363,7 +363,7 @@ msgstr "タイプ表示"
#: assets/serializers/account.py:18 assets/serializers/cmd_filter.py:28
#: assets/serializers/cmd_filter.py:48 common/db/models.py:114
#: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30
#: orgs/models.py:67 orgs/models.py:218 perms/models/base.py:92
#: orgs/models.py:72 orgs/models.py:223 perms/models/base.py:92
#: users/models/group.py:18 users/models/user.py:922
#: xpack/plugins/cloud/models.py:125
msgid "Date created"
@ -373,7 +373,7 @@ msgstr "作成された日付"
#: assets/models/gathered_user.py:20 assets/serializers/account.py:21
#: assets/serializers/cmd_filter.py:29 assets/serializers/cmd_filter.py:49
#: common/db/models.py:115 common/mixins/models.py:51 ops/models/adhoc.py:40
#: orgs/models.py:219
#: orgs/models.py:224
msgid "Date updated"
msgstr "更新日"
@ -627,8 +627,8 @@ msgstr "ラベル"
#: assets/models/asset.py:229 assets/models/base.py:183
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:52
#: assets/models/cmd_filter.py:99 assets/models/group.py:21
#: common/db/models.py:112 common/mixins/models.py:49 orgs/models.py:66
#: orgs/models.py:220 perms/models/base.py:91 users/models/user.py:706
#: common/db/models.py:112 common/mixins/models.py:49 orgs/models.py:71
#: orgs/models.py:225 perms/models/base.py:91 users/models/user.py:706
#: users/serializers/group.py:33
#: xpack/plugins/change_auth_plan/models/base.py:48
#: xpack/plugins/cloud/models.py:122 xpack/plugins/gathered_user/models.py:30
@ -907,11 +907,11 @@ msgstr "家を無視する"
msgid "Command filter rule"
msgstr "コマンドフィルタルール"
#: assets/models/cmd_filter.py:144
#: assets/models/cmd_filter.py:147
msgid "The generated regular expression is incorrect: {}"
msgstr "生成された正規表現が正しくありません: {}"
#: assets/models/cmd_filter.py:170 tickets/const.py:13
#: assets/models/cmd_filter.py:173 tickets/const.py:13
msgid "Command confirm"
msgstr "コマンドの確認"
@ -1914,7 +1914,7 @@ msgstr "このアカウントは期限切れです"
msgid "Auth backend not match"
msgstr "Authバックエンドが一致しない"
#: authentication/errors/const.py:28
#: authentication/errors/const.py:28 authentication/errors/failed.py:145
msgid "ACL is not allowed"
msgstr "ACLは許可されません"
@ -1982,23 +1982,15 @@ msgstr "受け入れのためのログイン確認チケットを待つ"
msgid "Login confirm ticket was {}"
msgstr "ログイン確認チケットは {} でした"
#: authentication/errors/failed.py:145
msgid "IP is not allowed"
msgstr "IPは許可されていません"
#: authentication/errors/failed.py:152
msgid "Time Period is not allowed"
msgstr "期間は許可されていません"
#: authentication/errors/failed.py:157
#: authentication/errors/failed.py:150
msgid "Please enter MFA code"
msgstr "MFAコードを入力してください"
#: authentication/errors/failed.py:162
#: authentication/errors/failed.py:155
msgid "Please enter SMS code"
msgstr "SMSコードを入力してください"
#: authentication/errors/failed.py:167 users/exceptions.py:15
#: authentication/errors/failed.py:160 users/exceptions.py:15
msgid "Phone not set"
msgstr "電話が設定されていない"
@ -2226,7 +2218,7 @@ msgstr "有効性"
msgid "Expired time"
msgstr "期限切れ時間"
#: authentication/serializers/connection_token.py:74
#: authentication/serializers/connection_token.py:73
msgid "Asset or application required"
msgstr "アセットまたはアプリが必要"
@ -3028,26 +3020,26 @@ msgstr "組織のリソース ({}) は削除できません"
msgid "App organizations"
msgstr "アプリ組織"
#: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:80
#: orgs/models.py:212 rbac/const.py:7 rbac/models/rolebinding.py:48
#: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:85
#: orgs/models.py:217 rbac/const.py:7 rbac/models/rolebinding.py:48
#: rbac/serializers/rolebinding.py:40 settings/serializers/auth/ldap.py:62
#: tickets/models/ticket/general.py:300 tickets/serializers/ticket/ticket.py:71
msgid "Organization"
msgstr "組織"
#: orgs/models.py:74
#: orgs/models.py:79
msgid "GLOBAL"
msgstr "グローバル組織"
#: orgs/models.py:82
#: orgs/models.py:87
msgid "Can view root org"
msgstr "グローバル組織を表示できます"
#: orgs/models.py:83
#: orgs/models.py:88
msgid "Can view all joined org"
msgstr "参加しているすべての組織を表示できます"
#: orgs/models.py:217 rbac/models/role.py:46 rbac/models/rolebinding.py:44
#: orgs/models.py:222 rbac/models/role.py:46 rbac/models/rolebinding.py:44
#: users/models/user.py:671
msgid "Role"
msgstr "ロール"
@ -3136,27 +3128,27 @@ msgstr "クリップボードコピーペースト"
msgid "From ticket"
msgstr "チケットから"
#: perms/notifications.py:18
#: perms/notifications.py:15
msgid "You permed assets is about to expire"
msgstr "パーマ資産の有効期限が近づいています"
#: perms/notifications.py:23
#: perms/notifications.py:20
msgid "permed assets"
msgstr "パーマ資産"
#: perms/notifications.py:62
#: perms/notifications.py:59
msgid "Asset permissions is about to expire"
msgstr "資産権限の有効期限が近づいています"
#: perms/notifications.py:67
#: perms/notifications.py:64
msgid "asset permissions of organization {}"
msgstr "組織 {} の資産権限"
#: perms/notifications.py:94
#: perms/notifications.py:91
msgid "Your permed applications is about to expire"
msgstr "パーマアプリケーションの有効期限が近づいています"
#: perms/notifications.py:98
#: perms/notifications.py:95
msgid "permed applications"
msgstr "Permedアプリケーション"
@ -3825,20 +3817,20 @@ msgstr "テンプレートコード"
msgid "Test phone"
msgstr "テスト電話"
#: settings/serializers/auth/sso.py:12
#: settings/serializers/auth/sso.py:11
msgid "Enable SSO auth"
msgstr "SSO Token認証の有効化"
#: settings/serializers/auth/sso.py:13
#: settings/serializers/auth/sso.py:12
msgid "Other service can using SSO token login to JumpServer without password"
msgstr ""
"他のサービスはパスワードなしでJumpServerへのSSOトークンログインを使用できます"
#: settings/serializers/auth/sso.py:16
#: settings/serializers/auth/sso.py:15
msgid "SSO auth key TTL"
msgstr "Token有効期間"
#: settings/serializers/auth/sso.py:16
#: settings/serializers/auth/sso.py:15
msgid "Unit: second"
msgstr "単位: 秒"
@ -4838,7 +4830,7 @@ msgstr "一括作成非サポート"
msgid "Storage is invalid"
msgstr "ストレージが無効です"
#: terminal/models/command.py:53
#: terminal/models/command.py:66
msgid "Command record"
msgstr "コマンドレコード"
@ -6853,5 +6845,11 @@ msgstr "究極のエディション"
msgid "Community edition"
msgstr "コミュニティ版"
#~ msgid "IP is not allowed"
#~ msgstr "IPは許可されていません"
#~ msgid "Time Period is not allowed"
#~ msgstr "期間は許可されていません"
#~ msgid "User cannot self-update fields: {}"
#~ msgstr "ユーザーは自分のフィールドを更新できません: {}"

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9c2b13f7242beec8786179e03de895bd3e9d8d6392b74c2398409c1bfa33d9f8
size 106088
oid sha256:aa7ee5bbc77ab0eb8ca89fffff32ce4d31d5405312c4f75d8bec98913346850a
size 105987

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-20 13:51+0800\n"
"POT-Creation-Date: 2022-07-29 11:26+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\n"
@ -26,7 +26,7 @@ msgstr "访问控制"
#: assets/models/base.py:175 assets/models/cluster.py:18
#: assets/models/cmd_filter.py:27 assets/models/domain.py:23
#: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24
#: orgs/models.py:65 perms/models/base.py:83 rbac/models/role.py:29
#: orgs/models.py:70 perms/models/base.py:83 rbac/models/role.py:29
#: settings/models.py:29 settings/serializers/sms.py:6
#: terminal/models/endpoint.py:10 terminal/models/endpoint.py:86
#: terminal/models/storage.py:26 terminal/models/task.py:16
@ -58,7 +58,7 @@ msgstr "激活中"
#: assets/models/cluster.py:29 assets/models/cmd_filter.py:48
#: assets/models/cmd_filter.py:96 assets/models/domain.py:24
#: assets/models/domain.py:65 assets/models/group.py:23
#: assets/models/label.py:23 ops/models/adhoc.py:38 orgs/models.py:68
#: assets/models/label.py:23 ops/models/adhoc.py:38 orgs/models.py:73
#: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34
#: terminal/models/endpoint.py:23 terminal/models/endpoint.py:96
#: terminal/models/storage.py:29 terminal/models/terminal.py:114
@ -79,7 +79,7 @@ msgstr "拒绝"
msgid "Allow"
msgstr "允许"
#: acls/models/login_acl.py:20 acls/models/login_acl.py:104
#: acls/models/login_acl.py:20 acls/models/login_acl.py:75
#: acls/models/login_asset_acl.py:17 tickets/const.py:9
msgid "Login confirm"
msgstr "登录复核"
@ -87,7 +87,7 @@ msgstr "登录复核"
#: acls/models/login_acl.py:24 acls/models/login_asset_acl.py:20
#: assets/models/cmd_filter.py:30 assets/models/label.py:15 audits/models.py:37
#: audits/models.py:62 audits/models.py:87 audits/serializers.py:100
#: authentication/models.py:54 authentication/models.py:78 orgs/models.py:215
#: authentication/models.py:54 authentication/models.py:78 orgs/models.py:220
#: perms/models/base.py:84 rbac/builtin.py:120 rbac/models/rolebinding.py:41
#: terminal/backends/command/models.py:20
#: terminal/backends/command/serializers.py:13 terminal/models/session.py:44
@ -358,7 +358,7 @@ msgstr "类型名称"
#: assets/serializers/account.py:18 assets/serializers/cmd_filter.py:28
#: assets/serializers/cmd_filter.py:48 common/db/models.py:114
#: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30
#: orgs/models.py:67 orgs/models.py:218 perms/models/base.py:92
#: orgs/models.py:72 orgs/models.py:223 perms/models/base.py:92
#: users/models/group.py:18 users/models/user.py:922
#: xpack/plugins/cloud/models.py:125
msgid "Date created"
@ -368,7 +368,7 @@ msgstr "创建日期"
#: assets/models/gathered_user.py:20 assets/serializers/account.py:21
#: assets/serializers/cmd_filter.py:29 assets/serializers/cmd_filter.py:49
#: common/db/models.py:115 common/mixins/models.py:51 ops/models/adhoc.py:40
#: orgs/models.py:219
#: orgs/models.py:224
msgid "Date updated"
msgstr "更新日期"
@ -622,8 +622,8 @@ msgstr "标签管理"
#: assets/models/asset.py:229 assets/models/base.py:183
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:52
#: assets/models/cmd_filter.py:99 assets/models/group.py:21
#: common/db/models.py:112 common/mixins/models.py:49 orgs/models.py:66
#: orgs/models.py:220 perms/models/base.py:91 users/models/user.py:706
#: common/db/models.py:112 common/mixins/models.py:49 orgs/models.py:71
#: orgs/models.py:225 perms/models/base.py:91 users/models/user.py:706
#: users/serializers/group.py:33
#: xpack/plugins/change_auth_plan/models/base.py:48
#: xpack/plugins/cloud/models.py:122 xpack/plugins/gathered_user/models.py:30
@ -902,11 +902,11 @@ msgstr "忽略大小写"
msgid "Command filter rule"
msgstr "命令过滤规则"
#: assets/models/cmd_filter.py:144
#: assets/models/cmd_filter.py:147
msgid "The generated regular expression is incorrect: {}"
msgstr "生成的正则表达式有误"
#: assets/models/cmd_filter.py:170 tickets/const.py:13
#: assets/models/cmd_filter.py:173 tickets/const.py:13
msgid "Command confirm"
msgstr "命令复核"
@ -1900,7 +1900,7 @@ msgstr "此账号已过期"
msgid "Auth backend not match"
msgstr "没有匹配到认证后端"
#: authentication/errors/const.py:28
#: authentication/errors/const.py:28 authentication/errors/failed.py:145
msgid "ACL is not allowed"
msgstr "ACL 不被允许"
@ -1962,23 +1962,15 @@ msgstr "等待登录复核处理"
msgid "Login confirm ticket was {}"
msgstr "登录复核: {}"
#: authentication/errors/failed.py:145
msgid "IP is not allowed"
msgstr "来源 IP 不被允许登录"
#: authentication/errors/failed.py:152
msgid "Time Period is not allowed"
msgstr "该 时间段 不被允许登录"
#: authentication/errors/failed.py:157
#: authentication/errors/failed.py:150
msgid "Please enter MFA code"
msgstr "请输入 MFA 验证码"
#: authentication/errors/failed.py:162
#: authentication/errors/failed.py:155
msgid "Please enter SMS code"
msgstr "请输入短信验证码"
#: authentication/errors/failed.py:167 users/exceptions.py:15
#: authentication/errors/failed.py:160 users/exceptions.py:15
msgid "Phone not set"
msgstr "手机号没有设置"
@ -2201,7 +2193,7 @@ msgstr "有效"
msgid "Expired time"
msgstr "过期时间"
#: authentication/serializers/connection_token.py:74
#: authentication/serializers/connection_token.py:73
msgid "Asset or application required"
msgstr "资产或应用必填"
@ -2988,26 +2980,26 @@ msgstr "组织存在资源 ({}) 不能被删除"
msgid "App organizations"
msgstr "组织管理"
#: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:80
#: orgs/models.py:212 rbac/const.py:7 rbac/models/rolebinding.py:48
#: orgs/mixins/models.py:57 orgs/mixins/serializers.py:25 orgs/models.py:85
#: orgs/models.py:217 rbac/const.py:7 rbac/models/rolebinding.py:48
#: rbac/serializers/rolebinding.py:40 settings/serializers/auth/ldap.py:62
#: tickets/models/ticket/general.py:300 tickets/serializers/ticket/ticket.py:71
msgid "Organization"
msgstr "组织"
#: orgs/models.py:74
#: orgs/models.py:79
msgid "GLOBAL"
msgstr "全局组织"
#: orgs/models.py:82
#: orgs/models.py:87
msgid "Can view root org"
msgstr "可以查看全局组织"
#: orgs/models.py:83
#: orgs/models.py:88
msgid "Can view all joined org"
msgstr "可以查看所有加入的组织"
#: orgs/models.py:217 rbac/models/role.py:46 rbac/models/rolebinding.py:44
#: orgs/models.py:222 rbac/models/role.py:46 rbac/models/rolebinding.py:44
#: users/models/user.py:671
msgid "Role"
msgstr "角色"
@ -3096,27 +3088,27 @@ msgstr "剪贴板复制粘贴"
msgid "From ticket"
msgstr "来自工单"
#: perms/notifications.py:18
#: perms/notifications.py:15
msgid "You permed assets is about to expire"
msgstr "你授权的资产即将到期"
#: perms/notifications.py:23
#: perms/notifications.py:20
msgid "permed assets"
msgstr "授权的资产"
#: perms/notifications.py:62
#: perms/notifications.py:59
msgid "Asset permissions is about to expire"
msgstr "资产授权规则将要过期"
#: perms/notifications.py:67
#: perms/notifications.py:64
msgid "asset permissions of organization {}"
msgstr "组织 ({}) 的资产授权"
#: perms/notifications.py:94
#: perms/notifications.py:91
msgid "Your permed applications is about to expire"
msgstr "你授权的应用即将过期"
#: perms/notifications.py:98
#: perms/notifications.py:95
msgid "permed applications"
msgstr "授权的应用"
@ -3782,19 +3774,19 @@ msgstr "模板"
msgid "Test phone"
msgstr "测试手机号"
#: settings/serializers/auth/sso.py:12
#: settings/serializers/auth/sso.py:11
msgid "Enable SSO auth"
msgstr "启用 SSO Token 认证"
#: settings/serializers/auth/sso.py:13
#: settings/serializers/auth/sso.py:12
msgid "Other service can using SSO token login to JumpServer without password"
msgstr "其它系统可以使用 SSO Token 对接 JumpServer, 免去登录的过程"
#: settings/serializers/auth/sso.py:16
#: settings/serializers/auth/sso.py:15
msgid "SSO auth key TTL"
msgstr "Token 有效期"
#: settings/serializers/auth/sso.py:16
#: settings/serializers/auth/sso.py:15
msgid "Unit: second"
msgstr "单位: 秒"
@ -4762,7 +4754,7 @@ msgstr "不支持批量创建"
msgid "Storage is invalid"
msgstr "存储无效"
#: terminal/models/command.py:53
#: terminal/models/command.py:66
msgid "Command record"
msgstr "命令记录"
@ -6756,5 +6748,11 @@ msgstr "旗舰版"
msgid "Community edition"
msgstr "社区版"
#~ msgid "IP is not allowed"
#~ msgstr "来源 IP 不被允许登录"
#~ msgid "Time Period is not allowed"
#~ msgstr "该 时间段 不被允许登录"
#~ msgid "User cannot self-update fields: {}"
#~ msgstr "用户不能更新自己的字段: {}"