mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-12-15 08:32:48 +00:00
Compare commits
7 Commits
revert-162
...
v2.24.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3cd9d50c9 | ||
|
|
07caaa5e46 | ||
|
|
9e9190aed5 | ||
|
|
3cddaef798 | ||
|
|
99a6d7b0ab | ||
|
|
306f078a09 | ||
|
|
c1cb211724 |
@@ -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
|
||||
|
||||
@@ -6,7 +6,7 @@ from django.shortcuts import get_object_or_404
|
||||
from django.db.models import Q
|
||||
|
||||
from common.utils import get_logger, get_object_or_none
|
||||
from common.mixins.api import SuggestionMixin
|
||||
from common.mixins.api import SuggestionMixin, RenderToJsonMixin
|
||||
from users.models import User, UserGroup
|
||||
from users.serializers import UserSerializer, UserGroupSerializer
|
||||
from users.filters import UserFilter
|
||||
@@ -88,7 +88,7 @@ class AssetPlatformRetrieveApi(RetrieveAPIView):
|
||||
return asset.platform
|
||||
|
||||
|
||||
class AssetPlatformViewSet(ModelViewSet):
|
||||
class AssetPlatformViewSet(ModelViewSet, RenderToJsonMixin):
|
||||
queryset = Platform.objects.all()
|
||||
serializer_class = serializers.PlatformSerializer
|
||||
filterset_fields = ['name', 'base']
|
||||
|
||||
@@ -189,6 +189,9 @@ class PlatformSerializer(serializers.ModelSerializer):
|
||||
'id', 'name', 'base', 'charset',
|
||||
'internal', 'meta', 'comment'
|
||||
]
|
||||
extra_kwargs = {
|
||||
'internal': {'read_only': True},
|
||||
}
|
||||
|
||||
|
||||
class AssetSimpleSerializer(serializers.ModelSerializer):
|
||||
|
||||
@@ -12,12 +12,13 @@ class AuthFailedNeedLogMixin:
|
||||
username = ''
|
||||
request = None
|
||||
error = ''
|
||||
msg = ''
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
post_auth_failed.send(
|
||||
sender=self.__class__, username=self.username,
|
||||
request=self.request, reason=self.error
|
||||
request=self.request, reason=self.msg
|
||||
)
|
||||
|
||||
|
||||
@@ -138,18 +139,11 @@ class ACLError(AuthFailedNeedLogMixin, AuthFailedError):
|
||||
}
|
||||
|
||||
|
||||
class LoginIPNotAllowed(ACLError):
|
||||
class LoginACLIPAndTimePeriodNotAllowed(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__(_("Current IP and Time period is not allowed"), **kwargs)
|
||||
|
||||
|
||||
class MFACodeRequiredError(AuthFailedError):
|
||||
|
||||
@@ -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.LoginACLIPAndTimePeriodNotAllowed(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, '')
|
||||
|
||||
|
||||
@@ -255,6 +255,8 @@ def decrypt_password(value):
|
||||
if len(cipher) != 2:
|
||||
return value
|
||||
key_cipher, password_cipher = cipher
|
||||
if not all([key_cipher, password_cipher]):
|
||||
return value
|
||||
aes_key = rsa_decrypt_by_session_pkey(key_cipher)
|
||||
aes = get_aes_crypto(aes_key, 'ECB')
|
||||
try:
|
||||
|
||||
@@ -160,7 +160,7 @@ class Config(dict):
|
||||
'SESSION_COOKIE_DOMAIN': None,
|
||||
'CSRF_COOKIE_DOMAIN': None,
|
||||
'SESSION_COOKIE_NAME_PREFIX': None,
|
||||
'SESSION_COOKIE_AGE': 3600,
|
||||
'SESSION_COOKIE_AGE': 3600 * 24,
|
||||
'SESSION_EXPIRE_AT_BROWSER_CLOSE': False,
|
||||
'LOGIN_URL': reverse_lazy('authentication:login'),
|
||||
'CONNECTION_TOKEN_EXPIRATION': 5 * 60,
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0f2fdd3a7bd34a26d068fc6ce521d0ea9983c477b13536ba3f51700a554d4ae3
|
||||
size 128706
|
||||
oid sha256:3414a662f323c5d3b04780d67230ea4911127e2bceb040bded1b64292622ceed
|
||||
size 128606
|
||||
|
||||
@@ -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-08-02 14:32+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 "コマンドの確認"
|
||||
|
||||
@@ -1983,22 +1983,18 @@ msgid "Login confirm ticket was {}"
|
||||
msgstr "ログイン確認チケットは {} でした"
|
||||
|
||||
#: authentication/errors/failed.py:145
|
||||
msgid "IP is not allowed"
|
||||
msgstr "IPは許可されていません"
|
||||
msgid "Current IP and Time period 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 +2222,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 +3024,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 +3132,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 +3821,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 +4834,7 @@ msgstr "一括作成非サポート"
|
||||
msgid "Storage is invalid"
|
||||
msgstr "ストレージが無効です"
|
||||
|
||||
#: terminal/models/command.py:53
|
||||
#: terminal/models/command.py:66
|
||||
msgid "Command record"
|
||||
msgstr "コマンドレコード"
|
||||
|
||||
@@ -6853,5 +6849,8 @@ msgstr "究極のエディション"
|
||||
msgid "Community edition"
|
||||
msgstr "コミュニティ版"
|
||||
|
||||
#~ msgid "IP is not allowed"
|
||||
#~ msgstr "IPは許可されていません"
|
||||
|
||||
#~ msgid "User cannot self-update fields: {}"
|
||||
#~ msgstr "ユーザーは自分のフィールドを更新できません: {}"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9c2b13f7242beec8786179e03de895bd3e9d8d6392b74c2398409c1bfa33d9f8
|
||||
size 106088
|
||||
oid sha256:aa7ee5bbc77ab0eb8ca89fffff32ce4d31d5405312c4f75d8bec98913346850a
|
||||
size 105987
|
||||
|
||||
@@ -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-08-02 14:32+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 "命令复核"
|
||||
|
||||
@@ -1963,22 +1963,18 @@ msgid "Login confirm ticket was {}"
|
||||
msgstr "登录复核: {}"
|
||||
|
||||
#: authentication/errors/failed.py:145
|
||||
msgid "IP is not allowed"
|
||||
msgstr "来源 IP 不被允许登录"
|
||||
msgid "Current IP and Time period 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 +2197,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 +2984,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 +3092,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 +3778,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 +4758,7 @@ msgstr "不支持批量创建"
|
||||
msgid "Storage is invalid"
|
||||
msgstr "存储无效"
|
||||
|
||||
#: terminal/models/command.py:53
|
||||
#: terminal/models/command.py:66
|
||||
msgid "Command record"
|
||||
msgstr "命令记录"
|
||||
|
||||
@@ -6756,5 +6752,8 @@ msgstr "旗舰版"
|
||||
msgid "Community edition"
|
||||
msgstr "社区版"
|
||||
|
||||
#~ msgid "IP is not allowed"
|
||||
#~ msgstr "来源 IP 不被允许登录"
|
||||
|
||||
#~ msgid "User cannot self-update fields: {}"
|
||||
#~ msgstr "用户不能更新自己的字段: {}"
|
||||
|
||||
@@ -20,4 +20,4 @@ class SuperTicketStatusAPI(RetrieveDestroyAPIView):
|
||||
return Ticket.objects.all()
|
||||
|
||||
def perform_destroy(self, instance):
|
||||
instance.close(processor=instance.applicant)
|
||||
instance.close()
|
||||
|
||||
Reference in New Issue
Block a user