Merge pull request #14319 from jumpserver/dev

v4.3.0
pull/14321/head
Bryan 2024-10-17 14:55:38 +08:00 committed by GitHub
commit 6720ecc6e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
66 changed files with 1127 additions and 786 deletions

View File

@ -1,4 +1,4 @@
FROM jumpserver/core-base:20240919_024156 AS stage-build
FROM jumpserver/core-base:20240924_031841 AS stage-build
ARG VERSION

View File

@ -1,3 +1,5 @@
from django.utils.translation import gettext_lazy as _
from accounts.const import AutomationTypes
from assets.automations.ping_gateway.manager import PingGatewayManager
from common.utils import get_logger
@ -13,7 +15,7 @@ class VerifyGatewayAccountManager(PingGatewayManager):
@staticmethod
def before_runner_start():
logger.info(">>> 开始执行测试网关账号可连接性任务")
logger.info(_(">>> Start executing the task to test gateway account connectivity"))
def get_accounts(self, gateway):
account_ids = self.execution.snapshot['accounts']

View File

@ -53,7 +53,8 @@ class Account(AbsConnectivity, LabeledMixin, BaseAccount):
on_delete=models.SET_NULL, verbose_name=_("Su from")
)
version = models.IntegerField(default=0, verbose_name=_('Version'))
history = AccountHistoricalRecords(included_fields=['id', '_secret', 'secret_type', 'version'])
history = AccountHistoricalRecords(included_fields=['id', '_secret', 'secret_type', 'version'],
verbose_name=_("historical Account"))
source = models.CharField(max_length=30, default=Source.LOCAL, verbose_name=_('Source'))
source_id = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Source ID'))

View File

@ -10,7 +10,7 @@ from .base import BaseAccountSerializer
class PasswordRulesSerializer(serializers.Serializer):
length = serializers.IntegerField(min_value=8, max_value=30, default=16, label=_('Password length'))
length = serializers.IntegerField(min_value=8, max_value=36, default=16, label=_('Password length'))
lowercase = serializers.BooleanField(default=True, label=_('Lowercase'))
uppercase = serializers.BooleanField(default=True, label=_('Uppercase'))
digit = serializers.BooleanField(default=True, label=_('Digit'))

View File

@ -75,19 +75,6 @@ class ChangeSecretAutomationSerializer(AuthValidateMixin, BaseAutomationSerializ
if self.initial_data.get('secret_strategy') == SecretStrategy.custom:
return password_rules
length = password_rules.get('length')
try:
length = int(length)
except Exception as e:
logger.error(e)
msg = _("* Please enter the correct password length")
raise serializers.ValidationError(msg)
if length < 6 or length > 30:
msg = _('* Password length range 6-30 bits')
raise serializers.ValidationError(msg)
return password_rules
def validate(self, attrs):

View File

@ -115,7 +115,7 @@ class PingGatewayManager:
@staticmethod
def before_runner_start():
print(">>> 开始执行测试网关可连接性任务")
print(_(">>> Start executing the task to test gateway connectivity"))
def get_accounts(self, gateway):
account = gateway.select_account

View File

@ -112,7 +112,7 @@ class BaseType(TextChoices):
@classmethod
def get_choices(cls):
if not settings.XPACK_ENABLED:
if not settings.XPACK_LICENSE_IS_VALID:
choices = [(tp.value, tp.label) for tp in cls.get_community_types()]
else:
choices = cls.choices

View File

@ -18,7 +18,7 @@ from common.serializers.fields import LabeledChoiceField
from labels.models import Label
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from ...const import Category, AllTypes
from ...models import Asset, Node, Platform, Protocol
from ...models import Asset, Node, Platform, Protocol, Host, Device, Database, Cloud, Web, Custom
__all__ = [
'AssetSerializer', 'AssetSimpleSerializer', 'MiniAssetSerializer',
@ -309,6 +309,17 @@ class AssetSerializer(BulkOrgResourceModelSerializer, ResourceLabelsMixin, Writa
})
return protocols_data_map.values()
def validate_platform(self, platform_data):
check_models = {Host, Device, Database, Cloud, Web, Custom}
if self.Meta.model not in check_models:
return platform_data
model_name = self.Meta.model.__name__.lower()
if model_name != platform_data.category:
raise serializers.ValidationError({
'platform': f"Platform does not match: {platform_data.name}"
})
return platform_data
@staticmethod
def update_account_su_from(accounts, include_su_from_accounts):
if not include_su_from_accounts:

View File

@ -146,7 +146,9 @@ class MyLoginLogViewSet(UserLoginCommonMixin, OrgReadonlyModelViewSet):
def get_queryset(self):
qs = super().get_queryset()
qs = qs.filter(username=self.request.user.username)
username = self.request.user.username
q = Q(username=username) | Q(username__icontains=f'({username})')
qs = qs.filter(q)
return qs

View File

@ -74,6 +74,9 @@ class OperateLogStore(object):
@classmethod
def convert_diff_friendly(cls, op_log):
diff_list = list()
# 标记翻译字符串
labels = _("labels")
operate_log_id = _("operate_log_id")
handler = cls._get_special_handler(op_log.resource_type)
for k, v in op_log.diff.items():
before_value, after_value = cls.split_value(v)

View File

@ -187,7 +187,7 @@ def on_django_start_set_operate_log_monitor_models(sender, **kwargs):
'PermedAsset', 'PermedAccount', 'MenuPermission',
'Permission', 'TicketSession', 'ApplyLoginTicket',
'ApplyCommandTicket', 'ApplyLoginAssetTicket',
'FavoriteAsset', 'ChangeSecretRecord'
'FavoriteAsset', 'ChangeSecretRecord', 'AppProvider',
}
include_models = {'UserSession'}
for i, app in enumerate(apps.get_models(), 1):

View File

