mirror of https://github.com/jumpserver/jumpserver
Merge branch 'dev' of github.com:jumpserver/jumpserver into pr@dev@feat_account_backend_support_aws
commit
a6fa1dab2a
|
@ -24,6 +24,7 @@ ENV LANG=en_US.UTF-8 \
|
|||
PATH=/opt/py3/bin:$PATH
|
||||
|
||||
ARG DEPENDENCIES=" \
|
||||
libldap2-dev \
|
||||
libx11-dev"
|
||||
|
||||
ARG TOOLS=" \
|
||||
|
|
|
@ -30,6 +30,6 @@
|
|||
login_user: "{{ account.username }}"
|
||||
login_password: "{{ account.secret }}"
|
||||
login_secret_type: "{{ account.secret_type }}"
|
||||
gateway_args: "{{ jms_gateway | default(None) }}"
|
||||
gateway_args: "{{ jms_gateway | default({}) }}"
|
||||
when: account.secret_type == "password"
|
||||
delegate_to: localhost
|
||||
|
|
|
@ -30,6 +30,6 @@
|
|||
login_user: "{{ account.username }}"
|
||||
login_password: "{{ account.secret }}"
|
||||
login_secret_type: "{{ account.secret_type }}"
|
||||
gateway_args: "{{ jms_gateway | default(None) }}"
|
||||
gateway_args: "{{ jms_gateway | default({}) }}"
|
||||
when: account.secret_type == "password"
|
||||
delegate_to: localhost
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
from importlib import import_module
|
||||
|
||||
from django.utils.functional import LazyObject
|
||||
from django.utils.functional import LazyObject, empty
|
||||
|
||||
from common.utils import get_logger
|
||||
from ..const import VaultTypeChoices
|
||||
|
||||
__all__ = ['vault_client', 'get_vault_client']
|
||||
|
||||
__all__ = ['vault_client', 'get_vault_client', 'refresh_vault_client']
|
||||
|
||||
logger = get_logger(__file__)
|
||||
|
||||
|
||||
def get_vault_client(raise_exception=False, **kwargs):
|
||||
tp = kwargs.get('VAULT_BACKEND') if kwargs.get('VAULT_ENABLED') else VaultTypeChoices.local
|
||||
|
||||
# TODO: Temporary processing, subsequent deletion
|
||||
tp = VaultTypeChoices.local if tp == VaultTypeChoices.azure else tp
|
||||
|
||||
try:
|
||||
module_path = f'apps.accounts.backends.{tp}.main'
|
||||
client = import_module(module_path).Vault(**kwargs)
|
||||
|
@ -38,3 +41,7 @@ class VaultClient(LazyObject):
|
|||
|
||||
""" 为了安全, 页面修改配置, 重启服务后才会重新初始化 vault_client """
|
||||
vault_client = VaultClient()
|
||||
|
||||
|
||||
def refresh_vault_client():
|
||||
vault_client._wrapped = empty
|
||||
|
|
|
@ -49,9 +49,9 @@ class SecretStrategy(models.TextChoices):
|
|||
|
||||
|
||||
class SSHKeyStrategy(models.TextChoices):
|
||||
add = 'add', _('Append SSH KEY')
|
||||
set = 'set', _('Empty and append SSH KEY')
|
||||
set_jms = 'set_jms', _('Replace (Replace only keys pushed by JumpServer) ')
|
||||
set = 'set', _('Empty and append SSH KEY')
|
||||
add = 'add', _('Append SSH KEY')
|
||||
|
||||
|
||||
class TriggerChoice(models.TextChoices, TreeChoices):
|
||||
|
|
|
@ -50,7 +50,7 @@ class Migration(migrations.Migration):
|
|||
('secret', common.db.fields.EncryptTextField(blank=True, null=True, verbose_name='Secret')),
|
||||
('secret_strategy', models.CharField(choices=[('specific', 'Specific secret'), ('random', 'Random generate')], default='specific', max_length=16, verbose_name='Secret strategy')),
|
||||
('password_rules', models.JSONField(default=dict, verbose_name='Password rules')),
|
||||
('ssh_key_change_strategy', models.CharField(choices=[('add', 'Append SSH KEY'), ('set', 'Empty and append SSH KEY'), ('set_jms', 'Replace (Replace only keys pushed by JumpServer) ')], default='add', max_length=16, verbose_name='SSH key change strategy')),
|
||||
('ssh_key_change_strategy', models.CharField(choices=[('set_jms', 'Replace (Replace only keys pushed by JumpServer) '), ('set', 'Empty and append SSH KEY'), ('add', 'Append SSH KEY')], default='set_jms', max_length=16, verbose_name='SSH key change strategy')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Change secret automation',
|
||||
|
@ -76,7 +76,7 @@ class Migration(migrations.Migration):
|
|||
('secret', common.db.fields.EncryptTextField(blank=True, null=True, verbose_name='Secret')),
|
||||
('secret_strategy', models.CharField(choices=[('specific', 'Specific secret'), ('random', 'Random generate')], default='specific', max_length=16, verbose_name='Secret strategy')),
|
||||
('password_rules', models.JSONField(default=dict, verbose_name='Password rules')),
|
||||
('ssh_key_change_strategy', models.CharField(choices=[('add', 'Append SSH KEY'), ('set', 'Empty and append SSH KEY'), ('set_jms', 'Replace (Replace only keys pushed by JumpServer) ')], default='add', max_length=16, verbose_name='SSH key change strategy')),
|
||||
('ssh_key_change_strategy', models.CharField(choices=[('set_jms', 'Replace (Replace only keys pushed by JumpServer) '), ('set', 'Empty and append SSH KEY'), ('add', 'Append SSH KEY')], default='set_jms', max_length=16, verbose_name='SSH key change strategy')),
|
||||
('triggers', models.JSONField(default=list, max_length=16, verbose_name='Triggers')),
|
||||
('username', models.CharField(max_length=128, verbose_name='Username')),
|
||||
('action', models.CharField(max_length=16, verbose_name='Action')),
|
||||
|
|
|
@ -51,7 +51,7 @@ class AutomationExecution(AssetAutomationExecution):
|
|||
class ChangeSecretMixin(SecretWithRandomMixin):
|
||||
ssh_key_change_strategy = models.CharField(
|
||||
choices=SSHKeyStrategy.choices, max_length=16,
|
||||
default=SSHKeyStrategy.add, verbose_name=_('SSH key change strategy')
|
||||
default=SSHKeyStrategy.set_jms, verbose_name=_('SSH key change strategy')
|
||||
)
|
||||
get_all_assets: callable # get all assets
|
||||
|
||||
|
|
|
@ -3,14 +3,17 @@ from collections import defaultdict
|
|||
from django.db.models.signals import post_delete
|
||||
from django.db.models.signals import pre_save, post_save
|
||||
from django.dispatch import receiver
|
||||
from django.utils.functional import LazyObject
|
||||
from django.utils.translation import gettext_noop
|
||||
|
||||
from accounts.backends import vault_client
|
||||
from accounts.backends import vault_client, refresh_vault_client
|
||||
from accounts.const import Source
|
||||
from audits.const import ActivityChoices
|
||||
from audits.signal_handlers import create_activities
|
||||
from common.decorators import merge_delay_run
|
||||
from common.signals import django_ready
|
||||
from common.utils import get_logger, i18n_fmt
|
||||
from common.utils.connection import RedisPubSub
|
||||
from .models import Account, AccountTemplate
|
||||
from .tasks.push_account import push_accounts_to_assets_task
|
||||
|
||||
|
@ -91,3 +94,18 @@ class VaultSignalHandler(object):
|
|||
for model in (Account, AccountTemplate, Account.history.model):
|
||||
post_save.connect(VaultSignalHandler.save_to_vault, sender=model)
|
||||
post_delete.connect(VaultSignalHandler.delete_to_vault, sender=model)
|
||||
|
||||
|
||||
class VaultPubSub(LazyObject):
|
||||
def _setup(self):
|
||||
self._wrapped = RedisPubSub('refresh_vault')
|
||||
|
||||
|
||||
vault_pub_sub = VaultPubSub()
|
||||
|
||||
|
||||
@receiver(django_ready)
|
||||
def subscribe_vault_change(sender, **kwargs):
|
||||
logger.debug("Start subscribe vault change")
|
||||
|
||||
vault_pub_sub.subscribe(lambda name: refresh_vault_client())
|
||||
|
|
|
@ -7,6 +7,7 @@ from django.db.models import F, Value, CharField, Q
|
|||
from django.db.models.functions import Cast
|
||||
from django.http import HttpResponse, FileResponse
|
||||
from django.utils.encoding import escape_uri_path
|
||||
from django_celery_beat.models import PeriodicTask
|
||||
from rest_framework import generics
|
||||
from rest_framework import status
|
||||
from rest_framework import viewsets
|
||||
|
@ -74,6 +75,21 @@ class JobsAuditViewSet(OrgModelViewSet):
|
|||
queryset = queryset.exclude(type=Types.upload_file).filter(instant=False)
|
||||
return queryset
|
||||
|
||||
def perform_update(self, serializer):
|
||||
job = self.get_object()
|
||||
is_periodic = serializer.validated_data.get('is_periodic')
|
||||
if job.is_periodic != is_periodic:
|
||||
job.is_periodic = is_periodic
|
||||
job.save()
|
||||
name, task, args, kwargs = job.get_register_task()
|
||||
task_obj = PeriodicTask.objects.filter(name=name).first()
|
||||
if task_obj:
|
||||
is_periodic = job.is_periodic
|
||||
if task_obj.enabled != is_periodic:
|
||||
task_obj.enabled = is_periodic
|
||||
task_obj.save()
|
||||
return super().perform_update(serializer)
|
||||
|
||||
|
||||
class FTPLogViewSet(OrgModelViewSet):
|
||||
model = FTPLog
|
||||
|
|
|
@ -38,10 +38,12 @@ class JobsAuditSerializer(JobSerializer):
|
|||
material = serializers.ReadOnlyField(label=_("Command"))
|
||||
summary = serializers.ReadOnlyField(label=_("Summary"))
|
||||
crontab = serializers.ReadOnlyField(label=_("Execution cycle"))
|
||||
is_periodic_display = serializers.BooleanField(read_only=True, source='is_periodic')
|
||||
|
||||
class Meta(JobSerializer.Meta):
|
||||
read_only_fields = [
|
||||
"id", 'name', 'args', 'material', 'type', 'crontab', 'interval', 'date_last_run', 'summary', 'created_by'
|
||||
"id", 'name', 'args', 'material', 'type', 'crontab', 'interval', 'date_last_run', 'summary', 'created_by',
|
||||
'is_periodic_display'
|
||||
]
|
||||
fields = read_only_fields + ['is_periodic']
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.shortcuts import reverse
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from authentication.mixins import MFAFaceMixin
|
||||
from common.const import LicenseEditionChoices
|
||||
from settings.api import settings
|
||||
|
||||
|
||||
|
@ -32,7 +33,10 @@ class MFAFace(BaseMFA, MFAFaceMixin):
|
|||
|
||||
@staticmethod
|
||||
def global_enabled():
|
||||
return settings.XPACK_LICENSE_IS_VALID and settings.FACE_RECOGNITION_ENABLED
|
||||
return settings.XPACK_LICENSE_IS_VALID \
|
||||
and LicenseEditionChoices.ULTIMATE == \
|
||||
LicenseEditionChoices.from_key(settings.XPACK_LICENSE_EDITION) \
|
||||
and settings.FACE_RECOGNITION_ENABLED
|
||||
|
||||
def get_enable_url(self) -> str:
|
||||
return reverse('authentication:user-face-enable')
|
||||
|
|
|
@ -35,7 +35,7 @@ class MFAMiddleware:
|
|||
|
||||
# 这个是 mfa 登录页需要的请求, 也得放出来, 用户其实已经在 CAS/OIDC 中完成登录了
|
||||
white_urls = [
|
||||
'login/mfa', 'mfa/select', 'jsi18n/', '/static/',
|
||||
'login/mfa', 'mfa/select', 'mfa/face','jsi18n/', '/static/',
|
||||
'/profile/otp', '/logout/',
|
||||
]
|
||||
for url in white_urls:
|
||||
|
|
|
@ -238,7 +238,7 @@ class MFAFaceMixin:
|
|||
|
||||
if not self.is_context_success(context):
|
||||
msg = context.get('error_message', '')
|
||||
raise RuntimeError("Face recognition failed,{}".format(msg))
|
||||
raise RuntimeError(msg)
|
||||
|
||||
face_code = context.get('face_code')
|
||||
if not face_code:
|
||||
|
|
|
@ -2,28 +2,18 @@
|
|||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
<style>
|
||||
.ibox-content {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ibox-context-margin {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
{% if 'code' in form.errors %}
|
||||
<div class="alert alert-danger" id="messages">
|
||||
<p class="red-fonts">{{ form.code.errors.as_text }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div id="retry_container" style="text-align: center; margin-top: 20px; display: none;">
|
||||
<button id="retry_button" class="btn btn-primary">{% trans 'Retry' %}</button>
|
||||
</div>
|
||||
|
||||
<form class="m-t" role="form" method="post" action="" style="display: none">
|
||||
{% csrf_token %}
|
||||
<button id="submit_button" type="submit" style="display: none"></button>
|
||||
|
@ -40,9 +30,7 @@
|
|||
</iframe>
|
||||
</div>
|
||||
|
||||
<div id="retry_container" style="text-align: center; margin-top: 20px; display: none;">
|
||||
<button id="retry_button" class="btn btn-primary">{% trans 'Retry' %}</button>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
|
|
|
@ -76,3 +76,32 @@ class Language(models.TextChoices):
|
|||
|
||||
|
||||
COUNTRY_CALLING_CODES = get_country_phone_choices()
|
||||
|
||||
|
||||
class LicenseEditionChoices(models.TextChoices):
|
||||
COMMUNITY = 'community', _('Community edition')
|
||||
BASIC = 'basic', _('Basic edition')
|
||||
STANDARD = 'standard', _('Standard edition')
|
||||
PROFESSIONAL = 'professional', _('Professional edition')
|
||||
ULTIMATE = 'ultimate', _('Ultimate edition')
|
||||
|
||||
@staticmethod
|
||||
def from_key(key: str):
|
||||
for choice in LicenseEditionChoices:
|
||||
if choice == key:
|
||||
return choice
|
||||
return LicenseEditionChoices.COMMUNITY
|
||||
@staticmethod
|
||||
def parse_license_edition(info):
|
||||
count = info.get('license', {}).get('count', 0)
|
||||
|
||||
if 50 >= count > 0:
|
||||
return LicenseEditionChoices.BASIC
|
||||
elif count <= 500:
|
||||
return LicenseEditionChoices.STANDARD
|
||||
elif count < 5000:
|
||||
return LicenseEditionChoices.PROFESSIONAL
|
||||
elif count >= 5000:
|
||||
return LicenseEditionChoices.ULTIMATE
|
||||
else:
|
||||
return LicenseEditionChoices.COMMUNITY
|
||||
|
|
|
@ -73,6 +73,7 @@ known_unauth_urls = [
|
|||
"/api/v1/authentication/password/reset-code/",
|
||||
"/api/v1/authentication/login-confirm-ticket/status/",
|
||||
"/api/v1/authentication/mfa/select/",
|
||||
"/api/v1/authentication/mfa/face/context/",
|
||||
"/api/v1/authentication/mfa/send-code/",
|
||||
"/api/v1/authentication/sso/login/",
|
||||
"/api/v1/authentication/user-session/",
|
||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: JumpServer 0.3.3\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-11-19 18:55+0800\n"
|
||||
"POT-Creation-Date: 2024-11-20 19:32+0800\n"
|
||||
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
|
||||
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
||||
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
||||
|
@ -35,7 +35,7 @@ msgstr "生成资产或应用相关备份信息文件"
|
|||
|
||||
#: accounts/automations/backup_account/handlers.py:156
|
||||
#: accounts/automations/backup_account/handlers.py:295
|
||||
#: accounts/automations/backup_account/manager.py:40 ops/serializers/job.py:82
|
||||
#: accounts/automations/backup_account/manager.py:40 ops/serializers/job.py:94
|
||||
#: settings/templates/ldap/_msg_import_ldap_user.html:7
|
||||
msgid "Time cost"
|
||||
msgstr "花费时间"
|
||||
|
@ -57,7 +57,7 @@ msgid "The backup file will be sent to"
|
|||
msgstr "备份文件将被发送至"
|
||||
|
||||
#: accounts/automations/backup_account/handlers.py:213
|
||||
#: users/forms/profile.py:75
|
||||
#: users/forms/profile.py:76
|
||||
msgid "Finish"
|
||||
msgstr "完成"
|
||||
|
||||
|
@ -130,7 +130,7 @@ msgstr ">>> 开始执行测试网关账号可连接性任务"
|
|||
#: settings/serializers/auth/ldap.py:26 settings/serializers/auth/ldap.py:52
|
||||
#: settings/serializers/auth/ldap_ha.py:34 settings/serializers/msg.py:37
|
||||
#: settings/serializers/terminal.py:28 terminal/serializers/storage.py:123
|
||||
#: terminal/serializers/storage.py:142 users/forms/profile.py:21
|
||||
#: terminal/serializers/storage.py:142 users/forms/profile.py:22
|
||||
#: users/serializers/user.py:144
|
||||
#: users/templates/users/_msg_user_created.html:13
|
||||
#: users/templates/users/user_password_verify.html:18
|
||||
|
@ -149,7 +149,7 @@ msgid "Access key"
|
|||
msgstr "Access key"
|
||||
|
||||
#: accounts/const/account.py:9 authentication/backends/passkey/models.py:16
|
||||
#: authentication/models/sso_token.py:14 settings/serializers/feature.py:74
|
||||
#: authentication/models/sso_token.py:14 settings/serializers/feature.py:83
|
||||
msgid "Token"
|
||||
msgstr "令牌"
|
||||
|
||||
|
@ -233,17 +233,17 @@ msgstr "指定"
|
|||
msgid "Random generate"
|
||||
msgstr "随机生成"
|
||||
|
||||
#: accounts/const/automation.py:52 ops/const.py:13
|
||||
msgid "Append SSH KEY"
|
||||
msgstr "追加"
|
||||
#: accounts/const/automation.py:52 ops/const.py:15
|
||||
msgid "Replace (Replace only keys pushed by JumpServer) "
|
||||
msgstr "替换 (只替换由 JumpServer 推送的密钥)"
|
||||
|
||||
#: accounts/const/automation.py:53 ops/const.py:14
|
||||
msgid "Empty and append SSH KEY"
|
||||
msgstr "清空所有并添加"
|
||||
|
||||
#: accounts/const/automation.py:54 ops/const.py:15
|
||||
msgid "Replace (Replace only keys pushed by JumpServer) "
|
||||
msgstr "替换 (只替换由 JumpServer 推送的密钥)"
|
||||
#: accounts/const/automation.py:54 ops/const.py:13
|
||||
msgid "Append SSH KEY"
|
||||
msgstr "追加"
|
||||
|
||||
#: accounts/const/automation.py:59
|
||||
msgid "On asset create"
|
||||
|
@ -297,8 +297,8 @@ msgstr "仅创建"
|
|||
#: authentication/serializers/password_mfa.py:17
|
||||
#: authentication/serializers/password_mfa.py:25
|
||||
#: notifications/backends/__init__.py:10 settings/serializers/msg.py:21
|
||||
#: settings/serializers/msg.py:61 users/forms/profile.py:100
|
||||
#: users/forms/profile.py:108 users/models/user/__init__.py:65
|
||||
#: settings/serializers/msg.py:61 users/forms/profile.py:101
|
||||
#: users/forms/profile.py:111 users/models/user/__init__.py:65
|
||||
#: users/templates/users/forgot_password.html:162
|
||||
#: users/views/profile/reset.py:94
|
||||
msgid "Email"
|
||||
|
@ -319,11 +319,11 @@ msgstr "待定的"
|
|||
msgid "Database"
|
||||
msgstr "数据库"
|
||||
|
||||
#: accounts/const/vault.py:9 settings/serializers/feature.py:69
|
||||
#: accounts/const/vault.py:9 settings/serializers/feature.py:78
|
||||
msgid "HCP Vault"
|
||||
msgstr "HashiCorp Vault"
|
||||
|
||||
#: accounts/const/vault.py:10 settings/serializers/feature.py:82
|
||||
#: accounts/const/vault.py:10 settings/serializers/feature.py:91
|
||||
msgid "Azure Key Vault"
|
||||
msgstr "Azure Key Vault"
|
||||
|
||||
|
@ -510,7 +510,7 @@ msgstr "原因"
|
|||
#: accounts/models/automations/backup_account.py:136
|
||||
#: accounts/serializers/automations/change_secret.py:117
|
||||
#: accounts/serializers/automations/change_secret.py:152
|
||||
#: ops/serializers/job.py:80 terminal/serializers/session.py:54
|
||||
#: ops/serializers/job.py:92 terminal/serializers/session.py:54
|
||||
msgid "Is success"
|
||||
msgstr "是否成功"
|
||||
|
||||
|
@ -593,7 +593,7 @@ msgstr "结束日期"
|
|||
#: accounts/models/automations/change_secret.py:44
|
||||
#: assets/models/automations/base.py:113
|
||||
#: assets/serializers/automations/base.py:39 audits/models.py:208
|
||||
#: audits/serializers.py:76 ops/models/base.py:49 ops/models/job.py:235
|
||||
#: audits/serializers.py:78 ops/models/base.py:49 ops/models/job.py:235
|
||||
#: terminal/models/applet/applet.py:331 terminal/models/applet/host.py:140
|
||||
#: terminal/models/component/status.py:30
|
||||
#: terminal/models/virtualapp/virtualapp.py:99
|
||||
|
@ -635,8 +635,8 @@ msgstr "最后登录日期"
|
|||
#: authentication/forms.py:23 authentication/models/temp_token.py:9
|
||||
#: authentication/templates/authentication/_msg_different_city.html:9
|
||||
#: authentication/templates/authentication/_msg_oauth_bind.html:9
|
||||
#: terminal/serializers/storage.py:136 users/forms/profile.py:31
|
||||
#: users/forms/profile.py:114 users/models/user/__init__.py:63
|
||||
#: terminal/serializers/storage.py:136 users/forms/profile.py:32
|
||||
#: users/forms/profile.py:117 users/models/user/__init__.py:63
|
||||
#: users/templates/users/_msg_user_created.html:12
|
||||
#: xpack/plugins/cloud/serializers/account_attrs.py:26
|
||||
msgid "Username"
|
||||
|
@ -665,7 +665,7 @@ msgstr "触发方式"
|
|||
|
||||
#: accounts/models/automations/push_account.py:16 acls/models/base.py:41
|
||||
#: acls/serializers/base.py:57 assets/models/cmd_filter.py:81
|
||||
#: audits/models.py:92 audits/serializers.py:106
|
||||
#: audits/models.py:92 audits/serializers.py:108
|
||||
#: authentication/serializers/connect_token_secret.py:119
|
||||
#: authentication/templates/authentication/_access_key_modal.html:34
|
||||
#: perms/serializers/permission.py:52 perms/serializers/permission.py:74
|
||||
|
@ -734,7 +734,7 @@ msgstr "密码规则"
|
|||
#: 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/forms/profile.py:33 users/models/group.py:13
|
||||
#: users/models/preference.py:11 users/models/user/__init__.py:64
|
||||
#: xpack/plugins/cloud/models.py:34 xpack/plugins/cloud/models.py:310
|
||||
#: xpack/plugins/cloud/serializers/task.py:75
|
||||
|
@ -885,8 +885,8 @@ msgstr "类别"
|
|||
#: acls/serializers/command_acl.py:19 assets/models/automations/base.py:20
|
||||
#: assets/models/cmd_filter.py:74 assets/models/platform.py:96
|
||||
#: assets/serializers/asset/common.py:146 assets/serializers/platform.py:159
|
||||
#: assets/serializers/platform.py:171 audits/serializers.py:75
|
||||
#: audits/serializers.py:192
|
||||
#: assets/serializers/platform.py:171 audits/serializers.py:77
|
||||
#: audits/serializers.py:194
|
||||
#: authentication/serializers/connect_token_secret.py:126 ops/models/job.py:153
|
||||
#: perms/serializers/user_permission.py:27 terminal/models/applet/applet.py:40
|
||||
#: terminal/models/component/storage.py:58
|
||||
|
@ -959,7 +959,7 @@ msgstr "ID"
|
|||
#: acls/templates/acls/user_login_reminder.html:8
|
||||
#: assets/models/cmd_filter.py:24 assets/models/label.py:16 audits/models.py:54
|
||||
#: audits/models.py:90 audits/models.py:172 audits/models.py:271
|
||||
#: audits/serializers.py:193 authentication/models/connection_token.py:32
|
||||
#: audits/serializers.py:195 authentication/models/connection_token.py:32
|
||||
#: authentication/models/ssh_key.py:22 authentication/models/sso_token.py:16
|
||||
#: notifications/models/notification.py:12
|
||||
#: perms/api/user_permission/mixin.py:55 perms/models/asset_permission.py:63
|
||||
|
@ -1136,17 +1136,17 @@ msgstr "参数设置,目前只对 AIX LINUX UNIX 类型的资产有效。"
|
|||
msgid "Automation task execution"
|
||||
msgstr "自动化任务执行历史"
|
||||
|
||||
#: accounts/signal_handlers.py:48
|
||||
#: accounts/signal_handlers.py:51
|
||||
#, python-format
|
||||
msgid "Push related accounts to assets: %s, by system"
|
||||
msgstr "推送账号到资产: %s, 由系统执行"
|
||||
|
||||
#: accounts/signal_handlers.py:57
|
||||
#: accounts/signal_handlers.py:60
|
||||
#, python-format
|
||||
msgid "Add account: %s"
|
||||
msgstr "添加账号: %s"
|
||||
|
||||
#: accounts/signal_handlers.py:59
|
||||
#: accounts/signal_handlers.py:62
|
||||
#, python-format
|
||||
msgid "Delete account: %s"
|
||||
msgstr "删除账号: %s"
|
||||
|
@ -1269,11 +1269,11 @@ msgid ""
|
|||
" Accounts' this task will be executed"
|
||||
msgstr "当在控制台-账号模板-账号-同步更新账号信息点击同步时,执行该任务"
|
||||
|
||||
#: accounts/tasks/vault.py:32
|
||||
#: accounts/tasks/vault.py:33
|
||||
msgid "Sync secret to vault"
|
||||
msgstr "同步密文到 vault"
|
||||
|
||||
#: accounts/tasks/vault.py:34
|
||||
#: accounts/tasks/vault.py:35
|
||||
msgid ""
|
||||
"When clicking 'Sync' in 'System Settings - Features - Account Storage' this "
|
||||
"task will be executed"
|
||||
|
@ -1388,7 +1388,7 @@ msgstr "激活中"
|
|||
|
||||
#: acls/models/base.py:81 perms/serializers/permission.py:42
|
||||
#: tickets/models/flow.py:23 users/models/preference.py:16
|
||||
#: users/serializers/group.py:21 users/serializers/user.py:424
|
||||
#: users/serializers/group.py:21 users/serializers/user.py:432
|
||||
msgid "Users"
|
||||
msgstr "用户"
|
||||
|
||||
|
@ -1400,7 +1400,7 @@ msgid "Accounts"
|
|||
msgstr "账号"
|
||||
|
||||
#: acls/models/command_acl.py:16 assets/models/cmd_filter.py:60
|
||||
#: audits/serializers.py:38 ops/serializers/job.py:79 terminal/const.py:88
|
||||
#: audits/serializers.py:38 ops/serializers/job.py:91 terminal/const.py:88
|
||||
#: terminal/models/session/session.py:43 terminal/serializers/command.py:18
|
||||
#: terminal/templates/terminal/_msg_command_alert.html:12
|
||||
#: terminal/templates/terminal/_msg_command_execute_alert.html:10
|
||||
|
@ -1588,7 +1588,7 @@ msgid "Login city"
|
|||
msgstr "登录城市"
|
||||
|
||||
#: acls/templates/acls/user_login_reminder.html:11 audits/models.py:197
|
||||
#: audits/models.py:266 audits/serializers.py:90
|
||||
#: audits/models.py:266 audits/serializers.py:92
|
||||
msgid "User agent"
|
||||
msgstr "用户代理"
|
||||
|
||||
|
@ -1722,7 +1722,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:71 settings/serializers/feature.py:84
|
||||
#: settings/serializers/feature.py:80 settings/serializers/feature.py:93
|
||||
#: settings/serializers/msg.py:30 terminal/models/component/endpoint.py:14
|
||||
#: terminal/serializers/applet.py:17 xpack/plugins/cloud/manager.py:89
|
||||
#: xpack/plugins/cloud/serializers/account_attrs.py:72
|
||||
|
@ -2031,7 +2031,7 @@ msgstr "忽略证书校验"
|
|||
msgid "Postgresql SSL mode"
|
||||
msgstr "PostgreSQL SSL 模式"
|
||||
|
||||
#: assets/models/asset/gpt.py:8 settings/serializers/feature.py:114
|
||||
#: assets/models/asset/gpt.py:8 settings/serializers/feature.py:123
|
||||
msgid "Proxy"
|
||||
msgstr "代理"
|
||||
|
||||
|
@ -2858,7 +2858,7 @@ msgstr "是"
|
|||
msgid "No"
|
||||
msgstr "否"
|
||||
|
||||
#: audits/models.py:47 rbac/tree.py:67
|
||||
#: audits/models.py:47
|
||||
msgid "Job audit log"
|
||||
msgstr "作业审计日志"
|
||||
|
||||
|
@ -2867,7 +2867,7 @@ msgstr "作业审计日志"
|
|||
msgid "Remote addr"
|
||||
msgstr "远端地址"
|
||||
|
||||
#: audits/models.py:61 audits/serializers.py:60
|
||||
#: audits/models.py:61 audits/serializers.py:62
|
||||
msgid "Operate"
|
||||
msgstr "操作"
|
||||
|
||||
|
@ -2892,12 +2892,12 @@ msgstr "会话"
|
|||
msgid "File transfer log"
|
||||
msgstr "文件传输"
|
||||
|
||||
#: audits/models.py:94 audits/serializers.py:108
|
||||
#: audits/models.py:94 audits/serializers.py:110
|
||||
msgid "Resource Type"
|
||||
msgstr "资源类型"
|
||||
|
||||
#: audits/models.py:95 audits/models.py:98 audits/models.py:144
|
||||
#: audits/serializers.py:107 labels/serializers.py:46
|
||||
#: audits/serializers.py:109 labels/serializers.py:46
|
||||
msgid "Resource"
|
||||
msgstr "资源"
|
||||
|
||||
|
@ -2939,9 +2939,9 @@ msgstr "登录方式"
|
|||
msgid "Login IP"
|
||||
msgstr "登录 IP"
|
||||
|
||||
#: audits/models.py:200 audits/serializers.py:74
|
||||
#: audits/models.py:200 audits/serializers.py:76
|
||||
#: authentication/templates/authentication/_mfa_confirm_modal.html:14
|
||||
#: users/forms/profile.py:63 users/models/user/__init__.py:86
|
||||
#: users/forms/profile.py:64 users/models/user/__init__.py:86
|
||||
#: users/serializers/profile.py:70
|
||||
msgid "MFA"
|
||||
msgstr "MFA"
|
||||
|
@ -2992,20 +2992,20 @@ msgstr "汇总"
|
|||
msgid "Execution cycle"
|
||||
msgstr "周期执行"
|
||||
|
||||
#: audits/serializers.py:91
|
||||
#: audits/serializers.py:93
|
||||
msgid "Reason display"
|
||||
msgstr "原因描述"
|
||||
|
||||
#: audits/serializers.py:92 audits/serializers.py:206
|
||||
#: audits/serializers.py:94 audits/serializers.py:208
|
||||
msgid "Auth backend display"
|
||||
msgstr "认证方式"
|
||||
|
||||
#: audits/serializers.py:156
|
||||
#: audits/serializers.py:158
|
||||
#, python-format
|
||||
msgid "%s %s this resource"
|
||||
msgstr "用户 %s %s 了当前资源"
|
||||
|
||||
#: audits/serializers.py:194 authentication/models/connection_token.py:47
|
||||
#: audits/serializers.py:196 authentication/models/connection_token.py:47
|
||||
#: authentication/models/temp_token.py:13 perms/models/asset_permission.py:80
|
||||
#: tickets/models/ticket/apply_application.py:31
|
||||
#: tickets/models/ticket/apply_asset.py:20 users/models/user/__init__.py:105
|
||||
|
@ -3150,22 +3150,22 @@ msgstr "ACL 动作是复核"
|
|||
msgid "Current user not support mfa type: {}"
|
||||
msgstr "当前用户不支持 MFA 类型: {}"
|
||||
|
||||
#: authentication/api/password.py:33 terminal/api/session/session.py:334
|
||||
#: authentication/api/password.py:34 terminal/api/session/session.py:334
|
||||
#: users/views/profile/reset.py:63
|
||||
msgid "User does not exist: {}"
|
||||
msgstr "用户不存在: {}"
|
||||
|
||||
#: authentication/api/password.py:33 users/views/profile/reset.py:166
|
||||
#: authentication/api/password.py:34 users/views/profile/reset.py:166
|
||||
msgid "No user matched"
|
||||
msgstr "没有匹配到用户"
|
||||
|
||||
#: authentication/api/password.py:37
|
||||
#: authentication/api/password.py:38
|
||||
msgid ""
|
||||
"The user is from {}, please go to the corresponding system to change the "
|
||||
"password"
|
||||
msgstr "用户来自 {} 请去相应系统修改密码"
|
||||
|
||||
#: authentication/api/password.py:65
|
||||
#: authentication/api/password.py:69
|
||||
#: authentication/templates/authentication/login.html:393
|
||||
#: users/templates/users/forgot_password.html:41
|
||||
#: users/templates/users/forgot_password.html:42
|
||||
|
@ -3404,15 +3404,15 @@ msgstr "您的密码无效"
|
|||
msgid "Please wait for %s seconds before retry"
|
||||
msgstr "请在 %s 秒后重试"
|
||||
|
||||
#: authentication/errors/redirect.py:85 authentication/mixins.py:365
|
||||
#: authentication/errors/redirect.py:85 authentication/mixins.py:373
|
||||
msgid "Your password is too simple, please change it for security"
|
||||
msgstr "你的密码过于简单,为了安全,请修改"
|
||||
|
||||
#: authentication/errors/redirect.py:93 authentication/mixins.py:374
|
||||
#: authentication/errors/redirect.py:93 authentication/mixins.py:382
|
||||
msgid "You should to change your password before login"
|
||||
msgstr "登录完成前,请先修改密码"
|
||||
|
||||
#: authentication/errors/redirect.py:101 authentication/mixins.py:383
|
||||
#: authentication/errors/redirect.py:101 authentication/mixins.py:391
|
||||
msgid "Your password has expired, please reset before logging in"
|
||||
msgstr "您的密码已过期,先修改再登录"
|
||||
|
||||
|
@ -3433,7 +3433,7 @@ msgstr "MFA 类型"
|
|||
msgid "Captcha"
|
||||
msgstr "验证码"
|
||||
|
||||
#: authentication/forms.py:66 users/forms/profile.py:27
|
||||
#: authentication/forms.py:66 users/forms/profile.py:28
|
||||
msgid "MFA code"
|
||||
msgstr "MFA 验证码"
|
||||
|
||||
|
@ -3497,28 +3497,28 @@ msgstr "Radius 动态安全码"
|
|||
msgid "Radius global enabled, cannot disable"
|
||||
msgstr "Radius MFA 全局开启,无法被禁用"
|
||||
|
||||
#: authentication/mfa/sms.py:7
|
||||
#: authentication/mfa/sms.py:8
|
||||
msgid "SMS verify code invalid"
|
||||
msgstr "短信验证码校验失败"
|
||||
|
||||
#: authentication/mfa/sms.py:12 authentication/serializers/password_mfa.py:17
|
||||
#: authentication/mfa/sms.py:13 authentication/serializers/password_mfa.py:17
|
||||
#: authentication/serializers/password_mfa.py:25
|
||||
#: settings/serializers/auth/sms.py:18 settings/serializers/auth/sms.py:36
|
||||
#: users/forms/profile.py:103 users/forms/profile.py:108
|
||||
#: users/forms/profile.py:104 users/forms/profile.py:111
|
||||
#: users/templates/users/forgot_password.html:157
|
||||
#: users/views/profile/reset.py:100
|
||||
msgid "SMS"
|
||||
msgstr "短信"
|
||||
|
||||
#: authentication/mfa/sms.py:13
|
||||
#: authentication/mfa/sms.py:14
|
||||
msgid "SMS verification code"
|
||||
msgstr "短信验证码"
|
||||
|
||||
#: authentication/mfa/sms.py:57
|
||||
#: authentication/mfa/sms.py:63
|
||||
msgid "Set phone number to enable"
|
||||
msgstr "设置手机号码启用"
|
||||
|
||||
#: authentication/mfa/sms.py:61
|
||||
#: authentication/mfa/sms.py:67
|
||||
msgid "Clear phone number to disable"
|
||||
msgstr "清空手机号码禁用"
|
||||
|
||||
|
@ -3536,11 +3536,11 @@ msgid ""
|
|||
" The current user source is {}. Please contact the administrator."
|
||||
msgstr "管理员已开启'仅允许从用户来源登录',当前用户来源为{},请联系管理员。"
|
||||
|
||||
#: authentication/mixins.py:311
|
||||
#: authentication/mixins.py:319
|
||||
msgid "The MFA type ({}) is not enabled"
|
||||
msgstr "该 MFA ({}) 方式没有启用"
|
||||
|
||||
#: authentication/mixins.py:353
|
||||
#: authentication/mixins.py:361
|
||||
msgid "Please change your password"
|
||||
msgstr "请修改密码"
|
||||
|
||||
|
@ -3641,7 +3641,7 @@ msgid "Private key"
|
|||
msgstr "ssh私钥"
|
||||
|
||||
#: authentication/models/ssh_key.py:18 settings/serializers/terminal.py:34
|
||||
#: users/forms/profile.py:172 users/models/user/__init__.py:96
|
||||
#: users/forms/profile.py:175 users/models/user/__init__.py:96
|
||||
#: xpack/plugins/cloud/serializers/account_attrs.py:210
|
||||
msgid "Public key"
|
||||
msgstr "SSH公钥"
|
||||
|
@ -3752,7 +3752,7 @@ msgid ""
|
|||
"downloaded once"
|
||||
msgstr "创建完成后请下载私钥,每个私钥只有一次下载机会"
|
||||
|
||||
#: authentication/serializers/ssh_key.py:57 users/forms/profile.py:161
|
||||
#: authentication/serializers/ssh_key.py:57 users/forms/profile.py:164
|
||||
#: users/serializers/profile.py:133 users/serializers/profile.py:160
|
||||
msgid "Not a valid ssh public key"
|
||||
msgstr "SSH密钥不合法"
|
||||
|
@ -3886,7 +3886,7 @@ msgstr "重新申请"
|
|||
#: authentication/templates/authentication/_msg_reset_password_code.html:12
|
||||
#: terminal/models/session/sharing.py:27 terminal/models/session/sharing.py:97
|
||||
#: terminal/templates/terminal/_msg_session_sharing.html:12
|
||||
#: users/forms/profile.py:106 users/templates/users/forgot_password.html:98
|
||||
#: users/forms/profile.py:108 users/templates/users/forgot_password.html:98
|
||||
msgid "Verify code"
|
||||
msgstr "验证码"
|
||||
|
||||
|
@ -3934,7 +3934,7 @@ msgstr "如果这次公钥更新不是由你发起的,那么你的账号可能
|
|||
msgid "Cancel"
|
||||
msgstr "取消"
|
||||
|
||||
#: authentication/templates/authentication/face_capture.html:44
|
||||
#: authentication/templates/authentication/face_capture.html:14
|
||||
msgid "Retry"
|
||||
msgstr "重试"
|
||||
|
||||
|
@ -4706,6 +4706,10 @@ msgstr "Ansible 已禁用"
|
|||
msgid "Skip hosts below:"
|
||||
msgstr "跳过以下主机: "
|
||||
|
||||
#: ops/api/adhoc.py:32
|
||||
msgid "Deleting other people's script is not allowed"
|
||||
msgstr "不允许删除别人的脚本"
|
||||
|
||||
#: ops/api/celery.py:66 ops/api/celery.py:81
|
||||
msgid "Waiting task start"
|
||||
msgstr "等待任务开始"
|
||||
|
@ -4750,6 +4754,10 @@ msgid ""
|
|||
"The task is being created and cannot be interrupted. Please try again later."
|
||||
msgstr "正在创建任务,无法中断,请稍后重试。"
|
||||
|
||||
#: ops/api/playbook.py:49
|
||||
msgid "Deleting other people's playbook is not allowed"
|
||||
msgstr "不允许删除别人的playbook"
|
||||
|
||||
#: ops/api/playbook.py:55
|
||||
msgid "Currently playbook is being used in a job"
|
||||
msgstr "当前 playbook 正在作业中使用"
|
||||
|
@ -4815,7 +4823,7 @@ msgid "VCS"
|
|||
msgstr "VCS"
|
||||
|
||||
#: ops/const.py:38 ops/models/adhoc.py:44 ops/models/variable.py:26
|
||||
#: settings/serializers/feature.py:145
|
||||
#: settings/serializers/feature.py:154
|
||||
msgid "Adhoc"
|
||||
msgstr "命令"
|
||||
|
||||
|
@ -5024,7 +5032,7 @@ msgstr "运行用户"
|
|||
msgid "Run as policy"
|
||||
msgstr "用户策略"
|
||||
|
||||
#: ops/models/job.py:223 ops/models/variable.py:28 ops/serializers/job.py:98
|
||||
#: ops/models/job.py:223 ops/models/variable.py:28 ops/serializers/job.py:110
|
||||
#: terminal/notifications.py:182
|
||||
msgid "Job"
|
||||
msgstr "作业"
|
||||
|
@ -5115,23 +5123,23 @@ msgstr "下次执行时间"
|
|||
msgid "Execute after saving"
|
||||
msgstr "保存后执行"
|
||||
|
||||
#: ops/serializers/job.py:58 terminal/serializers/session.py:49
|
||||
#: ops/serializers/job.py:70 terminal/serializers/session.py:49
|
||||
msgid "Duration"
|
||||
msgstr "时长"
|
||||
|
||||
#: ops/serializers/job.py:78
|
||||
#: ops/serializers/job.py:90
|
||||
msgid "Job type"
|
||||
msgstr "任务类型"
|
||||
|
||||
#: ops/serializers/job.py:81 terminal/serializers/session.py:58
|
||||
#: ops/serializers/job.py:93 terminal/serializers/session.py:58
|
||||
msgid "Is finished"
|
||||
msgstr "是否完成"
|
||||
|
||||
#: ops/serializers/job.py:95
|
||||
#: ops/serializers/job.py:107
|
||||
msgid "Task id"
|
||||
msgstr "任务 ID"
|
||||
|
||||
#: ops/serializers/job.py:104
|
||||
#: ops/serializers/job.py:116
|
||||
msgid "You do not have permission for the current job."
|
||||
msgstr "你没有当前作业的权限。"
|
||||
|
||||
|
@ -5441,7 +5449,7 @@ msgid "today"
|
|||
msgstr "今天"
|
||||
|
||||
#: perms/notifications.py:12 perms/notifications.py:44
|
||||
#: settings/serializers/feature.py:136
|
||||
#: settings/serializers/feature.py:145
|
||||
msgid "day"
|
||||
msgstr "天"
|
||||
|
||||
|
@ -5696,7 +5704,7 @@ msgstr "账号改密"
|
|||
msgid "App ops"
|
||||
msgstr "作业中心"
|
||||
|
||||
#: rbac/tree.py:57 settings/serializers/feature.py:142
|
||||
#: rbac/tree.py:57 settings/serializers/feature.py:151
|
||||
msgid "Feature"
|
||||
msgstr "功能"
|
||||
|
||||
|
@ -5719,10 +5727,14 @@ msgid "Appearance"
|
|||
msgstr "界面"
|
||||
|
||||
#: rbac/tree.py:65 xpack/plugins/license/meta.py:10
|
||||
#: xpack/plugins/license/models.py:155
|
||||
#: xpack/plugins/license/models.py:154
|
||||
msgid "License"
|
||||
msgstr "许可证"
|
||||
|
||||
#: rbac/tree.py:67
|
||||
msgid "Job audit"
|
||||
msgstr "作业审计"
|
||||
|
||||
#: rbac/tree.py:159
|
||||
msgid "App organizations"
|
||||
msgstr "组织管理"
|
||||
|
@ -5731,8 +5743,8 @@ msgstr "组织管理"
|
|||
msgid "Ticket comment"
|
||||
msgstr "工单评论"
|
||||
|
||||
#: rbac/tree.py:161 settings/serializers/feature.py:123
|
||||
#: settings/serializers/feature.py:125 tickets/models/ticket/general.py:308
|
||||
#: rbac/tree.py:161 settings/serializers/feature.py:132
|
||||
#: settings/serializers/feature.py:134 tickets/models/ticket/general.py:308
|
||||
msgid "Ticket"
|
||||
msgstr "工单"
|
||||
|
||||
|
@ -6143,13 +6155,13 @@ msgstr "图标"
|
|||
msgid "Service provider"
|
||||
msgstr "服务提供商"
|
||||
|
||||
#: settings/serializers/auth/oauth2.py:31 settings/serializers/feature.py:87
|
||||
#: settings/serializers/auth/oauth2.py:31 settings/serializers/feature.py:96
|
||||
#: xpack/plugins/cloud/serializers/account_attrs.py:35
|
||||
msgid "Client ID"
|
||||
msgstr "客户端 ID"
|
||||
|
||||
#: settings/serializers/auth/oauth2.py:34 settings/serializers/auth/oidc.py:24
|
||||
#: settings/serializers/feature.py:90
|
||||
#: settings/serializers/feature.py:99
|
||||
#: xpack/plugins/cloud/serializers/account_attrs.py:38
|
||||
msgid "Client Secret"
|
||||
msgstr "客户端密钥"
|
||||
|
@ -6590,19 +6602,19 @@ msgstr "结束日期"
|
|||
msgid "Announcement"
|
||||
msgstr "公告"
|
||||
|
||||
#: settings/serializers/feature.py:47 settings/serializers/feature.py:50
|
||||
#: settings/serializers/feature.py:56 settings/serializers/feature.py:59
|
||||
msgid "Vault"
|
||||
msgstr "启用 Vault"
|
||||
|
||||
#: settings/serializers/feature.py:53
|
||||
#: settings/serializers/feature.py:62
|
||||
msgid "Vault provider"
|
||||
msgstr "保管库服务商"
|
||||
|
||||
#: settings/serializers/feature.py:57
|
||||
#: settings/serializers/feature.py:66
|
||||
msgid "Record limit"
|
||||
msgstr "记录限制"
|
||||
|
||||
#: settings/serializers/feature.py:59
|
||||
#: settings/serializers/feature.py:68
|
||||
msgid ""
|
||||
"If the specific value is less than 999 (default), the system will "
|
||||
"automatically perform a task every night: check and delete historical "
|
||||
|
@ -6612,83 +6624,83 @@ msgstr ""
|
|||
"若特定数值小于999,系统将在每日晚间自动执行任务:检查并删除超出预定数量的历史"
|
||||
"账号。如果该数值达到或超过999,则不进行任何历史账号的删除操作。"
|
||||
|
||||
#: settings/serializers/feature.py:77
|
||||
#: settings/serializers/feature.py:86
|
||||
msgid "Mount Point"
|
||||
msgstr "挂载点"
|
||||
|
||||
#: settings/serializers/feature.py:93
|
||||
#: settings/serializers/feature.py:102
|
||||
#: xpack/plugins/cloud/serializers/account_attrs.py:41
|
||||
msgid "Tenant ID"
|
||||
msgstr "租户 ID"
|
||||
|
||||
#: settings/serializers/feature.py:98 settings/serializers/feature.py:104
|
||||
#: settings/serializers/feature.py:107 settings/serializers/feature.py:113
|
||||
msgid "Chat AI"
|
||||
msgstr "聊天 AI"
|
||||
|
||||
#: settings/serializers/feature.py:107
|
||||
#: settings/serializers/feature.py:116
|
||||
msgid "GPT Base URL"
|
||||
msgstr "GPT 地址"
|
||||
|
||||
#: settings/serializers/feature.py:108
|
||||
#: settings/serializers/feature.py:117
|
||||
msgid "The base URL of the GPT service. For example: https://api.openai.com/v1"
|
||||
msgstr "GPT 服务的基本 URL。例如:https://api.openai.com/v1"
|
||||
|
||||
#: settings/serializers/feature.py:111 templates/_header_bar.html:96
|
||||
#: settings/serializers/feature.py:120 templates/_header_bar.html:96
|
||||
msgid "API Key"
|
||||
msgstr "API Key"
|
||||
|
||||
#: settings/serializers/feature.py:115
|
||||
#: settings/serializers/feature.py:124
|
||||
msgid ""
|
||||
"The proxy server address of the GPT service. For example: http://ip:port"
|
||||
msgstr "GPT 服务的代理服务器地址。例如:http://ip:port"
|
||||
|
||||
#: settings/serializers/feature.py:118
|
||||
#: settings/serializers/feature.py:127
|
||||
msgid "GPT Model"
|
||||
msgstr "GPT 模型"
|
||||
|
||||
#: settings/serializers/feature.py:127
|
||||
#: settings/serializers/feature.py:136
|
||||
msgid "Approval without login"
|
||||
msgstr "免登录审批"
|
||||
|
||||
#: settings/serializers/feature.py:128
|
||||
#: settings/serializers/feature.py:137
|
||||
msgid "Allow direct approval ticket without login"
|
||||
msgstr "允许无需登录直接批准工单"
|
||||
|
||||
#: settings/serializers/feature.py:132
|
||||
#: settings/serializers/feature.py:141
|
||||
msgid "Period"
|
||||
msgstr "时段"
|
||||
|
||||
#: settings/serializers/feature.py:133
|
||||
#: settings/serializers/feature.py:142
|
||||
msgid ""
|
||||
"The default authorization time period when applying for assets via a ticket"
|
||||
msgstr "工单申请资产的默认授权时间段"
|
||||
|
||||
#: settings/serializers/feature.py:136
|
||||
#: settings/serializers/feature.py:145
|
||||
msgid "hour"
|
||||
msgstr "时"
|
||||
|
||||
#: settings/serializers/feature.py:137
|
||||
#: settings/serializers/feature.py:146
|
||||
msgid "Unit"
|
||||
msgstr "单位"
|
||||
|
||||
#: settings/serializers/feature.py:137
|
||||
#: settings/serializers/feature.py:146
|
||||
msgid "The unit of period"
|
||||
msgstr "执行周期"
|
||||
|
||||
#: settings/serializers/feature.py:146
|
||||
#: settings/serializers/feature.py:155
|
||||
msgid ""
|
||||
"Allow users to execute batch commands in the Workbench - Job Center - Adhoc"
|
||||
msgstr "允许用户在工作台 - 作业中心 - Adhoc 中执行批量命令"
|
||||
|
||||
#: settings/serializers/feature.py:150
|
||||
#: settings/serializers/feature.py:159
|
||||
msgid "Command blacklist"
|
||||
msgstr "作业中心命令黑名单"
|
||||
|
||||
#: settings/serializers/feature.py:151
|
||||
#: settings/serializers/feature.py:160
|
||||
msgid "Command blacklist in Adhoc"
|
||||
msgstr "作业中心命令黑名单"
|
||||
|
||||
#: settings/serializers/feature.py:156
|
||||
#: settings/serializers/feature.py:165
|
||||
#: terminal/models/virtualapp/provider.py:17
|
||||
#: terminal/models/virtualapp/virtualapp.py:36
|
||||
#: terminal/models/virtualapp/virtualapp.py:97
|
||||
|
@ -6696,11 +6708,11 @@ msgstr "作业中心命令黑名单"
|
|||
msgid "Virtual app"
|
||||
msgstr "虚拟应用"
|
||||
|
||||
#: settings/serializers/feature.py:159
|
||||
#: settings/serializers/feature.py:168
|
||||
msgid "Virtual App"
|
||||
msgstr "虚拟应用"
|
||||
|
||||
#: settings/serializers/feature.py:161
|
||||
#: settings/serializers/feature.py:170
|
||||
msgid ""
|
||||
"Virtual applications, you can use the Linux operating system as an "
|
||||
"application server in remote applications."
|
||||
|
@ -7351,7 +7363,7 @@ msgstr "文档"
|
|||
msgid "Commercial support"
|
||||
msgstr "商业支持"
|
||||
|
||||
#: templates/_header_bar.html:85 users/forms/profile.py:43
|
||||
#: templates/_header_bar.html:85 users/forms/profile.py:44
|
||||
msgid "Profile"
|
||||
msgstr "个人信息"
|
||||
|
||||
|
@ -9051,7 +9063,7 @@ msgstr "无法删除全部用户"
|
|||
msgid "Create failed. The number of SSH keys has reached the limit"
|
||||
msgstr "创建失败,SSH密钥数量已达到上限"
|
||||
|
||||
#: users/forms/profile.py:48
|
||||
#: users/forms/profile.py:49
|
||||
msgid ""
|
||||
"When enabled, you will enter the MFA binding process the next time you log "
|
||||
"in. you can also directly bind in \"personal information -> quick "
|
||||
|
@ -9060,11 +9072,11 @@ msgstr ""
|
|||
"启用之后您将会在下次登录时进入多因子认证绑定流程;您也可以在 (个人信息->快速"
|
||||
"修改->设置 MFA 多因子认证)中直接绑定!"
|
||||
|
||||
#: users/forms/profile.py:59
|
||||
#: users/forms/profile.py:60
|
||||
msgid "* Enable MFA to make the account more secure."
|
||||
msgstr "* 启用 MFA 多因子认证,使账号更加安全。"
|
||||
|
||||
#: users/forms/profile.py:68
|
||||
#: users/forms/profile.py:69
|
||||
msgid ""
|
||||
"In order to protect you and your company, please keep your account, password "
|
||||
"and key sensitive information properly. (for example: setting complex "
|
||||
|
@ -9073,47 +9085,47 @@ msgstr ""
|
|||
"为了保护您和公司的安全,请妥善保管您的账号、密码和密钥等重要敏感信息; (如:"
|
||||
"设置复杂密码,并启用 MFA 多因子认证)"
|
||||
|
||||
#: users/forms/profile.py:82 users/serializers/preference/lina.py:21
|
||||
#: users/forms/profile.py:83 users/serializers/preference/lina.py:21
|
||||
msgid "New password"
|
||||
msgstr "新密码"
|
||||
|
||||
#: users/forms/profile.py:87 users/serializers/preference/lina.py:26
|
||||
#: users/forms/profile.py:88 users/serializers/preference/lina.py:26
|
||||
msgid "Confirm password"
|
||||
msgstr "确认密码"
|
||||
|
||||
#: users/forms/profile.py:95
|
||||
#: users/forms/profile.py:96
|
||||
msgid "Password does not match"
|
||||
msgstr "密码不一致"
|
||||
|
||||
#: users/forms/profile.py:104
|
||||
#: users/forms/profile.py:105
|
||||
msgid "The phone number must contain an area code, for example, +86"
|
||||
msgstr "手机号码必须包含区号,例如 +86"
|
||||
|
||||
#: users/forms/profile.py:120
|
||||
#: users/forms/profile.py:123
|
||||
msgid "Old password"
|
||||
msgstr "原来密码"
|
||||
|
||||
#: users/forms/profile.py:130
|
||||
#: users/forms/profile.py:133
|
||||
msgid "Old password error"
|
||||
msgstr "原来密码错误"
|
||||
|
||||
#: users/forms/profile.py:140
|
||||
#: users/forms/profile.py:143
|
||||
msgid "Automatically configure and download the SSH key"
|
||||
msgstr "自动配置并下载SSH密钥"
|
||||
|
||||
#: users/forms/profile.py:142
|
||||
#: users/forms/profile.py:145
|
||||
msgid "ssh public key"
|
||||
msgstr "SSH公钥"
|
||||
|
||||
#: users/forms/profile.py:143
|
||||
#: users/forms/profile.py:146
|
||||
msgid "ssh-rsa AAAA..."
|
||||
msgstr "ssh-rsa AAAA..."
|
||||
|
||||
#: users/forms/profile.py:144
|
||||
#: users/forms/profile.py:147
|
||||
msgid "Paste your id_rsa.pub here."
|
||||
msgstr "复制你的公钥到这里"
|
||||
|
||||
#: users/forms/profile.py:157
|
||||
#: users/forms/profile.py:160
|
||||
msgid "Public key should not be the same as your old one."
|
||||
msgstr "不能和原来的密钥相同"
|
||||
|
||||
|
@ -9422,12 +9434,12 @@ msgstr "MFA"
|
|||
msgid "Multi-Factor Authentication"
|
||||
msgstr "认证"
|
||||
|
||||
#: users/serializers/user.py:426
|
||||
#: users/serializers/user.py:434
|
||||
msgid ""
|
||||
"* For security, only a partial of users is displayed. You can search for more"
|
||||
msgstr "* 为安全起见,只显示部分用户。您可以搜索更多"
|
||||
|
||||
#: users/serializers/user.py:461
|
||||
#: users/serializers/user.py:469
|
||||
msgid "name not unique"
|
||||
msgstr "名称重复"
|
||||
|
||||
|
@ -10608,7 +10620,7 @@ msgstr "企业专业版"
|
|||
msgid "Ultimate edition"
|
||||
msgstr "企业旗舰版"
|
||||
|
||||
#: xpack/plugins/license/models.py:101
|
||||
#: xpack/plugins/license/models.py:100
|
||||
msgid "FIT2CLOUD"
|
||||
msgstr "飞致云"
|
||||
|
||||
|
|
|
@ -69,5 +69,7 @@
|
|||
"VerifyCode": "Verify Code",
|
||||
"WaitFileTransfer": "Wait file transfer to finish",
|
||||
"WebSocketClosed": "WebSocket closed",
|
||||
"Writable": "Writable"
|
||||
"Writable": "Writable",
|
||||
"UploadStart": "Upload start",
|
||||
"UploadEnd": "Upload completed, please wait for further processing"
|
||||
}
|
|
@ -69,5 +69,7 @@
|
|||
"VerifyCode": "認証コード",
|
||||
"WaitFileTransfer": "ファイル転送終了待ち",
|
||||
"WebSocketClosed": "WebSocket 閉店",
|
||||
"Writable": "書き込み可能"
|
||||
"Writable": "書き込み可能",
|
||||
"UploadStart": "アップロード開始",
|
||||
"UploadEnd": "アップロードが完了しました。後の処理をお待ちください"
|
||||
}
|
|
@ -65,6 +65,8 @@
|
|||
"UploadSuccess": "上传成功",
|
||||
"UploadTips": "将文件拖到此处,或点击上传",
|
||||
"UploadTitle": "上传文件",
|
||||
"UploadStart": "上传开始",
|
||||
"UploadEnd": "上传已完成,请等待后续处理",
|
||||
"User": "用户",
|
||||
"VerifyCode": "验证码",
|
||||
"WaitFileTransfer": "等待文件传输结束",
|
||||
|
|
|
@ -69,5 +69,7 @@
|
|||
"VerifyCode": "驗證碼",
|
||||
"WaitFileTransfer": "等待文件傳輸結束",
|
||||
"WebSocketClosed": "WebSocket 已關閉",
|
||||
"Writable": "讀寫"
|
||||
"Writable": "讀寫",
|
||||
"UploadStart": "上傳開始",
|
||||
"UploadEnd": "上傳已完成,請等待後續處理"
|
||||
}
|
|
@ -177,6 +177,8 @@
|
|||
"AwaitingMyApproval": "Assigned",
|
||||
"Azure": "Azure (China)",
|
||||
"Azure_Int": "Azure (International)",
|
||||
"AzureKeyVault": "Azure vault",
|
||||
"HashicorpVault": "HCP vault",
|
||||
"Backup": "Backup",
|
||||
"BackupAccountsHelpText": "Backup account information externally. it can be stored in an external system or sent via email, supporting segmented delivery.",
|
||||
"BadConflictErrorMsg": "Refreshing, please try again later",
|
||||
|
@ -651,7 +653,7 @@
|
|||
"JobCenter": "Job center",
|
||||
"JobCreate": "Create job",
|
||||
"JobDetail": "Job details",
|
||||
"JobExecutionLog": "Execution record",
|
||||
"JobExecutionLog": "Executions",
|
||||
"JobManagement": "Job List",
|
||||
"JobUpdate": "Update the job",
|
||||
"KingSoftCloud": "KingSoft cloud",
|
||||
|
@ -1411,7 +1413,7 @@
|
|||
"forceEnableMFAHelpText": "If force enable, user can not disable by themselves",
|
||||
"removeWarningMsg": "Are you sure you want to remove",
|
||||
"setVariable": "Set variable",
|
||||
"JobsAudit": "Jobs audit",
|
||||
"JobsAudit": "Job audits",
|
||||
"JobList": "Job List",
|
||||
"StopJobMsg": "Stop job successfully",
|
||||
"ExtraArgsFormatError": "Format error, please enter according to the requirements",
|
||||
|
|
|
@ -177,6 +177,8 @@
|
|||
"AwaitingMyApproval": "私の承認待ち",
|
||||
"Azure": "Azure(中国)",
|
||||
"Azure_Int": "アジュール(インターナショナル)",
|
||||
"AzureKeyVault": "Azure vault",
|
||||
"HashicorpVault": "HCP vault",
|
||||
"Backup": "バックアップ",
|
||||
"BackupAccountsHelpText": "アカウント情報を外部にバックアップする。外部システムに保存するかメールを送信することもできます、セクション方式をサポートしています",
|
||||
"BadConflictErrorMsg": "更新中です、しばらくお待ちください",
|
||||
|
|
|
@ -177,6 +177,8 @@
|
|||
"AwaitingMyApproval": "待我审批",
|
||||
"Azure": "Azure (中国)",
|
||||
"Azure_Int": "Azure (国际)",
|
||||
"AzureKeyVault": "Azure vault",
|
||||
"HashicorpVault": "HCP vault",
|
||||
"Backup": "备份",
|
||||
"BackupAccountsHelpText": "备份账号信息到外部。可以存储到外部系统或发送邮件,支持分段方式",
|
||||
"BadConflictErrorMsg": "正在刷新中,请稍后再试",
|
||||
|
|
|
@ -238,6 +238,8 @@
|
|||
"AwaitingMyApproval": "待我審批",
|
||||
"Azure": "Azure (中國)",
|
||||
"Azure_Int": "Azure (國際)",
|
||||
"AzureKeyVault": "Azure vault",
|
||||
"HashicorpVault": "HCP vault",
|
||||
"Backup": "備份",
|
||||
"BackupAccountsHelpText": "備份帳號資訊至外部。可以儲存到外部系統或寄送郵件,支援分段方式",
|
||||
"BadConflictErrorMsg": "正在刷新中,請稍後再試",
|
||||
|
|
|
@ -18,11 +18,12 @@ if not XPACK_DISABLED:
|
|||
XPACK_TEMPLATES_DIR = []
|
||||
XPACK_CONTEXT_PROCESSOR = []
|
||||
XPACK_LICENSE_IS_VALID = False
|
||||
XPACK_LICENSE_EDITION = ""
|
||||
XPACK_LICENSE_INFO = {
|
||||
'corporation': corporation,
|
||||
}
|
||||
|
||||
XPACK_LICENSE_CONTENT = ''
|
||||
XPACK_LICENSE_CONTENT = 'community'
|
||||
|
||||
if XPACK_ENABLED:
|
||||
from xpack.utils import get_xpack_templates_dir, get_xpack_context_processor
|
||||
|
|
|
@ -101,7 +101,7 @@ class ResourceDownload(TemplateView):
|
|||
MRD_VERSION=10.6.7
|
||||
OPENSSH_VERSION=v9.4.0.0
|
||||
TINKER_VERSION=v0.1.6
|
||||
VIDEO_PLAYER_VERSION=0.1.9
|
||||
VIDEO_PLAYER_VERSION=0.2.0
|
||||
CLIENT_VERSION=v2.1.3
|
||||
"""
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from django.db.models import Q
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from common.api.generic import JMSBulkModelViewSet
|
||||
from common.utils.http import is_true
|
||||
|
@ -28,7 +29,7 @@ class AdHocViewSet(JMSBulkModelViewSet):
|
|||
def check_object_permissions(self, request, obj):
|
||||
if request.method != 'GET' and obj.creator != request.user:
|
||||
self.permission_denied(
|
||||
request, message={"detail": "Deleting other people's script is not allowed"}
|
||||
request, message={"detail": _("Deleting other people's script is not allowed")}
|
||||
)
|
||||
return super().check_object_permissions(request, obj)
|
||||
|
||||
|
|
|
@ -105,6 +105,7 @@ class JobViewSet(OrgBulkModelViewSet):
|
|||
|
||||
def perform_update(self, serializer):
|
||||
run_after_save = serializer.validated_data.pop('run_after_save', False)
|
||||
self._parameters = serializer.validated_data.pop('parameters', None)
|
||||
instance = serializer.save()
|
||||
if run_after_save:
|
||||
self.run_job(instance, serializer)
|
||||
|
@ -227,9 +228,9 @@ class JobExecutionViewSet(OrgBulkModelViewSet):
|
|||
try:
|
||||
user = request.user
|
||||
if user.has_perm("audits.view_joblog"):
|
||||
instance = get_object_or_404(JobExecution, pk=task_id)
|
||||
instance = get_object_or_404(JobExecution, task_id=task_id)
|
||||
else:
|
||||
instance = get_object_or_404(JobExecution, pk=task_id, creator=request.user)
|
||||
instance = get_object_or_404(JobExecution, task_id=task_id, creator=request.user)
|
||||
except Http404:
|
||||
return Response(
|
||||
{'error': _('The task is being created and cannot be interrupted. Please try again later.')},
|
||||
|
|
|
@ -46,7 +46,7 @@ class PlaybookViewSet(JMSBulkModelViewSet):
|
|||
def check_object_permissions(self, request, obj):
|
||||
if request.method != 'GET' and obj.creator != request.user:
|
||||
self.permission_denied(
|
||||
request, message={"detail": "Deleting other people's playbook is not allowed"}
|
||||
request, message={"detail": _("Deleting other people's playbook is not allowed")}
|
||||
)
|
||||
return super().check_object_permissions(request, obj)
|
||||
|
||||
|
|
|
@ -38,6 +38,18 @@ class JobSerializer(BulkOrgResourceModelSerializer, PeriodTaskSerializerMixin, W
|
|||
user = request.user if request else None
|
||||
return user
|
||||
|
||||
def get_periodic_variable(self, variables):
|
||||
periodic_variable = {}
|
||||
for variable in variables:
|
||||
periodic_variable[variable['var_name']] = variable['default_value']
|
||||
return periodic_variable
|
||||
|
||||
def validate(self, attrs):
|
||||
attrs = super().validate(attrs)
|
||||
if attrs.get('is_periodic') is True:
|
||||
attrs['periodic_variable'] = self.get_periodic_variable(attrs.get('variable', []))
|
||||
return attrs
|
||||
|
||||
class Meta:
|
||||
model = Job
|
||||
read_only_fields = [
|
||||
|
|
|
@ -4,9 +4,12 @@ import os
|
|||
import aiofiles
|
||||
from asgiref.sync import sync_to_async
|
||||
from channels.generic.websocket import AsyncJsonWebsocketConsumer
|
||||
from http.cookies import SimpleCookie
|
||||
|
||||
from common.db.utils import close_old_connections
|
||||
from common.utils import get_logger
|
||||
from orgs.models import Organization
|
||||
from orgs.utils import tmp_to_org, current_org
|
||||
from rbac.builtin import BuiltinRole
|
||||
from .ansible.utils import get_ansible_task_log_path
|
||||
from .celery.utils import get_celery_task_log_path
|
||||
|
@ -18,6 +21,8 @@ logger = get_logger(__name__)
|
|||
|
||||
class TaskLogWebsocket(AsyncJsonWebsocketConsumer):
|
||||
disconnected = False
|
||||
cookie = None
|
||||
org = None
|
||||
user_tasks = (
|
||||
'ops.tasks.run_ops_job',
|
||||
'ops.tasks.run_ops_job_execution',
|
||||
|
@ -28,10 +33,25 @@ class TaskLogWebsocket(AsyncJsonWebsocketConsumer):
|
|||
'ansible': get_ansible_task_log_path
|
||||
}
|
||||
|
||||
def get_cookie(self):
|
||||
try:
|
||||
headers = self.scope['headers']
|
||||
headers_dict = {key.decode('utf-8'): value.decode('utf-8') for key, value in headers}
|
||||
cookie = SimpleCookie(headers_dict.get('cookie', ''))
|
||||
except Exception as e:
|
||||
cookie = SimpleCookie()
|
||||
return cookie
|
||||
|
||||
def get_current_org(self):
|
||||
oid = self.cookie.get('X-JMS-ORG')
|
||||
return oid.value if oid else None
|
||||
|
||||
async def connect(self):
|
||||
user = self.scope["user"]
|
||||
if user.is_authenticated:
|
||||
await self.accept()
|
||||
self.cookie = self.get_cookie()
|
||||
self.org = self.get_current_org()
|
||||
else:
|
||||
await self.close()
|
||||
|
||||
|
@ -51,10 +71,18 @@ class TaskLogWebsocket(AsyncJsonWebsocketConsumer):
|
|||
|
||||
@sync_to_async
|
||||
def get_current_user_role_ids(self, user):
|
||||
roles = user.system_roles.all() | user.org_roles.all()
|
||||
with tmp_to_org(self.org):
|
||||
org_roles = user.org_roles.all()
|
||||
system_roles = user.system_roles.all()
|
||||
roles = system_roles | org_roles
|
||||
user_role_ids = set(map(str, roles.values_list('id', flat=True)))
|
||||
return user_role_ids
|
||||
|
||||
@sync_to_async
|
||||
def has_perms(self, user, perms):
|
||||
with tmp_to_org(self.org):
|
||||
return user.has_perms(perms)
|
||||
|
||||
async def receive_json(self, content, **kwargs):
|
||||
task_id = content.get('task')
|
||||
task = await self.get_task(task_id)
|
||||
|
@ -71,8 +99,10 @@ class TaskLogWebsocket(AsyncJsonWebsocketConsumer):
|
|||
user = self.scope['user']
|
||||
user_role_ids = await self.get_current_user_role_ids(user)
|
||||
has_admin_auditor_role = bool(admin_auditor_role_ids & user_role_ids)
|
||||
|
||||
if not has_admin_auditor_role and task.name in self.user_tasks and task.creator != user:
|
||||
has_perms = await self.has_perms(user, ['audits.view_joblog'])
|
||||
user_can_view = task.name in self.user_tasks and (task.creator == user or has_perms)
|
||||
# (有管理员或审计员角色) 或者 (任务是用户自己创建的 或者 有查看任务日志权限), 其他情况没有权限
|
||||
if not (has_admin_auditor_role or user_can_view):
|
||||
await self.send_json({'message': 'No permission', 'task': task_id})
|
||||
return
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ extra_nodes_data = [
|
|||
{'id': "tasks", "name": _("Task"), "pId": "view_setting"},
|
||||
{'id': "license", "name": _("License"), "pId": "view_setting"},
|
||||
{'id': "other", "name": _("Other"), "pId": "view_setting"},
|
||||
{'id': "job_audit", "name": _("Job audit log"), "pId": "view_audit"},
|
||||
{'id': "job_audit", "name": _("Job audit"), "pId": "view_audit"},
|
||||
]
|
||||
|
||||
# 将 model 放到其它节点下,而不是本来的 app 中
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import uuid
|
||||
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from accounts.const import VaultTypeChoices
|
||||
from assets.const import Protocol
|
||||
from common.serializers.fields import EncryptedField
|
||||
from common.utils import date_expired_default
|
||||
|
@ -43,7 +43,16 @@ class AnnouncementSettingSerializer(serializers.Serializer):
|
|||
ANNOUNCEMENT = AnnouncementSerializer(label=_("Announcement"))
|
||||
|
||||
|
||||
class VaultSettingSerializer(serializers.Serializer):
|
||||
class BaseVaultSettingSerializer(serializers.Serializer):
|
||||
|
||||
def validate(self, data):
|
||||
from accounts.signal_handlers import vault_pub_sub
|
||||
data = super().validate(data)
|
||||
vault_pub_sub.publish('vault')
|
||||
return data
|
||||
|
||||
|
||||
class VaultSettingSerializer(BaseVaultSettingSerializer, serializers.Serializer):
|
||||
PREFIX_TITLE = _('Vault')
|
||||
|
||||
VAULT_ENABLED = serializers.BooleanField(
|
||||
|
@ -65,7 +74,7 @@ class VaultSettingSerializer(serializers.Serializer):
|
|||
)
|
||||
|
||||
|
||||
class HashicorpKVSerializer(serializers.Serializer):
|
||||
class HashicorpKVSerializer(BaseVaultSettingSerializer, serializers.Serializer):
|
||||
PREFIX_TITLE = _('HCP Vault')
|
||||
VAULT_HCP_HOST = serializers.CharField(
|
||||
max_length=256, allow_blank=True, required=False, label=_('Host')
|
||||
|
@ -78,7 +87,7 @@ class HashicorpKVSerializer(serializers.Serializer):
|
|||
)
|
||||
|
||||
|
||||
class AzureKVSerializer(serializers.Serializer):
|
||||
class AzureKVSerializer(BaseVaultSettingSerializer, serializers.Serializer):
|
||||
PREFIX_TITLE = _('Azure Key Vault')
|
||||
VAULT_AZURE_HOST = serializers.CharField(
|
||||
max_length=256, allow_blank=True, required=False, label=_('Host')
|
||||
|
|
|
@ -50,10 +50,10 @@ p {
|
|||
</div>
|
||||
|
||||
<div class="group">
|
||||
<h2>JumpServer {% trans 'Offline video player' %} v0.1.9</h2>
|
||||
<h2>JumpServer {% trans 'Offline video player' %} v{{ VIDEO_PLAYER_VERSION }}</h2>
|
||||
<ul>
|
||||
<li><a href="/download/public/JumpServer.Video.Player-{{ VIDEO_PLAYER_VERSION }}.dmg">jumpserver-video-player.dmg</a></li>
|
||||
<li><a href="/download/public/JumpServer.Video.Player.Setup.{{ VIDEO_PLAYER_VERSION }}.exe">jumpserver-video-player.exe</a></li>
|
||||
<li><a href="/download/public/JumpServerVideoPlayer-{{ VIDEO_PLAYER_VERSION }}.dmg">jumpserver-video-player.dmg</a></li>
|
||||
<li><a href="/download/public/JumpServerVideoPlayer-{{ VIDEO_PLAYER_VERSION }}.exe">jumpserver-video-player.exe</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue