Merge branch 'dev' of github.com:jumpserver/jumpserver into dev

pull/8877/head
ibuler 2022-09-21 14:09:57 +08:00
commit bbb802d894
29 changed files with 768 additions and 315 deletions

View File

@ -16,7 +16,7 @@ from .. import const
__all__ = [
'AppSerializer', 'MiniAppSerializer', 'AppSerializerMixin',
'AppAccountSerializer', 'AppAccountSecretSerializer'
'AppAccountSerializer', 'AppAccountSecretSerializer', 'AppAccountBackUpSerializer'
]
@ -32,21 +32,23 @@ class AppSerializerMixin(serializers.Serializer):
return instance
def get_attrs_serializer(self):
default_serializer = serializers.Serializer(read_only=True)
instance = self.app
if instance:
_type = instance.type
_category = instance.category
else:
_type = self.context['request'].query_params.get('type')
_category = self.context['request'].query_params.get('category')
if _type:
if isinstance(self, AppAccountSecretSerializer):
serializer_class = type_secret_serializer_classes_mapping.get(_type)
tp = getattr(self, 'tp', None)
default_serializer = serializers.Serializer(read_only=True)
if not tp:
if instance:
tp = instance.type
category = instance.category
else:
serializer_class = type_serializer_classes_mapping.get(_type)
elif _category:
serializer_class = category_serializer_classes_mapping.get(_category)
tp = self.context['request'].query_params.get('type')
category = self.context['request'].query_params.get('category')
if tp:
if isinstance(self, AppAccountBackUpSerializer):
serializer_class = type_secret_serializer_classes_mapping.get(tp)
else:
serializer_class = type_serializer_classes_mapping.get(tp)
elif category:
serializer_class = category_serializer_classes_mapping.get(category)
else:
serializer_class = default_serializer
@ -154,11 +156,6 @@ class AppAccountSerializer(AppSerializerMixin, AuthSerializerMixin, BulkOrgResou
class AppAccountSecretSerializer(SecretReadableMixin, AppAccountSerializer):
class Meta(AppAccountSerializer.Meta):
fields_backup = [
'id', 'app_display', 'attrs', 'username', 'password', 'private_key',
'public_key', 'date_created', 'date_updated', 'version'
]
extra_kwargs = {
'password': {'write_only': False},
'private_key': {'write_only': False},
@ -166,3 +163,22 @@ class AppAccountSecretSerializer(SecretReadableMixin, AppAccountSerializer):
'app_display': {'label': _('Application display')},
'systemuser_display': {'label': _('System User')}
}
class AppAccountBackUpSerializer(AppAccountSecretSerializer):
class Meta(AppAccountSecretSerializer.Meta):
fields = [
'id', 'app_display', 'attrs', 'username', 'password', 'private_key',
'public_key', 'date_created', 'date_updated', 'version'
]
def __init__(self, *args, **kwargs):
self.tp = kwargs.pop('tp', None)
super().__init__(*args, **kwargs)
@classmethod
def setup_eager_loading(cls, queryset):
return queryset
def to_representation(self, instance):
return super(AppAccountSerializer, self).to_representation(instance)

View File

@ -17,3 +17,10 @@ class DBSerializer(serializers.Serializer):
ca_cert = serializers.CharField(
required=False, allow_null=True, label=_('CA certificate')
)
client_cert = serializers.CharField(
required=False, allow_null=True, label=_('Client certificate file')
)
cert_key = serializers.CharField(
required=False, allow_null=True, label=_('Certificate key file')
)
allow_invalid_cert = serializers.BooleanField(default=False, label=_('Allow invalid cert'))

View File

@ -76,10 +76,6 @@ class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
class AccountSecretSerializer(SecretReadableMixin, AccountSerializer):
class Meta(AccountSerializer.Meta):
fields_backup = [
'hostname', 'ip', 'platform', 'protocols', 'username', 'password',
'private_key', 'public_key', 'date_created', 'date_updated', 'version'
]
extra_kwargs = {
'password': {'write_only': False},
'private_key': {'write_only': False},
@ -88,6 +84,22 @@ class AccountSecretSerializer(SecretReadableMixin, AccountSerializer):
}
class AccountBackUpSerializer(AccountSecretSerializer):
class Meta(AccountSecretSerializer.Meta):
fields = [
'id', 'hostname', 'ip', 'username', 'password',
'private_key', 'public_key', 'date_created',
'date_updated', 'version'
]
@classmethod
def setup_eager_loading(cls, queryset):
return queryset
def to_representation(self, instance):
return super(AccountSerializer, self).to_representation(instance)
class AccountTaskSerializer(serializers.Serializer):
ACTION_CHOICES = (
('test', 'test'),

View File

@ -4,15 +4,16 @@ from openpyxl import Workbook
from collections import defaultdict, OrderedDict
from django.conf import settings
from django.db.models import F
from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from assets.models import AuthBook
from assets.serializers import AccountSecretSerializer
from assets.models import AuthBook, SystemUser, Asset
from assets.serializers import AccountBackUpSerializer
from assets.notifications import AccountBackupExecutionTaskMsg
from applications.models import Account
from applications.models import Account, Application
from applications.const import AppType
from applications.serializers import AppAccountSecretSerializer
from applications.serializers import AppAccountBackUpSerializer
from users.models import User
from common.utils import get_logger
from common.utils.timezone import local_now_display
@ -38,7 +39,7 @@ class BaseAccountHandler:
@classmethod
def get_header_fields(cls, serializer: serializers.Serializer):
try:
backup_fields = getattr(serializer, 'Meta').fields_backup
backup_fields = getattr(serializer, 'Meta').fields
except AttributeError:
backup_fields = serializer.fields.keys()
header_fields = {}
@ -51,17 +52,41 @@ class BaseAccountHandler:
header_fields[field] = str(v.label)
return header_fields
@staticmethod
def load_auth(tp, value, system_user):
if value:
return value
if system_user:
return getattr(system_user, tp, '')
return ''
@classmethod
def create_row(cls, account, serializer_cls, header_fields=None):
serializer = serializer_cls(account)
if not header_fields:
header_fields = cls.get_header_fields(serializer)
data = cls.unpack_data(serializer.data)
def replace_auth(cls, account, system_user_dict):
system_user = system_user_dict.get(account.systemuser_id)
account.username = cls.load_auth('username', account.username, system_user)
account.password = cls.load_auth('password', account.password, system_user)
account.private_key = cls.load_auth('private_key', account.private_key, system_user)
account.public_key = cls.load_auth('public_key', account.public_key, system_user)
return account
@classmethod
def create_row(cls, data, header_fields):
data = cls.unpack_data(data)
row_dict = {}
for field, header_name in header_fields.items():
row_dict[header_name] = str(data[field])
row_dict[header_name] = str(data.get(field, field))
return row_dict
@classmethod
def add_rows(cls, data, header_fields, sheet):
data_map = defaultdict(list)
for i in data:
row = cls.create_row(i, header_fields)
if sheet not in data_map:
data_map[sheet].append(list(row.keys()))
data_map[sheet].append(list(row.values()))
return data_map
class AssetAccountHandler(BaseAccountHandler):
@staticmethod
@ -72,22 +97,27 @@ class AssetAccountHandler(BaseAccountHandler):
return filename
@classmethod
def create_data_map(cls):
data_map = defaultdict(list)
def replace_account_info(cls, account, asset_dict, system_user_dict):
asset = asset_dict.get(account.asset_id)
account.ip = asset.ip if asset else ''
account.hostname = asset.hostname if asset else ''
account = cls.replace_auth(account, system_user_dict)
return account
@classmethod
def create_data_map(cls, system_user_dict):
sheet_name = AuthBook._meta.verbose_name
assets = Asset.objects.only('id', 'hostname', 'ip')
asset_dict = {asset.id: asset for asset in assets}
accounts = AuthBook.objects.all()
if not accounts.exists():
return
accounts = AuthBook.get_queryset().select_related('systemuser')
if not accounts.first():
return data_map
header_fields = cls.get_header_fields(AccountSecretSerializer(accounts.first()))
header_fields = cls.get_header_fields(AccountBackUpSerializer(accounts.first()))
for account in accounts:
account.load_auth()
row = cls.create_row(account, AccountSecretSerializer, header_fields)
if sheet_name not in data_map:
data_map[sheet_name].append(list(row.keys()))
data_map[sheet_name].append(list(row.values()))
cls.replace_account_info(account, asset_dict, system_user_dict)
data = AccountBackUpSerializer(accounts, many=True).data
data_map = cls.add_rows(data, header_fields, sheet_name)
logger.info('\n\033[33m- 共收集 {} 条资产账号\033[0m'.format(accounts.count()))
return data_map
@ -101,18 +131,36 @@ class AppAccountHandler(BaseAccountHandler):
return filename
@classmethod
def create_data_map(cls):
data_map = defaultdict(list)
accounts = Account.get_queryset().select_related('systemuser')
for account in accounts:
account.load_auth()
app_type = account.type
def replace_account_info(cls, account, app_dict, system_user_dict):
app = app_dict.get(account.app_id)
account.type = app.type if app else ''
account.app_display = app.name if app else ''
account.category = app.category if app else ''
account = cls.replace_auth(account, system_user_dict)
return account
@classmethod
def create_data_map(cls, system_user_dict):
apps = Application.objects.only('id', 'type', 'name', 'category')
app_dict = {app.id: app for app in apps}
qs = Account.objects.all().annotate(app_type=F('app__type'))
if not qs.exists():
return
account_type_map = defaultdict(list)
for i in qs:
account_type_map[i.app_type].append(i)
data_map = {}
for app_type, accounts in account_type_map.items():
sheet_name = AppType.get_label(app_type)
row = cls.create_row(account, AppAccountSecretSerializer)
if sheet_name not in data_map:
data_map[sheet_name].append(list(row.keys()))
data_map[sheet_name].append(list(row.values()))
logger.info('\n\033[33m- 共收集{}条应用账号\033[0m'.format(accounts.count()))
header_fields = cls.get_header_fields(AppAccountBackUpSerializer(tp=app_type))
if not accounts:
continue
for account in accounts:
cls.replace_account_info(account, app_dict, system_user_dict)
data = AppAccountBackUpSerializer(accounts, many=True, tp=app_type).data
data_map.update(cls.add_rows(data, header_fields, sheet_name))
logger.info('\n\033[33m- 共收集{}条应用账号\033[0m'.format(qs.count()))
return data_map
@ -137,12 +185,16 @@ class AccountBackupHandler:
# Print task start date
time_start = time.time()
files = []
system_user_qs = SystemUser.objects.only(
'id', 'username', 'password', 'private_key', 'public_key'
)
system_user_dict = {i.id: i for i in system_user_qs}
for account_type in self.execution.types:
handler = handler_map.get(account_type)
if not handler:
continue
data_map = handler.create_data_map()
data_map = handler.create_data_map(system_user_dict)
if not data_map:
continue

View File

@ -7,5 +7,6 @@ from . import views
urlpatterns = [
path('login/', views.OAuth2AuthRequestView.as_view(), name='login'),
path('callback/', views.OAuth2AuthCallbackView.as_view(), name='login-callback')
path('callback/', views.OAuth2AuthCallbackView.as_view(), name='login-callback'),
path('logout/', views.OAuth2EndSessionView.as_view(), name='logout')
]

View File

@ -1,6 +1,6 @@
from django.views import View
from django.conf import settings
from django.contrib.auth import login
from django.contrib import auth
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils.http import urlencode
@ -48,7 +48,7 @@ class OAuth2AuthCallbackView(View):
user = authenticate(code=callback_params['code'], request=request)
if user and user.is_valid:
logger.debug(log_prompt.format('Login: {}'.format(user)))
login(self.request, user)
auth.login(self.request, user)
logger.debug(log_prompt.format('Redirect'))
return HttpResponseRedirect(
settings.AUTH_OAUTH2_AUTHENTICATION_REDIRECT_URI
@ -56,3 +56,33 @@ class OAuth2AuthCallbackView(View):
logger.debug(log_prompt.format('Redirect'))
return HttpResponseRedirect(settings.AUTH_OAUTH2_AUTHENTICATION_FAILURE_REDIRECT_URI)
class OAuth2EndSessionView(View):
http_method_names = ['get', 'post', ]
def get(self, request):
""" Processes GET requests. """
log_prompt = "Process GET requests [OAuth2EndSessionView]: {}"
logger.debug(log_prompt.format('Start'))
return self.post(request)
def post(self, request):
""" Processes POST requests. """
log_prompt = "Process POST requests [OAuth2EndSessionView]: {}"
logger.debug(log_prompt.format('Start'))
logout_url = settings.LOGOUT_REDIRECT_URL or '/'
# Log out the current user.
if request.user.is_authenticated:
logger.debug(log_prompt.format('Log out the current user: {}'.format(request.user)))
auth.logout(request)
if settings.AUTH_OAUTH2_LOGOUT_COMPLETELY:
logger.debug(log_prompt.format('Log out OAUTH2 platform user session synchronously'))
next_url = settings.AUTH_OAUTH2_PROVIDER_END_SESSION_ENDPOINT
return HttpResponseRedirect(next_url)
logger.debug(log_prompt.format('Redirect'))
return HttpResponseRedirect(logout_url)

View File

@ -3,7 +3,7 @@ import copy
from urllib import parse
from django.views import View
from django.contrib import auth as auth
from django.contrib import auth
from django.urls import reverse
from django.conf import settings
from django.views.decorators.csrf import csrf_exempt
@ -271,7 +271,10 @@ class Saml2AuthCallbackView(View, PrepareRequestMixin):
auth.login(self.request, user)
logger.debug(log_prompt.format('Redirect'))
next_url = saml_instance.redirect_to(post_data.get('RelayState', '/'))
redir = post_data.get('RelayState')
if not redir or len(redir) == 0:
redir = "/"
next_url = saml_instance.redirect_to(redir)
return HttpResponseRedirect(next_url)
@csrf_exempt

View File

@ -330,6 +330,8 @@ class UserLogoutView(TemplateView):
return settings.CAS_LOGOUT_URL_NAME
elif 'saml2' in backend:
return settings.SAML2_LOGOUT_URL_NAME
elif 'oauth2' in backend:
return settings.AUTH_OAUTH2_LOGOUT_URL_NAME
return None
def get(self, request, *args, **kwargs):

View File

@ -62,15 +62,22 @@ class UserConfirmation(permissions.BasePermission):
confirm_level = request.session.get('CONFIRM_LEVEL')
confirm_time = request.session.get('CONFIRM_TIME')
ttl = self.get_ttl()
if not confirm_level or not confirm_time or \
confirm_level < self.min_level or \
confirm_time < time.time() - self.ttl:
confirm_time < time.time() - ttl:
raise UserConfirmRequired(code=self.confirm_type)
return True
def get_ttl(self):
if self.confirm_type == ConfirmType.MFA:
ttl = settings.SECURITY_MFA_VERIFY_TTL
else:
ttl = self.ttl
return ttl
@classmethod
def require(cls, confirm_type=ConfirmType.ReLogin, ttl=300):
def require(cls, confirm_type=ConfirmType.ReLogin, ttl=60 * 5):
min_level = ConfirmType.values.index(confirm_type) + 1
name = 'UserConfirmationLevel{}TTL{}'.format(min_level, ttl)
return type(name, (cls,), {'min_level': min_level, 'ttl': ttl, 'confirm_type': confirm_type})

View File

@ -15,6 +15,7 @@ logger = get_logger(__name__)
class BACKENDS(TextChoices):
ALIBABA = 'alibaba', _('Alibaba cloud')
TENCENT = 'tencent', _('Tencent cloud')
HUAWEI = 'huawei', _('Huawei Cloud')
CMPP2 = 'cmpp2', _('CMPP v2.0')

View File

@ -0,0 +1,94 @@
import base64
import hashlib
import time
import uuid
import requests
from collections import OrderedDict
from django.conf import settings
from common.exceptions import JMSException
from common.utils import get_logger
from .base import BaseSMSClient
logger = get_logger(__file__)
class HuaweiClient:
def __init__(self, app_key, app_secret, url, sign_channel_num):
self.url = url[:-1] if url.endswith('/') else url
self.app_key = app_key
self.app_secret = app_secret
self.sign_channel_num = sign_channel_num
def build_wsse_header(self):
now = time.strftime('%Y-%m-%dT%H:%M:%SZ')
nonce = str(uuid.uuid4()).replace('-', '')
digest = hashlib.sha256((nonce + now + self.app_secret).encode()).hexdigest()
digestBase64 = base64.b64encode(digest.encode()).decode()
formatter = 'UsernameToken Username="{}",PasswordDigest="{}",Nonce="{}",Created="{}"'
return formatter.format(self.app_key, digestBase64, nonce, now)
def send_sms(self, receiver, signature, template_id, template_param):
sms_url = '%s/%s' % (self.url, 'sms/batchSendSms/v1')
headers = {
'Authorization': 'WSSE realm="SDP",profile="UsernameToken",type="Appkey"',
'X-WSSE': self.build_wsse_header()
}
body = {
'from': self.sign_channel_num, 'to': receiver, 'templateId': template_id,
'templateParas': template_param, 'signature': signature
}
try:
response = requests.post(sms_url, headers=headers, data=body)
msg = response.json()
except Exception as error:
raise JMSException(code='response_bad', detail=error)
return msg
class HuaweiSMS(BaseSMSClient):
SIGN_AND_TMPL_SETTING_FIELD_PREFIX = 'HUAWEI'
@classmethod
def new_from_settings(cls):
return cls(
app_key=settings.HUAWEI_APP_KEY,
app_secret=settings.HUAWEI_APP_SECRET,
url=settings.HUAWEI_SMS_ENDPOINT,
sign_channel_num=settings.HUAWEI_SIGN_CHANNEL_NUM
)
def __init__(self, app_key: str, app_secret: str, url: str, sign_channel_num: str):
self.client = HuaweiClient(app_key, app_secret, url, sign_channel_num)
def send_sms(
self, phone_numbers: list, sign_name: str, template_code: str,
template_param: OrderedDict, **kwargs
):
phone_numbers_str = ','.join(phone_numbers)
template_param = '["%s"]' % template_param.get('code')
req_params = {
'receiver': phone_numbers_str, 'signature': sign_name,
'template_id': template_code, 'template_param': template_param
}
try:
logger.info(f'Huawei sms send: '
f'phone_numbers={phone_numbers} '
f'sign_name={sign_name} '
f'template_code={template_code} '
f'template_param={template_param}')
resp_msg = self.client.send_sms(**req_params)
except Exception as error:
raise JMSException(code='response_bad', detail=error)
if resp_msg.get('code') != '000000':
raise JMSException(code='response_bad', detail=resp_msg)
return resp_msg
client = HuaweiSMS

View File

@ -4,6 +4,10 @@ import csv
import pyzipper
import requests
from hashlib import md5
from django.conf import settings
def create_csv_file(filename, headers, rows, ):
with open(filename, 'w', encoding='utf-8-sig')as f:
@ -28,3 +32,18 @@ def download_file(src, path):
with open(path, 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
def save_content_to_temp_path(content, file_mode=0o400):
if not content:
return
project_dir = settings.PROJECT_DIR
tmp_dir = os.path.join(project_dir, 'tmp')
filename = '.' + md5(content.encode('utf-8')).hexdigest()
filepath = os.path.join(tmp_dir, filename)
if not os.path.exists(filepath):
with open(filepath, 'w') as f:
f.write(content)
os.chmod(filepath, file_mode)
return filepath

View File

@ -334,8 +334,10 @@ class Config(dict):
'AUTH_OAUTH2_CLIENT_ID': 'client-id',
'AUTH_OAUTH2_SCOPE': '',
'AUTH_OAUTH2_CLIENT_SECRET': '',
'AUTH_OAUTH2_LOGOUT_COMPLETELY': True,
'AUTH_OAUTH2_PROVIDER_AUTHORIZATION_ENDPOINT': 'https://oauth2.example.com/authorize',
'AUTH_OAUTH2_PROVIDER_USERINFO_ENDPOINT': 'https://oauth2.example.com/userinfo',
'AUTH_OAUTH2_PROVIDER_END_SESSION_ENDPOINT': 'https://oauth2.example.com/logout',
'AUTH_OAUTH2_ACCESS_TOKEN_ENDPOINT': 'https://oauth2.example.com/access_token',
'AUTH_OAUTH2_ACCESS_TOKEN_METHOD': 'GET',
'AUTH_OAUTH2_USER_ATTR_MAP': {
@ -379,6 +381,13 @@ class Config(dict):
'TENCENT_VERIFY_SIGN_NAME': '',
'TENCENT_VERIFY_TEMPLATE_CODE': '',
'HUAWEI_APP_KEY': '',
'HUAWEI_APP_SECRET': '',
'HUAWEI_SMS_ENDPOINT': '',
'HUAWEI_SIGN_CHANNEL_NUM': '',
'HUAWEI_VERIFY_SIGN_NAME': '',
'HUAWEI_VERIFY_TEMPLATE_CODE': '',
'CMPP2_HOST': '',
'CMPP2_PORT': 7890,
'CMPP2_SP_ID': '',

View File

@ -164,6 +164,7 @@ AUTH_OAUTH2_USER_ATTR_MAP = CONFIG.AUTH_OAUTH2_USER_ATTR_MAP
AUTH_OAUTH2_AUTH_LOGIN_CALLBACK_URL_NAME = 'authentication:oauth2:login-callback'
AUTH_OAUTH2_AUTHENTICATION_REDIRECT_URI = '/'
AUTH_OAUTH2_AUTHENTICATION_FAILURE_REDIRECT_URI = '/'
AUTH_OAUTH2_LOGOUT_URL_NAME = "authentication:oauth2:logout"
# 临时 token
AUTH_TEMP_TOKEN = CONFIG.AUTH_TEMP_TOKEN

View File

@ -142,6 +142,7 @@ WSGI_APPLICATION = 'jumpserver.wsgi.application'
LOGIN_REDIRECT_URL = reverse_lazy('index')
LOGIN_URL = reverse_lazy('authentication:login')
LOGOUT_REDIRECT_URL = CONFIG.LOGOUT_REDIRECT_URL
SESSION_COOKIE_DOMAIN = CONFIG.SESSION_COOKIE_DOMAIN
CSRF_COOKIE_DOMAIN = CONFIG.SESSION_COOKIE_DOMAIN

View File

@ -111,6 +111,8 @@ HTTP_LISTEN_PORT = CONFIG.HTTP_LISTEN_PORT
WS_LISTEN_PORT = CONFIG.WS_LISTEN_PORT
LOGIN_LOG_KEEP_DAYS = CONFIG.LOGIN_LOG_KEEP_DAYS
TASK_LOG_KEEP_DAYS = CONFIG.TASK_LOG_KEEP_DAYS
OPERATE_LOG_KEEP_DAYS = CONFIG.OPERATE_LOG_KEEP_DAYS
FTP_LOG_KEEP_DAYS = CONFIG.FTP_LOG_KEEP_DAYS
ORG_CHANGE_TO_URL = CONFIG.ORG_CHANGE_TO_URL
WINDOWS_SKIP_ALL_MANUAL_PASSWORD = CONFIG.WINDOWS_SKIP_ALL_MANUAL_PASSWORD

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d7d4ace7d7ec976b0321bde41789f994f02e3ab6f034828cbfb7e675a313611f
size 131531
oid sha256:4d5dcc300fa64f04b513b670af0d9717fcdb108b54ddf264971b355cc72178de
size 132193

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-08-17 16:28+0800\n"
"POT-Creation-Date: 2022-09-15 15:52+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"
@ -32,7 +32,7 @@ msgstr "Acls"
#: terminal/models/endpoint.py:10 terminal/models/endpoint.py:86
#: terminal/models/storage.py:26 terminal/models/task.py:16
#: terminal/models/terminal.py:100 users/forms/profile.py:33
#: users/models/group.py:15 users/models/user.py:665
#: users/models/group.py:15 users/models/user.py:669
#: xpack/plugins/cloud/models.py:28
msgid "Name"
msgstr "名前"
@ -64,7 +64,7 @@ msgstr "アクティブ"
#: terminal/models/endpoint.py:23 terminal/models/endpoint.py:96
#: terminal/models/storage.py:29 terminal/models/terminal.py:114
#: tickets/models/comment.py:32 tickets/models/ticket/general.py:288
#: users/models/group.py:16 users/models/user.py:702
#: users/models/group.py:16 users/models/user.py:706
#: xpack/plugins/change_auth_plan/models/base.py:44
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:116
#: xpack/plugins/gathered_user/models.py:26
@ -94,7 +94,7 @@ msgstr "ログイン確認"
#: terminal/backends/command/serializers.py:13 terminal/models/session.py:44
#: terminal/models/sharing.py:33 terminal/notifications.py:91
#: terminal/notifications.py:139 tickets/models/comment.py:21 users/const.py:14
#: users/models/user.py:894 users/models/user.py:925
#: users/models/user.py:899 users/models/user.py:930
#: users/serializers/group.py:19
msgid "User"
msgstr "ユーザー"
@ -120,8 +120,8 @@ msgid "Login acl"
msgstr "ログインacl"
#: acls/models/login_asset_acl.py:21
#: applications/serializers/application.py:122
#: applications/serializers/application.py:167
#: applications/serializers/application.py:124
#: applications/serializers/application.py:164
msgid "System User"
msgstr "システムユーザー"
@ -160,7 +160,7 @@ msgstr "コンマ区切り文字列の形式。* はすべて一致すること
#: authentication/models.py:260
#: authentication/templates/authentication/_msg_different_city.html:9
#: authentication/templates/authentication/_msg_oauth_bind.html:9
#: ops/models/adhoc.py:159 users/forms/profile.py:32 users/models/user.py:663
#: ops/models/adhoc.py:159 users/forms/profile.py:32 users/models/user.py:667
#: users/templates/users/_msg_user_created.html:12
#: xpack/plugins/change_auth_plan/models/asset.py:34
#: xpack/plugins/change_auth_plan/models/asset.py:195
@ -301,7 +301,7 @@ msgid "Can change application account secret"
msgstr "アプリケーションアカウントの秘密を変更できます"
#: applications/models/application.py:222
#: applications/serializers/application.py:99 assets/models/label.py:21
#: applications/serializers/application.py:101 assets/models/label.py:21
#: perms/models/application_permission.py:21
#: perms/serializers/application/user_permission.py:33
#: tickets/models/ticket/apply_application.py:15
@ -310,7 +310,7 @@ msgid "Category"
msgstr "カテゴリ"
#: applications/models/application.py:225
#: applications/serializers/application.py:101 assets/models/backup.py:49
#: applications/serializers/application.py:103 assets/models/backup.py:49
#: assets/models/cmd_filter.py:82 assets/models/user.py:250
#: authentication/models.py:70 perms/models/application_permission.py:24
#: perms/serializers/application/user_permission.py:34
@ -329,7 +329,7 @@ msgid "Domain"
msgstr "ドメイン"
#: applications/models/application.py:231 xpack/plugins/cloud/models.py:33
#: xpack/plugins/cloud/serializers/account.py:61
#: xpack/plugins/cloud/serializers/account.py:63
msgid "Attrs"
msgstr "ツールバーの"
@ -341,14 +341,14 @@ msgstr "アプリケーションを一致させることができます"
msgid "Application user"
msgstr "アプリケーションユーザー"
#: applications/serializers/application.py:70
#: applications/serializers/application.py:100 assets/serializers/label.py:13
#: applications/serializers/application.py:72
#: applications/serializers/application.py:102 assets/serializers/label.py:13
#: perms/serializers/application/permission.py:18
msgid "Category display"
msgstr "カテゴリ表示"
#: applications/serializers/application.py:71
#: applications/serializers/application.py:102
#: applications/serializers/application.py:73
#: applications/serializers/application.py:104
#: assets/serializers/cmd_filter.py:34 assets/serializers/system_user.py:34
#: audits/serializers.py:29 authentication/serializers/connection_token.py:22
#: perms/serializers/application/permission.py:19
@ -356,7 +356,7 @@ msgstr "カテゴリ表示"
msgid "Type display"
msgstr "タイプ表示"
#: applications/serializers/application.py:103 assets/models/asset.py:230
#: applications/serializers/application.py:105 assets/models/asset.py:230
#: assets/models/base.py:181 assets/models/cluster.py:26
#: assets/models/domain.py:26 assets/models/gathered_user.py:19
#: assets/models/group.py:22 assets/models/label.py:25
@ -364,12 +364,12 @@ msgstr "タイプ表示"
#: assets/serializers/cmd_filter.py:48 common/db/models.py:114
#: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30
#: orgs/models.py:72 orgs/models.py:223 perms/models/base.py:92
#: users/models/group.py:18 users/models/user.py:926
#: users/models/group.py:18 users/models/user.py:931
#: xpack/plugins/cloud/models.py:125
msgid "Date created"
msgstr "作成された日付"
#: applications/serializers/application.py:104 assets/models/base.py:182
#: applications/serializers/application.py:106 assets/models/base.py:182
#: assets/models/gathered_user.py:20 assets/serializers/account.py:21
#: assets/serializers/cmd_filter.py:29 assets/serializers/cmd_filter.py:49
#: common/db/models.py:115 common/mixins/models.py:51 ops/models/adhoc.py:40
@ -377,12 +377,12 @@ msgstr "作成された日付"
msgid "Date updated"
msgstr "更新日"
#: applications/serializers/application.py:121
#: applications/serializers/application.py:166 authentication/models.py:99
#: applications/serializers/application.py:123
#: applications/serializers/application.py:163 authentication/models.py:99
msgid "Application display"
msgstr "アプリケーション表示"
#: applications/serializers/application.py:123
#: applications/serializers/application.py:125
msgid "account"
msgstr "アカウント"
@ -393,7 +393,7 @@ msgstr "クラスター"
#: applications/serializers/attrs/application_category/db.py:11
#: ops/models/adhoc.py:157 settings/serializers/auth/radius.py:14
#: settings/serializers/auth/sms.py:56 terminal/models/endpoint.py:11
#: settings/serializers/auth/sms.py:65 terminal/models/endpoint.py:11
#: xpack/plugins/cloud/serializers/account_attrs.py:72
msgid "Host"
msgstr "ホスト"
@ -407,11 +407,32 @@ msgstr "ホスト"
#: applications/serializers/attrs/application_type/redis.py:10
#: applications/serializers/attrs/application_type/sqlserver.py:10
#: assets/models/asset.py:214 assets/models/domain.py:62
#: settings/serializers/auth/radius.py:15 settings/serializers/auth/sms.py:57
#: settings/serializers/auth/radius.py:15 settings/serializers/auth/sms.py:66
#: xpack/plugins/cloud/serializers/account_attrs.py:73
msgid "Port"
msgstr "ポート"
#: applications/serializers/attrs/application_category/db.py:16
#: settings/serializers/email.py:36
msgid "Use SSL"
msgstr "SSLの使用"
#: applications/serializers/attrs/application_category/db.py:18
msgid "CA certificate"
msgstr "CA 証明書"
#: applications/serializers/attrs/application_category/db.py:21
msgid "Client certificate file"
msgstr "クライアント証明書"
#: applications/serializers/attrs/application_category/db.py:24
msgid "Certificate key file"
msgstr "証明書キー"
#: applications/serializers/attrs/application_category/db.py:26
msgid "Allow invalid cert"
msgstr "証明書チェックを無視"
#: applications/serializers/attrs/application_category/remote_app.py:34
msgid "Asset Info"
msgstr "資産情報"
@ -529,7 +550,7 @@ msgstr "内部"
#: assets/models/asset.py:162 assets/models/asset.py:216
#: assets/serializers/account.py:15 assets/serializers/asset.py:63
#: perms/serializers/asset/user_permission.py:43
#: xpack/plugins/cloud/serializers/account_attrs.py:162
#: xpack/plugins/cloud/serializers/account_attrs.py:179
msgid "Platform"
msgstr "プラットフォーム"
@ -629,7 +650,7 @@ msgstr "ラベル"
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:52
#: assets/models/cmd_filter.py:99 assets/models/group.py:21
#: common/db/models.py:112 common/mixins/models.py:49 orgs/models.py:71
#: orgs/models.py:225 perms/models/base.py:91 users/models/user.py:710
#: orgs/models.py:225 perms/models/base.py:91 users/models/user.py:714
#: users/serializers/group.py:33
#: xpack/plugins/change_auth_plan/models/base.py:48
#: xpack/plugins/cloud/models.py:122 xpack/plugins/gathered_user/models.py:30
@ -774,7 +795,7 @@ msgstr "OK"
#: assets/models/base.py:32 audits/models.py:118
#: xpack/plugins/change_auth_plan/serializers/app.py:88
#: xpack/plugins/change_auth_plan/serializers/asset.py:199
#: xpack/plugins/cloud/const.py:33
#: xpack/plugins/cloud/const.py:35
msgid "Failed"
msgstr "失敗しました"
@ -825,7 +846,7 @@ msgstr "帯域幅"
msgid "Contact"
msgstr "連絡先"
#: assets/models/cluster.py:22 users/models/user.py:685
#: assets/models/cluster.py:22 users/models/user.py:689
msgid "Phone"
msgstr "電話"
@ -851,7 +872,7 @@ msgid "Default"
msgstr "デフォルト"
#: assets/models/cluster.py:36 assets/models/label.py:14 rbac/const.py:6
#: users/models/user.py:911
#: users/models/user.py:916
msgid "System"
msgstr "システム"
@ -860,7 +881,7 @@ msgid "Default Cluster"
msgstr "デフォルトクラスター"
#: assets/models/cmd_filter.py:34 perms/models/base.py:86
#: users/models/group.py:31 users/models/user.py:671
#: users/models/group.py:31 users/models/user.py:675
msgid "User group"
msgstr "ユーザーグループ"
@ -1101,7 +1122,7 @@ msgstr ""
"されていません-個人情報にアクセスしてください-> ファイル暗号化パスワードを設"
"定してください暗号化パスワード"
#: assets/serializers/account.py:36 assets/serializers/account.py:87
#: assets/serializers/account.py:36 assets/serializers/account.py:83
#: assets/serializers/account_history.py:10 authentication/models.py:87
msgid "System user display"
msgstr "システムユーザー表示"
@ -1159,7 +1180,7 @@ msgstr "定期的なパフォーマンス"
msgid "Currently only mail sending is supported"
msgstr "現在、メール送信のみがサポートされています"
#: assets/serializers/base.py:16 users/models/user.py:693
#: assets/serializers/base.py:16 users/models/user.py:697
msgid "Private key"
msgstr "ssh秘密鍵"
@ -1537,7 +1558,7 @@ msgstr "ユーザーエージェント"
#: audits/models.py:126
#: authentication/templates/authentication/_mfa_confirm_modal.html:14
#: users/forms/profile.py:65 users/models/user.py:688
#: users/forms/profile.py:65 users/models/user.py:692
#: users/serializers/profile.py:126
msgid "MFA"
msgstr "MFA"
@ -1616,19 +1637,19 @@ msgstr "認証トークン"
#: audits/signal_handlers.py:53 authentication/notifications.py:73
#: authentication/views/login.py:73 authentication/views/wecom.py:178
#: notifications/backends/__init__.py:11 users/models/user.py:724
#: notifications/backends/__init__.py:11 users/models/user.py:728
msgid "WeCom"
msgstr "企業微信"
#: audits/signal_handlers.py:54 authentication/views/feishu.py:144
#: authentication/views/login.py:85 notifications/backends/__init__.py:14
#: users/models/user.py:726
#: users/models/user.py:730
msgid "FeiShu"
msgstr "本を飛ばす"
#: audits/signal_handlers.py:55 authentication/views/dingtalk.py:179
#: authentication/views/login.py:79 notifications/backends/__init__.py:12
#: users/models/user.py:725
#: users/models/user.py:729
msgid "DingTalk"
msgstr "DingTalk"
@ -1816,6 +1837,11 @@ msgstr "現在のユーザーはmfaタイプをサポートしていません: {
msgid "Authentication"
msgstr "認証"
#: authentication/backends/custom.py:58
#: authentication/backends/oauth2/backends.py:158 authentication/models.py:158
msgid "User invalid, disabled or expired"
msgstr "ユーザーが無効、無効、または期限切れです"
#: authentication/backends/drf.py:56
msgid "Invalid signature header. No credentials provided."
msgstr "署名ヘッダーが無効です。資格情報は提供されていません。"
@ -1869,10 +1895,6 @@ msgstr ""
msgid "Invalid token or cache refreshed."
msgstr "無効なトークンまたはキャッシュの更新。"
#: authentication/backends/oauth2/backends.py:155 authentication/models.py:158
msgid "User invalid, disabled or expired"
msgstr "ユーザーが無効、無効、または期限切れです"
#: authentication/confirm/password.py:16
msgid "Authentication failed password incorrect"
msgstr "認証に失敗しました (ユーザー名またはパスワードが正しくありません)"
@ -2152,7 +2174,7 @@ msgstr "ひみつ"
#: authentication/models.py:74 authentication/models.py:264
#: perms/models/base.py:90 tickets/models/ticket/apply_application.py:30
#: tickets/models/ticket/apply_asset.py:24 users/models/user.py:707
#: tickets/models/ticket/apply_asset.py:24 users/models/user.py:711
msgid "Date expired"
msgstr "期限切れの日付"
@ -2324,7 +2346,7 @@ msgstr "コードエラー"
#: authentication/templates/authentication/_msg_reset_password.html:3
#: authentication/templates/authentication/_msg_rest_password_success.html:2
#: authentication/templates/authentication/_msg_rest_public_key_success.html:2
#: jumpserver/conf.py:390 ops/tasks.py:145 ops/tasks.py:148
#: jumpserver/conf.py:402 ops/tasks.py:145 ops/tasks.py:148
#: perms/templates/perms/_msg_item_permissions_expire.html:3
#: perms/templates/perms/_msg_permed_items_expire.html:3
#: tickets/templates/tickets/approve_check_password.html:33
@ -2473,7 +2495,7 @@ msgid "Copy success"
msgstr "コピー成功"
#: authentication/utils.py:28 common/utils/ip/geoip/utils.py:24
#: xpack/plugins/cloud/const.py:24
#: xpack/plugins/cloud/const.py:26
msgid "LAN"
msgstr "ローカルエリアネットワーク"
@ -2571,11 +2593,11 @@ msgstr ""
msgid "No ticket found"
msgstr "チケットが見つかりません"
#: authentication/views/login.py:346
#: authentication/views/login.py:348
msgid "Logout success"
msgstr "ログアウト成功"
#: authentication/views/login.py:347
#: authentication/views/login.py:349
msgid "Logout success, return login page"
msgstr "ログアウト成功、ログインページを返す"
@ -2747,15 +2769,19 @@ msgstr "アリ雲"
msgid "Tencent cloud"
msgstr "テンセント雲"
#: common/sdk/sms/endpoint.py:18
#: common/sdk/sms/endpoint.py:18 xpack/plugins/cloud/const.py:13
msgid "Huawei Cloud"
msgstr "華為雲"
#: common/sdk/sms/endpoint.py:19
msgid "CMPP v2.0"
msgstr "CMPP v2.0"
#: common/sdk/sms/endpoint.py:29
#: common/sdk/sms/endpoint.py:30
msgid "SMS provider not support: {}"
msgstr "SMSプロバイダーはサポートしていません: {}"
#: common/sdk/sms/endpoint.py:50
#: common/sdk/sms/endpoint.py:51
msgid "SMS verification code signature or template invalid"
msgstr "SMS検証コードの署名またはテンプレートが無効"
@ -2787,11 +2813,11 @@ msgstr "特殊文字を含むべきではない"
msgid "The mobile phone number format is incorrect"
msgstr "携帯電話番号の形式が正しくありません"
#: jumpserver/conf.py:389
#: jumpserver/conf.py:401
msgid "Create account successfully"
msgstr "アカウントを正常に作成"
#: jumpserver/conf.py:391
#: jumpserver/conf.py:403
msgid "Your account has been created successfully"
msgstr "アカウントが正常に作成されました"
@ -2836,7 +2862,7 @@ msgid "Notifications"
msgstr "通知"
#: notifications/backends/__init__.py:10 users/forms/profile.py:102
#: users/models/user.py:667
#: users/models/user.py:671
msgid "Email"
msgstr "メール"
@ -3070,7 +3096,7 @@ msgid "Can view all joined org"
msgstr "参加しているすべての組織を表示できます"
#: orgs/models.py:222 rbac/models/role.py:46 rbac/models/rolebinding.py:44
#: users/models/user.py:675
#: users/models/user.py:679
msgid "Role"
msgstr "ロール"
@ -3488,7 +3514,7 @@ msgid "Execute batch command"
msgstr "バッチ実行コマンド"
#: settings/api/dingtalk.py:31 settings/api/feishu.py:36
#: settings/api/sms.py:131 settings/api/wecom.py:37
#: settings/api/sms.py:148 settings/api/wecom.py:37
msgid "Test success"
msgstr "テストの成功"
@ -3516,11 +3542,11 @@ msgstr "Ldapユーザーを取得するにはNone"
msgid "Imported {} users successfully (Organization: {})"
msgstr "{} 人のユーザーを正常にインポートしました (組織: {})"
#: settings/api/sms.py:113
#: settings/api/sms.py:130
msgid "Invalid SMS platform"
msgstr "無効なショートメッセージプラットフォーム"
#: settings/api/sms.py:119
#: settings/api/sms.py:136
msgid "test_phone is required"
msgstr "携帯番号をテストこのフィールドは必須です"
@ -3620,7 +3646,8 @@ msgstr "サービス側アドレス"
msgid "Proxy server url"
msgstr "コールバックアドレス"
#: settings/serializers/auth/cas.py:16 settings/serializers/auth/saml2.py:32
#: settings/serializers/auth/cas.py:16 settings/serializers/auth/oauth2.py:53
#: settings/serializers/auth/saml2.py:32
msgid "Logout completely"
msgstr "同期ログアウト"
@ -3677,7 +3704,7 @@ msgstr "ユーザー検索フィルター"
msgid "Choice may be (cn|uid|sAMAccountName)=%(user)s)"
msgstr "選択は (cnまたはuidまたはsAMAccountName)=%(user)s)"
#: settings/serializers/auth/ldap.py:57 settings/serializers/auth/oauth2.py:51
#: settings/serializers/auth/ldap.py:57 settings/serializers/auth/oauth2.py:55
#: settings/serializers/auth/oidc.py:36
msgid "User attr map"
msgstr "ユーザー属性マッピング"
@ -3739,7 +3766,11 @@ msgstr "クライアント認証方式"
msgid "Provider userinfo endpoint"
msgstr "プロバイダーuserinfoエンドポイント"
#: settings/serializers/auth/oauth2.py:54 settings/serializers/auth/oidc.py:92
#: settings/serializers/auth/oauth2.py:51 settings/serializers/auth/oidc.py:74
msgid "Provider end session endpoint"
msgstr "プロバイダーのセッション終了エンドポイント"
#: settings/serializers/auth/oauth2.py:58 settings/serializers/auth/oidc.py:92
#: settings/serializers/auth/saml2.py:33
msgid "Always update user"
msgstr "常にユーザーを更新"
@ -3784,10 +3815,6 @@ msgstr "プロバイダーエンドポイント"
msgid "Provider jwks endpoint"
msgstr "プロバイダーjwksエンドポイント"
#: settings/serializers/auth/oidc.py:74
msgid "Provider end session endpoint"
msgstr "プロバイダーのセッション終了エンドポイント"
#: settings/serializers/auth/oidc.py:77
msgid "Provider sign alg"
msgstr "プロビダーサインalg"
@ -3857,13 +3884,13 @@ msgid "SMS provider / Protocol"
msgstr "SMSプロバイダ / プロトコル"
#: settings/serializers/auth/sms.py:22 settings/serializers/auth/sms.py:43
#: settings/serializers/auth/sms.py:51 settings/serializers/auth/sms.py:62
#: settings/serializers/email.py:65
#: settings/serializers/auth/sms.py:51 settings/serializers/auth/sms.py:60
#: settings/serializers/auth/sms.py:71 settings/serializers/email.py:65
msgid "Signature"
msgstr "署名"
#: settings/serializers/auth/sms.py:23 settings/serializers/auth/sms.py:44
#: settings/serializers/auth/sms.py:52
#: settings/serializers/auth/sms.py:52 settings/serializers/auth/sms.py:61
msgid "Template code"
msgstr "テンプレートコード"
@ -3872,26 +3899,34 @@ msgid "Test phone"
msgstr "テスト電話"
#: settings/serializers/auth/sms.py:58
msgid "App Access Address"
msgstr "アプリケーションアドレス"
#: settings/serializers/auth/sms.py:59
msgid "Signature channel number"
msgstr "署名チャネル番号"
#: settings/serializers/auth/sms.py:67
msgid "Enterprise code(SP id)"
msgstr "企業コード(SP id)"
#: settings/serializers/auth/sms.py:59
#: settings/serializers/auth/sms.py:68
msgid "Shared secret(Shared secret)"
msgstr "パスワードを共有する(Shared secret)"
#: settings/serializers/auth/sms.py:60
#: settings/serializers/auth/sms.py:69
msgid "Original number(Src id)"
msgstr "元の番号(Src id)"
#: settings/serializers/auth/sms.py:61
#: settings/serializers/auth/sms.py:70
msgid "Business type(Service id)"
msgstr "ビジネス・タイプ(Service id)"
#: settings/serializers/auth/sms.py:64
#: settings/serializers/auth/sms.py:73
msgid "Template"
msgstr "テンプレート"
#: settings/serializers/auth/sms.py:65
#: settings/serializers/auth/sms.py:74
#, python-brace-format
msgid ""
"Template need contain {code} and Signature + template length does not exceed "
@ -3902,12 +3937,12 @@ msgstr ""
"満です。たとえば、認証コードは{code}で、有効期間は5分です。他の人には言わない"
"でください。"
#: settings/serializers/auth/sms.py:74
#: settings/serializers/auth/sms.py:83
#, python-brace-format
msgid "The template needs to contain {code}"
msgstr "テンプレートには{code}を含める必要があります"
#: settings/serializers/auth/sms.py:77
#: settings/serializers/auth/sms.py:86
msgid "Signature + Template must not exceed 65 words"
msgstr "署名+テンプレートの長さは65文字以内"
@ -3925,7 +3960,7 @@ msgid "SSO auth key TTL"
msgstr "Token有効期間"
#: settings/serializers/auth/sso.py:15
#: xpack/plugins/cloud/serializers/account_attrs.py:159
#: xpack/plugins/cloud/serializers/account_attrs.py:176
msgid "Unit: second"
msgstr "単位: 秒"
@ -4061,10 +4096,6 @@ msgstr "テスト受信者"
msgid "Tips: Used only as a test mail recipient"
msgstr "ヒント: テストメールの受信者としてのみ使用"
#: settings/serializers/email.py:36
msgid "Use SSL"
msgstr "SSLの使用"
#: settings/serializers/email.py:37
msgid "If SMTP port is 465, may be select"
msgstr "SMTPポートが465の場合は、"
@ -5763,7 +5794,7 @@ msgstr "公開鍵は古いものと同じであってはなりません。"
msgid "Not a valid ssh public key"
msgstr "有効なssh公開鍵ではありません"
#: users/forms/profile.py:161 users/models/user.py:696
#: users/forms/profile.py:161 users/models/user.py:700
msgid "Public key"
msgstr "公開キー"
@ -5775,55 +5806,55 @@ msgstr "強制有効"
msgid "Local"
msgstr "ローカル"
#: users/models/user.py:677 users/serializers/user.py:149
#: users/models/user.py:681 users/serializers/user.py:149
msgid "Is service account"
msgstr "サービスアカウントです"
#: users/models/user.py:679
#: users/models/user.py:683
msgid "Avatar"
msgstr "アバター"
#: users/models/user.py:682
#: users/models/user.py:686
msgid "Wechat"
msgstr "微信"
#: users/models/user.py:699
#: users/models/user.py:703
msgid "Secret key"
msgstr "秘密キー"
#: users/models/user.py:715
#: users/models/user.py:719
msgid "Source"
msgstr "ソース"
#: users/models/user.py:719
#: users/models/user.py:723
msgid "Date password last updated"
msgstr "最終更新日パスワード"
#: users/models/user.py:722
#: users/models/user.py:726
msgid "Need update password"
msgstr "更新パスワードが必要"
#: users/models/user.py:896
#: users/models/user.py:901
msgid "Can invite user"
msgstr "ユーザーを招待できます"
#: users/models/user.py:897
#: users/models/user.py:902
msgid "Can remove user"
msgstr "ユーザーを削除できます"
#: users/models/user.py:898
#: users/models/user.py:903
msgid "Can match user"
msgstr "ユーザーに一致できます"
#: users/models/user.py:907
#: users/models/user.py:912
msgid "Administrator"
msgstr "管理者"
#: users/models/user.py:910
#: users/models/user.py:915
msgid "Administrator is the super user of system"
msgstr "管理者はシステムのスーパーユーザーです"
#: users/models/user.py:935
#: users/models/user.py:940
msgid "User password history"
msgstr "ユーザーパスワード履歴"
@ -6433,10 +6464,6 @@ msgstr "Azure (中国)"
msgid "Azure (International)"
msgstr "Azure (国際)"
#: xpack/plugins/cloud/const.py:13
msgid "Huawei Cloud"
msgstr "華為雲"
#: xpack/plugins/cloud/const.py:14
msgid "Baidu Cloud"
msgstr "百度雲"
@ -6450,58 +6477,66 @@ msgid "Tencent Cloud"
msgstr "テンセント雲"
#: xpack/plugins/cloud/const.py:17
msgid "Tencent Cloud (Lighthouse)"
msgstr "テンセント雲(軽量アプリケーション)"
#: xpack/plugins/cloud/const.py:18
msgid "VMware"
msgstr "VMware"
#: xpack/plugins/cloud/const.py:18 xpack/plugins/cloud/providers/nutanix.py:13
#: xpack/plugins/cloud/const.py:19 xpack/plugins/cloud/providers/nutanix.py:13
msgid "Nutanix"
msgstr "Nutanix"
#: xpack/plugins/cloud/const.py:19
#: xpack/plugins/cloud/const.py:20
msgid "Huawei Private Cloud"
msgstr "華為私有雲"
#: xpack/plugins/cloud/const.py:20
#: xpack/plugins/cloud/const.py:21
msgid "Qingyun Private Cloud"
msgstr "青雲私有雲"
#: xpack/plugins/cloud/const.py:21
#: xpack/plugins/cloud/const.py:22
msgid "CTYun Private Cloud"
msgstr "スカイウィング私有雲"
#: xpack/plugins/cloud/const.py:23
msgid "OpenStack"
msgstr "OpenStack"
#: xpack/plugins/cloud/const.py:22
#: xpack/plugins/cloud/const.py:24
msgid "Google Cloud Platform"
msgstr "谷歌雲"
#: xpack/plugins/cloud/const.py:23
#: xpack/plugins/cloud/const.py:25
msgid "Fusion Compute"
msgstr ""
#: xpack/plugins/cloud/const.py:28
#: xpack/plugins/cloud/const.py:30
msgid "Instance name"
msgstr "インスタンス名"
#: xpack/plugins/cloud/const.py:29
#: xpack/plugins/cloud/const.py:31
msgid "Instance name and Partial IP"
msgstr "インスタンス名と部分IP"
#: xpack/plugins/cloud/const.py:34
#: xpack/plugins/cloud/const.py:36
msgid "Succeed"
msgstr "成功"
#: xpack/plugins/cloud/const.py:38
#: xpack/plugins/cloud/const.py:40
msgid "Unsync"
msgstr "同期していません"
#: xpack/plugins/cloud/const.py:39
#: xpack/plugins/cloud/const.py:41
msgid "New Sync"
msgstr "新しい同期"
#: xpack/plugins/cloud/const.py:40
#: xpack/plugins/cloud/const.py:42
msgid "Synced"
msgstr "同期済み"
#: xpack/plugins/cloud/const.py:41
#: xpack/plugins/cloud/const.py:43
msgid "Released"
msgstr "リリース済み"
@ -6771,11 +6806,11 @@ msgstr "華南-広州-友好ユーザー環境"
msgid "CN East-Suqian"
msgstr "華東-宿遷"
#: xpack/plugins/cloud/serializers/account.py:62
#: xpack/plugins/cloud/serializers/account.py:64
msgid "Validity display"
msgstr "有効表示"
#: xpack/plugins/cloud/serializers/account.py:63
#: xpack/plugins/cloud/serializers/account.py:65
msgid "Provider display"
msgstr "プロバイダ表示"
@ -6793,7 +6828,8 @@ msgstr "サブスクリプションID"
#: xpack/plugins/cloud/serializers/account_attrs.py:95
#: xpack/plugins/cloud/serializers/account_attrs.py:100
#: xpack/plugins/cloud/serializers/account_attrs.py:124
#: xpack/plugins/cloud/serializers/account_attrs.py:116
#: xpack/plugins/cloud/serializers/account_attrs.py:141
msgid "API Endpoint"
msgstr "APIエンドポイント"
@ -6810,24 +6846,32 @@ msgid "User domain"
msgstr "ユーザードメイン"
#: xpack/plugins/cloud/serializers/account_attrs.py:117
msgid "Cert File"
msgstr "証明書ファイル"
#: xpack/plugins/cloud/serializers/account_attrs.py:118
msgid "Key File"
msgstr "キーファイル"
#: xpack/plugins/cloud/serializers/account_attrs.py:134
msgid "Service account key"
msgstr "サービスアカウントキー"
#: xpack/plugins/cloud/serializers/account_attrs.py:118
#: xpack/plugins/cloud/serializers/account_attrs.py:135
msgid "The file is in JSON format"
msgstr "ファイルはJSON形式です。"
#: xpack/plugins/cloud/serializers/account_attrs.py:131
#: xpack/plugins/cloud/serializers/account_attrs.py:148
msgid "IP address invalid `{}`, {}"
msgstr "IPアドレスが無効: '{}', {}"
#: xpack/plugins/cloud/serializers/account_attrs.py:137
#: xpack/plugins/cloud/serializers/account_attrs.py:154
msgid ""
"Format for comma-delimited string,Such as: 192.168.1.0/24, "
"10.0.0.0-10.0.0.255"
msgstr "形式はコンマ区切りの文字列です192.168.1.0/24,10.0.0.0-10.0.0.255"
#: xpack/plugins/cloud/serializers/account_attrs.py:141
#: xpack/plugins/cloud/serializers/account_attrs.py:158
msgid ""
"The port is used to detect the validity of the IP address. When the "
"synchronization task is executed, only the valid IP address will be "
@ -6837,19 +6881,19 @@ msgstr ""
"実行されると、有効な IP アドレスのみが同期されます。 <br>ポートが0の場合、す"
"べてのIPアドレスが有効です。"
#: xpack/plugins/cloud/serializers/account_attrs.py:149
#: xpack/plugins/cloud/serializers/account_attrs.py:166
msgid "Hostname prefix"
msgstr "ホスト名プレフィックス"
#: xpack/plugins/cloud/serializers/account_attrs.py:152
#: xpack/plugins/cloud/serializers/account_attrs.py:169
msgid "IP segment"
msgstr "IP セグメント"
#: xpack/plugins/cloud/serializers/account_attrs.py:156
#: xpack/plugins/cloud/serializers/account_attrs.py:173
msgid "Test port"
msgstr "テストポート"
#: xpack/plugins/cloud/serializers/account_attrs.py:159
#: xpack/plugins/cloud/serializers/account_attrs.py:176
msgid "Test timeout"
msgstr "テストタイムアウト"

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:114dc04325f5a778a7cd0fb1b4d5aa71dfb60ada57b1b4f3ae43d89c1c818e0f
size 108398
oid sha256:618dce0f2521591410fb16b3d0afa536333d2e4f317d75d1955fe413dc0e64cb
size 108949

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-08-17 16:28+0800\n"
"POT-Creation-Date: 2022-09-15 15:52+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"
@ -31,7 +31,7 @@ msgstr "访问控制"
#: terminal/models/endpoint.py:10 terminal/models/endpoint.py:86
#: terminal/models/storage.py:26 terminal/models/task.py:16
#: terminal/models/terminal.py:100 users/forms/profile.py:33
#: users/models/group.py:15 users/models/user.py:665
#: users/models/group.py:15 users/models/user.py:669
#: xpack/plugins/cloud/models.py:28
msgid "Name"
msgstr "名称"
@ -63,7 +63,7 @@ msgstr "激活中"
#: terminal/models/endpoint.py:23 terminal/models/endpoint.py:96
#: terminal/models/storage.py:29 terminal/models/terminal.py:114
#: tickets/models/comment.py:32 tickets/models/ticket/general.py:288
#: users/models/group.py:16 users/models/user.py:702
#: users/models/group.py:16 users/models/user.py:706
#: xpack/plugins/change_auth_plan/models/base.py:44
#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:116
#: xpack/plugins/gathered_user/models.py:26
@ -93,7 +93,7 @@ msgstr "登录复核"
#: terminal/backends/command/serializers.py:13 terminal/models/session.py:44
#: terminal/models/sharing.py:33 terminal/notifications.py:91
#: terminal/notifications.py:139 tickets/models/comment.py:21 users/const.py:14
#: users/models/user.py:894 users/models/user.py:925
#: users/models/user.py:899 users/models/user.py:930
#: users/serializers/group.py:19
msgid "User"
msgstr "用户"
@ -119,8 +119,8 @@ msgid "Login acl"
msgstr "登录访问控制"
#: acls/models/login_asset_acl.py:21
#: applications/serializers/application.py:122
#: applications/serializers/application.py:167
#: applications/serializers/application.py:124
#: applications/serializers/application.py:164
msgid "System User"
msgstr "系统用户"
@ -159,7 +159,7 @@ msgstr "格式为逗号分隔的字符串, * 表示匹配所有. "
#: authentication/models.py:260
#: authentication/templates/authentication/_msg_different_city.html:9
#: authentication/templates/authentication/_msg_oauth_bind.html:9
#: ops/models/adhoc.py:159 users/forms/profile.py:32 users/models/user.py:663
#: ops/models/adhoc.py:159 users/forms/profile.py:32 users/models/user.py:667
#: users/templates/users/_msg_user_created.html:12
#: xpack/plugins/change_auth_plan/models/asset.py:34
#: xpack/plugins/change_auth_plan/models/asset.py:195
@ -296,7 +296,7 @@ msgid "Can change application account secret"
msgstr "可以查看应用账号密码"
#: applications/models/application.py:222
#: applications/serializers/application.py:99 assets/models/label.py:21
#: applications/serializers/application.py:101 assets/models/label.py:21
#: perms/models/application_permission.py:21
#: perms/serializers/application/user_permission.py:33
#: tickets/models/ticket/apply_application.py:15
@ -305,7 +305,7 @@ msgid "Category"
msgstr "类别"
#: applications/models/application.py:225
#: applications/serializers/application.py:101 assets/models/backup.py:49
#: applications/serializers/application.py:103 assets/models/backup.py:49
#: assets/models/cmd_filter.py:82 assets/models/user.py:250
#: authentication/models.py:70 perms/models/application_permission.py:24
#: perms/serializers/application/user_permission.py:34
@ -324,7 +324,7 @@ msgid "Domain"
msgstr "网域"
#: applications/models/application.py:231 xpack/plugins/cloud/models.py:33
#: xpack/plugins/cloud/serializers/account.py:61
#: xpack/plugins/cloud/serializers/account.py:63
msgid "Attrs"
msgstr "属性"
@ -336,14 +336,14 @@ msgstr "匹配应用"
msgid "Application user"
msgstr "应用用户"
#: applications/serializers/application.py:70
#: applications/serializers/application.py:100 assets/serializers/label.py:13
#: applications/serializers/application.py:72
#: applications/serializers/application.py:102 assets/serializers/label.py:13
#: perms/serializers/application/permission.py:18
msgid "Category display"
msgstr "类别名称"
#: applications/serializers/application.py:71
#: applications/serializers/application.py:102
#: applications/serializers/application.py:73
#: applications/serializers/application.py:104
#: assets/serializers/cmd_filter.py:34 assets/serializers/system_user.py:34
#: audits/serializers.py:29 authentication/serializers/connection_token.py:22
#: perms/serializers/application/permission.py:19
@ -351,7 +351,7 @@ msgstr "类别名称"
msgid "Type display"
msgstr "类型名称"
#: applications/serializers/application.py:103 assets/models/asset.py:230
#: applications/serializers/application.py:105 assets/models/asset.py:230
#: assets/models/base.py:181 assets/models/cluster.py:26
#: assets/models/domain.py:26 assets/models/gathered_user.py:19
#: assets/models/group.py:22 assets/models/label.py:25
@ -359,12 +359,12 @@ msgstr "类型名称"
#: assets/serializers/cmd_filter.py:48 common/db/models.py:114
#: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30
#: orgs/models.py:72 orgs/models.py:223 perms/models/base.py:92
#: users/models/group.py:18 users/models/user.py:926
#: users/models/group.py:18 users/models/user.py:931
#: xpack/plugins/cloud/models.py:125
msgid "Date created"
msgstr "创建日期"
#: applications/serializers/application.py:104 assets/models/base.py:182
#: applications/serializers/application.py:106 assets/models/base.py:182
#: assets/models/gathered_user.py:20 assets/serializers/account.py:21
#: assets/serializers/cmd_filter.py:29 assets/serializers/cmd_filter.py:49
#: common/db/models.py:115 common/mixins/models.py:51 ops/models/adhoc.py:40
@ -372,12 +372,12 @@ msgstr "创建日期"
msgid "Date updated"
msgstr "更新日期"
#: applications/serializers/application.py:121
#: applications/serializers/application.py:166 authentication/models.py:99
#: applications/serializers/application.py:123
#: applications/serializers/application.py:163 authentication/models.py:99
msgid "Application display"
msgstr "应用名称"
#: applications/serializers/application.py:123
#: applications/serializers/application.py:125
msgid "account"
msgstr "账号"
@ -388,7 +388,7 @@ msgstr "集群"
#: applications/serializers/attrs/application_category/db.py:11
#: ops/models/adhoc.py:157 settings/serializers/auth/radius.py:14
#: settings/serializers/auth/sms.py:56 terminal/models/endpoint.py:11
#: settings/serializers/auth/sms.py:65 terminal/models/endpoint.py:11
#: xpack/plugins/cloud/serializers/account_attrs.py:72
msgid "Host"
msgstr "主机"
@ -402,11 +402,32 @@ msgstr "主机"
#: applications/serializers/attrs/application_type/redis.py:10
#: applications/serializers/attrs/application_type/sqlserver.py:10
#: assets/models/asset.py:214 assets/models/domain.py:62
#: settings/serializers/auth/radius.py:15 settings/serializers/auth/sms.py:57
#: settings/serializers/auth/radius.py:15 settings/serializers/auth/sms.py:66
#: xpack/plugins/cloud/serializers/account_attrs.py:73
msgid "Port"
msgstr "端口"
#: applications/serializers/attrs/application_category/db.py:16
#: settings/serializers/email.py:36
msgid "Use SSL"
msgstr "使用 SSL"
#: applications/serializers/attrs/application_category/db.py:18
msgid "CA certificate"
msgstr "CA 证书"
#: applications/serializers/attrs/application_category/db.py:21
msgid "Client certificate file"
msgstr "客户端证书"
#: applications/serializers/attrs/application_category/db.py:24
msgid "Certificate key file"
msgstr "证书秘钥"
#: applications/serializers/attrs/application_category/db.py:26
msgid "Allow invalid cert"
msgstr "忽略证书校验"
#: applications/serializers/attrs/application_category/remote_app.py:34
msgid "Asset Info"
msgstr "资产信息"
@ -524,7 +545,7 @@ msgstr "内部的"
#: assets/models/asset.py:162 assets/models/asset.py:216
#: assets/serializers/account.py:15 assets/serializers/asset.py:63
#: perms/serializers/asset/user_permission.py:43
#: xpack/plugins/cloud/serializers/account_attrs.py:162
#: xpack/plugins/cloud/serializers/account_attrs.py:179
msgid "Platform"
msgstr "系统平台"
@ -624,7 +645,7 @@ msgstr "标签管理"
#: assets/models/cluster.py:28 assets/models/cmd_filter.py:52
#: assets/models/cmd_filter.py:99 assets/models/group.py:21
#: common/db/models.py:112 common/mixins/models.py:49 orgs/models.py:71
#: orgs/models.py:225 perms/models/base.py:91 users/models/user.py:710
#: orgs/models.py:225 perms/models/base.py:91 users/models/user.py:714
#: users/serializers/group.py:33
#: xpack/plugins/change_auth_plan/models/base.py:48
#: xpack/plugins/cloud/models.py:122 xpack/plugins/gathered_user/models.py:30
@ -769,7 +790,7 @@ msgstr "成功"
#: assets/models/base.py:32 audits/models.py:118
#: xpack/plugins/change_auth_plan/serializers/app.py:88
#: xpack/plugins/change_auth_plan/serializers/asset.py:199
#: xpack/plugins/cloud/const.py:33
#: xpack/plugins/cloud/const.py:35
msgid "Failed"
msgstr "失败"
@ -820,7 +841,7 @@ msgstr "带宽"
msgid "Contact"
msgstr "联系人"
#: assets/models/cluster.py:22 users/models/user.py:685
#: assets/models/cluster.py:22 users/models/user.py:689
msgid "Phone"
msgstr "手机"
@ -846,7 +867,7 @@ msgid "Default"
msgstr "默认"
#: assets/models/cluster.py:36 assets/models/label.py:14 rbac/const.py:6
#: users/models/user.py:911
#: users/models/user.py:916
msgid "System"
msgstr "系统"
@ -855,7 +876,7 @@ msgid "Default Cluster"
msgstr "默认Cluster"
#: assets/models/cmd_filter.py:34 perms/models/base.py:86
#: users/models/group.py:31 users/models/user.py:671
#: users/models/group.py:31 users/models/user.py:675
msgid "User group"
msgstr "用户组"
@ -1093,7 +1114,7 @@ msgstr ""
"{} - 账号备份任务已完成: 未设置加密密码 - 请前往个人信息 -> 文件加密密码中设"
"置加密密码"
#: assets/serializers/account.py:36 assets/serializers/account.py:87
#: assets/serializers/account.py:36 assets/serializers/account.py:83
#: assets/serializers/account_history.py:10 authentication/models.py:87
msgid "System user display"
msgstr "系统用户名称"
@ -1151,7 +1172,7 @@ msgstr "定时执行"
msgid "Currently only mail sending is supported"
msgstr "当前只支持邮件发送"
#: assets/serializers/base.py:16 users/models/user.py:693
#: assets/serializers/base.py:16 users/models/user.py:697
msgid "Private key"
msgstr "ssh私钥"
@ -1525,7 +1546,7 @@ msgstr "用户代理"
#: audits/models.py:126
#: authentication/templates/authentication/_mfa_confirm_modal.html:14
#: users/forms/profile.py:65 users/models/user.py:688
#: users/forms/profile.py:65 users/models/user.py:692
#: users/serializers/profile.py:126
msgid "MFA"
msgstr "MFA"
@ -1604,19 +1625,19 @@ msgstr "认证令牌"
#: audits/signal_handlers.py:53 authentication/notifications.py:73
#: authentication/views/login.py:73 authentication/views/wecom.py:178
#: notifications/backends/__init__.py:11 users/models/user.py:724
#: notifications/backends/__init__.py:11 users/models/user.py:728
msgid "WeCom"
msgstr "企业微信"
#: audits/signal_handlers.py:54 authentication/views/feishu.py:144
#: authentication/views/login.py:85 notifications/backends/__init__.py:14
#: users/models/user.py:726
#: users/models/user.py:730
msgid "FeiShu"
msgstr "飞书"
#: audits/signal_handlers.py:55 authentication/views/dingtalk.py:179
#: authentication/views/login.py:79 notifications/backends/__init__.py:12
#: users/models/user.py:725
#: users/models/user.py:729
msgid "DingTalk"
msgstr "钉钉"
@ -1804,6 +1825,11 @@ msgstr "当前用户不支持 MFA 类型: {}"
msgid "Authentication"
msgstr "认证"
#: authentication/backends/custom.py:58
#: authentication/backends/oauth2/backends.py:158 authentication/models.py:158
msgid "User invalid, disabled or expired"
msgstr "用户无效,已禁用或已过期"
#: authentication/backends/drf.py:56
msgid "Invalid signature header. No credentials provided."
msgstr "不合法的签名头"
@ -1855,10 +1881,6 @@ msgstr "无效的令牌头。符号字符串不应包含无效字符。"
msgid "Invalid token or cache refreshed."
msgstr "刷新的令牌或缓存无效。"
#: authentication/backends/oauth2/backends.py:155 authentication/models.py:158
msgid "User invalid, disabled or expired"
msgstr "用户无效,已禁用或已过期"
#: authentication/confirm/password.py:16
msgid "Authentication failed password incorrect"
msgstr "认证失败 (用户名或密码不正确)"
@ -2131,7 +2153,7 @@ msgstr "密钥"
#: authentication/models.py:74 authentication/models.py:264
#: perms/models/base.py:90 tickets/models/ticket/apply_application.py:30
#: tickets/models/ticket/apply_asset.py:24 users/models/user.py:707
#: tickets/models/ticket/apply_asset.py:24 users/models/user.py:711
msgid "Date expired"
msgstr "失效日期"
@ -2299,7 +2321,7 @@ msgstr "代码错误"
#: authentication/templates/authentication/_msg_reset_password.html:3
#: authentication/templates/authentication/_msg_rest_password_success.html:2
#: authentication/templates/authentication/_msg_rest_public_key_success.html:2
#: jumpserver/conf.py:390 ops/tasks.py:145 ops/tasks.py:148
#: jumpserver/conf.py:402 ops/tasks.py:145 ops/tasks.py:148
#: perms/templates/perms/_msg_item_permissions_expire.html:3
#: perms/templates/perms/_msg_permed_items_expire.html:3
#: tickets/templates/tickets/approve_check_password.html:33
@ -2439,7 +2461,7 @@ msgid "Copy success"
msgstr "复制成功"
#: authentication/utils.py:28 common/utils/ip/geoip/utils.py:24
#: xpack/plugins/cloud/const.py:24
#: xpack/plugins/cloud/const.py:26
msgid "LAN"
msgstr "局域网"
@ -2537,11 +2559,11 @@ msgstr ""
msgid "No ticket found"
msgstr "没有发现工单"
#: authentication/views/login.py:346
#: authentication/views/login.py:348
msgid "Logout success"
msgstr "退出登录成功"
#: authentication/views/login.py:347
#: authentication/views/login.py:349
msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面"
@ -2713,15 +2735,19 @@ msgstr "阿里云"
msgid "Tencent cloud"
msgstr "腾讯云"
#: common/sdk/sms/endpoint.py:18
#: common/sdk/sms/endpoint.py:18 xpack/plugins/cloud/const.py:13
msgid "Huawei Cloud"
msgstr "华为云"
#: common/sdk/sms/endpoint.py:19
msgid "CMPP v2.0"
msgstr "CMPP v2.0"
#: common/sdk/sms/endpoint.py:29
#: common/sdk/sms/endpoint.py:30
msgid "SMS provider not support: {}"
msgstr "短信服务商不支持:{}"
#: common/sdk/sms/endpoint.py:50
#: common/sdk/sms/endpoint.py:51
msgid "SMS verification code signature or template invalid"
msgstr "短信验证码签名或模版无效"
@ -2753,11 +2779,11 @@ msgstr "不能包含特殊字符"
msgid "The mobile phone number format is incorrect"
msgstr "手机号格式不正确"
#: jumpserver/conf.py:389
#: jumpserver/conf.py:401
msgid "Create account successfully"
msgstr "创建账号成功"
#: jumpserver/conf.py:391
#: jumpserver/conf.py:403
msgid "Your account has been created successfully"
msgstr "你的账号已创建成功"
@ -2797,7 +2823,7 @@ msgid "Notifications"
msgstr "通知"
#: notifications/backends/__init__.py:10 users/forms/profile.py:102
#: users/models/user.py:667
#: users/models/user.py:671
msgid "Email"
msgstr "邮件"
@ -3030,7 +3056,7 @@ msgid "Can view all joined org"
msgstr "可以查看所有加入的组织"
#: orgs/models.py:222 rbac/models/role.py:46 rbac/models/rolebinding.py:44
#: users/models/user.py:675
#: users/models/user.py:679
msgid "Role"
msgstr "角色"
@ -3445,7 +3471,7 @@ msgid "Execute batch command"
msgstr "执行批量命令"
#: settings/api/dingtalk.py:31 settings/api/feishu.py:36
#: settings/api/sms.py:131 settings/api/wecom.py:37
#: settings/api/sms.py:148 settings/api/wecom.py:37
msgid "Test success"
msgstr "测试成功"
@ -3473,11 +3499,11 @@ msgstr "获取 LDAP 用户为 None"
msgid "Imported {} users successfully (Organization: {})"
msgstr "成功导入 {} 个用户 ( 组织: {} )"
#: settings/api/sms.py:113
#: settings/api/sms.py:130
msgid "Invalid SMS platform"
msgstr "无效的短信平台"
#: settings/api/sms.py:119
#: settings/api/sms.py:136
msgid "test_phone is required"
msgstr "测试手机号 该字段是必填项。"
@ -3577,7 +3603,8 @@ msgstr "服务端地址"
msgid "Proxy server url"
msgstr "回调地址"
#: settings/serializers/auth/cas.py:16 settings/serializers/auth/saml2.py:32
#: settings/serializers/auth/cas.py:16 settings/serializers/auth/oauth2.py:53
#: settings/serializers/auth/saml2.py:32
msgid "Logout completely"
msgstr "同步注销"
@ -3634,7 +3661,7 @@ msgstr "用户过滤器"
msgid "Choice may be (cn|uid|sAMAccountName)=%(user)s)"
msgstr "可能的选项是(cn或uid或sAMAccountName=%(user)s)"
#: settings/serializers/auth/ldap.py:57 settings/serializers/auth/oauth2.py:51
#: settings/serializers/auth/ldap.py:57 settings/serializers/auth/oauth2.py:55
#: settings/serializers/auth/oidc.py:36
msgid "User attr map"
msgstr "用户属性映射"
@ -3696,7 +3723,11 @@ msgstr "客户端认证方式"
msgid "Provider userinfo endpoint"
msgstr "用户信息端点地址"
#: settings/serializers/auth/oauth2.py:54 settings/serializers/auth/oidc.py:92
#: settings/serializers/auth/oauth2.py:51 settings/serializers/auth/oidc.py:74
msgid "Provider end session endpoint"
msgstr "注销会话端点地址"
#: settings/serializers/auth/oauth2.py:58 settings/serializers/auth/oidc.py:92
#: settings/serializers/auth/saml2.py:33
msgid "Always update user"
msgstr "总是更新用户信息"
@ -3741,10 +3772,6 @@ msgstr "端点地址"
msgid "Provider jwks endpoint"
msgstr "jwks 端点地址"
#: settings/serializers/auth/oidc.py:74
msgid "Provider end session endpoint"
msgstr "注销会话端点地址"
#: settings/serializers/auth/oidc.py:77
msgid "Provider sign alg"
msgstr "签名算法"
@ -3814,13 +3841,13 @@ msgid "SMS provider / Protocol"
msgstr "短信服务商 / 协议"
#: settings/serializers/auth/sms.py:22 settings/serializers/auth/sms.py:43
#: settings/serializers/auth/sms.py:51 settings/serializers/auth/sms.py:62
#: settings/serializers/email.py:65
#: settings/serializers/auth/sms.py:51 settings/serializers/auth/sms.py:60
#: settings/serializers/auth/sms.py:71 settings/serializers/email.py:65
msgid "Signature"
msgstr "签名"
#: settings/serializers/auth/sms.py:23 settings/serializers/auth/sms.py:44
#: settings/serializers/auth/sms.py:52
#: settings/serializers/auth/sms.py:52 settings/serializers/auth/sms.py:61
msgid "Template code"
msgstr "模板"
@ -3829,26 +3856,34 @@ msgid "Test phone"
msgstr "测试手机号"
#: settings/serializers/auth/sms.py:58
msgid "App Access Address"
msgstr "应用地址"
#: settings/serializers/auth/sms.py:59
msgid "Signature channel number"
msgstr "签名通道号"
#: settings/serializers/auth/sms.py:67
msgid "Enterprise code(SP id)"
msgstr "企业代码(SP id)"
#: settings/serializers/auth/sms.py:59
#: settings/serializers/auth/sms.py:68
msgid "Shared secret(Shared secret)"
msgstr "共享密码(Shared secret)"
#: settings/serializers/auth/sms.py:60
#: settings/serializers/auth/sms.py:69
msgid "Original number(Src id)"
msgstr "原始号码(Src id)"
#: settings/serializers/auth/sms.py:61
#: settings/serializers/auth/sms.py:70
msgid "Business type(Service id)"
msgstr "业务类型(Service id)"
#: settings/serializers/auth/sms.py:64
#: settings/serializers/auth/sms.py:73
msgid "Template"
msgstr "模板"
#: settings/serializers/auth/sms.py:65
#: settings/serializers/auth/sms.py:74
#, python-brace-format
msgid ""
"Template need contain {code} and Signature + template length does not exceed "
@ -3858,12 +3893,12 @@ msgstr ""
"模板需要包含 {code},并且模板+签名长度不能超过67个字。例如, 您的验证码是 "
"{code}, 有效期为5分钟。请不要泄露给其他人。"
#: settings/serializers/auth/sms.py:74
#: settings/serializers/auth/sms.py:83
#, python-brace-format
msgid "The template needs to contain {code}"
msgstr "模板需要包含 {code}"
#: settings/serializers/auth/sms.py:77
#: settings/serializers/auth/sms.py:86
msgid "Signature + Template must not exceed 65 words"
msgstr "模板+签名不能超过65个字"
@ -3880,7 +3915,7 @@ msgid "SSO auth key TTL"
msgstr "Token 有效期"
#: settings/serializers/auth/sso.py:15
#: xpack/plugins/cloud/serializers/account_attrs.py:159
#: xpack/plugins/cloud/serializers/account_attrs.py:176
msgid "Unit: second"
msgstr "单位: 秒"
@ -4014,10 +4049,6 @@ msgstr "测试收件人"
msgid "Tips: Used only as a test mail recipient"
msgstr "提示:仅用来作为测试邮件收件人"
#: settings/serializers/email.py:36
msgid "Use SSL"
msgstr "使用 SSL"
#: settings/serializers/email.py:37
msgid "If SMTP port is 465, may be select"
msgstr "如果SMTP端口是465通常需要启用 SSL"
@ -5680,7 +5711,7 @@ msgstr "不能和原来的密钥相同"
msgid "Not a valid ssh public key"
msgstr "SSH密钥不合法"
#: users/forms/profile.py:161 users/models/user.py:696
#: users/forms/profile.py:161 users/models/user.py:700
msgid "Public key"
msgstr "SSH公钥"
@ -5692,55 +5723,55 @@ msgstr "强制启用"
msgid "Local"
msgstr "数据库"
#: users/models/user.py:677 users/serializers/user.py:149
#: users/models/user.py:681 users/serializers/user.py:149
msgid "Is service account"
msgstr "服务账号"
#: users/models/user.py:679
#: users/models/user.py:683
msgid "Avatar"
msgstr "头像"
#: users/models/user.py:682
#: users/models/user.py:686
msgid "Wechat"
msgstr "微信"
#: users/models/user.py:699
#: users/models/user.py:703
msgid "Secret key"
msgstr "Secret key"
#: users/models/user.py:715
#: users/models/user.py:719
msgid "Source"
msgstr "来源"
#: users/models/user.py:719
#: users/models/user.py:723
msgid "Date password last updated"
msgstr "最后更新密码日期"
#: users/models/user.py:722
#: users/models/user.py:726
msgid "Need update password"
msgstr "需要更新密码"
#: users/models/user.py:896
#: users/models/user.py:901
msgid "Can invite user"
msgstr "可以邀请用户"
#: users/models/user.py:897
#: users/models/user.py:902
msgid "Can remove user"
msgstr "可以移除用户"
#: users/models/user.py:898
#: users/models/user.py:903
msgid "Can match user"
msgstr "可以匹配用户"
#: users/models/user.py:907
#: users/models/user.py:912
msgid "Administrator"
msgstr "管理员"
#: users/models/user.py:910
#: users/models/user.py:915
msgid "Administrator is the super user of system"
msgstr "Administrator是初始的超级管理员"
#: users/models/user.py:935
#: users/models/user.py:940
msgid "User password history"
msgstr "用户密码历史"
@ -6337,10 +6368,6 @@ msgstr "Azure (中国)"
msgid "Azure (International)"
msgstr "Azure (国际)"
#: xpack/plugins/cloud/const.py:13
msgid "Huawei Cloud"
msgstr "华为云"
#: xpack/plugins/cloud/const.py:14
msgid "Baidu Cloud"
msgstr "百度云"
@ -6354,58 +6381,66 @@ msgid "Tencent Cloud"
msgstr "腾讯云"
#: xpack/plugins/cloud/const.py:17
msgid "Tencent Cloud (Lighthouse)"
msgstr "腾讯云(轻量服务器应用)"
#: xpack/plugins/cloud/const.py:18
msgid "VMware"
msgstr "VMware"
#: xpack/plugins/cloud/const.py:18 xpack/plugins/cloud/providers/nutanix.py:13
#: xpack/plugins/cloud/const.py:19 xpack/plugins/cloud/providers/nutanix.py:13
msgid "Nutanix"
msgstr "Nutanix"
#: xpack/plugins/cloud/const.py:19
#: xpack/plugins/cloud/const.py:20
msgid "Huawei Private Cloud"
msgstr "华为私有云"
#: xpack/plugins/cloud/const.py:20
#: xpack/plugins/cloud/const.py:21
msgid "Qingyun Private Cloud"
msgstr "青云私有云"
#: xpack/plugins/cloud/const.py:21
#: xpack/plugins/cloud/const.py:22
msgid "CTYun Private Cloud"
msgstr "天翼私有云"
#: xpack/plugins/cloud/const.py:23
msgid "OpenStack"
msgstr "OpenStack"
#: xpack/plugins/cloud/const.py:22
#: xpack/plugins/cloud/const.py:24
msgid "Google Cloud Platform"
msgstr "谷歌云"
#: xpack/plugins/cloud/const.py:23
#: xpack/plugins/cloud/const.py:25
msgid "Fusion Compute"
msgstr ""
#: xpack/plugins/cloud/const.py:28
#: xpack/plugins/cloud/const.py:30
msgid "Instance name"
msgstr "实例名称"
#: xpack/plugins/cloud/const.py:29
#: xpack/plugins/cloud/const.py:31
msgid "Instance name and Partial IP"
msgstr "实例名称和部分IP"
#: xpack/plugins/cloud/const.py:34
#: xpack/plugins/cloud/const.py:36
msgid "Succeed"
msgstr "成功"
#: xpack/plugins/cloud/const.py:38
#: xpack/plugins/cloud/const.py:40
msgid "Unsync"
msgstr "未同步"
#: xpack/plugins/cloud/const.py:39
#: xpack/plugins/cloud/const.py:41
msgid "New Sync"
msgstr "新同步"
#: xpack/plugins/cloud/const.py:40
#: xpack/plugins/cloud/const.py:42
msgid "Synced"
msgstr "已同步"
#: xpack/plugins/cloud/const.py:41
#: xpack/plugins/cloud/const.py:43
msgid "Released"
msgstr "已释放"
@ -6675,11 +6710,11 @@ msgstr "华南-广州-友好用户环境"
msgid "CN East-Suqian"
msgstr "华东-宿迁"
#: xpack/plugins/cloud/serializers/account.py:62
#: xpack/plugins/cloud/serializers/account.py:64
msgid "Validity display"
msgstr "有效性显示"
#: xpack/plugins/cloud/serializers/account.py:63
#: xpack/plugins/cloud/serializers/account.py:65
msgid "Provider display"
msgstr "服务商显示"
@ -6697,7 +6732,8 @@ msgstr "订阅 ID"
#: xpack/plugins/cloud/serializers/account_attrs.py:95
#: xpack/plugins/cloud/serializers/account_attrs.py:100
#: xpack/plugins/cloud/serializers/account_attrs.py:124
#: xpack/plugins/cloud/serializers/account_attrs.py:116
#: xpack/plugins/cloud/serializers/account_attrs.py:141
msgid "API Endpoint"
msgstr "API 端点"
@ -6714,24 +6750,32 @@ msgid "User domain"
msgstr "用户域"
#: xpack/plugins/cloud/serializers/account_attrs.py:117
msgid "Cert File"
msgstr "证书文件"
#: xpack/plugins/cloud/serializers/account_attrs.py:118
msgid "Key File"
msgstr "秘钥文件"
#: xpack/plugins/cloud/serializers/account_attrs.py:134
msgid "Service account key"
msgstr "服务账号密钥"
#: xpack/plugins/cloud/serializers/account_attrs.py:118
#: xpack/plugins/cloud/serializers/account_attrs.py:135
msgid "The file is in JSON format"
msgstr "JSON 格式的文件"
#: xpack/plugins/cloud/serializers/account_attrs.py:131
#: xpack/plugins/cloud/serializers/account_attrs.py:148
msgid "IP address invalid `{}`, {}"
msgstr "IP 地址无效: `{}`, {}"
#: xpack/plugins/cloud/serializers/account_attrs.py:137
#: xpack/plugins/cloud/serializers/account_attrs.py:154
msgid ""
"Format for comma-delimited string,Such as: 192.168.1.0/24, "
"10.0.0.0-10.0.0.255"
msgstr "格式为逗号分隔的字符串192.168.1.0/24,10.0.0.0-10.0.0.255"
#: xpack/plugins/cloud/serializers/account_attrs.py:141
#: xpack/plugins/cloud/serializers/account_attrs.py:158
msgid ""
"The port is used to detect the validity of the IP address. When the "
"synchronization task is executed, only the valid IP address will be "
@ -6740,19 +6784,19 @@ msgstr ""
"端口用来检测 IP 地址的有效性,在同步任务执行时,只会同步有效的 IP 地址。 <br>"
"如果端口为 0则表示所有 IP 地址均有效。"
#: xpack/plugins/cloud/serializers/account_attrs.py:149
#: xpack/plugins/cloud/serializers/account_attrs.py:166
msgid "Hostname prefix"
msgstr "主机名前缀"
#: xpack/plugins/cloud/serializers/account_attrs.py:152
#: xpack/plugins/cloud/serializers/account_attrs.py:169
msgid "IP segment"
msgstr "IP 网段"
#: xpack/plugins/cloud/serializers/account_attrs.py:156
#: xpack/plugins/cloud/serializers/account_attrs.py:173
msgid "Test port"
msgstr "测试端口"
#: xpack/plugins/cloud/serializers/account_attrs.py:159
#: xpack/plugins/cloud/serializers/account_attrs.py:176
msgid "Test timeout"
msgstr "测试超时时间"

View File

@ -40,6 +40,7 @@ class SettingsApi(generics.RetrieveUpdateAPIView):
'sms': serializers.SMSSettingSerializer,
'alibaba': serializers.AlibabaSMSSettingSerializer,
'tencent': serializers.TencentSMSSettingSerializer,
'huawei': serializers.HuaweiSMSSettingSerializer,
'cmpp2': serializers.CMPP2SMSSettingSerializer,
}

View File

@ -38,6 +38,7 @@ class SMSTestingAPI(GenericAPIView):
backends_serializer = {
'alibaba': serializers.AlibabaSMSSettingSerializer,
'tencent': serializers.TencentSMSSettingSerializer,
'huawei': serializers.HuaweiSMSSettingSerializer,
'cmpp2': serializers.CMPP2SMSSettingSerializer
}
rbac_perms = {
@ -82,6 +83,22 @@ class SMSTestingAPI(GenericAPIView):
}
return init_params, send_sms_params
def get_huawei_params(self, data):
init_params = {
'app_key': data['HUAWEI_APP_KEY'],
'app_secret': self.get_or_from_setting(
'HUAWEI_APP_SECRET', data.get('HUAWEI_APP_SECRET')
),
'url': data['HUAWEI_SMS_ENDPOINT'],
'sign_channel_num': data['HUAWEI_SIGN_CHANNEL_NUM'],
}
send_sms_params = {
'sign_name': data['HUAWEI_VERIFY_SIGN_NAME'],
'template_code': data['HUAWEI_VERIFY_TEMPLATE_CODE'],
'template_param': OrderedDict(code='666666')
}
return init_params, send_sms_params
def get_cmpp2_params(self, data):
init_params = {
'host': data['CMPP2_HOST'], 'port': data['CMPP2_PORT'],

View File

@ -47,6 +47,10 @@ class OAuth2SettingSerializer(serializers.Serializer):
AUTH_OAUTH2_PROVIDER_USERINFO_ENDPOINT = serializers.CharField(
required=True, max_length=1024, label=_('Provider userinfo endpoint')
)
AUTH_OAUTH2_PROVIDER_END_SESSION_ENDPOINT = serializers.CharField(
required=False, max_length=1024, label=_('Provider end session endpoint')
)
AUTH_OAUTH2_LOGOUT_COMPLETELY = serializers.BooleanField(required=False, label=_('Logout completely'))
AUTH_OAUTH2_USER_ATTR_MAP = serializers.DictField(
required=True, label=_('User attr map')
)

View File

@ -7,7 +7,7 @@ from common.sdk.sms import BACKENDS
__all__ = [
'SMSSettingSerializer', 'AlibabaSMSSettingSerializer', 'TencentSMSSettingSerializer',
'CMPP2SMSSettingSerializer'
'HuaweiSMSSettingSerializer', 'CMPP2SMSSettingSerializer'
]
@ -52,6 +52,15 @@ class TencentSMSSettingSerializer(BaseSMSSettingSerializer):
TENCENT_VERIFY_TEMPLATE_CODE = serializers.CharField(max_length=256, required=True, label=_('Template code'))
class HuaweiSMSSettingSerializer(BaseSMSSettingSerializer):
HUAWEI_APP_KEY = serializers.CharField(max_length=256, required=True, label='App key')
HUAWEI_APP_SECRET = EncryptedField(max_length=256, required=False, label='App secret')
HUAWEI_SMS_ENDPOINT = serializers.CharField(max_length=1024, required=True, label=_('App Access Address'))
HUAWEI_SIGN_CHANNEL_NUM = serializers.CharField(max_length=1024, required=True, label=_('Signature channel number'))
HUAWEI_VERIFY_SIGN_NAME = serializers.CharField(max_length=256, required=True, label=_('Signature'))
HUAWEI_VERIFY_TEMPLATE_CODE = serializers.CharField(max_length=256, required=True, label=_('Template code'))
class CMPP2SMSSettingSerializer(BaseSMSSettingSerializer):
CMPP2_HOST = serializers.CharField(max_length=256, required=True, label=_('Host'))
CMPP2_PORT = serializers.IntegerField(default=7890, label=_('Port'))

View File

@ -13,7 +13,7 @@ def telnet(dest_addr, port_number=23, timeout=10):
return False, str(e)
expected_regexes = [bytes(PROMPT_REGEX, encoding='ascii')]
index, prompt_regex, output = connection.expect(expected_regexes, timeout=3)
return True, output.decode('ascii')
return True, output.decode('utf-8', 'ignore')
if __name__ == "__main__":

View File

@ -1549,10 +1549,13 @@ function encryptPassword(password) {
if (!password) {
return ''
}
const aesKey = (Math.random() + 1).toString(36).substring(2)
// public key base64 存储的
const rsaPublicKeyText = getCookie('jms_public_key')
.replaceAll('"', '')
let rsaPublicKeyText = getCookie('jms_public_key')
if (!rsaPublicKeyText) {
return password
}
const aesKey = (Math.random() + 1).toString(36).substring(2)
rsaPublicKeyText = rsaPublicKeyText.replaceAll('"', '')
const rsaPublicKey = atob(rsaPublicKeyText)
const keyCipher = rsaEncrypt(aesKey, rsaPublicKey)
const passwordCipher = aesEncrypt(password, aesKey)

View File

@ -1,5 +1,6 @@
from django_filters import rest_framework as filters
from django.db.models import Subquery, OuterRef
from django.db.models.functions import Concat
from django.db.models import Subquery, OuterRef, Value, F, Q
from common.drf.filters import BaseFilterSet
@ -11,6 +12,10 @@ from tickets.models import (
class TicketFilter(BaseFilterSet):
assignees__id = filters.UUIDFilter(method='filter_assignees_id')
relevant_app = filters.CharFilter(method='filter_relevant_app')
relevant_asset = filters.CharFilter(method='filter_relevant_asset')
relevant_system_user = filters.CharFilter(method='filter_relevant_system_user')
relevant_command = filters.CharFilter(method='filter_relevant_command')
class Meta:
model = Ticket
@ -27,6 +32,72 @@ class TicketFilter(BaseFilterSet):
ticket_steps__ticket_assignees__assignee__id=value
)
def filter_relevant_asset(self, queryset, name, value):
asset_ids = ApplyAssetTicket.objects.annotate(
asset_str=Concat(
F('apply_assets__hostname'), Value('('),
F('apply_assets__ip'), Value(')')
)
).filter(
asset_str__icontains=value
).values_list('id', flat=True)
login_asset_ids = ApplyLoginAssetTicket.objects.annotate(
asset_str=Concat(
F('apply_login_asset__hostname'), Value('('),
F('apply_login_asset__ip'), Value(')')
)
).filter(
asset_str__icontains=value
).values_list('id', flat=True)
command_ids = ApplyCommandTicket.objects.filter(
apply_run_asset__icontains=value
).values_list('id', flat=True)
ticket_ids = list(set(list(asset_ids) + list(login_asset_ids) + list(command_ids)))
return queryset.filter(id__in=ticket_ids)
def filter_relevant_app(self, queryset, name, value):
app_ids = ApplyApplicationTicket.objects.filter(
apply_applications__name__icontains=value
).values_list('id', flat=True)
command_ids = ApplyCommandTicket.objects.filter(
apply_run_asset__icontains=value
).values_list('id', flat=True)
ticket_ids = list(set(list(app_ids) + list(command_ids)))
return queryset.filter(id__in=ticket_ids)
def filter_relevant_system_user(self, queryset, name, value):
system_user_query = Q(apply_system_users__name__icontains=value)
asset_ids = ApplyAssetTicket.objects.filter(
system_user_query
).values_list('id', flat=True)
app_ids = ApplyApplicationTicket.objects.filter(
system_user_query
).values_list('id', flat=True)
login_asset_ids = ApplyLoginAssetTicket.objects.filter(
apply_login_system_user__name__icontains=value
).values_list('id', flat=True)
command_ids = ApplyCommandTicket.objects.filter(
apply_run_system_user__name__icontains=value
).values_list('id', flat=True)
ticket_ids = list(
set(list(asset_ids) + list(app_ids) + list(login_asset_ids) + list(command_ids))
)
return queryset.filter(id__in=ticket_ids)
def filter_relevant_command(self, queryset, name, value):
command_ids = ApplyCommandTicket.objects.filter(
apply_run_command__icontains=value
).values_list('id', flat=True)
return queryset.filter(id__in=list(command_ids))
class ApplyAssetTicketFilter(BaseFilterSet):
class Meta:

View File

@ -11,6 +11,9 @@ action="${1-start}"
service="${2-all}"
trap cleanup EXIT
rm -f /opt/jumpserver/tmp/*.pid
if [[ "$action" == "bash" || "$action" == "sh" ]];then
bash
elif [[ "$action" == "sleep" ]];then
@ -19,4 +22,3 @@ elif [[ "$action" == "sleep" ]];then
else
python jms "${action}" "${service}"
fi

View File

@ -62,7 +62,7 @@ jsonfield2==4.0.0.post0
geoip2==4.5.0
ipip-ipdb==1.6.1
# Django environment
Django==3.2.14
Django==3.2.15
django-bootstrap3==14.2.0
django-filter==2.4.0
django-formtools==2.2
@ -91,7 +91,7 @@ eventlet==0.33.1
greenlet==1.1.2
gunicorn==20.1.0
celery==5.2.7
flower==1.0.0
flower==1.2.0
django-celery-beat==2.3.0
kombu==5.2.4
# Auth
@ -134,9 +134,10 @@ django-mysql==3.9.0
django-redis==5.2.0
python-redis-lock==3.7.0
redis==4.3.3
pymongo==4.2.0
# Debug
ipython==8.4.0
ForgeryPy3==0.3.1
django-debug-toolbar==3.5
Pympler==1.0.1
IPy==1.1
IPy==1.1