@ -472,6 +472,7 @@ class SuperConnectionTokenViewSet(ConnectionTokenViewSet):
rbac_perms = {
'create': 'authentication.add_superconnectiontoken',
'renewal': 'authentication.add_superconnectiontoken',
'check': 'authentication.view_superconnectiontoken',
'get_secret_detail': 'authentication.view_superconnectiontokensecret',
'get_applet_info': 'authentication.view_superconnectiontoken',
'release_applet_account': 'authentication.view_superconnectiontoken',
@ -484,6 +485,28 @@ class SuperConnectionTokenViewSet(ConnectionTokenViewSet):
def get_user(self, serializer):
return serializer.validated_data.get('user')
@action(methods=['GET'], detail=True, url_path='check')
def check(self, request, *args, **kwargs):
instance = self.get_object()
data = {
"detail": "OK",
"code": "perm_ok",
"expired": instance.is_expired
}
try:
self._validate_perm(
instance.user,
instance.asset,
instance.account,
instance.protocol
)
except JMSException as e:
data['code'] = e.detail.code
data['detail'] = str(e.detail)
return Response(data=data, status=status.HTTP_400_BAD_REQUEST)
return Response(data=data, status=status.HTTP_200_OK)
@action(methods=['PATCH'], detail=False)
def renewal(self, request, *args, **kwargs):
from common.utils.timezone import as_current_tz

View File

@ -2,6 +2,7 @@ import base64
from django.conf import settings
from django.contrib.auth import logout as auth_logout
from django.core.cache import cache
from django.http import HttpResponse
from django.shortcuts import redirect, reverse, render
from django.utils.deprecation import MiddlewareMixin
@ -116,23 +117,43 @@ class ThirdPartyLoginMiddleware(mixins.AuthMixin):
class SessionCookieMiddleware(MiddlewareMixin):
USER_LOGIN_ENCRYPTION_KEY_PAIR = 'user_login_encryption_key_pair'
@staticmethod
def set_cookie_public_key(request, response):
def set_cookie_public_key(self, request, response):
if request.path.startswith('/api'):
return
pub_key_name = settings.SESSION_RSA_PUBLIC_KEY_NAME
public_key = request.session.get(pub_key_name)
cookie_key = request.COOKIES.get(pub_key_name)
if public_key and public_key == cookie_key:
session_public_key_name = settings.SESSION_RSA_PUBLIC_KEY_NAME
session_private_key_name = settings.SESSION_RSA_PRIVATE_KEY_NAME
session_public_key = request.session.get(session_public_key_name)
cookie_public_key = request.COOKIES.get(session_public_key_name)
if session_public_key and session_public_key == cookie_public_key:
return
pri_key_name = settings.SESSION_RSA_PRIVATE_KEY_NAME
private_key, public_key = gen_key_pair()
private_key, public_key = self.get_key_pair()
public_key_decode = base64.b64encode(public_key.encode()).decode()
request.session[pub_key_name] = public_key_decode
request.session[pri_key_name] = private_key
response.set_cookie(pub_key_name, public_key_decode)
request.session[session_public_key_name] = public_key_decode
request.session[session_private_key_name] = private_key
response.set_cookie(session_public_key_name, public_key_decode)
def get_key_pair(self):
key_pair = cache.get(self.USER_LOGIN_ENCRYPTION_KEY_PAIR)
if key_pair:
return key_pair['private_key'], key_pair['public_key']
private_key, public_key = gen_key_pair()
key_pair = {
'private_key': private_key,
'public_key': public_key
}
cache.set(self.USER_LOGIN_ENCRYPTION_KEY_PAIR, key_pair, None)
return private_key, public_key
@staticmethod
def set_cookie_session_prefix(request, response):

View File

@ -8,10 +8,8 @@
<p>
<b>{% trans 'Username' %}:</b> {{ username }}<br>
<b>{% trans 'Login Date' %}:</b> {{ time }}<br>
<b>{% trans 'Login city' %}:</b> {{ city }}({{ ip }})
<b>{% trans 'Login city' %}:</b> {{ city }}({{ ip }})<br>
</p>
-
<p>
{% trans 'If you suspect that the login behavior is abnormal, please modify the account password in time.' %}
</p>

View File

@ -10,8 +10,7 @@
{% trans 'Click here reset password' %}
</a>
</p>
-
<br>
<p>
{% trans 'This link is valid for 1 hour. After it expires' %}
<a href="{{ forget_password_url }}?email={{ user.email }}">{% trans 'request new one' %}</a>

View File

@ -5,10 +5,9 @@
{% trans 'Your password has just been successfully updated' %}
</p>
<p>
<b>{% trans 'IP' %}:</b> {{ ip_address }} <br/>
<b>{% trans 'Browser' %}:</b> {{ browser }}
<b>{% trans 'IP' %}:</b> {{ ip_address }} <br>
<b>{% trans 'Browser' %}:</b> {{ browser }} <br>
</p>
-
<p>
{% trans 'If the password update was not initiated by you, your account may have security issues' %} <br/>
{% trans 'If you have any questions, you can contact the administrator' %}

View File

@ -5,10 +5,9 @@
{% trans 'Your public key has just been successfully updated' %}
</p>
<p>
<b>{% trans 'IP' %}:</b> {{ ip_address }} <br/>
<b>{% trans 'Browser' %}:</b> {{ browser }}
<b>{% trans 'IP' %}:</b> {{ ip_address }} <br>
<b>{% trans 'Browser' %}:</b> {{ browser }} <br>
</p>
-
<p>
{% trans 'If the public key update was not initiated by you, your account may have security issues' %} <br/>
{% trans 'If you have any questions, you can contact the administrator' %}

View File

@ -1,4 +1,4 @@
from .utils import gen_key_pair, rsa_decrypt, rsa_encrypt
from common.utils import gen_key_pair, rsa_decrypt, rsa_encrypt
def test_rsa_encrypt_decrypt(message='test-password-$%^&*'):

View File

@ -1,6 +1,8 @@
import json
import os
import shutil
import tarfile
import time
from itertools import chain
from django.core.files.storage import default_storage
@ -62,16 +64,17 @@ class SessionPartReplayStorageHandler(object):
# 保存到storage的路径
target_path = os.path.join(default_storage.base_location, local_path)
target_tmp_path = target_path + f'.tmp{int(time.time())}'
target_dir = os.path.dirname(target_path)
if not os.path.isdir(target_dir):
make_dirs(target_dir, exist_ok=True)
ok, err = storage.download(remote_path, target_path)
ok, err = storage.download(remote_path, target_tmp_path)
if not ok:
msg = 'Failed download {} file: {}'.format(part_filename, err)
logger.error(msg)
return None, msg
shutil.move(target_tmp_path, target_path)
url = default_storage.url(local_path)
return local_path, url

View File

@ -47,6 +47,7 @@ class Subscription:
self.ch = pb.ch
self.sub = sub
self.unsubscribed = False
logger.info("Subscribed to channel: ", sub)
def _handle_msg(self, _next, error, complete):
"""
@ -105,10 +106,11 @@ class Subscription:
def unsubscribe(self):
self.unsubscribed = True
logger.info("Unsubscribed from channel: ", self.sub)
try:
self.sub.close()
except Exception as e:
logger.debug('Unsubscribe msg error: {}'.format(e))
logger.warning('Unsubscribe msg error: {}'.format(e))
def retry(self, _next, error, complete):
logger.info('Retry subscribe channel: {}'.format(self.ch))

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:860b4d38beff81667c64da41c026a7dd28c3c93a28ae61fefaa7c26875f35638
size 73906864
oid sha256:c5119fd8911a107a7112422ade326766fe3d9538ac15bca06e3c622191c84e18
size 61086554

View File

@ -9,6 +9,7 @@
"CommandReviewMessage": "The command you entered requires verification before it can be executed. Would you like to initiate a review request?",
"CommandReviewRejectBy": "Command review request has been rejected by %s",
"CommandReviewTimeoutError": "Command review request has timed out",
"CommandWarningDialogMessage": "The command you executed is risky and an alert notification will be sent to the administrator. Do you want to continue?",
"Confirm": "Confirm",
"ConnectError": "Error while fetching data",
"ConnectSuccess": "Connected successfully",
@ -22,6 +23,7 @@
"ErrorMessage": "Error message",
"ExecuteError": "Error while executing",
"ExecuteSuccess": "Executed successfully",
"ExecutionCanceled": "Execution Canceled",
"ExportALL": "Export all data",
"ExportAll": "Export all",
"ExportCurrent": "Export current page",
@ -42,6 +44,9 @@
"OverMaxSessionTimeError": "Since this session has been active for more than %d hours, it has been closed",
"ParseError": "Error while parsing",
"PasteNotAllowed": "You are not allowed to paste, please contact the administrator to open it!",
"PermissionAlreadyExpired": "Permission already expired",
"PermissionExpiredDialogMessage": "Permission has expired, and the session will expire in ten minutes. Please contact the administrator promptly for renewal",
"PermissionExpiredDialogTitle": "Permission expired",
"PermissionsExpiredOn": "Permissions associated with this session expired on %s",
"Properties": "Properties",
"Refresh": "Refresh",
@ -67,8 +72,6 @@
"Version": "Version",
"ViewData": "View data",
"WaitCommandReviewMessage": "The review request has been initiated, please wait for the review results",
"initializingDatasourceFailedMessage": "Connection failed, please check if the database connection configuration is correct",
"Warning": "Warning",
"ExecutionCanceled": "Execution Canceled",
"CommandWarningDialogMessage": "The command you executed is risky and an alert notification will be sent to the administrator. Do you want to continue?"
"initializingDatasourceFailedMessage": "Connection failed, please check if the database connection configuration is correct"
}

View File

@ -44,6 +44,9 @@
"OverMaxSessionTimeError": "このセッションの時間が%d時間を超えたため、閉じられました",
"ParseError": "解析に失敗しました",
"PasteNotAllowed": "貼り付けは許可されていません。管理者に連絡して権限を開いてください!",
"PermissionAlreadyExpired": "権限が期限切れ",
"PermissionExpiredDialogMessage": "権限が期限切れで、セッションは10分後に期限切れになります。管理者に連絡し、期限を延長してください。",
"PermissionExpiredDialogTitle": "権限が期限切れ",
"PermissionsExpiredOn": "このセッションに関連する権限は%sに期限切れです",
"Properties": "プロパティ",
"Refresh": "リフレッシュ",

View File

@ -9,6 +9,7 @@
"CommandReviewMessage": "您输入的命令需要复核后才可以执行, 是否发起复核请求?",
"CommandReviewRejectBy": "命令复核被 %s 拒绝",
"CommandReviewTimeoutError": "命令复核超时",
"CommandWarningDialogMessage": "您执行的命令存在风险,告警通知将发送给管理员。是否继续?",
"Confirm": "确认",
"ConnectError": "连接失败",
"ConnectSuccess": "连接成功",
@ -22,6 +23,7 @@
"ErrorMessage": "错误消息",
"ExecuteError": "执行失败",
"ExecuteSuccess": "执行成功",
"ExecutionCanceled": "执行已取消",
"ExportALL": "导出所有数据",
"ExportAll": "导出全部",
"ExportCurrent": "导出当前页面",
@ -42,6 +44,9 @@
"OverMaxSessionTimeError": "由于此会话时间大于 %d 小时,已经被关闭",
"ParseError": "解析失败",
"PasteNotAllowed": "不允许粘贴,请联系管理员开启权限!",
"PermissionAlreadyExpired": "授权已过期",
"PermissionExpiredDialogMessage": "授权已过期,会话将在十分钟后过期,请及时联系管理员续期",
"PermissionExpiredDialogTitle": "授权已过期",
"PermissionsExpiredOn": "此会话关联的权限已于 %s 过期",
"Properties": "属性",
"Refresh": "刷新",
@ -67,8 +72,6 @@
"Version": "版本",
"ViewData": "查看数据",
"WaitCommandReviewMessage": "复核请求已发起, 请等待复核结果",
"initializingDatasourceFailedMessage": "连接失败,请检查数据库连接配置是否正确",
"Warning": "警告",
"ExecutionCanceled": "执行已取消",
"CommandWarningDialogMessage": "您执行的命令存在风险,告警通知将发送给管理员。是否继续?"
"initializingDatasourceFailedMessage": "连接失败,请检查数据库连接配置是否正确"
}

View File

@ -44,6 +44,9 @@
"OverMaxSessionTimeError": "由於此會話時間大於 %d 小時,已經被關閉",
"ParseError": "解析失敗",
"PasteNotAllowed": "不允許貼上,請聯絡管理員開啟權限!",
"PermissionAlreadyExpired": "授權已過期",
"PermissionExpiredDialogMessage": "授權已過期,對話將在十分鐘後過期,請及時聯繫管理員續期。",
"PermissionExpiredDialogTitle": "授權已過期",
"PermissionsExpiredOn": "此會話關聯的權限已於 %s 過期",
"Properties": "屬性",
"Refresh": "刷新",

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-09-19 16:31+0800\n"
"POT-Creation-Date: 2024-10-17 11:45+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"
@ -64,7 +64,7 @@ msgstr ""
#: accounts/automations/backup_account/handlers.py:219
#: accounts/const/automation.py:110
#: accounts/serializers/automations/change_secret.py:166
#: accounts/serializers/automations/change_secret.py:153
#: assets/serializers/automations/base.py:52 audits/const.py:64
#: audits/models.py:64 audits/signal_handlers/activity_log.py:33
#: common/const/choices.py:65 ops/const.py:74 ops/serializers/celery.py:48
@ -75,7 +75,7 @@ msgstr "Success"
#: accounts/automations/backup_account/handlers.py:221
#: accounts/const/account.py:34 accounts/const/automation.py:109
#: accounts/serializers/automations/change_secret.py:167 audits/const.py:65
#: accounts/serializers/automations/change_secret.py:154 audits/const.py:65
#: audits/signal_handlers/activity_log.py:33 common/const/choices.py:66
#: ops/const.py:76 terminal/const.py:79 xpack/plugins/cloud/const.py:47
msgid "Failed"
@ -118,6 +118,10 @@ msgstr ""
msgid "Success: %s, Failed: %s, Total: %s"
msgstr ""
#: accounts/automations/verify_gateway_account/manager.py:18
msgid ">>> Start executing the task to test gateway account connectivity"
msgstr ""
#: accounts/const/account.py:6
#: accounts/serializers/automations/change_secret.py:34
#: audits/signal_handlers/login_log.py:34 authentication/confirm/password.py:9
@ -343,8 +347,8 @@ msgstr ""
#: accounts/serializers/account/account.py:226
#: accounts/serializers/account/account.py:272
#: accounts/serializers/account/gathered_account.py:10
#: accounts/serializers/automations/change_secret.py:111
#: accounts/serializers/automations/change_secret.py:143
#: accounts/serializers/automations/change_secret.py:98
#: accounts/serializers/automations/change_secret.py:130
#: accounts/templates/accounts/asset_account_change_info.html:7
#: accounts/templates/accounts/change_secret_failed_info.html:11
#: acls/serializers/base.py:123 assets/models/asset/common.py:102
@ -352,10 +356,10 @@ msgstr ""
#: audits/models.py:58 authentication/models/connection_token.py:36
#: perms/models/asset_permission.py:69 terminal/backends/command/models.py:17
#: terminal/models/session/session.py:32 terminal/notifications.py:155
#: terminal/serializers/command.py:17 terminal/serializers/session.py:28
#: terminal/serializers/command.py:17 terminal/serializers/session.py:30
#: terminal/templates/terminal/_msg_command_warning.html:4
#: terminal/templates/terminal/_msg_session_sharing.html:4
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:288
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:289
msgid "Asset"
msgstr ""
@ -373,18 +377,22 @@ msgstr "Switch from"
msgid "Version"
msgstr ""
#: accounts/models/account.py:57 accounts/serializers/account/account.py:228
#: accounts/models/account.py:57
msgid "historical Account"
msgstr ""
#: accounts/models/account.py:58 accounts/serializers/account/account.py:228
#: users/models/user/__init__.py:119
msgid "Source"
msgstr ""
#: accounts/models/account.py:58
#: accounts/models/account.py:59
msgid "Source ID"
msgstr ""
#: accounts/models/account.py:61
#: accounts/serializers/automations/change_secret.py:113
#: accounts/serializers/automations/change_secret.py:144
#: accounts/models/account.py:62
#: accounts/serializers/automations/change_secret.py:100
#: accounts/serializers/automations/change_secret.py:131
#: accounts/templates/accounts/change_secret_failed_info.html:12
#: acls/serializers/base.py:124
#: acls/templates/acls/asset_login_reminder.html:10
@ -400,27 +408,27 @@ msgstr ""
msgid "Account"
msgstr ""
#: accounts/models/account.py:67
#: accounts/models/account.py:68
msgid "Can view asset account secret"
msgstr ""
#: accounts/models/account.py:68
#: accounts/models/account.py:69
msgid "Can view asset history account"
msgstr ""
#: accounts/models/account.py:69
#: accounts/models/account.py:70
msgid "Can view asset history account secret"
msgstr ""
#: accounts/models/account.py:70
#: accounts/models/account.py:71
msgid "Can verify account"
msgstr ""
#: accounts/models/account.py:71
#: accounts/models/account.py:72
msgid "Can push account"
msgstr ""
#: accounts/models/account.py:72
#: accounts/models/account.py:73
msgid "Can remove account"
msgstr ""
@ -485,21 +493,21 @@ msgstr ""
#: accounts/serializers/account/backup.py:48
#: accounts/serializers/automations/base.py:56
#: assets/models/automations/base.py:122
#: assets/serializers/automations/base.py:40 xpack/plugins/cloud/models.py:240
#: xpack/plugins/cloud/serializers/task.py:243
#: assets/serializers/automations/base.py:40 xpack/plugins/cloud/models.py:241
#: xpack/plugins/cloud/serializers/task.py:247
msgid "Trigger mode"
msgstr ""
#: accounts/models/automations/backup_account.py:134 audits/models.py:203
#: terminal/models/session/sharing.py:125 xpack/plugins/cloud/manager.py:158
#: xpack/plugins/cloud/models.py:229
#: xpack/plugins/cloud/models.py:230
msgid "Reason"
msgstr ""
#: accounts/models/automations/backup_account.py:136
#: accounts/serializers/automations/change_secret.py:110
#: accounts/serializers/automations/change_secret.py:145
#: ops/serializers/job.py:74 terminal/serializers/session.py:52
#: accounts/serializers/automations/change_secret.py:97
#: accounts/serializers/automations/change_secret.py:132
#: ops/serializers/job.py:74 terminal/serializers/session.py:54
msgid "Is success"
msgstr "Is success"
@ -589,8 +597,8 @@ msgstr ""
#: terminal/serializers/applet.py:18 terminal/serializers/applet_host.py:148
#: terminal/serializers/virtualapp.py:35 tickets/models/ticket/general.py:284
#: tickets/serializers/super_ticket.py:13
#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:225
#: xpack/plugins/cloud/models.py:292
#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:226
#: xpack/plugins/cloud/models.py:293
msgid "Status"
msgstr ""
@ -716,15 +724,15 @@ msgstr ""
#: perms/models/asset_permission.py:61 rbac/models/role.py:29
#: rbac/serializers/role.py:28 settings/models.py:35 settings/models.py:184
#: settings/serializers/msg.py:89 settings/serializers/terminal.py:9
#: terminal/models/applet/applet.py:34 terminal/models/component/endpoint.py:12
#: terminal/models/component/endpoint.py:109
#: terminal/models/applet/applet.py:34 terminal/models/component/endpoint.py:13
#: terminal/models/component/endpoint.py:111
#: terminal/models/component/storage.py:26 terminal/models/component/task.py:13
#: terminal/models/component/terminal.py:85
#: terminal/models/virtualapp/provider.py:10
#: terminal/models/virtualapp/virtualapp.py:19 tickets/api/ticket.py:87
#: users/forms/profile.py:32 users/models/group.py:13
#: users/models/preference.py:11 users/models/user/__init__.py:57
#: xpack/plugins/cloud/models.py:34 xpack/plugins/cloud/models.py:308
#: xpack/plugins/cloud/models.py:34 xpack/plugins/cloud/models.py:309
#: xpack/plugins/cloud/serializers/task.py:75
msgid "Name"
msgstr ""
@ -753,7 +761,7 @@ msgstr ""
msgid "Push params"
msgstr ""
#: accounts/models/template.py:26 xpack/plugins/cloud/models.py:389
#: accounts/models/template.py:26 xpack/plugins/cloud/models.py:390
msgid "Account template"
msgstr ""
@ -870,7 +878,7 @@ msgstr ""
#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:40
#: terminal/models/component/storage.py:58
#: terminal/models/component/storage.py:152 terminal/serializers/applet.py:29
#: terminal/serializers/session.py:23 terminal/serializers/storage.py:281
#: terminal/serializers/session.py:25 terminal/serializers/storage.py:281
#: terminal/serializers/storage.py:294 tickets/models/comment.py:26
#: tickets/models/flow.py:42 tickets/models/ticket/apply_application.py:16
#: tickets/models/ticket/general.py:276 tickets/serializers/flow.py:25
@ -922,7 +930,7 @@ msgstr ""
#: accounts/serializers/account/account.py:459
#: accounts/serializers/account/base.py:93
#: accounts/serializers/account/template.py:83
#: assets/serializers/asset/common.py:407
#: assets/serializers/asset/common.py:418
msgid "Spec info"
msgstr ""
@ -1048,12 +1056,12 @@ msgstr ""
#: ops/models/job.py:158 ops/models/playbook.py:33 rbac/models/role.py:37
#: settings/models.py:40 terminal/models/applet/applet.py:46
#: terminal/models/applet/applet.py:332 terminal/models/applet/host.py:143
#: terminal/models/component/endpoint.py:25
#: terminal/models/component/endpoint.py:119
#: terminal/models/component/endpoint.py:26
#: terminal/models/component/endpoint.py:121
#: terminal/models/session/session.py:47
#: terminal/models/virtualapp/virtualapp.py:28 tickets/models/comment.py:32
#: tickets/models/ticket/general.py:298 users/models/user/__init__.py:91
#: xpack/plugins/cloud/models.py:41 xpack/plugins/cloud/models.py:122
#: xpack/plugins/cloud/models.py:41 xpack/plugins/cloud/models.py:123
msgid "Comment"
msgstr "Description"
@ -1098,15 +1106,7 @@ msgid ""
"type."
msgstr ""
#: accounts/serializers/automations/change_secret.py:84
msgid "* Please enter the correct password length"
msgstr ""
#: accounts/serializers/automations/change_secret.py:88
msgid "* Password length range 6-30 bits"
msgstr ""
#: accounts/serializers/automations/change_secret.py:117
#: accounts/serializers/automations/change_secret.py:104
#: assets/models/automations/base.py:127
msgid "Automation task execution"
msgstr ""
@ -1328,12 +1328,12 @@ msgid "Notify and warn"
msgstr ""
#: acls/models/base.py:37 assets/models/cmd_filter.py:76
#: terminal/models/component/endpoint.py:112 xpack/plugins/cloud/models.py:314
#: terminal/models/component/endpoint.py:114 xpack/plugins/cloud/models.py:315
msgid "Priority"
msgstr ""
#: acls/models/base.py:38 assets/models/cmd_filter.py:76
#: terminal/models/component/endpoint.py:113 xpack/plugins/cloud/models.py:315
#: terminal/models/component/endpoint.py:115 xpack/plugins/cloud/models.py:316
msgid "1-100, the lower the value will be match first"
msgstr ""
@ -1347,8 +1347,8 @@ msgstr ""
#: authentication/models/connection_token.py:53
#: authentication/models/ssh_key.py:13
#: authentication/templates/authentication/_access_key_modal.html:32
#: perms/models/asset_permission.py:82
#: terminal/models/component/endpoint.py:120
#: perms/models/asset_permission.py:82 terminal/models/component/endpoint.py:27
#: terminal/models/component/endpoint.py:122
#: terminal/models/session/sharing.py:29 terminal/serializers/terminal.py:44
#: tickets/const.py:36
msgid "Active"
@ -1362,7 +1362,7 @@ msgstr ""
#: acls/models/base.py:98 assets/models/automations/base.py:17
#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:148
#: assets/serializers/asset/common.py:406 perms/serializers/permission.py:55
#: assets/serializers/asset/common.py:417 perms/serializers/permission.py:55
#: perms/serializers/user_permission.py:75 rbac/tree.py:35
msgid "Accounts"
msgstr ""
@ -1377,7 +1377,7 @@ msgid "Command"
msgstr ""
#: acls/models/command_acl.py:17 assets/models/cmd_filter.py:59
#: xpack/plugins/cloud/models.py:355
#: xpack/plugins/cloud/models.py:356
msgid "Regex"
msgstr ""
@ -1494,7 +1494,7 @@ msgstr ""
#: authentication/templates/authentication/_msg_oauth_bind.html:12
#: authentication/templates/authentication/_msg_rest_password_success.html:8
#: authentication/templates/authentication/_msg_rest_public_key_success.html:8
#: common/drf/renders/base.py:150 xpack/plugins/cloud/models.py:390
#: common/drf/renders/base.py:150 xpack/plugins/cloud/models.py:391
msgid "IP"
msgstr ""
@ -1631,7 +1631,7 @@ msgid "Unable to connect to port {port} on {address}"
msgstr ""
#: assets/automations/ping_gateway/manager.py:58
#: authentication/middleware.py:93 xpack/plugins/cloud/providers/fc.py:47
#: authentication/middleware.py:94 xpack/plugins/cloud/providers/fc.py:47
msgid "Authentication failed"
msgstr ""
@ -1640,6 +1640,10 @@ msgstr ""
msgid "Connect failed"
msgstr ""
#: assets/automations/ping_gateway/manager.py:118
msgid ">>> Start executing the task to test gateway connectivity"
msgstr ""
#: assets/const/automation.py:6 audits/const.py:6 audits/const.py:47
#: audits/signal_handlers/activity_log.py:62 common/utils/ip/geoip/utils.py:31
#: common/utils/ip/geoip/utils.py:37 common/utils/ip/utils.py:104
@ -1681,7 +1685,7 @@ msgstr ""
#: assets/const/category.py:10 assets/models/asset/host.py:8
#: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:76
#: settings/serializers/feature.py:52 settings/serializers/msg.py:30
#: terminal/models/component/endpoint.py:13 terminal/serializers/applet.py:17
#: terminal/models/component/endpoint.py:14 terminal/serializers/applet.py:17
#: xpack/plugins/cloud/manager.py:83
#: xpack/plugins/cloud/serializers/account_attrs.py:72
msgid "Host"
@ -1927,7 +1931,7 @@ msgstr ""
#: assets/models/asset/common.py:169 assets/models/platform.py:149
#: authentication/backends/passkey/models.py:12
#: authentication/serializers/connect_token_secret.py:118
#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:385
#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:386
msgid "Platform"
msgstr ""
@ -1935,7 +1939,7 @@ msgstr ""
msgid "Zone"
msgstr ""
#: assets/models/asset/common.py:179 assets/serializers/asset/common.py:408
#: assets/models/asset/common.py:179 assets/serializers/asset/common.py:419
#: assets/serializers/asset/host.py:11
msgid "Gathered info"
msgstr ""
@ -1990,7 +1994,7 @@ msgstr ""
#: assets/models/automations/base.py:18 assets/models/cmd_filter.py:32
#: assets/models/node.py:553 perms/models/asset_permission.py:72
#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:386
#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:387
msgid "Node"
msgstr ""
@ -2116,7 +2120,7 @@ msgstr ""
msgid "New node"
msgstr ""
#: assets/models/node.py:467 audits/backends/db.py:82 audits/backends/db.py:83
#: assets/models/node.py:467 audits/backends/db.py:85 audits/backends/db.py:86
msgid "empty"
msgstr ""
@ -2307,7 +2311,7 @@ msgstr ""
#: authentication/serializers/connect_token_secret.py:30
#: authentication/serializers/connect_token_secret.py:75
#: perms/models/asset_permission.py:76 perms/serializers/permission.py:56
#: perms/serializers/user_permission.py:74 xpack/plugins/cloud/models.py:388
#: perms/serializers/user_permission.py:74 xpack/plugins/cloud/models.py:389
#: xpack/plugins/cloud/serializers/task.py:35
msgid "Protocols"
msgstr ""
@ -2318,7 +2322,7 @@ msgid "Node path"
msgstr ""
#: assets/serializers/asset/common.py:168
#: assets/serializers/asset/common.py:409
#: assets/serializers/asset/common.py:420
msgid "Auto info"
msgstr ""
@ -2334,7 +2338,7 @@ msgstr ""
msgid "Protocol is required: {}"
msgstr ""
#: assets/serializers/asset/common.py:336
#: assets/serializers/asset/common.py:347
msgid "Invalid data"
msgstr ""
@ -2353,13 +2357,13 @@ msgstr ""
msgid "Postgresql ssl model help text"
msgstr ""
"Prefer: I don't care about encryption, but I wish to pay the overhead of "
"encryption if the server supports it.Require: I want my data to be "
"encrypted, and I accept the overhead. I trust that the network will make "
"sure I always connect to the server I want.Verify CA: I want my data "
"encrypted, and I accept the overhead. I want to be sure that I connect to a "
"server that I trust.Verify Full: I want my data encrypted, and I accept the "
"overhead. I want to be sure that I connect to a server I trust, and that "
"it's the one I specify."
"encryption if the server supports it.\n"
"Require: I want my data to be encrypted, and I accept the overhead. I trust "
"that the network will make sure I always connect to the server I want.\n"
"Verify CA: I want my data encrypted, and I accept the overhead. I want to be "
"sure that I connect to a server that I trust.\n"
"Verify Full: I want my data encrypted, and I accept the overhead. I want to "
"be sure that I connect to a server I trust, and that it's the one I specify."
#: assets/serializers/asset/gpt.py:20
msgid ""
@ -2668,7 +2672,15 @@ msgstr "Activities"
msgid "The text content is too long. Use Elasticsearch to store operation logs"
msgstr ""
#: audits/backends/db.py:108
#: audits/backends/db.py:78
msgid "labels"
msgstr "Labels"
#: audits/backends/db.py:79
msgid "operate_log_id"
msgstr ""
#: audits/backends/db.py:111
msgid "Tips"
msgstr ""
@ -2758,8 +2770,8 @@ msgstr ""
#: audits/const.py:46 settings/serializers/terminal.py:6
#: terminal/models/applet/host.py:26 terminal/models/component/terminal.py:174
#: terminal/models/virtualapp/provider.py:14 terminal/serializers/session.py:55
#: terminal/serializers/session.py:79
#: terminal/models/virtualapp/provider.py:14 terminal/serializers/session.py:57
#: terminal/serializers/session.py:113
msgid "Terminal"
msgstr ""
@ -3127,6 +3139,7 @@ msgid "OpenID Error"
msgstr ""
#: authentication/backends/oidc/views.py:175
#: authentication/backends/saml2/views.py:282
msgid "Please check if a user with the same username or email already exists"
msgstr ""
@ -3156,6 +3169,10 @@ msgstr ""
msgid "Credential ID"
msgstr ""
#: authentication/backends/saml2/views.py:281
msgid "SAML2 Error"
msgstr ""
#: authentication/confirm/password.py:16
msgid "Authentication failed password incorrect"
msgstr ""
@ -3424,7 +3441,7 @@ msgstr ""
msgid "Clear phone number to disable"
msgstr ""
#: authentication/middleware.py:94 settings/utils/ldap.py:691
#: authentication/middleware.py:95 settings/utils/ldap.py:691
msgid "Authentication failed (before login check failed): {}"
msgstr ""
@ -3447,7 +3464,7 @@ msgid "Please change your password"
msgstr ""
#: authentication/models/access_key.py:22
#: terminal/models/component/endpoint.py:110
#: terminal/models/component/endpoint.py:112
msgid "IP group"
msgstr ""
@ -3469,7 +3486,7 @@ msgstr ""
#: authentication/serializers/connect_token_secret.py:114
#: settings/serializers/msg.py:28 terminal/models/applet/applet.py:43
#: terminal/models/virtualapp/virtualapp.py:24
#: terminal/serializers/session.py:21 terminal/serializers/session.py:48
#: terminal/serializers/session.py:23 terminal/serializers/session.py:50
#: terminal/serializers/storage.py:71
msgid "Protocol"
msgstr ""
@ -3516,6 +3533,7 @@ msgid "Connection token expired at: {}"
msgstr ""
#: authentication/models/connection_token.py:125
#: terminal/serializers/session.py:95
msgid "No user or invalid user"
msgstr ""
@ -3581,7 +3599,7 @@ msgid "Component"
msgstr ""
#: authentication/serializers/connect_token_secret.py:136
#: perms/serializers/user_permission.py:28 xpack/plugins/cloud/models.py:387
#: perms/serializers/user_permission.py:28 xpack/plugins/cloud/models.py:388
msgid "Domain"
msgstr ""
@ -3750,7 +3768,7 @@ msgstr ""
msgid "Your account has remote login behavior, please pay attention"
msgstr ""
#: authentication/templates/authentication/_msg_different_city.html:16
#: authentication/templates/authentication/_msg_different_city.html:14
msgid ""
"If you suspect that the login behavior is abnormal, please modify the "
"account password in time."
@ -3774,13 +3792,13 @@ msgstr ""
msgid "Click here reset password"
msgstr ""
#: authentication/templates/authentication/_msg_reset_password.html:16
#: users/templates/users/_msg_user_created.html:22
#: authentication/templates/authentication/_msg_reset_password.html:15
#: users/templates/users/_msg_user_created.html:20
msgid "This link is valid for 1 hour. After it expires"
msgstr ""
#: authentication/templates/authentication/_msg_reset_password.html:17
#: users/templates/users/_msg_user_created.html:23
#: authentication/templates/authentication/_msg_reset_password.html:16
#: users/templates/users/_msg_user_created.html:21
msgid "request new one"
msgstr ""
@ -3809,14 +3827,14 @@ msgstr ""
msgid "Browser"
msgstr ""
#: authentication/templates/authentication/_msg_rest_password_success.html:13
#: authentication/templates/authentication/_msg_rest_password_success.html:12
msgid ""
"If the password update was not initiated by you, your account may have "
"security issues"
msgstr ""
#: authentication/templates/authentication/_msg_rest_password_success.html:14
#: authentication/templates/authentication/_msg_rest_public_key_success.html:14
#: authentication/templates/authentication/_msg_rest_password_success.html:13
#: authentication/templates/authentication/_msg_rest_public_key_success.html:13
msgid "If you have any questions, you can contact the administrator"
msgstr ""
@ -3824,7 +3842,7 @@ msgstr ""
msgid "Your public key has just been successfully updated"
msgstr ""
#: authentication/templates/authentication/_msg_rest_public_key_success.html:13
#: authentication/templates/authentication/_msg_rest_public_key_success.html:12
msgid ""
"If the public key update was not initiated by you, your account may have "
"security issues"
@ -3897,7 +3915,7 @@ msgid "LAN"
msgstr ""
#: authentication/views/base.py:71
#: perms/templates/perms/_msg_permed_items_expire.html:21
#: perms/templates/perms/_msg_permed_items_expire.html:20
msgid "If you have any question, please contact the administrator"
msgstr ""
@ -4134,7 +4152,8 @@ msgid "Invalid ids for ids, should be a list"
msgstr ""
#: common/db/fields.py:589 common/db/fields.py:594
#: common/serializers/fields.py:144 tickets/serializers/ticket/common.py:58
#: common/serializers/fields.py:144 terminal/serializers/session.py:81
#: tickets/serializers/ticket/common.py:58
#: xpack/plugins/cloud/serializers/account_attrs.py:56
#: xpack/plugins/cloud/serializers/account_attrs.py:79
#: xpack/plugins/cloud/serializers/account_attrs.py:150
@ -4511,7 +4530,7 @@ msgstr ""
#: labels/apps.py:8
msgid "App Labels"
msgstr "Labels"
msgstr "App labels"
#: labels/models.py:15
msgid "Color"
@ -4636,27 +4655,27 @@ msgstr ""
msgid "Currently playbook is being used in a job"
msgstr ""
#: ops/api/playbook.py:113
#: ops/api/playbook.py:123
msgid "Unsupported file content"
msgstr ""
#: ops/api/playbook.py:115 ops/api/playbook.py:161 ops/api/playbook.py:209
#: ops/api/playbook.py:125 ops/api/playbook.py:171 ops/api/playbook.py:219
msgid "Invalid file path"
msgstr ""
#: ops/api/playbook.py:187
#: ops/api/playbook.py:197
msgid "This file can not be rename"
msgstr ""
#: ops/api/playbook.py:206
#: ops/api/playbook.py:216
msgid "File already exists"
msgstr ""
#: ops/api/playbook.py:224
#: ops/api/playbook.py:234
msgid "File key is required"
msgstr ""
#: ops/api/playbook.py:227
#: ops/api/playbook.py:237
msgid "This file can not be delete"
msgstr ""
@ -4840,7 +4859,7 @@ msgid "Date last run"
msgstr ""
#: ops/models/base.py:51 ops/models/job.py:238
#: xpack/plugins/cloud/models.py:223
#: xpack/plugins/cloud/models.py:224
msgid "Result"
msgstr ""
@ -4910,7 +4929,7 @@ msgstr ""
msgid "Material Type"
msgstr ""
#: ops/models/job.py:548
#: ops/models/job.py:558
msgid "Job Execution"
msgstr ""
@ -4962,7 +4981,7 @@ msgstr ""
msgid "Execute after saving"
msgstr "Execute after saving"
#: ops/serializers/job.py:52 terminal/serializers/session.py:47
#: ops/serializers/job.py:52 terminal/serializers/session.py:49
msgid "Duration"
msgstr ""
@ -4970,7 +4989,7 @@ msgstr ""
msgid "Job type"
msgstr ""
#: ops/serializers/job.py:75 terminal/serializers/session.py:56
#: ops/serializers/job.py:75 terminal/serializers/session.py:58
msgid "Is finished"
msgstr "Finished"
@ -7040,11 +7059,11 @@ msgstr ""
msgid "Authentication success: {}"
msgstr ""
#: settings/ws.py:199
#: settings/ws.py:222
msgid "No LDAP user was found"
msgstr ""
#: settings/ws.py:205
#: settings/ws.py:228
msgid "Total {}, success {}, failure {}"
msgstr ""
@ -7516,51 +7535,51 @@ msgstr ""
msgid "Applet host deployment"
msgstr ""
#: terminal/models/component/endpoint.py:15
#: terminal/models/component/endpoint.py:16
msgid "HTTPS port"
msgstr ""
#: terminal/models/component/endpoint.py:16
#: terminal/models/component/endpoint.py:17
msgid "HTTP port"
msgstr ""
#: terminal/models/component/endpoint.py:17
#: terminal/models/component/endpoint.py:18
msgid "SSH port"
msgstr ""
#: terminal/models/component/endpoint.py:18
#: terminal/models/component/endpoint.py:19
msgid "RDP port"
msgstr ""
#: terminal/models/component/endpoint.py:19
#: terminal/models/component/endpoint.py:20
msgid "MySQL port"
msgstr ""
#: terminal/models/component/endpoint.py:20
#: terminal/models/component/endpoint.py:21
msgid "MariaDB port"
msgstr ""
#: terminal/models/component/endpoint.py:21
#: terminal/models/component/endpoint.py:22
msgid "PostgreSQL port"
msgstr ""
#: terminal/models/component/endpoint.py:22
#: terminal/models/component/endpoint.py:23
msgid "Redis port"
msgstr ""
#: terminal/models/component/endpoint.py:23
#: terminal/models/component/endpoint.py:24
msgid "SQLServer port"
msgstr ""
#: terminal/models/component/endpoint.py:30
#: terminal/models/component/endpoint.py:117
#: terminal/serializers/endpoint.py:73 terminal/serializers/storage.py:41
#: terminal/models/component/endpoint.py:32
#: terminal/models/component/endpoint.py:119
#: terminal/serializers/endpoint.py:80 terminal/serializers/storage.py:41
#: terminal/serializers/storage.py:53 terminal/serializers/storage.py:83
#: terminal/serializers/storage.py:93 terminal/serializers/storage.py:101
msgid "Endpoint"
msgstr ""
#: terminal/models/component/endpoint.py:123
#: terminal/models/component/endpoint.py:125
msgid "Endpoint rule"
msgstr ""
@ -7646,11 +7665,11 @@ msgstr ""
msgid "Replay"
msgstr ""
#: terminal/models/session/session.py:48 terminal/serializers/session.py:78
#: terminal/models/session/session.py:48 terminal/serializers/session.py:112
msgid "Command amount"
msgstr ""
#: terminal/models/session/session.py:49 terminal/serializers/session.py:30
#: terminal/models/session/session.py:49 terminal/serializers/session.py:32
msgid "Error reason"
msgstr ""
@ -7947,49 +7966,53 @@ msgid ""
"does not allow modification of the host)"
msgstr ""
#: terminal/serializers/endpoint.py:64
#: terminal/serializers/endpoint.py:71
msgid ""
"The assets within this IP range, the following endpoint will be used for the "
"connection"
msgstr ""
#: terminal/serializers/endpoint.py:65
#: terminal/serializers/endpoint.py:72
msgid ""
"If asset IP addresses under different endpoints conflict, use asset labels"
msgstr ""
#: terminal/serializers/endpoint.py:69
#: terminal/serializers/endpoint.py:76
msgid "Asset IP"
msgstr ""
#: terminal/serializers/session.py:25 terminal/serializers/session.py:53
#: terminal/serializers/session.py:27 terminal/serializers/session.py:55
msgid "Can replay"
msgstr ""
#: terminal/serializers/session.py:26 terminal/serializers/session.py:54
#: terminal/serializers/session.py:28 terminal/serializers/session.py:56
msgid "Can join"
msgstr ""
#: terminal/serializers/session.py:27 terminal/serializers/session.py:57
#: terminal/serializers/session.py:29 terminal/serializers/session.py:59
msgid "Can terminate"
msgstr ""
#: terminal/serializers/session.py:49
#: terminal/serializers/session.py:51
msgid "User ID"
msgstr ""
#: terminal/serializers/session.py:50
#: terminal/serializers/session.py:52
msgid "Asset ID"
msgstr ""
#: terminal/serializers/session.py:51
#: terminal/serializers/session.py:53
msgid "Login from display"
msgstr ""
#: terminal/serializers/session.py:58
#: terminal/serializers/session.py:60
msgid "Terminal display"
msgstr ""
#: terminal/serializers/session.py:103
msgid "No asset or invalid asset"
msgstr ""
#: terminal/serializers/storage.py:23
msgid "Endpoint invalid: remove path `{}`"
msgstr ""
@ -8008,7 +8031,7 @@ msgid "Access key secret"
msgstr ""
#: terminal/serializers/storage.py:68 xpack/plugins/cloud/manager.py:100
#: xpack/plugins/cloud/models.py:285
#: xpack/plugins/cloud/models.py:286
msgid "Region"
msgstr ""
@ -8850,7 +8873,7 @@ msgid "Force enabled"
msgstr ""
#: users/notifications.py:55
#: users/templates/users/_msg_password_expire_reminder.html:17
#: users/templates/users/_msg_password_expire_reminder.html:16
#: users/templates/users/reset_password.html:5
#: users/templates/users/reset_password.html:6
msgid "Reset password"
@ -9095,11 +9118,11 @@ msgid ""
"administrator."
msgstr ""
#: users/signal_handlers.py:196
#: users/signal_handlers.py:197
msgid "Clean up expired user sessions"
msgstr ""
#: users/signal_handlers.py:198
#: users/signal_handlers.py:199
msgid ""
"After logging in via the web, a user session record is created. At 2 a.m. "
"every day, \n"
@ -9195,7 +9218,7 @@ msgstr ""
msgid "Click here update password"
msgstr ""
#: users/templates/users/_msg_password_expire_reminder.html:16
#: users/templates/users/_msg_password_expire_reminder.html:15
msgid "If your password has expired, please click the link below to"
msgstr ""
@ -9529,7 +9552,7 @@ msgstr ""
msgid "Public IP"
msgstr ""
#: xpack/plugins/cloud/const.py:42 xpack/plugins/cloud/models.py:359
#: xpack/plugins/cloud/const.py:42 xpack/plugins/cloud/models.py:360
msgid "Instance name"
msgstr ""
@ -9694,133 +9717,133 @@ msgstr ""
msgid "IP network segment group"
msgstr ""
#: xpack/plugins/cloud/models.py:115
#: xpack/plugins/cloud/models.py:116
#: xpack/plugins/cloud/serializers/task.py:161
msgid "Sync IP type"
msgid "Preferred IP type"
msgstr ""
#: xpack/plugins/cloud/models.py:118
#: xpack/plugins/cloud/models.py:119
msgid "Always update"
msgstr ""
#: xpack/plugins/cloud/models.py:120
#: xpack/plugins/cloud/models.py:121
msgid "Fully synchronous"
msgstr ""
#: xpack/plugins/cloud/models.py:125
#: xpack/plugins/cloud/models.py:126
msgid "Date last sync"
msgstr ""
#: xpack/plugins/cloud/models.py:128 xpack/plugins/cloud/models.py:377
#: xpack/plugins/cloud/models.py:403
#: xpack/plugins/cloud/models.py:129 xpack/plugins/cloud/models.py:378
#: xpack/plugins/cloud/models.py:404
msgid "Strategy"
msgstr ""
#: xpack/plugins/cloud/models.py:133 xpack/plugins/cloud/models.py:221
#: xpack/plugins/cloud/models.py:134 xpack/plugins/cloud/models.py:222
msgid "Sync instance task"
msgstr ""
#: xpack/plugins/cloud/models.py:232 xpack/plugins/cloud/models.py:295
#: xpack/plugins/cloud/models.py:233 xpack/plugins/cloud/models.py:296
msgid "Date sync"
msgstr ""
#: xpack/plugins/cloud/models.py:236
#: xpack/plugins/cloud/models.py:237
msgid "Sync instance snapshot"
msgstr ""
#: xpack/plugins/cloud/models.py:244
#: xpack/plugins/cloud/models.py:245
msgid "Sync instance task execution"
msgstr ""
#: xpack/plugins/cloud/models.py:275
#: xpack/plugins/cloud/models.py:276
msgid "Sync task"
msgstr ""
#: xpack/plugins/cloud/models.py:279
#: xpack/plugins/cloud/models.py:280
msgid "Sync instance task history"
msgstr ""
#: xpack/plugins/cloud/models.py:282
#: xpack/plugins/cloud/models.py:283
msgid "Instance"
msgstr ""
#: xpack/plugins/cloud/models.py:299
#: xpack/plugins/cloud/models.py:300
msgid "Sync instance detail"
msgstr ""
#: xpack/plugins/cloud/models.py:311 xpack/plugins/cloud/serializers/task.py:77
#: xpack/plugins/cloud/models.py:312 xpack/plugins/cloud/serializers/task.py:77
msgid "Rule relation"
msgstr ""
#: xpack/plugins/cloud/models.py:321
#: xpack/plugins/cloud/models.py:322
msgid "Task strategy"
msgstr ""
#: xpack/plugins/cloud/models.py:348
#: xpack/plugins/cloud/models.py:349
msgid "Equal"
msgstr ""
#: xpack/plugins/cloud/models.py:349
#: xpack/plugins/cloud/models.py:350
msgid "Not Equal"
msgstr ""
#: xpack/plugins/cloud/models.py:350
#: xpack/plugins/cloud/models.py:351
msgid "In"
msgstr ""
#: xpack/plugins/cloud/models.py:351
#: xpack/plugins/cloud/models.py:352
msgid "Contains"
msgstr ""
#: xpack/plugins/cloud/models.py:352
#: xpack/plugins/cloud/models.py:353
msgid "Exclude"
msgstr ""
#: xpack/plugins/cloud/models.py:353
#: xpack/plugins/cloud/models.py:354
msgid "Startswith"
msgstr ""
#: xpack/plugins/cloud/models.py:354
#: xpack/plugins/cloud/models.py:355
msgid "Endswith"
msgstr ""
#: xpack/plugins/cloud/models.py:360
#: xpack/plugins/cloud/models.py:361
msgid "Instance platform"
msgstr ""
#: xpack/plugins/cloud/models.py:361
#: xpack/plugins/cloud/models.py:362
msgid "Instance address"
msgstr ""
#: xpack/plugins/cloud/models.py:368
#: xpack/plugins/cloud/models.py:369
msgid "Rule attr"
msgstr ""
#: xpack/plugins/cloud/models.py:372
#: xpack/plugins/cloud/models.py:373
msgid "Rule match"
msgstr ""
#: xpack/plugins/cloud/models.py:374
#: xpack/plugins/cloud/models.py:375
msgid "Rule value"
msgstr ""
#: xpack/plugins/cloud/models.py:381 xpack/plugins/cloud/serializers/task.py:80
#: xpack/plugins/cloud/models.py:382 xpack/plugins/cloud/serializers/task.py:80
msgid "Strategy rule"
msgstr ""
#: xpack/plugins/cloud/models.py:391
#: xpack/plugins/cloud/models.py:392
msgid "Name strategy"
msgstr ""
#: xpack/plugins/cloud/models.py:398
#: xpack/plugins/cloud/models.py:399
msgid "Action attr"
msgstr ""
#: xpack/plugins/cloud/models.py:400
#: xpack/plugins/cloud/models.py:401
msgid "Action value"
msgstr ""
#: xpack/plugins/cloud/models.py:407 xpack/plugins/cloud/serializers/task.py:83
#: xpack/plugins/cloud/models.py:408 xpack/plugins/cloud/serializers/task.py:83
msgid "Strategy action"
msgstr ""

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-09-19 17:03+0800\n"
"POT-Creation-Date: 2024-10-17 11:45+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"
@ -63,7 +63,7 @@ msgstr "完成"
#: accounts/automations/backup_account/handlers.py:219
#: accounts/const/automation.py:110
#: accounts/serializers/automations/change_secret.py:166
#: accounts/serializers/automations/change_secret.py:153
#: assets/serializers/automations/base.py:52 audits/const.py:64
#: audits/models.py:64 audits/signal_handlers/activity_log.py:33
#: common/const/choices.py:65 ops/const.py:74 ops/serializers/celery.py:48
@ -74,7 +74,7 @@ msgstr "成功"
#: accounts/automations/backup_account/handlers.py:221
#: accounts/const/account.py:34 accounts/const/automation.py:109
#: accounts/serializers/automations/change_secret.py:167 audits/const.py:65
#: accounts/serializers/automations/change_secret.py:154 audits/const.py:65
#: audits/signal_handlers/activity_log.py:33 common/const/choices.py:66
#: ops/const.py:76 terminal/const.py:79 xpack/plugins/cloud/const.py:47
msgid "Failed"
@ -117,6 +117,10 @@ msgstr "未找到待处理帐户"
msgid "Success: %s, Failed: %s, Total: %s"
msgstr "成功: %s, 失败: %s, 总数: %s"
#: accounts/automations/verify_gateway_account/manager.py:18
msgid ">>> Start executing the task to test gateway account connectivity"
msgstr ">>> 开始执行测试网关账号可连接性任务"
#: accounts/const/account.py:6
#: accounts/serializers/automations/change_secret.py:34
#: audits/signal_handlers/login_log.py:34 authentication/confirm/password.py:9
@ -342,8 +346,8 @@ msgstr "用户 %s 查看/导出 了密码"
#: accounts/serializers/account/account.py:226
#: accounts/serializers/account/account.py:272
#: accounts/serializers/account/gathered_account.py:10
#: accounts/serializers/automations/change_secret.py:111
#: accounts/serializers/automations/change_secret.py:143
#: accounts/serializers/automations/change_secret.py:98
#: accounts/serializers/automations/change_secret.py:130
#: accounts/templates/accounts/asset_account_change_info.html:7
#: accounts/templates/accounts/change_secret_failed_info.html:11
#: acls/serializers/base.py:123 assets/models/asset/common.py:102
@ -351,10 +355,10 @@ msgstr "用户 %s 查看/导出 了密码"
#: audits/models.py:58 authentication/models/connection_token.py:36
#: perms/models/asset_permission.py:69 terminal/backends/command/models.py:17
#: terminal/models/session/session.py:32 terminal/notifications.py:155
#: terminal/serializers/command.py:17 terminal/serializers/session.py:28
#: terminal/serializers/command.py:17 terminal/serializers/session.py:30
#: terminal/templates/terminal/_msg_command_warning.html:4
#: terminal/templates/terminal/_msg_session_sharing.html:4
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:288
#: tickets/models/ticket/apply_asset.py:16 xpack/plugins/cloud/models.py:289
msgid "Asset"
msgstr "资产"
@ -372,18 +376,22 @@ msgstr "切换自"
msgid "Version"
msgstr "版本"
#: accounts/models/account.py:57 accounts/serializers/account/account.py:228
#: accounts/models/account.py:57
msgid "historical Account"
msgstr "账号历史"
#: accounts/models/account.py:58 accounts/serializers/account/account.py:228
#: users/models/user/__init__.py:119
msgid "Source"
msgstr "来源"
#: accounts/models/account.py:58
#: accounts/models/account.py:59
msgid "Source ID"
msgstr "来源 ID"
#: accounts/models/account.py:61
#: accounts/serializers/automations/change_secret.py:113
#: accounts/serializers/automations/change_secret.py:144
#: accounts/models/account.py:62
#: accounts/serializers/automations/change_secret.py:100
#: accounts/serializers/automations/change_secret.py:131
#: accounts/templates/accounts/change_secret_failed_info.html:12
#: acls/serializers/base.py:124
#: acls/templates/acls/asset_login_reminder.html:10
@ -399,27 +407,27 @@ msgstr "来源 ID"
msgid "Account"
msgstr "账号"
#: accounts/models/account.py:67
#: accounts/models/account.py:68
msgid "Can view asset account secret"
msgstr "可以查看资产账号密码"
#: accounts/models/account.py:68
#: accounts/models/account.py:69
msgid "Can view asset history account"
msgstr "可以查看资产历史账号"
#: accounts/models/account.py:69
#: accounts/models/account.py:70
msgid "Can view asset history account secret"
msgstr "可以查看资产历史账号密码"
#: accounts/models/account.py:70
#: accounts/models/account.py:71
msgid "Can verify account"
msgstr "可以验证账号"
#: accounts/models/account.py:71
#: accounts/models/account.py:72
msgid "Can push account"
msgstr "可以推送账号"
#: accounts/models/account.py:72
#: accounts/models/account.py:73
msgid "Can remove account"
msgstr "可以移除账号"
@ -484,21 +492,21 @@ msgstr "账号备份快照"
#: accounts/serializers/account/backup.py:48
#: accounts/serializers/automations/base.py:56
#: assets/models/automations/base.py:122
#: assets/serializers/automations/base.py:40 xpack/plugins/cloud/models.py:240
#: xpack/plugins/cloud/serializers/task.py:243
#: assets/serializers/automations/base.py:40 xpack/plugins/cloud/models.py:241
#: xpack/plugins/cloud/serializers/task.py:247
msgid "Trigger mode"
msgstr "触发模式"
#: accounts/models/automations/backup_account.py:134 audits/models.py:203
#: terminal/models/session/sharing.py:125 xpack/plugins/cloud/manager.py:158
#: xpack/plugins/cloud/models.py:229
#: xpack/plugins/cloud/models.py:230
msgid "Reason"
msgstr "原因"
#: accounts/models/automations/backup_account.py:136
#: accounts/serializers/automations/change_secret.py:110
#: accounts/serializers/automations/change_secret.py:145
#: ops/serializers/job.py:74 terminal/serializers/session.py:52
#: accounts/serializers/automations/change_secret.py:97
#: accounts/serializers/automations/change_secret.py:132
#: ops/serializers/job.py:74 terminal/serializers/session.py:54
msgid "Is success"
msgstr "是否成功"
@ -588,8 +596,8 @@ msgstr "结束日期"
#: terminal/serializers/applet.py:18 terminal/serializers/applet_host.py:148
#: terminal/serializers/virtualapp.py:35 tickets/models/ticket/general.py:284
#: tickets/serializers/super_ticket.py:13
#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:225
#: xpack/plugins/cloud/models.py:292
#: tickets/serializers/ticket/ticket.py:20 xpack/plugins/cloud/models.py:226
#: xpack/plugins/cloud/models.py:293
msgid "Status"
msgstr "状态"
@ -715,15 +723,15 @@ msgstr "密码规则"
#: perms/models/asset_permission.py:61 rbac/models/role.py:29
#: rbac/serializers/role.py:28 settings/models.py:35 settings/models.py:184
#: settings/serializers/msg.py:89 settings/serializers/terminal.py:9
#: terminal/models/applet/applet.py:34 terminal/models/component/endpoint.py:12
#: terminal/models/component/endpoint.py:109
#: terminal/models/applet/applet.py:34 terminal/models/component/endpoint.py:13
#: terminal/models/component/endpoint.py:111
#: terminal/models/component/storage.py:26 terminal/models/component/task.py:13
#: terminal/models/component/terminal.py:85
#: terminal/models/virtualapp/provider.py:10
#: terminal/models/virtualapp/virtualapp.py:19 tickets/api/ticket.py:87
#: users/forms/profile.py:32 users/models/group.py:13
#: users/models/preference.py:11 users/models/user/__init__.py:57
#: xpack/plugins/cloud/models.py:34 xpack/plugins/cloud/models.py:308
#: xpack/plugins/cloud/models.py:34 xpack/plugins/cloud/models.py:309
#: xpack/plugins/cloud/serializers/task.py:75
msgid "Name"
msgstr "名称"
@ -752,7 +760,7 @@ msgstr "平台"
msgid "Push params"
msgstr "账号推送参数"
#: accounts/models/template.py:26 xpack/plugins/cloud/models.py:389
#: accounts/models/template.py:26 xpack/plugins/cloud/models.py:390
msgid "Account template"
msgstr "账号模板"
@ -878,7 +886,7 @@ msgstr "类别"
#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:40
#: terminal/models/component/storage.py:58
#: terminal/models/component/storage.py:152 terminal/serializers/applet.py:29
#: terminal/serializers/session.py:23 terminal/serializers/storage.py:281
#: terminal/serializers/session.py:25 terminal/serializers/storage.py:281
#: terminal/serializers/storage.py:294 tickets/models/comment.py:26
#: tickets/models/flow.py:42 tickets/models/ticket/apply_application.py:16
#: tickets/models/ticket/general.py:276 tickets/serializers/flow.py:25
@ -930,7 +938,7 @@ msgstr "账号已存在"
#: accounts/serializers/account/account.py:459
#: accounts/serializers/account/base.py:93
#: accounts/serializers/account/template.py:83
#: assets/serializers/asset/common.py:407
#: assets/serializers/asset/common.py:418
msgid "Spec info"
msgstr "特殊信息"
@ -1064,12 +1072,12 @@ msgstr "关联平台,可配置推送参数,如果不关联,将使用默认
#: ops/models/job.py:158 ops/models/playbook.py:33 rbac/models/role.py:37
#: settings/models.py:40 terminal/models/applet/applet.py:46
#: terminal/models/applet/applet.py:332 terminal/models/applet/host.py:143
#: terminal/models/component/endpoint.py:25
#: terminal/models/component/endpoint.py:119
#: terminal/models/component/endpoint.py:26
#: terminal/models/component/endpoint.py:121
#: terminal/models/session/session.py:47
#: terminal/models/virtualapp/virtualapp.py:28 tickets/models/comment.py:32
#: tickets/models/ticket/general.py:298 users/models/user/__init__.py:91
#: xpack/plugins/cloud/models.py:41 xpack/plugins/cloud/models.py:122
#: xpack/plugins/cloud/models.py:41 xpack/plugins/cloud/models.py:123
msgid "Comment"
msgstr "备注"
@ -1117,15 +1125,7 @@ msgid ""
"type."
msgstr "参数设置,目前只对 AIX LINUX UNIX 类型的资产有效。"
#: accounts/serializers/automations/change_secret.py:84
msgid "* Please enter the correct password length"
msgstr "* 请输入正确的密码长度"
#: accounts/serializers/automations/change_secret.py:88
msgid "* Password length range 6-30 bits"
msgstr "* 密码长度范围 6-30 位"
#: accounts/serializers/automations/change_secret.py:117
#: accounts/serializers/automations/change_secret.py:104
#: assets/models/automations/base.py:127
msgid "Automation task execution"
msgstr "自动化任务执行历史"
@ -1354,12 +1354,12 @@ msgid "Notify and warn"
msgstr "提示并告警"
#: acls/models/base.py:37 assets/models/cmd_filter.py:76
#: terminal/models/component/endpoint.py:112 xpack/plugins/cloud/models.py:314
#: terminal/models/component/endpoint.py:114 xpack/plugins/cloud/models.py:315
msgid "Priority"
msgstr "优先级"
#: acls/models/base.py:38 assets/models/cmd_filter.py:76
#: terminal/models/component/endpoint.py:113 xpack/plugins/cloud/models.py:315
#: terminal/models/component/endpoint.py:115 xpack/plugins/cloud/models.py:316
msgid "1-100, the lower the value will be match first"
msgstr "优先级可选范围为 1-100 (数值越小越优先)"
@ -1373,8 +1373,8 @@ msgstr "审批人"
#: authentication/models/connection_token.py:53
#: authentication/models/ssh_key.py:13
#: authentication/templates/authentication/_access_key_modal.html:32
#: perms/models/asset_permission.py:82
#: terminal/models/component/endpoint.py:120
#: perms/models/asset_permission.py:82 terminal/models/component/endpoint.py:27
#: terminal/models/component/endpoint.py:122
#: terminal/models/session/sharing.py:29 terminal/serializers/terminal.py:44
#: tickets/const.py:36
msgid "Active"
@ -1388,7 +1388,7 @@ msgstr "用户"
#: acls/models/base.py:98 assets/models/automations/base.py:17
#: assets/models/cmd_filter.py:38 assets/serializers/asset/common.py:148
#: assets/serializers/asset/common.py:406 perms/serializers/permission.py:55
#: assets/serializers/asset/common.py:417 perms/serializers/permission.py:55
#: perms/serializers/user_permission.py:75 rbac/tree.py:35
msgid "Accounts"
msgstr "账号"
@ -1403,7 +1403,7 @@ msgid "Command"
msgstr "命令"
#: acls/models/command_acl.py:17 assets/models/cmd_filter.py:59
#: xpack/plugins/cloud/models.py:355
#: xpack/plugins/cloud/models.py:356
msgid "Regex"
msgstr "正则表达式"
@ -1524,7 +1524,7 @@ msgstr ""
#: authentication/templates/authentication/_msg_oauth_bind.html:12
#: authentication/templates/authentication/_msg_rest_password_success.html:8
#: authentication/templates/authentication/_msg_rest_public_key_success.html:8
#: common/drf/renders/base.py:150 xpack/plugins/cloud/models.py:390
#: common/drf/renders/base.py:150 xpack/plugins/cloud/models.py:391
msgid "IP"
msgstr "IP"
@ -1663,7 +1663,7 @@ msgid "Unable to connect to port {port} on {address}"
msgstr "无法连接到 {port} 上的端口 {address}"
#: assets/automations/ping_gateway/manager.py:58
#: authentication/middleware.py:93 xpack/plugins/cloud/providers/fc.py:47
#: authentication/middleware.py:94 xpack/plugins/cloud/providers/fc.py:47
msgid "Authentication failed"
msgstr "认证失败"
@ -1672,6 +1672,10 @@ msgstr "认证失败"
msgid "Connect failed"
msgstr "连接失败"
#: assets/automations/ping_gateway/manager.py:118
msgid ">>> Start executing the task to test gateway connectivity"
msgstr ">>> 开始执行测试网关可连接性任务"
#: assets/const/automation.py:6 audits/const.py:6 audits/const.py:47
#: audits/signal_handlers/activity_log.py:62 common/utils/ip/geoip/utils.py:31
#: common/utils/ip/geoip/utils.py:37 common/utils/ip/utils.py:104
@ -1713,7 +1717,7 @@ msgstr "脚本"
#: assets/const/category.py:10 assets/models/asset/host.py:8
#: settings/serializers/auth/radius.py:17 settings/serializers/auth/sms.py:76
#: settings/serializers/feature.py:52 settings/serializers/msg.py:30
#: terminal/models/component/endpoint.py:13 terminal/serializers/applet.py:17
#: terminal/models/component/endpoint.py:14 terminal/serializers/applet.py:17
#: xpack/plugins/cloud/manager.py:83
#: xpack/plugins/cloud/serializers/account_attrs.py:72
msgid "Host"
@ -1964,7 +1968,7 @@ msgstr "地址"
#: assets/models/asset/common.py:169 assets/models/platform.py:149
#: authentication/backends/passkey/models.py:12
#: authentication/serializers/connect_token_secret.py:118
#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:385
#: perms/serializers/user_permission.py:25 xpack/plugins/cloud/models.py:386
msgid "Platform"
msgstr "平台"
@ -1972,7 +1976,7 @@ msgstr "平台"
msgid "Zone"
msgstr "网域"
#: assets/models/asset/common.py:179 assets/serializers/asset/common.py:408
#: assets/models/asset/common.py:179 assets/serializers/asset/common.py:419
#: assets/serializers/asset/host.py:11
msgid "Gathered info"
msgstr "收集资产硬件信息"
@ -2027,7 +2031,7 @@ msgstr "代理"
#: assets/models/automations/base.py:18 assets/models/cmd_filter.py:32
#: assets/models/node.py:553 perms/models/asset_permission.py:72
#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:386
#: tickets/models/ticket/apply_asset.py:14 xpack/plugins/cloud/models.py:387
msgid "Node"
msgstr "节点"
@ -2155,7 +2159,7 @@ msgstr "我的资产"
msgid "New node"
msgstr "新节点"
#: assets/models/node.py:467 audits/backends/db.py:82 audits/backends/db.py:83
#: assets/models/node.py:467 audits/backends/db.py:85 audits/backends/db.py:86
msgid "empty"
msgstr "空"
@ -2348,7 +2352,7 @@ msgstr "节点路径,格式为 [\"/组织/节点名\"], 如果节点不存在
#: authentication/serializers/connect_token_secret.py:30
#: authentication/serializers/connect_token_secret.py:75
#: perms/models/asset_permission.py:76 perms/serializers/permission.py:56
#: perms/serializers/user_permission.py:74 xpack/plugins/cloud/models.py:388
#: perms/serializers/user_permission.py:74 xpack/plugins/cloud/models.py:389
#: xpack/plugins/cloud/serializers/task.py:35
msgid "Protocols"
msgstr "协议组"
@ -2359,7 +2363,7 @@ msgid "Node path"
msgstr "节点路径"
#: assets/serializers/asset/common.py:168
#: assets/serializers/asset/common.py:409
#: assets/serializers/asset/common.py:420
msgid "Auto info"
msgstr "自动化信息"
@ -2375,7 +2379,7 @@ msgstr "端口超出范围 (0-65535)"
msgid "Protocol is required: {}"
msgstr "协议是必填的: {}"
#: assets/serializers/asset/common.py:336
#: assets/serializers/asset/common.py:347
msgid "Invalid data"
msgstr "无效的数据"
@ -2392,9 +2396,11 @@ msgstr ""
#: assets/serializers/asset/database.py:24
msgid "Postgresql ssl model help text"
msgstr ""
"Prefer我不关心加密但如果服务器支持加密我愿意支付加密的开销。Require我"
"希望我的数据被加密,我接受开销。我相信网络将确保我始终连接到我想要的服务器。"
"Verify CA我希望我的数据被加密我接受开销。我想确保我连接到我信任的服务器。"
"Prefer我不关心加密但如果服务器支持加密我愿意支付加密的开销。\n"
"Require我希望我的数据被加密我接受开销。我相信网络将确保我始终连接到我想要"
"的服务器。\n"
"Verify CA我希望我的数据被加密我接受开销。我想确保我连接到我信任的服务"
"器。\n"
"Verify Full我希望我的数据被加密我接受开销。我想确保我连接到我信任的服务"
"器,并且它是我指定的服务器。"
@ -2712,7 +2718,15 @@ msgstr "日志审计"
msgid "The text content is too long. Use Elasticsearch to store operation logs"
msgstr "文字内容太长。请使用 Elasticsearch 存储操作日志"
#: audits/backends/db.py:108
#: audits/backends/db.py:78
msgid "labels"
msgstr "标签"
#: audits/backends/db.py:79
msgid "operate_log_id"
msgstr "操作日志ID"
#: audits/backends/db.py:111
msgid "Tips"
msgstr "提示"
@ -2802,8 +2816,8 @@ msgstr "结束"
#: audits/const.py:46 settings/serializers/terminal.py:6
#: terminal/models/applet/host.py:26 terminal/models/component/terminal.py:174
#: terminal/models/virtualapp/provider.py:14 terminal/serializers/session.py:55
#: terminal/serializers/session.py:79
#: terminal/models/virtualapp/provider.py:14 terminal/serializers/session.py:57
#: terminal/serializers/session.py:113
msgid "Terminal"
msgstr "终端"
@ -3480,7 +3494,7 @@ msgstr "设置手机号码启用"
msgid "Clear phone number to disable"
msgstr "清空手机号码禁用"
#: authentication/middleware.py:94 settings/utils/ldap.py:691
#: authentication/middleware.py:95 settings/utils/ldap.py:691
msgid "Authentication failed (before login check failed): {}"
msgstr "认证失败 (登录前检查失败): {}"
@ -3503,7 +3517,7 @@ msgid "Please change your password"
msgstr "请修改密码"
#: authentication/models/access_key.py:22
#: terminal/models/component/endpoint.py:110
#: terminal/models/component/endpoint.py:112
msgid "IP group"
msgstr "IPグループ"
@ -3525,7 +3539,7 @@ msgstr "自定义密码"
#: authentication/serializers/connect_token_secret.py:114
#: settings/serializers/msg.py:28 terminal/models/applet/applet.py:43
#: terminal/models/virtualapp/virtualapp.py:24
#: terminal/serializers/session.py:21 terminal/serializers/session.py:48
#: terminal/serializers/session.py:23 terminal/serializers/session.py:50
#: terminal/serializers/storage.py:71
msgid "Protocol"
msgstr "协议"
@ -3572,6 +3586,7 @@ msgid "Connection token expired at: {}"
msgstr "连接令牌过期: {}"
#: authentication/models/connection_token.py:125
#: terminal/serializers/session.py:95
msgid "No user or invalid user"
msgstr "没有用户或用户失效"
@ -3637,7 +3652,7 @@ msgid "Component"
msgstr "组件"
#: authentication/serializers/connect_token_secret.py:136
#: perms/serializers/user_permission.py:28 xpack/plugins/cloud/models.py:387
#: perms/serializers/user_permission.py:28 xpack/plugins/cloud/models.py:388
msgid "Domain"
msgstr "网域"
@ -3806,7 +3821,7 @@ msgstr "你好"
msgid "Your account has remote login behavior, please pay attention"
msgstr "你的账号存在异地登录行为,请关注。"
#: authentication/templates/authentication/_msg_different_city.html:16
#: authentication/templates/authentication/_msg_different_city.html:14
msgid ""
"If you suspect that the login behavior is abnormal, please modify the "
"account password in time."
@ -3830,13 +3845,13 @@ msgstr "请点击下面链接重置密码, 如果不是您申请的,请关
msgid "Click here reset password"
msgstr "点击这里重置密码"
#: authentication/templates/authentication/_msg_reset_password.html:16
#: users/templates/users/_msg_user_created.html:22
#: authentication/templates/authentication/_msg_reset_password.html:15
#: users/templates/users/_msg_user_created.html:20
msgid "This link is valid for 1 hour. After it expires"
msgstr "这个链接有效期1小时, 超过时间您可以"
#: authentication/templates/authentication/_msg_reset_password.html:17
#: users/templates/users/_msg_user_created.html:23
#: authentication/templates/authentication/_msg_reset_password.html:16
#: users/templates/users/_msg_user_created.html:21
msgid "request new one"
msgstr "重新申请"
@ -3865,14 +3880,14 @@ msgstr "你的密码刚刚成功更新"
msgid "Browser"
msgstr "浏览器"
#: authentication/templates/authentication/_msg_rest_password_success.html:13
#: authentication/templates/authentication/_msg_rest_password_success.html:12
msgid ""
"If the password update was not initiated by you, your account may have "
"security issues"
msgstr "如果这次密码更新不是由你发起的,那么你的账号可能存在安全问题"
#: authentication/templates/authentication/_msg_rest_password_success.html:14
#: authentication/templates/authentication/_msg_rest_public_key_success.html:14
#: authentication/templates/authentication/_msg_rest_password_success.html:13
#: authentication/templates/authentication/_msg_rest_public_key_success.html:13
msgid "If you have any questions, you can contact the administrator"
msgstr "如果有疑问或需求,请联系系统管理员"
@ -3880,7 +3895,7 @@ msgstr "如果有疑问或需求,请联系系统管理员"
msgid "Your public key has just been successfully updated"
msgstr "你的公钥刚刚成功更新"
#: authentication/templates/authentication/_msg_rest_public_key_success.html:13
#: authentication/templates/authentication/_msg_rest_public_key_success.html:12
msgid ""
"If the public key update was not initiated by you, your account may have "
"security issues"
@ -3953,7 +3968,7 @@ msgid "LAN"
msgstr "局域网"
#: authentication/views/base.py:71
#: perms/templates/perms/_msg_permed_items_expire.html:21
#: perms/templates/perms/_msg_permed_items_expire.html:20
msgid "If you have any question, please contact the administrator"
msgstr "如果有疑问或需求,请联系系统管理员"
@ -4196,7 +4211,8 @@ msgid "Invalid ids for ids, should be a list"
msgstr "无效的ID应为列表"
#: common/db/fields.py:589 common/db/fields.py:594
#: common/serializers/fields.py:144 tickets/serializers/ticket/common.py:58
#: common/serializers/fields.py:144 terminal/serializers/session.py:81
#: tickets/serializers/ticket/common.py:58
#: xpack/plugins/cloud/serializers/account_attrs.py:56
#: xpack/plugins/cloud/serializers/account_attrs.py:79
#: xpack/plugins/cloud/serializers/account_attrs.py:150
@ -4706,27 +4722,27 @@ msgstr "正在创建任务,无法中断,请稍后重试。"
msgid "Currently playbook is being used in a job"
msgstr "当前 playbook 正在作业中使用"
#: ops/api/playbook.py:113
#: ops/api/playbook.py:123
msgid "Unsupported file content"
msgstr "不支持的文件内容"
#: ops/api/playbook.py:115 ops/api/playbook.py:161 ops/api/playbook.py:209
#: ops/api/playbook.py:125 ops/api/playbook.py:171 ops/api/playbook.py:219
msgid "Invalid file path"
msgstr "无效的文件路径"
#: ops/api/playbook.py:187
#: ops/api/playbook.py:197
msgid "This file can not be rename"
msgstr "该文件不能重命名"
#: ops/api/playbook.py:206
#: ops/api/playbook.py:216
msgid "File already exists"
msgstr "文件已存在"
#: ops/api/playbook.py:224
#: ops/api/playbook.py:234
msgid "File key is required"
msgstr "文件密钥该字段是必填项。"
#: ops/api/playbook.py:227
#: ops/api/playbook.py:237
msgid "This file can not be delete"
msgstr "无法删除此文件"
@ -4910,7 +4926,7 @@ msgid "Date last run"
msgstr "最后运行日期"
#: ops/models/base.py:51 ops/models/job.py:238
#: xpack/plugins/cloud/models.py:223
#: xpack/plugins/cloud/models.py:224
msgid "Result"
msgstr "结果"
@ -4980,7 +4996,7 @@ msgstr "Material"
msgid "Material Type"
msgstr "Material 类型"
#: ops/models/job.py:548
#: ops/models/job.py:558
msgid "Job Execution"
msgstr "作业执行"
@ -5032,7 +5048,7 @@ msgstr "下次执行时间"
msgid "Execute after saving"
msgstr "保存后执行"
#: ops/serializers/job.py:52 terminal/serializers/session.py:47
#: ops/serializers/job.py:52 terminal/serializers/session.py:49
msgid "Duration"
msgstr "时长"
@ -5040,7 +5056,7 @@ msgstr "时长"
msgid "Job type"
msgstr "任务类型"
#: ops/serializers/job.py:75 terminal/serializers/session.py:56
#: ops/serializers/job.py:75 terminal/serializers/session.py:58
msgid "Is finished"
msgstr "是否完成"
@ -7194,11 +7210,11 @@ msgstr "认证失败: (未知): {}"
msgid "Authentication success: {}"
msgstr "认证成功: {}"
#: settings/ws.py:199
#: settings/ws.py:222
msgid "No LDAP user was found"
msgstr "没有获取到 LDAP 用户"
#: settings/ws.py:205
#: settings/ws.py:228
msgid "Total {}, success {}, failure {}"
msgstr "总共 {},成功 {},失败 {}"
@ -7690,51 +7706,51 @@ msgstr "初始化"
msgid "Applet host deployment"
msgstr "应用部署"
#: terminal/models/component/endpoint.py:15
#: terminal/models/component/endpoint.py:16
msgid "HTTPS port"
msgstr "HTTPS 端口"
#: terminal/models/component/endpoint.py:16
#: terminal/models/component/endpoint.py:17
msgid "HTTP port"
msgstr "HTTP 端口"
#: terminal/models/component/endpoint.py:17
#: terminal/models/component/endpoint.py:18
msgid "SSH port"
msgstr "SSH 端口"
#: terminal/models/component/endpoint.py:18
#: terminal/models/component/endpoint.py:19
msgid "RDP port"
msgstr "RDP 端口"
#: terminal/models/component/endpoint.py:19
#: terminal/models/component/endpoint.py:20
msgid "MySQL port"
msgstr "MySQL 端口"
#: terminal/models/component/endpoint.py:20
#: terminal/models/component/endpoint.py:21
msgid "MariaDB port"
msgstr "MariaDB 端口"
#: terminal/models/component/endpoint.py:21
#: terminal/models/component/endpoint.py:22
msgid "PostgreSQL port"
msgstr "PostgreSQL 端口"
#: terminal/models/component/endpoint.py:22
#: terminal/models/component/endpoint.py:23
msgid "Redis port"
msgstr "Redis 端口"
#: terminal/models/component/endpoint.py:23
#: terminal/models/component/endpoint.py:24
msgid "SQLServer port"
msgstr "SQLServer 端口"
#: terminal/models/component/endpoint.py:30
#: terminal/models/component/endpoint.py:117
#: terminal/serializers/endpoint.py:73 terminal/serializers/storage.py:41
#: terminal/models/component/endpoint.py:32
#: terminal/models/component/endpoint.py:119
#: terminal/serializers/endpoint.py:80 terminal/serializers/storage.py:41
#: terminal/serializers/storage.py:53 terminal/serializers/storage.py:83
#: terminal/serializers/storage.py:93 terminal/serializers/storage.py:101
msgid "Endpoint"
msgstr "端点"
#: terminal/models/component/endpoint.py:123
#: terminal/models/component/endpoint.py:125
msgid "Endpoint rule"
msgstr "端点规则"
@ -7820,11 +7836,11 @@ msgstr "登录来源"
msgid "Replay"
msgstr "回放"
#: terminal/models/session/session.py:48 terminal/serializers/session.py:78
#: terminal/models/session/session.py:48 terminal/serializers/session.py:112
msgid "Command amount"
msgstr "命令数量"
#: terminal/models/session/session.py:49 terminal/serializers/session.py:30
#: terminal/models/session/session.py:49 terminal/serializers/session.py:32
msgid "Error reason"
msgstr "错误原因"
@ -8144,49 +8160,53 @@ msgstr ""
"连接资产时访问的主机地址,如果为空则使用当前浏览器的访问地址 (默认端点不允许"
"修改主机)"
#: terminal/serializers/endpoint.py:64
#: terminal/serializers/endpoint.py:71
msgid ""
"The assets within this IP range, the following endpoint will be used for the "
"connection"
msgstr "该 IP 范围内的资产,将使用下面的端点进行连接"
#: terminal/serializers/endpoint.py:65
#: terminal/serializers/endpoint.py:72
msgid ""
"If asset IP addresses under different endpoints conflict, use asset labels"
msgstr "如果不同端点下的资产 IP 有冲突,使用资产标签实现"
#: terminal/serializers/endpoint.py:69
#: terminal/serializers/endpoint.py:76
msgid "Asset IP"
msgstr "资产 IP"
#: terminal/serializers/session.py:25 terminal/serializers/session.py:53
#: terminal/serializers/session.py:27 terminal/serializers/session.py:55
msgid "Can replay"
msgstr "是否可重放"
#: terminal/serializers/session.py:26 terminal/serializers/session.py:54
#: terminal/serializers/session.py:28 terminal/serializers/session.py:56
msgid "Can join"
msgstr "是否可加入"
#: terminal/serializers/session.py:27 terminal/serializers/session.py:57
#: terminal/serializers/session.py:29 terminal/serializers/session.py:59
msgid "Can terminate"
msgstr "是否可中断"
#: terminal/serializers/session.py:49
#: terminal/serializers/session.py:51
msgid "User ID"
msgstr "用户 ID"
#: terminal/serializers/session.py:50
#: terminal/serializers/session.py:52
msgid "Asset ID"
msgstr "资产 ID"
#: terminal/serializers/session.py:51
#: terminal/serializers/session.py:53
msgid "Login from display"
msgstr "登录来源名称"
#: terminal/serializers/session.py:58
#: terminal/serializers/session.py:60
msgid "Terminal display"
msgstr "终端显示"
#: terminal/serializers/session.py:103
msgid "No asset or invalid asset"
msgstr "没有资产或资产未激活"
#: terminal/serializers/storage.py:23
msgid "Endpoint invalid: remove path `{}`"
msgstr "端点无效: 移除路径 `{}`"
@ -8205,7 +8225,7 @@ msgid "Access key secret"
msgstr "Access key secret(SK)"
#: terminal/serializers/storage.py:68 xpack/plugins/cloud/manager.py:100
#: xpack/plugins/cloud/models.py:285
#: xpack/plugins/cloud/models.py:286
msgid "Region"
msgstr "地域"
@ -9061,7 +9081,7 @@ msgid "Force enabled"
msgstr "强制启用"
#: users/notifications.py:55
#: users/templates/users/_msg_password_expire_reminder.html:17
#: users/templates/users/_msg_password_expire_reminder.html:16
#: users/templates/users/reset_password.html:5
#: users/templates/users/reset_password.html:6
msgid "Reset password"
@ -9315,11 +9335,11 @@ msgid ""
msgstr ""
"管理员已开启'仅允许已存在用户登录',当前用户不在用户列表中,请联系管理员。"
#: users/signal_handlers.py:196
#: users/signal_handlers.py:197
msgid "Clean up expired user sessions"
msgstr "清除过期的用户会话"
#: users/signal_handlers.py:198
#: users/signal_handlers.py:199
msgid ""
"After logging in via the web, a user session record is created. At 2 a.m. "
"every day, \n"
@ -9424,7 +9444,7 @@ msgstr "为了您的账号安全,请点击下面的链接及时更新密码"
msgid "Click here update password"
msgstr "点击这里更新密码"
#: users/templates/users/_msg_password_expire_reminder.html:16
#: users/templates/users/_msg_password_expire_reminder.html:15
msgid "If your password has expired, please click the link below to"
msgstr "如果你的密码已过期,请点击"
@ -9758,7 +9778,7 @@ msgstr "私有IP"
msgid "Public IP"
msgstr "公网IP"
#: xpack/plugins/cloud/const.py:42 xpack/plugins/cloud/models.py:359
#: xpack/plugins/cloud/const.py:42 xpack/plugins/cloud/models.py:360
msgid "Instance name"
msgstr "实例名称"
@ -9923,133 +9943,133 @@ msgstr "主机名策略"
msgid "IP network segment group"
msgstr "IP网段组"
#: xpack/plugins/cloud/models.py:115
#: xpack/plugins/cloud/models.py:116
#: xpack/plugins/cloud/serializers/task.py:161
msgid "Sync IP type"
msgstr "同步IP类型"
msgid "Preferred IP type"
msgstr ""
#: xpack/plugins/cloud/models.py:118
#: xpack/plugins/cloud/models.py:119
msgid "Always update"
msgstr "总是更新"
#: xpack/plugins/cloud/models.py:120
#: xpack/plugins/cloud/models.py:121
msgid "Fully synchronous"
msgstr "完全同步"
#: xpack/plugins/cloud/models.py:125
#: xpack/plugins/cloud/models.py:126
msgid "Date last sync"
msgstr "最后同步日期"
#: xpack/plugins/cloud/models.py:128 xpack/plugins/cloud/models.py:377
#: xpack/plugins/cloud/models.py:403
#: xpack/plugins/cloud/models.py:129 xpack/plugins/cloud/models.py:378
#: xpack/plugins/cloud/models.py:404
msgid "Strategy"
msgstr "策略"
#: xpack/plugins/cloud/models.py:133 xpack/plugins/cloud/models.py:221
#: xpack/plugins/cloud/models.py:134 xpack/plugins/cloud/models.py:222
msgid "Sync instance task"
msgstr "同步实例任务"
#: xpack/plugins/cloud/models.py:232 xpack/plugins/cloud/models.py:295
#: xpack/plugins/cloud/models.py:233 xpack/plugins/cloud/models.py:296
msgid "Date sync"
msgstr "同步日期"
#: xpack/plugins/cloud/models.py:236
#: xpack/plugins/cloud/models.py:237
msgid "Sync instance snapshot"
msgstr "同步实例快照"
#: xpack/plugins/cloud/models.py:244
#: xpack/plugins/cloud/models.py:245
msgid "Sync instance task execution"
msgstr "同步实例任务执行"
#: xpack/plugins/cloud/models.py:275
#: xpack/plugins/cloud/models.py:276
msgid "Sync task"
msgstr "同步任务"
#: xpack/plugins/cloud/models.py:279
#: xpack/plugins/cloud/models.py:280
msgid "Sync instance task history"
msgstr "同步实例任务历史"
#: xpack/plugins/cloud/models.py:282
#: xpack/plugins/cloud/models.py:283
msgid "Instance"
msgstr "实例"
#: xpack/plugins/cloud/models.py:299
#: xpack/plugins/cloud/models.py:300
msgid "Sync instance detail"
msgstr "同步实例详情"
#: xpack/plugins/cloud/models.py:311 xpack/plugins/cloud/serializers/task.py:77
#: xpack/plugins/cloud/models.py:312 xpack/plugins/cloud/serializers/task.py:77
msgid "Rule relation"
msgstr "条件关系"
#: xpack/plugins/cloud/models.py:321
#: xpack/plugins/cloud/models.py:322
msgid "Task strategy"
msgstr "任务策略"
#: xpack/plugins/cloud/models.py:348
#: xpack/plugins/cloud/models.py:349
msgid "Equal"
msgstr "等于"
#: xpack/plugins/cloud/models.py:349
#: xpack/plugins/cloud/models.py:350
msgid "Not Equal"
msgstr "不等于"
#: xpack/plugins/cloud/models.py:350
#: xpack/plugins/cloud/models.py:351
msgid "In"
msgstr "在...中"
#: xpack/plugins/cloud/models.py:351
#: xpack/plugins/cloud/models.py:352
msgid "Contains"
msgstr "包含"
#: xpack/plugins/cloud/models.py:352
#: xpack/plugins/cloud/models.py:353
msgid "Exclude"
msgstr "排除"
#: xpack/plugins/cloud/models.py:353
#: xpack/plugins/cloud/models.py:354
msgid "Startswith"
msgstr "以...开头"
#: xpack/plugins/cloud/models.py:354
#: xpack/plugins/cloud/models.py:355
msgid "Endswith"
msgstr "以...结尾"
#: xpack/plugins/cloud/models.py:360
#: xpack/plugins/cloud/models.py:361
msgid "Instance platform"
msgstr "实例平台"
#: xpack/plugins/cloud/models.py:361
#: xpack/plugins/cloud/models.py:362
msgid "Instance address"
msgstr "实例地址"
#: xpack/plugins/cloud/models.py:368
#: xpack/plugins/cloud/models.py:369
msgid "Rule attr"
msgstr "规则属性"
#: xpack/plugins/cloud/models.py:372
#: xpack/plugins/cloud/models.py:373
msgid "Rule match"
msgstr "规则匹配"
#: xpack/plugins/cloud/models.py:374
#: xpack/plugins/cloud/models.py:375
msgid "Rule value"
msgstr "规则值"
#: xpack/plugins/cloud/models.py:381 xpack/plugins/cloud/serializers/task.py:80
#: xpack/plugins/cloud/models.py:382 xpack/plugins/cloud/serializers/task.py:80
msgid "Strategy rule"
msgstr "条件"
#: xpack/plugins/cloud/models.py:391
#: xpack/plugins/cloud/models.py:392
msgid "Name strategy"
msgstr "主机名策略"
#: xpack/plugins/cloud/models.py:398
#: xpack/plugins/cloud/models.py:399
msgid "Action attr"
msgstr "动作属性"
#: xpack/plugins/cloud/models.py:400
#: xpack/plugins/cloud/models.py:401
msgid "Action value"
msgstr "动作值"
#: xpack/plugins/cloud/models.py:407 xpack/plugins/cloud/serializers/task.py:83
#: xpack/plugins/cloud/models.py:408 xpack/plugins/cloud/serializers/task.py:83
msgid "Strategy action"
msgstr "动作"
@ -10455,3 +10475,12 @@ msgstr "企业专业版"
#: xpack/plugins/license/models.py:86
msgid "Ultimate edition"
msgstr "企业旗舰版"
#~ msgid "* Please enter the correct password length"
#~ msgstr "* 请输入正确的密码长度"
#~ msgid "* Password length range 6-30 bits"
#~ msgstr "* 密码长度范围 6-30 位"
#~ msgid "Sync IP type"
#~ msgstr "同步 IP 类型"

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,9 @@
{
"ActionPerm": "Actions",
"Cancel": "Cancel",
"Clone Connect": "Clone Connect",
"Close All Tabs": "Close All Tabs",
"Close Current Tab": "Close Current Tab",
"Confirm": "Confirm",
"ConfirmBtn": "Confirm",
"Connect": "Connect",
@ -8,6 +11,7 @@
"CopyShareURLSuccess": "Copy Share URL Success",
"CreateLink": "Create Share Link",
"CreateSuccess": "Success",
"Custom Setting": "Custom Setting",
"DownArrow": "Down arrow",
"Download": "Download",
"DownloadSuccess": "Download success",
@ -32,7 +36,10 @@
"OnlineUsers": "Online Users",
"Paste": "Paste",
"PauseSession": "Pause Session",
"PermissionExpired": "Permission expired",
"PermissionValid": "Permission valid",
"ReadOnly": "Read-Only",
"Reconnect": "Reconnect",
"Refresh": "Refresh",
"Remove": "Remove",
"RemoveShareUser": "You have been removed from the shared session.",
@ -62,10 +69,5 @@
"VerifyCode": "Verify Code",
"WaitFileTransfer": "Wait file transfer to finish",
"WebSocketClosed": "WebSocket closed",
"Writable": "Writable",
"Reconnect": "Reconnect",
"Close Current Tab": "Close Current Tab",
"Close All Tabs": "Close All Tabs",
"Clone Connect": "Clone Connect",
"Custom Setting": "Custom Setting"
"Writable": "Writable"
}

View File

@ -36,6 +36,8 @@
"OnlineUsers": "オンラインスタッフ",
"Paste": "貼り付け",
"PauseSession": "セッションを一時停止",
"PermissionExpired": "許可が期限切れになりました",
"PermissionValid": "権限は有効です",
"ReadOnly": "読み取り専用",
"Reconnect": "再接続",
"Refresh": "リフレッシュ",

View File

@ -1,6 +1,9 @@
{
"ActionPerm": "操作权限",
"Cancel": "取消",
"Clone Connect": "复制窗口",
"Close All Tabs": "关闭所有",
"Close Current Tab": "关闭当前",
"Confirm": "确认",
"ConfirmBtn": "确定",
"Connect": "连接",
@ -8,6 +11,7 @@
"CopyShareURLSuccess": "复制分享地址成功",
"CreateLink": "创建分享链接",
"CreateSuccess": "创建成功",
"Custom Setting": "自定义设置",
"DownArrow": "向下箭头",
"Download": "下载",
"DownloadSuccess": "下载成功",
@ -32,7 +36,10 @@
"OnlineUsers": "在线人员",
"Paste": "粘贴",
"PauseSession": "暂停此会话",
"PermissionExpired": "权限已过期",
"PermissionValid": "权限有效",
"ReadOnly": "只读",
"Reconnect": "重新连接",
"Refresh": "刷新",
"Remove": "移除",
"RemoveShareUser": "你已经被移除共享会话",
@ -62,10 +69,5 @@
"VerifyCode": "验证码",
"WaitFileTransfer": "等待文件传输结束",
"WebSocketClosed": "WebSocket 已关闭",
"Reconnect": "重新连接",
"Writable": "可写",
"Close Current Tab": "关闭当前",
"Close All Tabs": "关闭所有",
"Clone Connect": "复制窗口",
"Custom Setting": "自定义设置"
"Writable": "可写"
}

View File

@ -36,6 +36,8 @@
"OnlineUsers": "在線人員",
"Paste": "貼上",
"PauseSession": "暫停此會話",
"PermissionExpired": "權限已過期",
"PermissionValid": "權限有效",
"ReadOnly": "只讀",
"Reconnect": "重新連線",
"Refresh": "刷新",

View File

@ -443,7 +443,6 @@
"Docs": "Docs",
"Download": "Download",
"DownloadCenter": "Download",
"DownloadFTPFileTip": "The current action does not record files, or the file size exceeds the threshold (default 100m), or it has not yet been saved to the corresponding storage",
"DownloadImportTemplateMsg": "Download creation template",
"DownloadReplay": "Download recording",
"DownloadUpdateTemplateMsg": "Download update template",
@ -505,6 +504,9 @@
"ExportOnlySelectedItems": "Export selected items",
"ExportRange": "Export range",
"FC": "Fusion compute",
"FTPFileNotStored": "The file has not been saved to storage yet, please check back later.",
"FTPStorageNotEnabled": "The file storage function is not enabled. Please modify the configuration file and add the following configuration: FTP_FILE_MAX_STORE=100 (supports saving files within 100M)",
"FTPUnknownStorageState": "Unknown file storage status, please contact your administrator.",
"Failed": "Failed",
"FailedAsset": "Failed assets",
"FaviconTip": "Note: website icon (suggested image size: 16px*16px)",
@ -622,6 +624,7 @@
"InputPhone": "Phone number",
"InstanceAddress": "Instance address",
"InstanceName": "Instance name",
"InstanceNamePartIp": "Instance name and Partial IP",
"InstancePlatformName": "Instance platform name",
"Interface": "Appearance",
"InterfaceSettings": "Appearance",
@ -1215,6 +1218,7 @@
"TaskID": "Task id",
"TaskList": "Tasks",
"TaskMonitor": "Monitoring",
"TaskPath": "Task path",
"TechnologyConsult": "Technical consultation",
"TempPasswordTip": "The temporary password is valid for 300 seconds and becomes invalid immediately after use",
"TempToken": "Temporary tokens",
@ -1397,6 +1401,5 @@
"ZoneUpdate": "Update the zone",
"disallowSelfUpdateFields": "Not allowed to modify the current fields yourself",
"forceEnableMFAHelpText": "If force enable, user can not disable by themselves",
"removeWarningMsg": "Are you sure you want to remove",
"TaskPath": "Task path"
"removeWarningMsg": "Are you sure you want to remove"
}

View File

@ -458,7 +458,7 @@
"Docs": "文書",
"Download": "ダウンロード",
"DownloadCenter": "ダウンロードセンター",
"DownloadFTPFileTip": "現在のActionでは、ファイルは記録されず、またはファイルサイズが閾値デフォルトは100Mを超える、またはまだ対応するストレージに保存されていない",
"DownloadFTPFileTip": "現在のActionはファイルを記録せず、またはファイルのサイズが閾値デフォルト100Mを超えている、またはまだ対応するストレージに保存されていません。",
"DownloadImportTemplateMsg": "テンプレートをダウンロードで作成",
"DownloadReplay": "ビデオのダウンロード",
"DownloadUpdateTemplateMsg": "更新テンプレートをダウンロード",
@ -520,6 +520,9 @@
"ExportOnlySelectedItems": "選択オプションのみをエクスポート",
"ExportRange": "エクスポート範囲",
"FC": "Fusion Compute",
"FTPFileNotStored": "ファイルはまだストレージに保存されていません、後で確認してください。",
"FTPStorageNotEnabled": "ファイルストレージ機能が有効になっていません、設定ファイルを変更し、次の設定を追加してくださいFTP_FILE_MAX_STORE=100100M以下のファイルを保存可能",
"FTPUnknownStorageState": "不明なファイルストレージの状態、管理者にご連絡ください。",
"Failed": "失敗",
"FailedAsset": "失敗した資産",
"FaviconTip": "ヒント:ウェブサイトのアイコン(推奨画像サイズ16px*16px)",
@ -637,6 +640,7 @@
"InputPhone": "携帯電話番号を入力してください",
"InstanceAddress": "インスタンスのアドレス",
"InstanceName": "インスタンス名",
"InstanceNamePartIp": "インスタンス名と部分IP",
"InstancePlatformName": "インスタンスプラットフォーム名",
"Interface": "ネットワークインターフェース",
"InterfaceSettings": "インターフェースの設定",
@ -1295,6 +1299,7 @@
"Timeout": "タイムアウト",
"TimeoutHelpText": "この値が-1の場合、タイムアウト時間を指定しない",
"Timer": "定期的にAction",
"TimerExecution": "定期実行",
"Title": "タイトル",
"To": "至",
"Today": "今日",

View File

@ -505,6 +505,9 @@
"ExportOnlySelectedItems": "仅导出选择项",
"ExportRange": "导出范围",
"FC": "Fusion Compute",
"FTPFileNotStored": "文件尚未保存到存储中,请稍后查看。",
"FTPStorageNotEnabled": "文件存储功能未开启请修改配置文件并添加配置FTP_FILE_MAX_STORE=100支持保存100M以内的文件",
"FTPUnknownStorageState": "未知的文件存储状态,请联系管理员。",
"Failed": "失败",
"FailedAsset": "失败的资产",
"FaviconTip": "提示:网站图标(建议图片大小为: 16px*16px",
@ -619,6 +622,7 @@
"InputPhone": "请输入手机号码",
"InstanceAddress": "实例地址",
"InstanceName": "实例名称",
"InstanceNamePartIp": "实例名称和部分IP",
"InstancePlatformName": "实例平台名称",
"Interface": "网络接口",
"InterfaceSettings": "界面设置",
@ -1218,6 +1222,7 @@
"TaskID": "任务 ID",
"TaskList": "任务列表",
"TaskMonitor": "任务监控",
"TaskPath": "任务路径",
"TechnologyConsult": "技术咨询",
"TempPasswordTip": "临时密码有效期为 300 秒,使用后立刻失效",
"TempToken": "临时密码",
@ -1400,6 +1405,5 @@
"ZoneUpdate": "更新网域",
"disallowSelfUpdateFields": "不允许自己修改当前字段",
"forceEnableMFAHelpText": "如果强制启用,用户无法自行禁用",
"removeWarningMsg": "你确定要移除",
"TaskPath": "任务路径"
"removeWarningMsg": "你确定要移除"
}

View File

@ -593,7 +593,7 @@
"DomainUpdate": "更新網域",
"Download": "下載",
"DownloadCenter": "下載中心",
"DownloadFTPFileTip": "當前動作不記錄文件或者檔案大小超過閾值默認100M或者還未保存到對應儲存中",
"DownloadFTPFileTip": "當前Action不記錄檔案或者檔案大小超過閾值預設100M或者還未儲存到對應儲存中。",
"DownloadImportTemplateMsg": "下載創建模板",
"DownloadReplay": "下載錄影",
"DownloadUpdateTemplateMsg": "下載更新範本",
@ -668,6 +668,9 @@
"ExportRange": "匯出範圍",
"FAILURE": "失敗",
"FC": "Fusion Compute",
"FTPFileNotStored": "檔案尚未儲存到儲存中,請稍後查看。",
"FTPStorageNotEnabled": "檔案儲存功能未開啟請修改配置檔並添加配置FTP_FILE_MAX_STORE=100支持儲存100M以內的檔案",
"FTPUnknownStorageState": "未知的檔案儲存狀態,請聯絡管理員。",
"Failed": "失敗",
"FailedAsset": "失敗的資產",
"False": "否",
@ -809,6 +812,7 @@
"InsecureCommandNotifyToSubscription": "危險命令通知已升級到消息訂閱中,支持更多通知方式",
"InstanceAddress": "實例地址",
"InstanceName": "實例名稱",
"InstanceNamePartIp": "實例名稱和部分IP",
"InstancePlatformName": "實例平台名稱",
"Interface": "網路介面",
"InterfaceSettings": "界面設置",
@ -1655,6 +1659,7 @@
"Timeout": "超時(秒)",
"TimeoutHelpText": "當此值為-1時不指定超時時間",
"Timer": "定時執行",
"TimerExecution": "定時執行",
"TimerPeriod": "定時執行週期",
"TimesWeekUnit": "次/周",
"Title": "Title",

View File

@ -129,6 +129,7 @@
"Password is your password login to system": "Password is your password login to system",
"Pause": "Pause",
"Pause task has been send": "Pause task has been send",
"Play List": "Play List",
"Please choose an account": "Please choose an account",
"Please input password": "Please input password",
"Port": "Port",
@ -216,11 +217,10 @@
"connectDisabledTipsNoAccount": "Tips: No valid authorization account found, current resource cannot be connected. Please contact the administrator for assistance",
"connectDisabledTipsNoConnectMethod": "Tips: No valid connection method found, current resource cannot be connected. Please contact the administrator for assistance",
"download": "download",
"recordingIsBeingDownloaded": "Recording is being downloaded, please wait.",
"rows": "rows",
"start time": "start time",
"success": "success",
"system user": "system user",
"user": "user",
"recordingIsBeingDownloaded": "Recording is being downloaded, please wait.",
"Play List": "Play List"
"user": "user"
}

View File

@ -130,6 +130,7 @@
"Password is your password login to system": "パスワードは、システムにログインするためのパスワードです",
"Pause": "タスクを一時停止",
"Pause task has been send": "一時停止タスクが送信されました",
"Play List": "再生リスト",
"Please choose an account": "ユーザーを選択してください",
"Please input password": "パスワードを入力してください",
"Port": "ポート",
@ -220,6 +221,7 @@
"connectDisabledTipsNoAccount": "ヒント:有効な認可アカウントが見つかりませんでした。このリソースは接続できません。管理者に連絡してください",
"connectDisabledTipsNoConnectMethod": "ヒント:有効な接続方法が見つかりませんでした。このリソースは接続できません。管理者に連絡してください",
"download": "ダウンロード",
"recordingIsBeingDownloaded": "ビデオのダウンロードが進行中です、お待ちください。",
"rows": "行数",
"start time": "開始時間",
"success": "成功",

View File

@ -128,6 +128,7 @@
"Password is your password login to system": "密码是你登录系统的密码",
"Pause": "暂停",
"Pause task has been send": "暂停任务已发送",
"Play List": "播放列表",
"Please choose an account": "请选择一个用户",
"Please input password": "请输入密码",
"Port": "端口",
@ -214,11 +215,10 @@
"connectDisabledTipsNoAccount": "提示:未找到有效的授权账号,当前资源无法连接,请联系管理员进行处理",
"connectDisabledTipsNoConnectMethod": "提示:未找到有效的连接方式,当前资源无法连接,请联系管理员进行处理",
"download": "下载",
"recordingIsBeingDownloaded": "录像正在下载中,请稍候",
"rows": "行数",
"start time": "开始时间",
"success": "成功",
"system user": "系统用户",
"user": "用户",
"recordingIsBeingDownloaded": "录像正在下载中,请稍候",
"Play List": "播放列表"
"user": "用户"
}

View File

@ -129,6 +129,7 @@
"Password is your password login to system": "密碼是你登入系統的密碼",
"Pause": "暫停",
"Pause task has been send": "暫停任務已發送",
"Play List": "播放清單",
"Please choose an account": "請選擇一個用戶",
"Please input password": "請輸入密碼",
"Port": "埠",
@ -218,6 +219,7 @@
"connectDisabledTipsNoAccount": "提示:未找到有效的授權帳號,當前資源無法連接,請聯繫管理員進行處理",
"connectDisabledTipsNoConnectMethod": "提示:未找到有效的連接方式,當前資源無法連接,請聯繫管理員進行處理",
"download": "下載",
"recordingIsBeingDownloaded": "錄影正在下載中,請稍等",
"rows": "行數",
"start time": "開始時間",
"success": "成功",

View File

@ -659,7 +659,6 @@ class Config(dict):
# API 分页
'MAX_LIMIT_PER_PAGE': 10000,
'DEFAULT_PAGE_SIZE': None,
'LIMIT_SUPER_PRIV': False,

View File

@ -33,17 +33,17 @@ def get_signature_user(scope):
return
if scope['type'] == 'websocket':
scope['method'] = 'GET'
try:
# 因为 ws 使用的是 scope所以需要转换成 request 对象,用于认证校验
request = ASGIRequest(scope, None)
backends = [SignatureAuthentication(),
AccessTokenAuthentication()]
for backend in backends:
# 因为 ws 使用的是 scope所以需要转换成 request 对象,用于认证校验
request = ASGIRequest(scope, None)
backends = [SignatureAuthentication(),
AccessTokenAuthentication()]
for backend in backends:
try:
user, _ = backend.authenticate(request)
if user:
return user
except Exception as e:
print(e)
except Exception as e:
print(e)
return None

View File

@ -210,7 +210,7 @@ SESSION_RSA_PUBLIC_KEY_NAME = 'jms_public_key'
OPERATE_LOG_ELASTICSEARCH_CONFIG = CONFIG.OPERATE_LOG_ELASTICSEARCH_CONFIG
MAX_LIMIT_PER_PAGE = CONFIG.MAX_LIMIT_PER_PAGE
DEFAULT_PAGE_SIZE = CONFIG.DEFAULT_PAGE_SIZE
DEFAULT_PAGE_SIZE = CONFIG.MAX_LIMIT_PER_PAGE
PERM_TREE_REGEN_INTERVAL = CONFIG.PERM_TREE_REGEN_INTERVAL
# Magnus DB Port

View File

@ -40,9 +40,10 @@ class AdHocRunner:
def check_module(self):
if self.module not in self.cmd_modules_choices:
return
if self.module_args and self.module_args.split()[0] in settings.SECURITY_COMMAND_BLACKLIST:
command = self.module_args
if command and set(command.split()).intersection(set(settings.SECURITY_COMMAND_BLACKLIST)):
raise CommandInBlackListException(
"Command is rejected by black list: {}".format(self.module_args.split()[0]))
"Command is rejected by black list: {}".format(self.module_args))
def set_local_connection(self):
if self.job_module in self.need_local_connection_modules_choices:

View File

@ -65,9 +65,19 @@ class PlaybookViewSet(JMSBulkModelViewSet):
def perform_create(self, serializer):
instance = serializer.save()
base_path = safe_join(settings.DATA_DIR, "ops", "playbook")
clone_id = self.request.query_params.get('clone_from')
if clone_id:
src_path = safe_join(base_path, clone_id)
dest_path = safe_join(base_path, str(instance.id))
if not os.path.exists(src_path):
raise JMSException(code='invalid_playbook_id', detail={"msg": "clone playbook file not found"})
shutil.copytree(src_path, dest_path)
return
if 'multipart/form-data' in self.request.headers['Content-Type']:
src_path = safe_join(settings.MEDIA_ROOT, instance.path.name)
dest_path = safe_join(settings.DATA_DIR, "ops", "playbook", instance.id.__str__())
dest_path = safe_join(base_path, str(instance.id))
try:
unzip_playbook(src_path, dest_path)
@ -78,7 +88,7 @@ class PlaybookViewSet(JMSBulkModelViewSet):
raise PlaybookNoValidEntry
elif instance.create_method == 'blank':
dest_path = safe_join(settings.DATA_DIR, "ops", "playbook", instance.id.__str__())
dest_path = safe_join(base_path, str(instance.id))
os.makedirs(dest_path)
with open(safe_join(dest_path, 'main.yml'), 'w') as f:
f.write('## write your playbook here')

View File

@ -28,6 +28,7 @@ class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('ops', '0002_celerytask'),
('orgs', '0002_auto_20180903_1132'),
]
operations = [

View File

@ -481,6 +481,16 @@ class JobExecution(JMSOrgBaseModel):
for acl in acls:
if self.match_command_group(acl, asset):
break
command = self.current_job.args
if command and set(command.split()).intersection(set(settings.SECURITY_COMMAND_BLACKLIST)):
CommandExecutionAlert({
"assets": self.current_job.assets.all(),
"input": self.material,
"risk_level": RiskLevelChoices.reject,
"user": self.creator,
}).publish_async()
raise CommandInBlackListException(
"Command is rejected by black list: {}".format(self.current_job.args))
def check_danger_keywords(self):
lines = self.job.playbook.check_dangerous_keywords()

View File

@ -15,5 +15,5 @@ class AdHocSerializer(ScopeSerializerMixin, CommonBulkModelSerializer):
class Meta:
model = AdHoc
read_only_field = ["id", "creator", "date_created", "date_updated"]
read_only_field = ["id", "creator", "date_created", "date_updated", "created_by"]
fields = read_only_field + ["id", "name", "scope", "module", "args", "comment"]

View File

@ -25,7 +25,7 @@ class PlaybookSerializer(ScopeSerializerMixin, CommonBulkModelSerializer):
class Meta:
model = Playbook
read_only_fields = ["id", "date_created", "date_updated"]
read_only_fields = ["id", "date_created", "date_updated", "created_by"]
fields = read_only_fields + [
"id", 'path', 'scope', "name", "comment", "creator",
'create_method', 'vcs_url',

View File

@ -56,8 +56,9 @@ class BaseUserPermedAssetsApi(SelfOrPKUserMixin, ExtraFilterFieldsMixin, ListAPI
return assets
def get_serializer(self, *args, **kwargs):
if len(args) == 1 and kwargs.get('many', False) and self.request_user_is_self():
MyAsset.set_asset_custom_value(args[0], self.request.user)
need_custom_value_user = self.request_user_is_self() or self.request.user.is_service_account
if len(args) == 1 and kwargs.get('many', False) and need_custom_value_user:
MyAsset.set_asset_custom_value(args[0], self.user)
return super().get_serializer(*args, **kwargs)
@abc.abstractmethod

View File

@ -15,8 +15,7 @@
{% endfor %}
</ul>
<br/>
-
<br>
<p>
{% trans 'If you have any question, please contact the administrator' %}
</p>

View File

@ -62,6 +62,7 @@ class PrivateSettingSerializer(PublicSettingSerializer):
CHAT_AI_ENABLED = serializers.BooleanField()
GPT_MODEL = serializers.CharField()
FILE_UPLOAD_SIZE_LIMIT_MB = serializers.IntegerField()
FTP_FILE_MAX_STORE = serializers.IntegerField()
LOKI_LOG_ENABLED = serializers.BooleanField()
TOOL_USER_ENABLED = serializers.BooleanField()

View File

@ -3,10 +3,11 @@
import json
import asyncio
from asgiref.sync import sync_to_async
from channels.generic.websocket import AsyncJsonWebsocketConsumer
from django.core.cache import cache
from django.conf import settings
from django.utils.translation import gettext_lazy as _, activate
from django.utils.translation import gettext_lazy as _
from django.utils import translation
from urllib.parse import parse_qs
@ -37,11 +38,27 @@ TASK_STATUS_IS_OVER = 'OVER'
class ToolsWebsocket(AsyncJsonWebsocketConsumer):
is_closed: bool = False
@staticmethod
@sync_to_async
def get_user_roles(user):
return [str(i) for i in user.system_roles.values_list('id', flat=True)]
async def is_superuser(self, user):
from rbac.builtin import BuiltinRole
ids = await self.get_user_roles(user)
return BuiltinRole.system_admin.id in ids
async def connect(self):
user = self.scope["user"]
if user.is_authenticated:
await self.accept()
has_perm = await sync_to_async(user.has_perm)('rbac.view_systemtools')
if await self.is_superuser(user) or (settings.TOOL_USER_ENABLED and has_perm):
await self.accept()
else:
await self.close()
else:
await self.close()
@ -96,6 +113,12 @@ class ToolsWebsocket(AsyncJsonWebsocketConsumer):
await self.send_msg()
await self.close()
async def close(self, code=None):
if self.is_closed:
return
await super().close(code)
self.is_closed = True
async def disconnect(self, code):
await self.close()
close_old_connections()

View File

@ -36,7 +36,7 @@ document.addEventListener("contextmenu", function (event) {
const AllowedKeys = ['P', 'F', 'C', 'V']
window.addEventListener("keydown", function (e) {
if (e.key === "F12" || (e.ctrlKey && !AllowedKeys.includes(e.key.toUpperCase()))) {
if (e.key === "F12" || e.key === "F1" || (e.ctrlKey && !AllowedKeys.includes(e.key.toUpperCase()))) {
e.preventDefault();
e.stopPropagation();
debug('Press key: ', e.ctrlKey ? 'Ctrl' : '', e.shiftKey ? ' Shift' : '', e.key)

View File

@ -18,7 +18,7 @@
PYTHON_VERSION: 3.11.6
CHROME_VERSION: 118.0.5993.118
CHROME_DRIVER_VERSION: 118.0.5993.70
TINKER_VERSION: v0.1.7
TINKER_VERSION: v0.1.9
tasks:
- block:

View File

@ -0,0 +1,18 @@
# Generated by Django 4.1.13 on 2024-09-25 07:38
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('terminal', '0003_auto_20171230_0308'),
]
operations = [
migrations.AddField(
model_name='endpoint',
name='is_active',
field=models.BooleanField(default=True, verbose_name='Active'),
),
]

View File

@ -1,5 +1,6 @@
from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
from django.db.models import Prefetch
from django.utils.translation import gettext_lazy as _
from assets.models import Asset
@ -23,6 +24,7 @@ class Endpoint(JMSBaseModel):
sqlserver_port = PortField(default=14330, verbose_name=_('SQLServer port'))
comment = models.TextField(default='', blank=True, verbose_name=_('Comment'))
is_active = models.BooleanField(default=True, verbose_name=_('Active'))
default_id = '00000000-0000-0000-0000-000000000001'
@ -98,7 +100,7 @@ class Endpoint(JMSBaseModel):
values = instance.labels.filter(label__name='endpoint').values_list('label__value', flat=True)
if not values:
return None
endpoints = cls.objects.filter(name__in=list(values)).order_by('-date_updated')
endpoints = cls.objects.filter(is_active=True, name__in=list(values)).order_by('-date_updated')
for endpoint in endpoints:
if endpoint.is_valid_for(instance, protocol):
endpoint = cls.handle_endpoint_host(endpoint, request)
@ -128,7 +130,8 @@ class EndpointRule(JMSBaseModel):
@classmethod
def match(cls, target_instance, target_ip, protocol):
for endpoint_rule in cls.objects.prefetch_related('endpoint').filter(is_active=True):
active_endpoints = Prefetch('endpoint', queryset=Endpoint.objects.filter(is_active=True))
for endpoint_rule in cls.objects.prefetch_related(active_endpoints).filter(is_active=True):
if not contains_ip(target_ip, endpoint_rule.ip_group):
continue
if not endpoint_rule.endpoint:

View File

@ -28,7 +28,7 @@ class EndpointSerializer(BulkModelSerializer):
fields_small = [
'host', 'https_port', 'http_port', 'ssh_port', 'rdp_port',
'mysql_port', 'mariadb_port', 'postgresql_port', 'redis_port',
'oracle_port_range', 'oracle_port', 'sqlserver_port',
'oracle_port_range', 'oracle_port', 'sqlserver_port', 'is_active'
]
fields = fields_mini + fields_small + [
'comment', 'date_created', 'date_updated', 'created_by'
@ -58,6 +58,13 @@ class EndpointSerializer(BulkModelSerializer):
extra_kwargs[field.name] = kwargs
return extra_kwargs
def validate_is_active(self, value):
if str(self.instance.id) == Endpoint.default_id:
# 默认端点不能禁用
return True
else:
return value
class EndpointRuleSerializer(BulkModelSerializer):
_ip_group_help_text = '{}, {} <br>{}'.format(

View File

@ -1,10 +1,12 @@
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from assets.models import Asset
from common.serializers.fields import LabeledChoiceField
from common.utils import pretty_string
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from terminal.session_lifecycle import lifecycle_events_map
from users.models import User
from .terminal import TerminalSmallSerializer
from ..const import SessionType, SessionErrorReason
from ..models import Session
@ -73,6 +75,38 @@ class SessionSerializer(BulkOrgResourceModelSerializer):
value = pretty_string(value, max_length=max_length)
return value
@staticmethod
def get_valid_instance(model_cls, instance_id, field_name, error_message, validation_attr='is_active'):
if instance_id is None:
raise serializers.ValidationError({field_name: _('This field is required.')})
instance = model_cls.objects.filter(id=instance_id).first()
if not instance or not getattr(instance, validation_attr, False):
raise serializers.ValidationError({field_name: error_message})
return instance
def create(self, validated_data):
user_id = validated_data.get('user_id')
asset_id = validated_data.get('asset_id')
user = self.get_valid_instance(
User,
user_id,
'user_id',
_('No user or invalid user'),
validation_attr='is_valid'
)
asset = self.get_valid_instance(
Asset,
asset_id,
'asset_id',
_('No asset or invalid asset')
)
validated_data['user'] = str(user)
validated_data['asset'] = str(asset)
return super().create(validated_data)
class SessionDisplaySerializer(SessionSerializer):
command_amount = serializers.IntegerField(read_only=True, label=_('Command amount'))

View File

@ -53,10 +53,11 @@ def user_authenticated_handle(user, created, source, attrs=None, **kwargs):
user.source = source
user.save()
if created and isinstance(attrs, dict):
if created:
org_ids = bind_user_to_org_role(user)
group_names = attrs.get('groups')
bind_user_to_group(org_ids, group_names, user)
if isinstance(attrs, dict):
group_names = attrs.get('groups')
bind_user_to_group(org_ids, group_names, user)
if not attrs:
return

View File

@ -9,9 +9,8 @@
<br />
<br />
<a href="{{ update_password_url }}">{% trans 'Click here update password' %}</a>
<br />
<br/>
</p>
-
<p>
{% trans 'If your password has expired, please click the link below to' %}
<a href="{{ forget_password_url }}?email={{ email }}">{% trans 'Reset password' %}</a>

View File

@ -15,9 +15,7 @@
{% trans 'click here to set your password' %}
</a>
</p>
-
<br>
<p>
{% trans 'This link is valid for 1 hour. After it expires' %}
<a href="{{ forget_password_url }}?email={{ user.email }}">{% trans 'request new one' %}</a>

View File

@ -110,6 +110,7 @@ class BlockUtil:
BLOCK_KEY_TMPL: str
def __init__(self, username):
username = username.lower()
self.block_key = self.BLOCK_KEY_TMPL.format(username)
self.key_ttl = int(settings.SECURITY_LOGIN_LIMIT_TIME) * 60
@ -125,6 +126,7 @@ class BlockUtilBase:
BLOCK_KEY_TMPL: str
def __init__(self, username, ip):
username = username.lower()
self.username = username
self.ip = ip
self.limit_key = self.LIMIT_KEY_TMPL.format(username, ip)
@ -158,6 +160,7 @@ class BlockUtilBase:
@classmethod
def unblock_user(cls, username):
username = username.lower()
key_limit = cls.LIMIT_KEY_TMPL.format(username, '*')
key_block = cls.BLOCK_KEY_TMPL.format(username)
# Redis 尽量不要用通配
@ -166,6 +169,7 @@ class BlockUtilBase:
@classmethod
def is_user_block(cls, username):
username = username.lower()
block_key = cls.BLOCK_KEY_TMPL.format(username)
return bool(cache.get(block_key))

16
poetry.lock generated
View File

@ -2662,19 +2662,23 @@ reference = "aliyun"
[[package]]
name = "geoip2"
version = "4.7.0"
version = "4.8.0"
description = "MaxMind GeoIP2 API"
optional = false
python-versions = ">=3.7"
python-versions = ">=3.8"
files = [
{file = "geoip2-4.7.0-py2.py3-none-any.whl", hash = "sha256:078fcd4cce26ea029b1e3252a0f0ec20a1f42e7ab0f19b7be3864f20f4db2b51"},
{file = "geoip2-4.7.0.tar.gz", hash = "sha256:3bdde4994f6bc917eafab5b51e772d737b2ae00037a5b85001fb06dc68f779df"},
{file = "geoip2-4.8.0-py2.py3-none-any.whl", hash = "sha256:39b38ec703575355d10475c0e6aa981827a2b4b5471d308c4ecb5e79cbe366ce"},
{file = "geoip2-4.8.0.tar.gz", hash = "sha256:dd9cc180b7d41724240ea481d5d539149e65b234f64282b231b9170794a9ac35"},
]
[package.dependencies]
aiohttp = ">=3.6.2,<4.0.0"
maxminddb = ">=2.3.0,<3.0.0"
maxminddb = ">=2.5.1,<3.0.0"
requests = ">=2.24.0,<3.0.0"
setuptools = ">=60.0.0"
[package.extras]
test = ["mocket (>=3.11.1)"]
[package.source]
type = "legacy"
@ -7670,4 +7674,4 @@ reference = "aliyun"
[metadata]
lock-version = "2.0"
python-versions = "^3.11"
content-hash = "9acfafd75bf7dbb7e0dffb54b7f11f6b09aa4ceff769d193a3906d03ae796ccc"
content-hash = "ecc26ab3966eeb87427e4a12fbed86ead9709ae85b8748aee89729c8c9cd143e"

View File

@ -82,7 +82,7 @@ python3-saml = "1.15.0"
websocket-client = "1.6.1"
pyjwkest = "1.4.2"
jsonfield2 = "4.0.0.post0"
geoip2 = "4.7.0"
geoip2 = "4.8.0"
ipip-ipdb = "1.6.1"
pywinrm = "0.4.3"
python-nmap = "0.7.1"