From f04378eaf8b03a5892118c408ef6f16ab00a33b5 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Fri, 11 Mar 2022 12:56:22 +0800 Subject: [PATCH 01/59] =?UTF-8?q?feat:=20JumpServer=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=83=A8=E7=BD=B2=E5=9C=A8=E4=BD=BF=E7=94=A8=E4=BA=86ssl?= =?UTF-8?q?=E7=9A=84redis=E4=B8=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/cache.py | 6 ++--- apps/common/utils/connection.py | 26 ++++++++++++--------- apps/common/utils/lock.py | 3 ++- apps/jumpserver/rewriting/session.py | 35 ++++++++++++++++++++++++++-- apps/jumpserver/settings/base.py | 25 +++++++++++++++----- apps/jumpserver/settings/libs.py | 31 +++++++++++++++++++----- utils/start_celery_beat.py | 15 +++++++++++- 7 files changed, 110 insertions(+), 31 deletions(-) diff --git a/apps/common/cache.py b/apps/common/cache.py index 168f9e9d3..b988a8673 100644 --- a/apps/common/cache.py +++ b/apps/common/cache.py @@ -1,11 +1,9 @@ import time -from redis import Redis - from common.utils.lock import DistributedLock +from common.utils.connection import get_redis_client from common.utils import lazyproperty from common.utils import get_logger -from jumpserver.const import CONFIG logger = get_logger(__file__) @@ -58,7 +56,7 @@ class Cache(metaclass=CacheType): def __init__(self): self._data = None - self.redis = Redis(host=CONFIG.REDIS_HOST, port=CONFIG.REDIS_PORT, password=CONFIG.REDIS_PASSWORD) + self.redis = get_redis_client() def __getitem__(self, item): return self.field_desc_mapper[item] diff --git a/apps/common/utils/connection.py b/apps/common/utils/connection.py index 22625c8ad..22030c809 100644 --- a/apps/common/utils/connection.py +++ b/apps/common/utils/connection.py @@ -1,23 +1,29 @@ import json import threading -import redis +from redis import Redis from django.conf import settings +from jumpserver.const import CONFIG +from common.http import is_true from common.db.utils import safe_db_connection from common.utils import get_logger logger = get_logger(__name__) -def get_redis_client(db): - rc = redis.StrictRedis( - host=settings.REDIS_HOST, - port=settings.REDIS_PORT, - password=settings.REDIS_PASSWORD, - db=db - ) - return rc +def get_redis_client(db=0): + params = { + 'host': CONFIG.REDIS_HOST, + 'port': CONFIG.REDIS_PORT, + 'password': CONFIG.REDIS_PASSWORD, + 'db': db, + "ssl": is_true(CONFIG.REDIS_USE_SSL), + 'ssl_keyfile': getattr(settings, 'REDIS_SSL_KEYFILE'), + 'ssl_certfile': getattr(settings, 'REDIS_SSL_CERTFILE'), + 'ssl_ca_certs': getattr(settings, 'REDIS_SSL_CA_CERTS'), + } + return Redis(**params) class Subscription: @@ -99,5 +105,3 @@ class RedisPubSub: data_json = json.dumps(data) self.redis.publish(self.ch, data_json) return True - - diff --git a/apps/common/utils/lock.py b/apps/common/utils/lock.py index c9e4e9734..a14fe1184 100644 --- a/apps/common/utils/lock.py +++ b/apps/common/utils/lock.py @@ -10,6 +10,7 @@ from django.db import transaction from common.utils import get_logger from common.utils.inspect import copy_function_args +from common.utils.connection import get_redis_client from jumpserver.const import CONFIG from common.local import thread_local @@ -44,7 +45,7 @@ class DistributedLock(RedisLock): 是否可重入 """ self.kwargs_copy = copy_function_args(self.__init__, locals()) - redis = Redis(host=CONFIG.REDIS_HOST, port=CONFIG.REDIS_PORT, password=CONFIG.REDIS_PASSWORD) + redis = get_redis_client() if expire is None: expire = auto_renewal_seconds diff --git a/apps/jumpserver/rewriting/session.py b/apps/jumpserver/rewriting/session.py index d0e698070..7b5ee150e 100644 --- a/apps/jumpserver/rewriting/session.py +++ b/apps/jumpserver/rewriting/session.py @@ -1,8 +1,39 @@ -from redis_sessions.session import force_unicode, SessionStore as RedisSessionStore -from redis import exceptions +from redis_sessions.session import ( + force_unicode, SessionStore as RedisSessionStore, + RedisServer as RedisRedisServer, settings as redis_setting +) +from redis import exceptions, Redis +from django.conf import settings + +from jumpserver.const import CONFIG + + +class RedisServer(RedisRedisServer): + __redis = {} + + def get(self): + if self.connection_key in self.__redis: + return self.__redis[self.connection_key] + + ssl_params = {} + if CONFIG.REDIS_USE_SSL: + ssl_params = { + 'ssl_keyfile': getattr(settings, 'REDIS_SSL_KEYFILE'), + 'ssl_certfile': getattr(settings, 'REDIS_SSL_CERTFILE'), + 'ssl_ca_certs': getattr(settings, 'REDIS_SSL_CA_CERTS'), + } + # 只根据 redis_url 方式连接 + self.__redis[self.connection_key] = Redis.from_url( + redis_setting.SESSION_REDIS_URL, **ssl_params + ) + + return self.__redis[self.connection_key] class SessionStore(RedisSessionStore): + def __init__(self, session_key=None): + super(SessionStore, self).__init__(session_key) + self.server = RedisServer(session_key).get() def load(self): try: diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index d81089a6d..cb77177ec 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -135,10 +135,13 @@ SESSION_EXPIRE_AT_BROWSER_CLOSE_FORCE = CONFIG.SESSION_EXPIRE_AT_BROWSER_CLOSE_F SESSION_SAVE_EVERY_REQUEST = CONFIG.SESSION_SAVE_EVERY_REQUEST SESSION_ENGINE = 'jumpserver.rewriting.session' SESSION_REDIS = { - 'host': CONFIG.REDIS_HOST, - 'port': CONFIG.REDIS_PORT, - 'password': CONFIG.REDIS_PASSWORD, - 'db': CONFIG.REDIS_DB_SESSION, + 'url': '%(protocol)s://:%(password)s@%(host)s:%(port)s/%(db)s' % { + 'protocol': 'rediss' if CONFIG.REDIS_USE_SSL else 'redis', + 'password': CONFIG.REDIS_PASSWORD, + 'host': CONFIG.REDIS_HOST, + 'port': CONFIG.REDIS_PORT, + 'db': CONFIG.REDIS_DB_CACHE, + }, 'prefix': 'auth_session', 'socket_timeout': 1, 'retry_on_timeout': False @@ -246,18 +249,28 @@ FILE_UPLOAD_PERMISSIONS = 0o644 FILE_UPLOAD_DIRECTORY_PERMISSIONS = 0o755 # Cache use redis +REDIS_SSL_KEYFILE = os.path.join(PROJECT_DIR, 'data', 'certs', 'redis_client.key') +REDIS_SSL_CERTFILE = os.path.join(PROJECT_DIR, 'data', 'certs', 'redis_client.crt') +REDIS_SSL_CA_CERTS = os.path.join(PROJECT_DIR, 'data', 'certs', 'redis_ca.crt') + CACHES = { 'default': { # 'BACKEND': 'redis_cache.RedisCache', 'BACKEND': 'redis_lock.django_cache.RedisCache', - 'LOCATION': 'redis://:%(password)s@%(host)s:%(port)s/%(db)s' % { + 'LOCATION': '%(protocol)s://:%(password)s@%(host)s:%(port)s/%(db)s' % { + 'protocol': 'rediss' if CONFIG.REDIS_USE_SSL else 'redis', 'password': CONFIG.REDIS_PASSWORD, 'host': CONFIG.REDIS_HOST, 'port': CONFIG.REDIS_PORT, 'db': CONFIG.REDIS_DB_CACHE, }, 'OPTIONS': { - "REDIS_CLIENT_KWARGS": {"health_check_interval": 30} + "REDIS_CLIENT_KWARGS": {"health_check_interval": 30}, + "CONNECTION_POOL_KWARGS": { + "ssl_keyfile": REDIS_SSL_KEYFILE, + "ssl_certfile": REDIS_SSL_CERTFILE, + "ssl_ca_certs": REDIS_SSL_CA_CERTS + } if CONFIG.REDIS_USE_SSL else {} } } } diff --git a/apps/jumpserver/settings/libs.py b/apps/jumpserver/settings/libs.py index eb7b5a9eb..9bd56122b 100644 --- a/apps/jumpserver/settings/libs.py +++ b/apps/jumpserver/settings/libs.py @@ -1,6 +1,9 @@ # -*- coding: utf-8 -*- # import os +import ssl + +from .base import REDIS_SSL_CA_CERTS, REDIS_SSL_CERTFILE, REDIS_SSL_KEYFILE from ..const import CONFIG, PROJECT_DIR REST_FRAMEWORK = { @@ -82,16 +85,24 @@ BOOTSTRAP3 = { # Django channels support websocket -CHANNEL_REDIS = "redis://:{}@{}:{}/{}".format( - CONFIG.REDIS_PASSWORD, CONFIG.REDIS_HOST, CONFIG.REDIS_PORT, - CONFIG.REDIS_DB_WS, -) +if not CONFIG.REDIS_USE_SSL: + context = None +else: + context = ssl.SSLContext() + context.check_hostname = False + context.load_verify_locations(REDIS_SSL_CA_CERTS) + context.load_cert_chain(REDIS_SSL_CERTFILE, REDIS_SSL_KEYFILE) CHANNEL_LAYERS = { 'default': { 'BACKEND': 'channels_redis.core.RedisChannelLayer', 'CONFIG': { - "hosts": [CHANNEL_REDIS], + "hosts": [{ + 'address': (CONFIG.REDIS_HOST, CONFIG.REDIS_PORT), + 'db': CONFIG.REDIS_DB_WS, + 'password': CONFIG.REDIS_PASSWORD, + 'ssl': context + }], }, }, } @@ -102,7 +113,8 @@ ASGI_APPLICATION = 'jumpserver.routing.application' CELERY_LOG_DIR = os.path.join(PROJECT_DIR, 'data', 'celery') # Celery using redis as broker -CELERY_BROKER_URL = 'redis://:%(password)s@%(host)s:%(port)s/%(db)s' % { +CELERY_BROKER_URL = '%(protocol)s://:%(password)s@%(host)s:%(port)s/%(db)s' % { + 'protocol': 'rediss' if CONFIG.REDIS_USE_SSL else 'redis', 'password': CONFIG.REDIS_PASSWORD, 'host': CONFIG.REDIS_HOST, 'port': CONFIG.REDIS_PORT, @@ -125,6 +137,13 @@ CELERY_WORKER_REDIRECT_STDOUTS_LEVEL = "INFO" # CELERY_WORKER_HIJACK_ROOT_LOGGER = True # CELERY_WORKER_MAX_TASKS_PER_CHILD = 40 CELERY_TASK_SOFT_TIME_LIMIT = 3600 +if CONFIG.REDIS_USE_SSL: + CELERY_BROKER_USE_SSL = CELERY_REDIS_BACKEND_USE_SSL = { + 'ssl_cert_reqs': 'required', + 'ssl_ca_certs': REDIS_SSL_CA_CERTS, + 'ssl_certfile': REDIS_SSL_CERTFILE, + 'ssl_keyfile': REDIS_SSL_KEYFILE + } ANSIBLE_LOG_DIR = os.path.join(PROJECT_DIR, 'data', 'ansible') diff --git a/utils/start_celery_beat.py b/utils/start_celery_beat.py index 236a61ba8..714dbd826 100644 --- a/utils/start_celery_beat.py +++ b/utils/start_celery_beat.py @@ -18,7 +18,20 @@ os.environ.setdefault('PYTHONOPTIMIZE', '1') if os.getuid() == 0: os.environ.setdefault('C_FORCE_ROOT', '1') -redis = Redis(host=CONFIG.REDIS_HOST, port=CONFIG.REDIS_PORT, password=CONFIG.REDIS_PASSWORD) +REDIS_SSL_KEYFILE = os.path.join(BASE_DIR, 'data', 'certs', 'redis_client.key') +REDIS_SSL_CERTFILE = os.path.join(BASE_DIR, 'data', 'certs', 'redis_client.crt') +REDIS_SSL_CA_CERTS = os.path.join(BASE_DIR, 'data', 'certs', 'redis_ca.crt') + +params = { + 'host': CONFIG.REDIS_HOST, + 'port': CONFIG.REDIS_PORT, + 'password': CONFIG.REDIS_PASSWORD, + "ssl": CONFIG.REDIS_USE_SSL, + "ssl_keyfile": REDIS_SSL_KEYFILE, + "ssl_certfile": REDIS_SSL_CERTFILE, + "ssl_ca_certs": REDIS_SSL_CA_CERTS +} +redis = Redis(**params) scheduler = "django_celery_beat.schedulers:DatabaseScheduler" cmd = [ From 794139782ff56ab17fc92f9538b65fbf2d7dc017 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Mon, 14 Mar 2022 11:35:14 +0800 Subject: [PATCH 02/59] =?UTF-8?q?feat:=20JumpServer=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=83=A8=E7=BD=B2=E5=9C=A8=E4=BD=BF=E7=94=A8=E4=BA=86ssl?= =?UTF-8?q?=E7=9A=84redis=E4=B8=8A=EF=BC=8C=E5=8F=AF=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E8=AF=81=E4=B9=A6=E8=BF=9E=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/utils/connection.py | 1 + apps/jumpserver/rewriting/session.py | 1 + apps/jumpserver/settings/base.py | 9 +++++++++ apps/jumpserver/settings/libs.py | 7 ++++--- utils/start_celery_beat.py | 9 +++++++++ 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/apps/common/utils/connection.py b/apps/common/utils/connection.py index 22030c809..291d4516d 100644 --- a/apps/common/utils/connection.py +++ b/apps/common/utils/connection.py @@ -19,6 +19,7 @@ def get_redis_client(db=0): 'password': CONFIG.REDIS_PASSWORD, 'db': db, "ssl": is_true(CONFIG.REDIS_USE_SSL), + 'ssl_cert_reqs': CONFIG.REDIS_SSL_REQUIRED, 'ssl_keyfile': getattr(settings, 'REDIS_SSL_KEYFILE'), 'ssl_certfile': getattr(settings, 'REDIS_SSL_CERTFILE'), 'ssl_ca_certs': getattr(settings, 'REDIS_SSL_CA_CERTS'), diff --git a/apps/jumpserver/rewriting/session.py b/apps/jumpserver/rewriting/session.py index 7b5ee150e..ff34caded 100644 --- a/apps/jumpserver/rewriting/session.py +++ b/apps/jumpserver/rewriting/session.py @@ -18,6 +18,7 @@ class RedisServer(RedisRedisServer): ssl_params = {} if CONFIG.REDIS_USE_SSL: ssl_params = { + 'ssl_cert_reqs': CONFIG.REDIS_SSL_REQUIRED, 'ssl_keyfile': getattr(settings, 'REDIS_SSL_KEYFILE'), 'ssl_certfile': getattr(settings, 'REDIS_SSL_CERTFILE'), 'ssl_ca_certs': getattr(settings, 'REDIS_SSL_CA_CERTS'), diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index cb77177ec..e5b382517 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -250,8 +250,16 @@ FILE_UPLOAD_DIRECTORY_PERMISSIONS = 0o755 # Cache use redis REDIS_SSL_KEYFILE = os.path.join(PROJECT_DIR, 'data', 'certs', 'redis_client.key') +if not os.path.exists(REDIS_SSL_KEYFILE): + REDIS_SSL_KEYFILE = None + REDIS_SSL_CERTFILE = os.path.join(PROJECT_DIR, 'data', 'certs', 'redis_client.crt') +if not os.path.exists(REDIS_SSL_CERTFILE): + REDIS_SSL_CERTFILE = None + REDIS_SSL_CA_CERTS = os.path.join(PROJECT_DIR, 'data', 'certs', 'redis_ca.crt') +if not os.path.exists(REDIS_SSL_CA_CERTS): + REDIS_SSL_CA_CERTS = os.path.join(PROJECT_DIR, 'data', 'certs', 'redis_ca.pem') CACHES = { 'default': { @@ -267,6 +275,7 @@ CACHES = { 'OPTIONS': { "REDIS_CLIENT_KWARGS": {"health_check_interval": 30}, "CONNECTION_POOL_KWARGS": { + 'ssl_cert_reqs': CONFIG.REDIS_SSL_REQUIRED, "ssl_keyfile": REDIS_SSL_KEYFILE, "ssl_certfile": REDIS_SSL_CERTFILE, "ssl_ca_certs": REDIS_SSL_CA_CERTS diff --git a/apps/jumpserver/settings/libs.py b/apps/jumpserver/settings/libs.py index 9bd56122b..11aa0ba16 100644 --- a/apps/jumpserver/settings/libs.py +++ b/apps/jumpserver/settings/libs.py @@ -89,9 +89,10 @@ if not CONFIG.REDIS_USE_SSL: context = None else: context = ssl.SSLContext() - context.check_hostname = False + context.check_hostname = bool(CONFIG.REDIS_SSL_REQUIRED) context.load_verify_locations(REDIS_SSL_CA_CERTS) - context.load_cert_chain(REDIS_SSL_CERTFILE, REDIS_SSL_KEYFILE) + if REDIS_SSL_CERTFILE and REDIS_SSL_KEYFILE: + context.load_cert_chain(REDIS_SSL_CERTFILE, REDIS_SSL_KEYFILE) CHANNEL_LAYERS = { 'default': { @@ -139,7 +140,7 @@ CELERY_WORKER_REDIRECT_STDOUTS_LEVEL = "INFO" CELERY_TASK_SOFT_TIME_LIMIT = 3600 if CONFIG.REDIS_USE_SSL: CELERY_BROKER_USE_SSL = CELERY_REDIS_BACKEND_USE_SSL = { - 'ssl_cert_reqs': 'required', + 'ssl_cert_reqs': CONFIG.REDIS_SSL_REQUIRED, 'ssl_ca_certs': REDIS_SSL_CA_CERTS, 'ssl_certfile': REDIS_SSL_CERTFILE, 'ssl_keyfile': REDIS_SSL_KEYFILE diff --git a/utils/start_celery_beat.py b/utils/start_celery_beat.py index 714dbd826..946fe9172 100644 --- a/utils/start_celery_beat.py +++ b/utils/start_celery_beat.py @@ -19,14 +19,23 @@ if os.getuid() == 0: os.environ.setdefault('C_FORCE_ROOT', '1') REDIS_SSL_KEYFILE = os.path.join(BASE_DIR, 'data', 'certs', 'redis_client.key') +if not os.path.exists(REDIS_SSL_KEYFILE): + REDIS_SSL_KEYFILE = None + REDIS_SSL_CERTFILE = os.path.join(BASE_DIR, 'data', 'certs', 'redis_client.crt') +if not os.path.exists(REDIS_SSL_CERTFILE): + REDIS_SSL_CERTFILE = None + REDIS_SSL_CA_CERTS = os.path.join(BASE_DIR, 'data', 'certs', 'redis_ca.crt') +if not os.path.exists(REDIS_SSL_CA_CERTS): + REDIS_SSL_CA_CERTS = os.path.join(BASE_DIR, 'data', 'certs', 'redis_ca.pem') params = { 'host': CONFIG.REDIS_HOST, 'port': CONFIG.REDIS_PORT, 'password': CONFIG.REDIS_PASSWORD, "ssl": CONFIG.REDIS_USE_SSL, + 'ssl_cert_reqs': CONFIG.REDIS_SSL_REQUIRED, "ssl_keyfile": REDIS_SSL_KEYFILE, "ssl_certfile": REDIS_SSL_CERTFILE, "ssl_ca_certs": REDIS_SSL_CA_CERTS From d4e4015d91ca19c996d33eee879278f04b0ea2d0 Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" Date: Fri, 18 Mar 2022 15:04:13 +0800 Subject: [PATCH 03/59] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=8E=BB?= =?UTF-8?q?=E9=99=A4rolebiding=20change=20=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/rbac/const.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/rbac/const.py b/apps/rbac/const.py index b5d584e0b..780232e5a 100644 --- a/apps/rbac/const.py +++ b/apps/rbac/const.py @@ -49,6 +49,8 @@ exclude_permissions = ( ('rbac', 'contenttype', '*', '*'), ('rbac', 'permission', 'add,delete,change', 'permission'), ('rbac', 'rolebinding', '*', '*'), + ('rbac', 'systemrolebinding', 'change', 'systemrolebinding'), + ('rbac', 'orgrolebinding', 'change', 'orgrolebinding'), ('rbac', 'role', '*', '*'), ('ops', 'adhoc', 'delete,change', '*'), ('ops', 'adhocexecution', 'add,delete,change', '*'), From ec9e5da6536be777e9f947f022171e131be6f065 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 18 Mar 2022 15:53:34 +0800 Subject: [PATCH 04/59] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dapikey=20perm=20?= =?UTF-8?q?(#7918)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng626 <1304903146@qq.com> --- apps/authentication/api/access_key.py | 1 - apps/rbac/const.py | 1 - 2 files changed, 2 deletions(-) diff --git a/apps/authentication/api/access_key.py b/apps/authentication/api/access_key.py index 716886c16..0762d0de9 100644 --- a/apps/authentication/api/access_key.py +++ b/apps/authentication/api/access_key.py @@ -8,7 +8,6 @@ from .. import serializers class AccessKeyViewSet(ModelViewSet): - permission_classes = (IsValidUser,) serializer_class = serializers.AccessKeySerializer search_fields = ['^id', '^secret'] diff --git a/apps/rbac/const.py b/apps/rbac/const.py index 780232e5a..8f2764d87 100644 --- a/apps/rbac/const.py +++ b/apps/rbac/const.py @@ -22,7 +22,6 @@ exclude_permissions = ( ('common', 'setting', '*', '*'), ('authentication', 'privatetoken', '*', '*'), - ('authentication', 'accesskey', 'change,delete', 'accesskey'), ('authentication', 'connectiontoken', 'change,delete', 'connectiontoken'), ('authentication', 'ssotoken', '*', '*'), ('authentication', 'superconnectiontoken', 'change,delete', 'superconnectiontoken'), From 996621f30381a8777e7718b843dbb78ca1f74167 Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" Date: Fri, 18 Mar 2022 16:53:09 +0800 Subject: [PATCH 05/59] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=E6=9D=83?= =?UTF-8?q?=E9=99=90dashboard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/rbac/tree.py | 1 - utils/clean_db_content_types.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/rbac/tree.py b/apps/rbac/tree.py index 083e64c96..5ea43e5ee 100644 --- a/apps/rbac/tree.py +++ b/apps/rbac/tree.py @@ -87,7 +87,6 @@ special_pid_mapper = { 'terminal.status': 'terminal_node', 'terminal.task': 'terminal_node', 'audits.ftplog': 'terminal', - 'rbac.menupermission': 'view_other', 'perms.view_myassets': 'my_assets', 'perms.view_myapps': 'my_apps', 'ops.add_commandexecution': 'view_workspace', diff --git a/utils/clean_db_content_types.py b/utils/clean_db_content_types.py index 9ca387be2..646a9d051 100644 --- a/utils/clean_db_content_types.py +++ b/utils/clean_db_content_types.py @@ -58,7 +58,7 @@ def clean_db_content_types(): ('perms', 'applicationpermission', 'view_permuserapplication'), ('perms', 'assetpermission', 'view_permuserasset'), ('perms', 'assetpermission', 'view_permusergroupasset'), - + ('rbac', 'menupermission', 'view_dashboard'), ('applications', 'databaseapp', 'add_databaseapp'), ('applications', 'databaseapp', 'change_databaseapp'), ('applications', 'databaseapp', 'delete_databaseapp'), From b8c083af7e67324b71e2383bc912d02b21d27307 Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" Date: Fri, 18 Mar 2022 17:32:31 +0800 Subject: [PATCH 06/59] =?UTF-8?q?fix:=20=E5=B7=A5=E5=8D=95=E6=9D=83?= =?UTF-8?q?=E9=99=90=E4=BD=8D=E6=94=BE=E5=88=B0sys=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/zh/LC_MESSAGES/django.mo | 2 +- apps/locale/zh/LC_MESSAGES/django.po | 2 +- apps/rbac/const.py | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 7095c929c..4aeb70566 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:449810c3661c09f6448b9c67e7a193f303a3bef7ccc3d0f1efe6e099804e782a +oid sha256:b1c6c0f9212f9d154a432d93785677ebc206eed4fd4338d3fe11b4b528d65c11 size 104323 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index f815acd61..3f5594eab 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -2050,7 +2050,7 @@ msgstr "请修改密码" #: authentication/models.py:33 terminal/serializers/storage.py:30 msgid "Access key" -msgstr "Api key" +msgstr "API key" #: authentication/models.py:40 msgid "Private Token" diff --git a/apps/rbac/const.py b/apps/rbac/const.py index 8f2764d87..58887947c 100644 --- a/apps/rbac/const.py +++ b/apps/rbac/const.py @@ -100,6 +100,7 @@ only_system_permissions = ( ('orgs', 'organization', '*', '*'), ('xpack', 'license', '*', '*'), ('settings', 'setting', '*', '*'), + ('tickets', '*', '*', '*'), ('ops', 'task', 'view', 'taskmonitor'), ('terminal', 'terminal', '*', '*'), ('terminal', 'commandstorage', '*', '*'), From 5da1ec55a78a2a48368ddc33ea7460915a4f54b6 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 18 Mar 2022 17:44:20 +0800 Subject: [PATCH 07/59] perf: org del ticket perm (#7932) Co-authored-by: feng626 <1304903146@qq.com> --- apps/rbac/const.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/rbac/const.py b/apps/rbac/const.py index 58887947c..5d6ae08ec 100644 --- a/apps/rbac/const.py +++ b/apps/rbac/const.py @@ -108,6 +108,7 @@ only_system_permissions = ( ('terminal', 'status', '*', '*'), ('terminal', 'task', '*', '*'), ('authentication', '*', '*', '*'), + ('tickets', '*', '*', '*'), ) only_org_permissions = ( From 60edbb36a19188570113f9b5b2b60d01412a280d Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" Date: Fri, 18 Mar 2022 17:58:54 +0800 Subject: [PATCH 08/59] =?UTF-8?q?fix:=20=E5=BA=94=E7=94=A8=E6=A0=91?= =?UTF-8?q?=E9=9A=90=E8=97=8Fmongodb=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/applications/models/application.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/applications/models/application.py b/apps/applications/models/application.py index fa8125887..a6552fffd 100644 --- a/apps/applications/models/application.py +++ b/apps/applications/models/application.py @@ -100,6 +100,9 @@ class ApplicationTreeNodeMixin: type_category_mapper = const.AppType.type_category_mapper() types = const.AppType.type_category_mapper().keys() for tp in types: + # TODO: Temporary exclude mongodb + if tp == const.AppType.mongodb: + continue if not settings.XPACK_ENABLED and const.AppType.is_xpack(tp): continue category = type_category_mapper.get(tp) From e993f31b6d3ab5f4dfce1400e59190cf93242a1a Mon Sep 17 00:00:00 2001 From: jiangweidong <80373698+f2c-jiangweidong@users.noreply.github.com> Date: Mon, 21 Mar 2022 10:39:47 +0800 Subject: [PATCH 09/59] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E7=BA=B3?= =?UTF-8?q?=E7=AE=A1=E7=99=BE=E5=BA=A6=E4=BA=91=E8=B5=84=E4=BA=A7=20(#7921?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: ibuler --- apps/locale/zh/LC_MESSAGES/django.po | 125 ++++++++++++++++----------- requirements/requirements.txt | 1 + 2 files changed, 77 insertions(+), 49 deletions(-) diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 3f5594eab..04cfeaedb 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-03-17 19:16+0800\n" +"POT-Creation-Date: 2022-03-21 10:37+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -22,7 +22,7 @@ msgid "Acls" msgstr "访问控制" #: acls/models/base.py:25 acls/serializers/login_asset_acl.py:47 -#: applications/models/application.py:209 assets/models/asset.py:138 +#: applications/models/application.py:212 assets/models/asset.py:138 #: assets/models/base.py:175 assets/models/cluster.py:18 #: assets/models/cmd_filter.py:27 assets/models/domain.py:23 #: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24 @@ -56,7 +56,7 @@ msgstr "优先级可选范围为 1-100 (数值越小越优先)" msgid "Active" msgstr "激活中" -#: acls/models/base.py:32 applications/models/application.py:222 +#: acls/models/base.py:32 applications/models/application.py:225 #: assets/models/asset.py:143 assets/models/asset.py:231 #: assets/models/backup.py:54 assets/models/base.py:180 #: assets/models/cluster.py:29 assets/models/cmd_filter.py:48 @@ -274,7 +274,7 @@ msgstr "远程应用" msgid "Custom" msgstr "自定义" -#: applications/models/account.py:12 applications/models/application.py:226 +#: applications/models/account.py:12 applications/models/application.py:229 #: assets/models/backup.py:32 assets/models/cmd_filter.py:45 #: perms/models/application_permission.py:28 msgid "Application" @@ -314,7 +314,7 @@ msgstr "可以查看应用账号密码" msgid "Can change application account secret" msgstr "可以查看应用账号密码" -#: applications/models/application.py:211 +#: applications/models/application.py:214 #: applications/serializers/application.py:99 assets/models/label.py:21 #: perms/models/application_permission.py:21 #: perms/serializers/application/user_permission.py:33 @@ -323,7 +323,7 @@ msgstr "可以查看应用账号密码" msgid "Category" msgstr "类别" -#: applications/models/application.py:214 +#: applications/models/application.py:217 #: applications/serializers/application.py:101 assets/models/backup.py:49 #: assets/models/cmd_filter.py:82 assets/models/user.py:233 #: perms/models/application_permission.py:24 @@ -336,21 +336,21 @@ msgstr "类别" msgid "Type" msgstr "类型" -#: applications/models/application.py:218 assets/models/asset.py:217 +#: applications/models/application.py:221 assets/models/asset.py:217 #: assets/models/domain.py:29 assets/models/domain.py:63 msgid "Domain" msgstr "网域" -#: applications/models/application.py:220 xpack/plugins/cloud/models.py:33 -#: xpack/plugins/cloud/serializers/account.py:57 +#: applications/models/application.py:223 xpack/plugins/cloud/models.py:33 +#: xpack/plugins/cloud/serializers/account.py:58 msgid "Attrs" msgstr "属性" -#: applications/models/application.py:230 +#: applications/models/application.py:233 msgid "Can match application" msgstr "匹配应用" -#: applications/models/application.py:278 +#: applications/models/application.py:281 msgid "Application user" msgstr "应用用户" @@ -766,7 +766,7 @@ msgstr "成功" #: assets/models/base.py:32 audits/models.py:116 #: xpack/plugins/change_auth_plan/serializers/app.py:88 #: xpack/plugins/change_auth_plan/serializers/asset.py:198 -#: xpack/plugins/cloud/const.py:29 +#: xpack/plugins/cloud/const.py:30 msgid "Failed" msgstr "失败" @@ -1380,7 +1380,7 @@ msgstr "日志审计" #: audits/models.py:27 audits/models.py:57 #: authentication/templates/authentication/_access_key_modal.html:65 -#: rbac/tree.py:167 users/templates/users/user_asset_permission.html:128 +#: rbac/tree.py:166 users/templates/users/user_asset_permission.html:128 #: users/templates/users/user_database_app_permission.html:111 msgid "Delete" msgstr "删除" @@ -1434,11 +1434,11 @@ msgstr "文件管理" #: audits/models.py:55 #: authentication/templates/authentication/_access_key_modal.html:22 -#: rbac/tree.py:164 +#: rbac/tree.py:163 msgid "Create" msgstr "创建" -#: audits/models.py:56 rbac/tree.py:166 templates/_csv_import_export.html:18 +#: audits/models.py:56 rbac/tree.py:165 templates/_csv_import_export.html:18 #: templates/_csv_update_modal.html:6 #: users/templates/users/user_asset_permission.html:127 #: users/templates/users/user_database_app_permission.html:110 @@ -2875,7 +2875,7 @@ msgstr "当前组织 ({}) 不能被删除" msgid "The organization have resource ({}) cannot be deleted" msgstr "组织存在资源 ({}) 不能被删除" -#: orgs/apps.py:7 rbac/tree.py:113 +#: orgs/apps.py:7 rbac/tree.py:112 msgid "App organizations" msgstr "组织管理" @@ -3288,27 +3288,27 @@ msgstr "我的资产" msgid "My apps" msgstr "我的应用" -#: rbac/tree.py:114 +#: rbac/tree.py:113 msgid "Ticket comment" msgstr "工单评论" -#: rbac/tree.py:115 tickets/models/ticket.py:163 +#: rbac/tree.py:114 tickets/models/ticket.py:163 msgid "Ticket" msgstr "工单管理" -#: rbac/tree.py:116 +#: rbac/tree.py:115 msgid "Common setting" msgstr "一般设置" -#: rbac/tree.py:117 +#: rbac/tree.py:116 msgid "View permission tree" msgstr "查看授权树" -#: rbac/tree.py:118 +#: rbac/tree.py:117 msgid "Execute batch command" msgstr "执行批量命令" -#: rbac/tree.py:165 +#: rbac/tree.py:164 msgid "View" msgstr "查看" @@ -6378,58 +6378,62 @@ msgid "Huawei Cloud" msgstr "华为云" #: xpack/plugins/cloud/const.py:14 +msgid "Baidu Cloud" +msgstr "百度云" + +#: xpack/plugins/cloud/const.py:15 msgid "Tencent Cloud" msgstr "腾讯云" -#: xpack/plugins/cloud/const.py:15 +#: xpack/plugins/cloud/const.py:16 msgid "VMware" msgstr "" -#: xpack/plugins/cloud/const.py:16 xpack/plugins/cloud/providers/nutanix.py:13 +#: xpack/plugins/cloud/const.py:17 xpack/plugins/cloud/providers/nutanix.py:13 msgid "Nutanix" msgstr "" -#: xpack/plugins/cloud/const.py:17 +#: xpack/plugins/cloud/const.py:18 msgid "Huawei Private Cloud" msgstr "华为私有云" -#: xpack/plugins/cloud/const.py:18 +#: xpack/plugins/cloud/const.py:19 msgid "Qingyun Private Cloud" msgstr "青云私有云" -#: xpack/plugins/cloud/const.py:19 +#: xpack/plugins/cloud/const.py:20 msgid "OpenStack" msgstr "OpenStack" -#: xpack/plugins/cloud/const.py:20 +#: xpack/plugins/cloud/const.py:21 msgid "Google Cloud Platform" msgstr "谷歌云" -#: xpack/plugins/cloud/const.py:24 +#: xpack/plugins/cloud/const.py:25 msgid "Instance name" msgstr "实例名称" -#: xpack/plugins/cloud/const.py:25 +#: xpack/plugins/cloud/const.py:26 msgid "Instance name and Partial IP" msgstr "实例名称和部分IP" -#: xpack/plugins/cloud/const.py:30 +#: xpack/plugins/cloud/const.py:31 msgid "Succeed" msgstr "成功" -#: xpack/plugins/cloud/const.py:34 +#: xpack/plugins/cloud/const.py:35 msgid "Unsync" msgstr "未同步" -#: xpack/plugins/cloud/const.py:35 +#: xpack/plugins/cloud/const.py:36 msgid "New Sync" msgstr "新同步" -#: xpack/plugins/cloud/const.py:36 +#: xpack/plugins/cloud/const.py:37 msgid "Synced" msgstr "已同步" -#: xpack/plugins/cloud/const.py:37 +#: xpack/plugins/cloud/const.py:38 msgid "Released" msgstr "已释放" @@ -6601,6 +6605,41 @@ msgstr "中东(巴林)" msgid "South America (São Paulo)" msgstr "南美洲(圣保罗)" +#: xpack/plugins/cloud/providers/baiducloud.py:54 +msgid "CN North-Beijing" +msgstr "华北-北京" + +#: xpack/plugins/cloud/providers/baiducloud.py:55 +#: xpack/plugins/cloud/providers/huaweicloud.py:40 +msgid "CN South-Guangzhou" +msgstr "华南-广州" + +#: xpack/plugins/cloud/providers/baiducloud.py:56 +msgid "CN East-Suzhou" +msgstr "华东-苏州" + +#: xpack/plugins/cloud/providers/baiducloud.py:57 +#: xpack/plugins/cloud/providers/huaweicloud.py:48 +msgid "CN-Hong Kong" +msgstr "中国-香港" + +#: xpack/plugins/cloud/providers/baiducloud.py:58 +msgid "CN Center-Wuhan" +msgstr "华中-武汉" + +#: xpack/plugins/cloud/providers/baiducloud.py:59 +msgid "CN North-Baoding" +msgstr "华北-保定" + +#: xpack/plugins/cloud/providers/baiducloud.py:60 +msgid "CN East-Shanghai" +msgstr "华东-上海" + +#: xpack/plugins/cloud/providers/baiducloud.py:61 +#: xpack/plugins/cloud/providers/huaweicloud.py:47 +msgid "AP-Singapore" +msgstr "亚太-新加坡" + #: xpack/plugins/cloud/providers/huaweicloud.py:35 msgid "AF-Johannesburg" msgstr "非洲-约翰内斯堡" @@ -6621,10 +6660,6 @@ msgstr "华东-上海2" msgid "CN East-Shanghai1" msgstr "华东-上海1" -#: xpack/plugins/cloud/providers/huaweicloud.py:40 -msgid "CN South-Guangzhou" -msgstr "华南-广州" - #: xpack/plugins/cloud/providers/huaweicloud.py:41 msgid "LA-Mexico City1" msgstr "拉美-墨西哥城一" @@ -6649,14 +6684,6 @@ msgstr "西南-贵阳1" msgid "AP-Bangkok" msgstr "亚太-曼谷" -#: xpack/plugins/cloud/providers/huaweicloud.py:47 -msgid "AP-Singapore" -msgstr "亚太-新加坡" - -#: xpack/plugins/cloud/providers/huaweicloud.py:48 -msgid "CN-Hong Kong" -msgstr "中国-香港" - #: xpack/plugins/cloud/providers/huaweicloud.py:50 msgid "CN Northeast-Dalian" msgstr "华北-大连" @@ -6669,11 +6696,11 @@ msgstr "华北-乌兰察布一" msgid "CN South-Guangzhou-InvitationOnly" msgstr "华南-广州-友好用户环境" -#: xpack/plugins/cloud/serializers/account.py:58 +#: xpack/plugins/cloud/serializers/account.py:59 msgid "Validity display" msgstr "有效性显示" -#: xpack/plugins/cloud/serializers/account.py:59 +#: xpack/plugins/cloud/serializers/account.py:60 msgid "Provider display" msgstr "服务商显示" diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 97ee5b2be..4648e413e 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -130,3 +130,4 @@ numpy==1.22.0 pandas==1.3.5 pyjwkest==1.4.2 jsonfield2==4.0.0.post0 +bce-python-sdk==0.8.64 From 5cc2fdae4f081b5c864d8bcca8945e9eb4c0be5f Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Mon, 21 Mar 2022 11:14:49 +0800 Subject: [PATCH 10/59] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dapi=20docs?= =?UTF-8?q?=E6=89=93=E4=B8=8D=E5=BC=80=E7=9A=84=E9=97=AE=E9=A2=98=20(#7938?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jiangjie.Bai --- apps/tickets/api/comment.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/tickets/api/comment.py b/apps/tickets/api/comment.py index ab0584eed..1515f7c9b 100644 --- a/apps/tickets/api/comment.py +++ b/apps/tickets/api/comment.py @@ -6,7 +6,7 @@ from common.exceptions import JMSException from common.utils import lazyproperty from rbac.permissions import RBACPermission from tickets import serializers -from tickets.models import Ticket +from tickets.models import Ticket, Comment from tickets.permissions.comment import IsAssignee, IsApplicant, IsSwagger @@ -36,5 +36,7 @@ class CommentViewSet(mixins.CreateModelMixin, viewsets.ReadOnlyModelViewSet): return context def get_queryset(self): + if getattr(self, 'swagger_fake_view', False): + return Comment.objects.none() queryset = self.ticket.comments.all() return queryset From 9e5c13248582850424297ea996573bd9acdf529f Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" Date: Mon, 21 Mar 2022 11:53:49 +0800 Subject: [PATCH 11/59] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=94=A8?= =?UTF-8?q?=E6=88=B7API=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/users/api/user.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/users/api/user.py b/apps/users/api/user.py index 6d203a548..c3fa1ce24 100644 --- a/apps/users/api/user.py +++ b/apps/users/api/user.py @@ -108,6 +108,9 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, SuggestionMixin, BulkModelV self.check_object_permissions(self.request, user) return super().perform_bulk_update(serializer) + def allow_bulk_destroy(self, qs, filtered): + return qs.count() != filtered.count() + def perform_bulk_destroy(self, objects): for obj in objects: self.check_object_permissions(self.request, obj) From 9ae74120ed60dbc980c0277e677509c56f4b62d4 Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" Date: Mon, 21 Mar 2022 11:58:36 +0800 Subject: [PATCH 12/59] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=94=A8?= =?UTF-8?q?=E6=88=B7API=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/users/api/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/users/api/user.py b/apps/users/api/user.py index c3fa1ce24..ee3b322bb 100644 --- a/apps/users/api/user.py +++ b/apps/users/api/user.py @@ -109,7 +109,7 @@ class UserViewSet(CommonApiMixin, UserQuerysetMixin, SuggestionMixin, BulkModelV return super().perform_bulk_update(serializer) def allow_bulk_destroy(self, qs, filtered): - return qs.count() != filtered.count() + return filtered.count() < qs.count() def perform_bulk_destroy(self, objects): for obj in objects: From 3345456dc2468dc869eb2a6f9e5ca95e60b375e9 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Mon, 21 Mar 2022 17:53:16 +0800 Subject: [PATCH 13/59] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dwateway=20api=20?= =?UTF-8?q?(#7947)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng626 <1304903146@qq.com> --- apps/assets/api/asset.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/assets/api/asset.py b/apps/assets/api/asset.py index ef4003c39..7be40c72b 100644 --- a/apps/assets/api/asset.py +++ b/apps/assets/api/asset.py @@ -16,7 +16,7 @@ from perms.filters import AssetPermissionFilter from orgs.mixins.api import OrgBulkModelViewSet from orgs.mixins import generics from assets.api import FilterAssetByNodeMixin -from ..models import Asset, Node, Platform +from ..models import Asset, Node, Platform, Gateway from .. import serializers from ..tasks import ( update_assets_hardware_info_manual, test_assets_connectivity_manual, @@ -199,7 +199,7 @@ class AssetGatewayListApi(generics.ListAPIView): asset_id = self.kwargs.get('pk') asset = get_object_or_404(Asset, pk=asset_id) if not asset.domain: - return [] + return Gateway.objects.none() queryset = asset.domain.gateways.filter(protocol='ssh') return queryset From e35fbfc7e95e63a87bd02e383900aa78025116c3 Mon Sep 17 00:00:00 2001 From: jiangweidong <80373698+f2c-jiangweidong@users.noreply.github.com> Date: Mon, 21 Mar 2022 19:02:30 +0800 Subject: [PATCH 14/59] Update session.py --- apps/jumpserver/rewriting/session.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/jumpserver/rewriting/session.py b/apps/jumpserver/rewriting/session.py index ff34caded..d7e0428aa 100644 --- a/apps/jumpserver/rewriting/session.py +++ b/apps/jumpserver/rewriting/session.py @@ -1,6 +1,6 @@ from redis_sessions.session import ( force_unicode, SessionStore as RedisSessionStore, - RedisServer as RedisRedisServer, settings as redis_setting + RedisServer as _RedisServer, settings as redis_setting ) from redis import exceptions, Redis from django.conf import settings @@ -8,7 +8,7 @@ from django.conf import settings from jumpserver.const import CONFIG -class RedisServer(RedisRedisServer): +class RedisServer(_RedisServer): __redis = {} def get(self): From 87c6eec6190c9c5d12f816b6cc60f92725ebc7be Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 21 Mar 2022 16:40:14 +0800 Subject: [PATCH 15/59] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20role=20bingd?= =?UTF-8?q?ing=EF=BC=8C=E4=BC=98=E5=8C=96=20is=5Fsuperuser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/rbac/models/role.py | 3 + apps/rbac/models/rolebinding.py | 14 ++++ apps/users/models/user.py | 116 +++++++++++++++++++++++++------- apps/users/signal_handlers.py | 2 +- 4 files changed, 110 insertions(+), 25 deletions(-) diff --git a/apps/rbac/models/role.py b/apps/rbac/models/role.py index 9d539ba13..b47bccb5b 100644 --- a/apps/rbac/models/role.py +++ b/apps/rbac/models/role.py @@ -118,6 +118,9 @@ class Role(JMSModel): return self.name return gettext(self.name) + def is_org(self): + return self.scope == const.Scope.org + class SystemRole(Role): objects = SystemRoleManager() diff --git a/apps/rbac/models/rolebinding.py b/apps/rbac/models/rolebinding.py index f7ee3881a..a2ee06022 100644 --- a/apps/rbac/models/rolebinding.py +++ b/apps/rbac/models/rolebinding.py @@ -1,6 +1,7 @@ from django.utils.translation import gettext_lazy as _ from django.db import models from django.db.models import Q +from django.core.exceptions import ValidationError from rest_framework.serializers import ValidationError from common.db.models import JMSModel @@ -67,6 +68,7 @@ class RoleBinding(JMSModel): def save(self, *args, **kwargs): self.scope = self.role.scope + self.clean() return super().save(*args, **kwargs) @classmethod @@ -95,6 +97,9 @@ class RoleBinding(JMSModel): def role_display(self): return self.role.display_name + def is_scope_org(self): + return self.scope == Scope.org + class OrgRoleBindingManager(RoleBindingManager): def get_queryset(self): @@ -147,3 +152,12 @@ class SystemRoleBinding(RoleBinding): def save(self, *args, **kwargs): self.scope = Scope.system return super().save(*args, **kwargs) + + def clean(self): + kwargs = dict(role=self.role, user=self.user, scope=self.scope) + exists = self.__class__.objects.filter(**kwargs).exists() + if exists: + msg = "Duplicate for key 'role_user' of system role binding, {}_{}".format( + self.role.id, self.user.id + ) + raise ValidationError(msg) diff --git a/apps/users/models/user.py b/apps/users/models/user.py index e7834a088..0940d6466 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -172,6 +172,22 @@ class RoleManager(models.Manager): def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) self.user = user + self.role_binding_cls = self.get_role_binding_cls() + self.role_cls = self.get_role_cls() + + def get_role_binding_cls(self): + from rbac.models import SystemRoleBinding, OrgRoleBinding + if self.scope == 'org': + return OrgRoleBinding + else: + return SystemRoleBinding + + def get_role_cls(self): + from rbac.models import SystemRole, OrgRole + if self.scope == 'org': + return OrgRole + else: + return SystemRole @property def display(self): @@ -181,15 +197,13 @@ class RoleManager(models.Manager): @property def role_bindings(self): - from rbac.models import RoleBinding - queryset = RoleBinding.objects.filter(user=self.user) + queryset = self.role_binding_cls.objects.filter(user=self.user) if self.scope: queryset = queryset.filter(scope=self.scope) return queryset def _get_queryset(self): - from rbac.models import RoleBinding - queryset = RoleBinding.get_user_roles(self.user) + queryset = self.role_binding_cls.get_user_roles(self.user) if self.scope: queryset = queryset.filter(scope=self.scope) return queryset @@ -204,36 +218,84 @@ class RoleManager(models.Manager): return return self.role_bindings.delete() - def add(self, *roles): - from rbac.models import RoleBinding - items = [] + def _clean_roles(self, roles_or_ids): + if not roles_or_ids: + return + is_model = isinstance(roles_or_ids[0], models.Model) + if not is_model: + roles = self.role_cls.objects.filter(id__in=roles_or_ids) + else: + roles = roles_or_ids + roles = list([r for r in roles if r.scope == self.scope]) + return roles - for role in roles: + def add(self, *roles): + if not roles: + return + + roles = self._clean_roles(roles) + old_ids = self.role_bindings.values_list('role', flat=True) + need_adds = [r for r in roles if r.id not in old_ids] + + items = [] + for role in need_adds: kwargs = { 'role': role, 'user': self.user, - 'scope': role.scope + 'scope': self.scope } - if self.scope and role.scope != self.scope: - continue - if not current_org.is_root() and role.scope == RoleBinding.Scope.org: + if not current_org.is_root(): kwargs['org_id'] = current_org.id - items.append(RoleBinding(**kwargs)) + items.append(self.role_binding_cls(**kwargs)) try: - RoleBinding.objects.bulk_create(items, ignore_conflicts=True) + self.role_binding_cls.objects.bulk_create(items, ignore_conflicts=True) except Exception as e: logger.error('Create role binding error: {}'.format(e)) - def set(self, roles): - self.clear() - self.add(*roles) + def set(self, roles, clear=False): + if clear: + self.clear() + self.add(*roles) + return + + role_ids = set([r.id for r in roles]) + old_ids = self.role_bindings.values_list('role', flat=True) + old_ids = set(old_ids) + + del_ids = old_ids - role_ids + add_ids = role_ids - old_ids + self.remove(*del_ids) + self.add(*add_ids) + + def remove(self, *roles): + if not roles: + return + roles = self._clean_roles(roles) + return self.role_bindings.filter(role__in=roles).delete() def cache_set(self, roles): query = self._get_queryset() query._result_cache = roles self._cache = query + def remove_role_system_admin(self): + role = self.builtin_role.system_admin.get_role() + return self.remove(role) + + def add_role_system_admin(self): + role = self.builtin_role.system_admin.get_role() + return self.add(role) + + def add_role_system_user(self): + role = self.builtin_role.system_user.get_role() + return self.add(role) + + @property + def builtin_role(self): + from rbac.builtin import BuiltinRole + return BuiltinRole + class OrgRoleManager(RoleManager): def __init__(self, *args, **kwargs): @@ -257,6 +319,7 @@ class RoleMixin: _org_roles = None _system_roles = None PERM_CACHE_KEY = 'USER_PERMS_{}_{}' + _is_superuser = None @lazyproperty def roles(self): @@ -288,17 +351,27 @@ class RoleMixin: key = cls.PERM_CACHE_KEY.format('*', '*') cache.delete_pattern(key) - @lazyproperty + @property def is_superuser(self): """ 由于这里用了 cache ,所以不能改成 self.system_roles.filter().exists() 会查询的 """ + if not self._is_superuser: + return self._is_superuser + from rbac.builtin import BuiltinRole - # return self.system_roles.all().filter(id=BuiltinRole.system_admin.id).exists() ids = [str(r.id) for r in self.system_roles.all()] yes = BuiltinRole.system_admin.id in ids + self._is_superuser = yes return yes + @is_superuser.setter + def is_superuser(self, value): + if value: + self.system_roles.add_role_system_admin() + else: + self.system_roles.remove_role_system_admin() + @lazyproperty def is_org_admin(self): from rbac.builtin import BuiltinRole @@ -382,11 +455,6 @@ class RoleMixin: perms = RoleBinding.get_user_perms(self) return perms - def set_default_system_role(self): - from rbac.builtin import BuiltinRole - role_user = BuiltinRole.system_user.get_role() - self.system_roles.add(role_user) - class TokenMixin: CACHE_KEY_USER_RESET_PASSWORD_PREFIX = "_KEY_USER_RESET_PASSWORD_{}" diff --git a/apps/users/signal_handlers.py b/apps/users/signal_handlers.py index 8f2065ca3..065386fde 100644 --- a/apps/users/signal_handlers.py +++ b/apps/users/signal_handlers.py @@ -68,7 +68,7 @@ def on_user_create_set_default_system_role(sender, instance, created, **kwargs): has_system_role = instance.system_roles.all().exists() if not has_system_role: logger.debug("Receive user create signal, set default role") - instance.set_default_system_role() + instance.system_roles.add_role_system_user() @receiver(post_user_create) From 54fd1fb0c8b9f6314a2286dae4b99802540496f3 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 21 Mar 2022 18:06:33 +0800 Subject: [PATCH 16/59] =?UTF-8?q?perf:=20=E7=A7=BB=E5=8A=A8=E5=88=B0?= =?UTF-8?q?=E4=BF=A1=E5=8F=B7=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/users/models/user.py | 3 +++ apps/users/signal_handlers.py | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/apps/users/models/user.py b/apps/users/models/user.py index 0940d6466..23745bf5c 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -320,6 +320,7 @@ class RoleMixin: _system_roles = None PERM_CACHE_KEY = 'USER_PERMS_{}_{}' _is_superuser = None + _update_superuser = False @lazyproperty def roles(self): @@ -367,6 +368,8 @@ class RoleMixin: @is_superuser.setter def is_superuser(self, value): + self._is_superuser = value + self._update_superuser = True if value: self.system_roles.add_role_system_admin() else: diff --git a/apps/users/signal_handlers.py b/apps/users/signal_handlers.py index 065386fde..bd9b01845 100644 --- a/apps/users/signal_handlers.py +++ b/apps/users/signal_handlers.py @@ -60,9 +60,20 @@ def save_passwd_change(sender, instance: User, **kwargs): ) +def update_role_superuser_if_need(user): + if not user._update_superuser: + return + value = user._is_superuser + if value: + user.system_roles.add_role_system_admin() + else: + user.system_roles.remove_role_system_admin() + + @receiver(post_save, sender=User) @on_transaction_commit def on_user_create_set_default_system_role(sender, instance, created, **kwargs): + update_role_superuser_if_need(instance) if not created: return has_system_role = instance.system_roles.all().exists() From d01d44b48dac1394c9d92c4f0cc840d8b44fe086 Mon Sep 17 00:00:00 2001 From: feng626 <1304903146@qq.com> Date: Tue, 22 Mar 2022 11:05:13 +0800 Subject: [PATCH 17/59] fix: api docs --- apps/assets/api/asset.py | 2 +- apps/rbac/backends.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/assets/api/asset.py b/apps/assets/api/asset.py index 7be40c72b..3f4b7a209 100644 --- a/apps/assets/api/asset.py +++ b/apps/assets/api/asset.py @@ -181,7 +181,7 @@ class AssetsTaskCreateApi(AssetsTaskMixin, generics.CreateAPIView): def check_permissions(self, request): action = request.data.get('action') action_perm_require = { - 'refresh': 'assets.refresh_assethardwareinfo1', + 'refresh': 'assets.refresh_assethardwareinfo', } perm_required = action_perm_require.get(action) has = self.request.user.has_perm(perm_required) diff --git a/apps/rbac/backends.py b/apps/rbac/backends.py index bc9dbb56a..76ebd1d70 100644 --- a/apps/rbac/backends.py +++ b/apps/rbac/backends.py @@ -16,7 +16,7 @@ class RBACBackend(JMSBaseAuthBackend): return False def has_perm(self, user_obj, perm, obj=None): - if not user_obj.is_active: + if not user_obj.is_active or not perm: raise PermissionDenied() if perm == '*': return True From 2ec0cb8a2c0db6a1ee22271b998cd0956dec11a6 Mon Sep 17 00:00:00 2001 From: feng626 <1304903146@qq.com> Date: Tue, 22 Mar 2022 16:14:25 +0800 Subject: [PATCH 18/59] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E7=BB=91=E5=AE=9A=E8=A7=92=E8=89=B2=E9=87=8D=E5=A4=A7?= =?UTF-8?q?bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/users/models/user.py | 4 ++-- apps/users/serializers/user.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/users/models/user.py b/apps/users/models/user.py index 23745bf5c..691324079 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -299,16 +299,16 @@ class RoleManager(models.Manager): class OrgRoleManager(RoleManager): def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) from rbac.const import Scope self.scope = Scope.org + super().__init__(*args, **kwargs) class SystemRoleManager(RoleManager): def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) from rbac.const import Scope self.scope = Scope.system + super().__init__(*args, **kwargs) class RoleMixin: diff --git a/apps/users/serializers/user.py b/apps/users/serializers/user.py index 7421c9cc1..b998e8f6d 100644 --- a/apps/users/serializers/user.py +++ b/apps/users/serializers/user.py @@ -49,6 +49,8 @@ class RolesSerializerMixin(serializers.Serializer): return fields action = view.action or 'list' + if action in ('partial_bulk_update', 'bulk_update', 'partial_update', 'update'): + action = 'create' model_cls_field_mapper = { SystemRoleBinding: ['system_roles', 'system_roles_display'], OrgRoleBinding: ['org_roles', 'system_roles_display'] From 2721793b8f8402ff47afa60fd5f8bf413b92da1c Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 22 Mar 2022 12:51:24 +0800 Subject: [PATCH 19/59] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=9D=83?= =?UTF-8?q?=E9=99=90=20view=20=E6=B2=A1=E6=9C=89=20Model=20=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/rbac/permissions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/rbac/permissions.py b/apps/rbac/permissions.py index bfcb71cc7..3538246b7 100644 --- a/apps/rbac/permissions.py +++ b/apps/rbac/permissions.py @@ -93,7 +93,7 @@ class RBACPermission(permissions.DjangoModelPermissions): try: queryset = self._queryset(view) model_cls = queryset.model - except AssertionError: + except: model_cls = None return model_cls From 6bde31cdd0cdbe462e405c2e9b3990bf1ed28fad Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" Date: Tue, 22 Mar 2022 18:42:11 +0800 Subject: [PATCH 20/59] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E8=BF=9C=E7=A8=8B=E5=BA=94=E7=94=A8=E8=AE=A4=E8=AF=81?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/applications/models/application.py | 9 +++++---- apps/assets/models/user.py | 13 +++++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/apps/applications/models/application.py b/apps/applications/models/application.py index a6552fffd..4cb488e23 100644 --- a/apps/applications/models/application.py +++ b/apps/applications/models/application.py @@ -8,6 +8,7 @@ from django.conf import settings from orgs.mixins.models import OrgModelMixin from common.mixins import CommonModelMixin from common.tree import TreeNode +from common.utils import is_uuid from assets.models import Asset, SystemUser from ..utils import KubernetesTree @@ -267,12 +268,12 @@ class Application(CommonModelMixin, OrgModelMixin, ApplicationTreeNodeMixin): 'parameters': parameters } - def get_remote_app_asset(self): + def get_remote_app_asset(self, raise_exception=True): asset_id = self.attrs.get('asset') - if not asset_id: + if is_uuid(asset_id): + return Asset.objects.filter(id=asset_id).first() + if raise_exception: raise ValueError("Remote App not has asset attr") - asset = Asset.objects.filter(id=asset_id).first() - return asset class ApplicationUser(SystemUser): diff --git a/apps/assets/models/user.py b/apps/assets/models/user.py index 678e5f8cf..ce0029768 100644 --- a/apps/assets/models/user.py +++ b/apps/assets/models/user.py @@ -133,6 +133,14 @@ class AuthMixin: self.password = password def load_app_more_auth(self, app_id=None, username=None, user_id=None): + from applications.models import Application + app = get_object_or_none(Application, pk=app_id) + if app and app.category_remote_app: + # Remote app + self._load_remoteapp_more_auth(app, username, user_id) + return + + # Other app self._clean_auth_info_if_manual_login_mode() # 加载临时认证信息 if self.login_mode == self.LOGIN_MANUAL: @@ -148,6 +156,11 @@ class AuthMixin: _username = username self.username = _username + def _load_remoteapp_more_auth(self, app, username, user_id): + asset = app.get_remote_app_asset(raise_exception=False) + if asset: + self.load_asset_more_auth(asset_id=asset.id, username=username, user_id=user_id) + def load_asset_special_auth(self, asset, username=''): """ AuthBook 的数据状态 From 9b73727bbcbab0b8d9fc8b5828b8d6320acd6024 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 23 Mar 2022 10:56:23 +0800 Subject: [PATCH 21/59] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E7=BB=84=E4=BB=B6=E7=BB=91=E5=AE=9A=E8=A7=92=E8=89=B2?= =?UTF-8?q?bug=20(#7962)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng626 <1304903146@qq.com> --- apps/users/models/user.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/apps/users/models/user.py b/apps/users/models/user.py index 691324079..f9335e40f 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -8,20 +8,21 @@ import random import datetime from typing import Callable +from django.db import models from django.conf import settings +from django.utils import timezone +from django.core.cache import cache +from django.shortcuts import reverse from django.contrib.auth.models import AbstractUser from django.contrib.auth.hashers import check_password -from django.core.cache import cache -from django.db import models from django.utils.translation import ugettext_lazy as _ -from django.utils import timezone -from django.shortcuts import reverse + from orgs.utils import current_org from orgs.models import Organization -from common.utils import date_expired_default, get_logger, lazyproperty, random_string +from rbac.const import Scope from common import fields -from django.db.models import TextChoices +from common.utils import date_expired_default, get_logger, lazyproperty, random_string from ..signals import post_user_change_password, post_user_leave_org, pre_user_leave_org __all__ = ['User', 'UserPasswordHistory'] @@ -177,14 +178,14 @@ class RoleManager(models.Manager): def get_role_binding_cls(self): from rbac.models import SystemRoleBinding, OrgRoleBinding - if self.scope == 'org': + if self.scope == Scope.org: return OrgRoleBinding else: return SystemRoleBinding def get_role_cls(self): from rbac.models import SystemRole, OrgRole - if self.scope == 'org': + if self.scope == Scope.org: return OrgRole else: return SystemRole @@ -244,7 +245,7 @@ class RoleManager(models.Manager): 'user': self.user, 'scope': self.scope } - if not current_org.is_root(): + if self.scope == Scope.org and not current_org.is_root(): kwargs['org_id'] = current_org.id items.append(self.role_binding_cls(**kwargs)) @@ -615,7 +616,7 @@ class MFAMixin: class User(AuthMixin, TokenMixin, RoleMixin, MFAMixin, AbstractUser): - class Source(TextChoices): + class Source(models.TextChoices): local = 'local', _('Local') ldap = 'ldap', 'LDAP/AD' openid = 'openid', 'OpenID' From fc06295d0423c22a9eddeeeb4613cd6fd672c5ad Mon Sep 17 00:00:00 2001 From: Eric Date: Fri, 25 Mar 2022 10:43:48 +0800 Subject: [PATCH 22/59] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20windows=20rd?= =?UTF-8?q?p=20=E7=AA=97=E5=8F=A3=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/api/connection_token.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index 6062f64ce..fd3d20e1a 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -92,7 +92,7 @@ class ClientProtocolMixin: 'autoreconnection enabled:i': '1', 'bookmarktype:i': '3', 'use redirection server name:i': '0', - 'smart sizing:i': '0', + 'smart sizing:i': '1', #'drivestoredirect:s': '*', # 'domain:s': '' # 'alternate shell:s:': '||MySQLWorkbench', @@ -134,8 +134,7 @@ class ClientProtocolMixin: if width and height: options['desktopwidth:i'] = width options['desktopheight:i'] = height - else: - options['smart sizing:i'] = '1' + options['winposstr:s:'] = f'0,1,0,0,{width},{height}' options['session bpp:i'] = os.getenv('JUMPSERVER_COLOR_DEPTH', '32') options['audiomode:i'] = self.parse_env_bool('JUMPSERVER_DISABLE_AUDIO', 'false', '2', '0') From 9e284f96e538d0007ee1859ac802a8a02c6bb630 Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 25 Mar 2022 10:35:59 +0800 Subject: [PATCH 23/59] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E5=86=99=E6=B3=95=EF=BC=8C=E9=81=BF=E5=85=8D=20github?= =?UTF-8?q?=20=E8=AE=A4=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements/alpine_requirements.txt | 1 - requirements/apk_pkg.sh | 2 ++ requirements/deb_pkg.sh | 5 +++++ requirements/deb_requirements.txt | 1 - requirements/{lfs_requirements.sh => mac_pkg.sh} | 8 ++++++-- requirements/mac_requirements.sh | 7 ------- requirements/requirements.txt | 2 +- requirements/rpm_pkg.sh | 2 ++ requirements/rpm_requirements.txt | 1 - 9 files changed, 16 insertions(+), 13 deletions(-) delete mode 100644 requirements/alpine_requirements.txt create mode 100644 requirements/apk_pkg.sh create mode 100644 requirements/deb_pkg.sh delete mode 100644 requirements/deb_requirements.txt rename requirements/{lfs_requirements.sh => mac_pkg.sh} (56%) delete mode 100644 requirements/mac_requirements.sh create mode 100644 requirements/rpm_pkg.sh delete mode 100644 requirements/rpm_requirements.txt diff --git a/requirements/alpine_requirements.txt b/requirements/alpine_requirements.txt deleted file mode 100644 index 52a6fb63b..000000000 --- a/requirements/alpine_requirements.txt +++ /dev/null @@ -1 +0,0 @@ -gcc make python3-dev python3 libffi-dev mariadb-dev libc-dev krb5-dev openldap-dev jpeg-dev linux-headers sshpass openssh-client build-base libressl libffi-dev libressl-dev libxslt-dev libxml2-dev xmlsec-dev xmlsec diff --git a/requirements/apk_pkg.sh b/requirements/apk_pkg.sh new file mode 100644 index 000000000..649435811 --- /dev/null +++ b/requirements/apk_pkg.sh @@ -0,0 +1,2 @@ +#!/bin/sh +apk add gcc make python3-dev python3 libffi-dev mariadb-dev libc-dev krb5-dev openldap-dev jpeg-dev linux-headers sshpass openssh-client build-base libressl libffi-dev libressl-dev libxslt-dev libxml2-dev xmlsec-dev xmlsec diff --git a/requirements/deb_pkg.sh b/requirements/deb_pkg.sh new file mode 100644 index 000000000..8a8586bcd --- /dev/null +++ b/requirements/deb_pkg.sh @@ -0,0 +1,5 @@ +#!/bin/bash +apt install \ + g++ make iputils-ping default-libmysqlclient-dev libpq-dev libffi-dev \ + libldap2-dev libsasl2-dev sshpass pkg-config libxml2-dev libxmlsec1-dev \ + libxmlsec1-openssl libaio-dev freetds-dev diff --git a/requirements/deb_requirements.txt b/requirements/deb_requirements.txt deleted file mode 100644 index 39b280ed7..000000000 --- a/requirements/deb_requirements.txt +++ /dev/null @@ -1 +0,0 @@ -g++ make iputils-ping default-libmysqlclient-dev libpq-dev libffi-dev libldap2-dev libsasl2-dev sshpass pkg-config libxml2-dev libxmlsec1-dev libxmlsec1-openssl libaio-dev freetds-dev diff --git a/requirements/lfs_requirements.sh b/requirements/mac_pkg.sh similarity index 56% rename from requirements/lfs_requirements.sh rename to requirements/mac_pkg.sh index f460164f4..d93350cbc 100644 --- a/requirements/lfs_requirements.sh +++ b/requirements/mac_pkg.sh @@ -1,9 +1,13 @@ #!/bin/bash -# BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" PROJECT_DIR=$(dirname "$BASE_DIR") +echo "1. 安装依赖" +brew install libtiff libjpeg webp little-cms2 openssl gettext git git-lfs mysql libxml2 libxmlsec1 pkg-config -echo "下载 IP 数据库" +echo "2. 下载 IP 数据库" ip_db_path="${PROJECT_DIR}/apps/common/utils/geoip/GeoLite2-City.mmdb" wget "https://download.jumpserver.org/files/GeoLite2-City.mmdb" -O "${ip_db_path}" + +echo "3. 安装依赖的插件" +git lfs install diff --git a/requirements/mac_requirements.sh b/requirements/mac_requirements.sh deleted file mode 100644 index 575e6d98c..000000000 --- a/requirements/mac_requirements.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -echo "安装依赖" -brew install libtiff libjpeg webp little-cms2 openssl gettext git git-lfs mysql libxml2 libxmlsec1 pkg-config - -echo "安装依赖的插件" -git lfs install diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 4648e413e..948774e7a 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -49,7 +49,7 @@ olefile==0.44 openapi-codec==1.3.2 paramiko==2.7.2 passlib==1.7.1 -Pillow==9.0.0 +Pillow==9.0.1 pyasn1==0.4.8 pycparser==2.19 pycryptodome==3.12.0 diff --git a/requirements/rpm_pkg.sh b/requirements/rpm_pkg.sh new file mode 100644 index 000000000..2836fac50 --- /dev/null +++ b/requirements/rpm_pkg.sh @@ -0,0 +1,2 @@ +#!/bin/bash +yum -y install gcc-c++ sshpass mariadb-devel openldap-devel libxml2-devel xmlsec1-devel xmlsec1-openssl-devel libtool-ltdl-devel diff --git a/requirements/rpm_requirements.txt b/requirements/rpm_requirements.txt deleted file mode 100644 index 360f5e026..000000000 --- a/requirements/rpm_requirements.txt +++ /dev/null @@ -1 +0,0 @@ -gcc-c++ sshpass mariadb-devel openldap-devel libxml2-devel xmlsec1-devel xmlsec1-openssl-devel libtool-ltdl-devel From 8718dc6751a237894c717860f5cc4fa5e48ab3f0 Mon Sep 17 00:00:00 2001 From: ibuler Date: Fri, 25 Mar 2022 10:53:07 +0800 Subject: [PATCH 24/59] =?UTF-8?q?pref:=20=E4=BC=98=E9=9B=85=E4=B8=80?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements/apk_pkg.sh | 6 +++++- requirements/deb_pkg.sh | 6 +++--- requirements/rpm_pkg.sh | 4 +++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/requirements/apk_pkg.sh b/requirements/apk_pkg.sh index 649435811..b85baf5e6 100644 --- a/requirements/apk_pkg.sh +++ b/requirements/apk_pkg.sh @@ -1,2 +1,6 @@ #!/bin/sh -apk add gcc make python3-dev python3 libffi-dev mariadb-dev libc-dev krb5-dev openldap-dev jpeg-dev linux-headers sshpass openssh-client build-base libressl libffi-dev libressl-dev libxslt-dev libxml2-dev xmlsec-dev xmlsec +apk add \ + gcc make python3-dev python3 libffi-dev mariadb-dev \ + libc-dev krb5-dev openldap-dev jpeg-dev linux-headers sshpass \ + openssh-client build-base libressl libffi-dev libressl-dev \ + libxslt-dev libxml2-dev xmlsec-dev xmlsec diff --git a/requirements/deb_pkg.sh b/requirements/deb_pkg.sh index 8a8586bcd..3643d25d0 100644 --- a/requirements/deb_pkg.sh +++ b/requirements/deb_pkg.sh @@ -1,5 +1,5 @@ #!/bin/bash apt install \ - g++ make iputils-ping default-libmysqlclient-dev libpq-dev libffi-dev \ - libldap2-dev libsasl2-dev sshpass pkg-config libxml2-dev libxmlsec1-dev \ - libxmlsec1-openssl libaio-dev freetds-dev + g++ make iputils-ping default-libmysqlclient-dev libpq-dev \ + libffi-dev libldap2-dev libsasl2-dev sshpass pkg-config libxml2-dev \ + libxmlsec1-dev libxmlsec1-openssl libaio-dev freetds-dev diff --git a/requirements/rpm_pkg.sh b/requirements/rpm_pkg.sh index 2836fac50..f48bd3ac8 100644 --- a/requirements/rpm_pkg.sh +++ b/requirements/rpm_pkg.sh @@ -1,2 +1,4 @@ #!/bin/bash -yum -y install gcc-c++ sshpass mariadb-devel openldap-devel libxml2-devel xmlsec1-devel xmlsec1-openssl-devel libtool-ltdl-devel +yum -y install \ + gcc-c++ sshpass mariadb-devel openldap-devel libxml2-devel \ + xmlsec1-devel xmlsec1-openssl-devel libtool-ltdl-devel From e0fdfa52b94d889e8ab9c1184f901cb3d89df3d0 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 25 Mar 2022 14:45:08 +0800 Subject: [PATCH 25/59] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=20magnus=20(#7?= =?UTF-8?q?965)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 支持 magnus * perf: 添加 setting 到 api * perf: 放出 mongodb Co-authored-by: ibuler --- apps/applications/const.py | 2 +- apps/applications/models/application.py | 4 +- apps/common/utils/django.py | 12 ++ apps/jumpserver/api.py | 26 --- apps/jumpserver/conf.py | 15 +- apps/jumpserver/settings/custom.py | 6 + apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 258 +++++++++++++----------- apps/settings/api/public.py | 30 ++- apps/settings/serializers/terminal.py | 25 ++- apps/settings/signal_handlers.py | 16 ++ apps/terminal/serializers/terminal.py | 8 +- apps/users/models/user.py | 69 ++++--- 13 files changed, 273 insertions(+), 202 deletions(-) diff --git a/apps/applications/const.py b/apps/applications/const.py index 8436f3ebd..313477c25 100644 --- a/apps/applications/const.py +++ b/apps/applications/const.py @@ -41,7 +41,7 @@ class AppType(models.TextChoices): def category_types_mapper(cls): return { AppCategory.db: [ - cls.mysql, cls.oracle, cls.pgsql, cls.mariadb, + cls.mysql, cls.mariadb, cls.oracle, cls.pgsql, cls.sqlserver, cls.redis, cls.mongodb ], AppCategory.remote_app: [ diff --git a/apps/applications/models/application.py b/apps/applications/models/application.py index 4cb488e23..d9b3efe23 100644 --- a/apps/applications/models/application.py +++ b/apps/applications/models/application.py @@ -100,10 +100,8 @@ class ApplicationTreeNodeMixin: temp_pid = pid type_category_mapper = const.AppType.type_category_mapper() types = const.AppType.type_category_mapper().keys() + for tp in types: - # TODO: Temporary exclude mongodb - if tp == const.AppType.mongodb: - continue if not settings.XPACK_ENABLED and const.AppType.is_xpack(tp): continue category = type_category_mapper.get(tp) diff --git a/apps/common/utils/django.py b/apps/common/utils/django.py index 28a63a954..3e8066cef 100644 --- a/apps/common/utils/django.py +++ b/apps/common/utils/django.py @@ -1,9 +1,12 @@ # -*- coding: utf-8 -*- # import re + from django.shortcuts import reverse as dj_reverse from django.conf import settings from django.utils import timezone +from django.db import models +from django.db.models.signals import post_save, pre_save UUID_PATTERN = re.compile(r'[0-9a-zA-Z\-]{36}') @@ -58,3 +61,12 @@ def get_log_keep_day(s, defaults=200): except ValueError: days = defaults return days + + +def bulk_create_with_signal(cls: models.Model, items, **kwargs): + for i in items: + pre_save.send(sender=cls, instance=i) + result = cls.objects.bulk_create(items, **kwargs) + for i in items: + post_save.send(sender=cls, instance=i, created=True) + return result diff --git a/apps/jumpserver/api.py b/apps/jumpserver/api.py index 2de05b9c6..d5ff38593 100644 --- a/apps/jumpserver/api.py +++ b/apps/jumpserver/api.py @@ -300,32 +300,6 @@ class IndexApi(DatesLoginMetricMixin, APIView): class HealthApiMixin(APIView): pass - # 先去掉 Health Api 的权限校验,方便各组件直接调用 - - # def is_token_right(self): - # token = self.request.query_params.get('token') - # ok_token = settings.HEALTH_CHECK_TOKEN - # if ok_token and token != ok_token: - # return False - # return True - - # def is_localhost(self): - # ip = get_request_ip(self.request) - # return ip in ['localhost', '127.0.0.1'] - - # def check_permissions(self, request): - # if self.is_token_right(): - # return - # if self.is_localhost(): - # return - # msg = ''' - # Health check token error, - # Please set query param in url and - # same with setting HEALTH_CHECK_TOKEN. - # eg: $PATH/?token=$HEALTH_CHECK_TOKEN - # ''' - # self.permission_denied(request, message={'error': msg}, code=403) - class HealthCheckView(HealthApiMixin): permission_classes = (AllowAny,) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 4af31bffb..d3625e156 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -16,8 +16,10 @@ import json import yaml import copy from importlib import import_module -from django.urls import reverse_lazy from urllib.parse import urljoin, urlparse + +from django.urls import reverse_lazy +from django.conf import settings from django.utils.translation import ugettext_lazy as _ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -307,9 +309,14 @@ class Config(dict): 'TERMINAL_HOST_KEY': '', 'TERMINAL_TELNET_REGEX': '', 'TERMINAL_COMMAND_STORAGE': {}, - 'TERMINAL_RDP_ADDR': '', + 'TERMINAL_RDP_ADDR': lambda: urlparse(settings.SITE_URL).hostname + ':3389', 'XRDP_ENABLED': True, + 'TERMINAL_MAGNUS_ENABLED': True, + 'TERMINAL_MAGNUS_HOST': lambda: urlparse(settings.SITE_URL).hostname, + 'TERMINAL_MAGNUS_MYSQL_PORT': 33060, + 'TERMINAL_MAGNUS_POSTGRE_PORT': 54320, + # 安全配置 'SECURITY_MFA_AUTH': 0, # 0 不开启 1 全局开启 2 管理员开启 'SECURITY_MFA_AUTH_ENABLED_FOR_THIRD_PARTY': True, @@ -392,6 +399,7 @@ class Config(dict): 'FORGOT_PASSWORD_URL': '', 'HEALTH_CHECK_TOKEN': '', + } @staticmethod @@ -540,7 +548,8 @@ class Config(dict): value = self.get_from_env(item) if value is not None: return value - return self.defaults.get(item) + value = self.defaults.get(item) + return value def __getitem__(self, item): return self.get(item) diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index 794180fd2..d8495e0ba 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -167,3 +167,9 @@ ANNOUNCEMENT = CONFIG.ANNOUNCEMENT # help HELP_DOCUMENT_URL = CONFIG.HELP_DOCUMENT_URL HELP_SUPPORT_URL = CONFIG.HELP_SUPPORT_URL + +# Magnus +MAGNUS_ENABLED = CONFIG.MAGNUS_ENABLED +TERMINAL_MAGNUS_HOST = CONFIG.TERMINAL_MAGNUS_HOST +TERMINAL_MAGNUS_MYSQL_PORT = CONFIG.TERMINAL_MAGNUS_MYSQL_PORT +TERMINAL_MAGNUS_POSTGRE_PORT = CONFIG.TERMINAL_MAGNUS_POSTGRE_PORT diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 4aeb70566..2143cac3a 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b1c6c0f9212f9d154a432d93785677ebc206eed4fd4338d3fe11b4b528d65c11 -size 104323 +oid sha256:d545e79536feb40608d809a54b8b2140e235373acf331202131882e7af002dfb +size 105242 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 04cfeaedb..13f102da7 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-03-21 10:37+0800\n" +"POT-Creation-Date: 2022-03-23 15:35+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -22,7 +22,7 @@ msgid "Acls" msgstr "访问控制" #: acls/models/base.py:25 acls/serializers/login_asset_acl.py:47 -#: applications/models/application.py:212 assets/models/asset.py:138 +#: applications/models/application.py:213 assets/models/asset.py:138 #: assets/models/base.py:175 assets/models/cluster.py:18 #: assets/models/cmd_filter.py:27 assets/models/domain.py:23 #: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24 @@ -30,7 +30,7 @@ msgstr "访问控制" #: settings/models.py:29 settings/serializers/sms.py:6 #: terminal/models/storage.py:23 terminal/models/task.py:16 #: terminal/models/terminal.py:100 users/forms/profile.py:32 -#: users/models/group.py:15 users/models/user.py:584 +#: users/models/group.py:15 users/models/user.py:655 #: users/templates/users/_select_user_modal.html:13 #: users/templates/users/user_asset_permission.html:37 #: users/templates/users/user_asset_permission.html:154 @@ -40,12 +40,12 @@ msgid "Name" msgstr "名称" #: acls/models/base.py:27 assets/models/cmd_filter.py:84 -#: assets/models/user.py:234 +#: assets/models/user.py:247 msgid "Priority" msgstr "优先级" #: acls/models/base.py:28 assets/models/cmd_filter.py:84 -#: assets/models/user.py:234 +#: assets/models/user.py:247 msgid "1-100, the lower the value will be match first" msgstr "优先级可选范围为 1-100 (数值越小越优先)" @@ -56,7 +56,7 @@ msgstr "优先级可选范围为 1-100 (数值越小越优先)" msgid "Active" msgstr "激活中" -#: acls/models/base.py:32 applications/models/application.py:225 +#: acls/models/base.py:32 applications/models/application.py:226 #: assets/models/asset.py:143 assets/models/asset.py:231 #: assets/models/backup.py:54 assets/models/base.py:180 #: assets/models/cluster.py:29 assets/models/cmd_filter.py:48 @@ -66,7 +66,7 @@ msgstr "激活中" #: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34 #: terminal/models/storage.py:26 terminal/models/terminal.py:114 #: tickets/models/comment.py:24 tickets/models/ticket.py:154 -#: users/models/group.py:16 users/models/user.py:621 +#: users/models/group.py:16 users/models/user.py:692 #: 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 @@ -90,12 +90,12 @@ msgstr "登录复核" #: assets/models/cmd_filter.py:30 assets/models/label.py:15 audits/models.py:37 #: audits/models.py:60 audits/models.py:85 audits/serializers.py:100 #: authentication/models.py:50 orgs/models.py:214 perms/models/base.py:84 -#: rbac/builtin.py:101 rbac/models/rolebinding.py:39 templates/index.html:78 +#: rbac/builtin.py:101 rbac/models/rolebinding.py:40 templates/index.html:78 #: terminal/backends/command/models.py:19 #: terminal/backends/command/serializers.py:12 terminal/models/session.py:42 #: terminal/notifications.py:91 terminal/notifications.py:139 -#: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:809 -#: users/models/user.py:840 users/serializers/group.py:19 +#: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:880 +#: users/models/user.py:911 users/serializers/group.py:19 #: users/templates/users/user_asset_permission.html:38 #: users/templates/users/user_asset_permission.html:64 #: users/templates/users/user_database_app_permission.html:37 @@ -169,7 +169,7 @@ msgstr "格式为逗号分隔的字符串, * 表示匹配所有. " #: authentication/forms.py:15 authentication/forms.py:17 #: 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:31 users/models/user.py:582 +#: ops/models/adhoc.py:159 users/forms/profile.py:31 users/models/user.py:653 #: users/templates/users/_msg_user_created.html:12 #: users/templates/users/_select_user_modal.html:14 #: xpack/plugins/change_auth_plan/models/asset.py:34 @@ -215,7 +215,7 @@ msgid "" msgstr "格式为逗号分隔的字符串, * 表示匹配所有. 可选的协议有: {}" #: acls/serializers/login_asset_acl.py:55 assets/models/asset.py:213 -#: assets/models/domain.py:62 assets/models/user.py:235 +#: assets/models/domain.py:62 assets/models/user.py:248 #: terminal/serializers/session.py:30 terminal/serializers/storage.py:69 msgid "Protocol" msgstr "协议" @@ -255,7 +255,7 @@ msgstr "时段" msgid "My applications" msgstr "我的应用" -#: applications/apps.py:9 applications/models/application.py:61 +#: applications/apps.py:9 applications/models/application.py:62 msgid "Applications" msgstr "应用管理" @@ -274,14 +274,14 @@ msgstr "远程应用" msgid "Custom" msgstr "自定义" -#: applications/models/account.py:12 applications/models/application.py:229 +#: applications/models/account.py:12 applications/models/application.py:230 #: assets/models/backup.py:32 assets/models/cmd_filter.py:45 #: perms/models/application_permission.py:28 msgid "Application" msgstr "应用程序" #: applications/models/account.py:15 assets/models/authbook.py:20 -#: assets/models/cmd_filter.py:42 assets/models/user.py:325 audits/models.py:40 +#: assets/models/cmd_filter.py:42 assets/models/user.py:338 audits/models.py:40 #: perms/models/application_permission.py:33 #: perms/models/asset_permission.py:25 terminal/backends/command/models.py:21 #: terminal/backends/command/serializers.py:14 terminal/models/session.py:46 @@ -314,7 +314,7 @@ msgstr "可以查看应用账号密码" msgid "Can change application account secret" msgstr "可以查看应用账号密码" -#: applications/models/application.py:214 +#: applications/models/application.py:215 #: applications/serializers/application.py:99 assets/models/label.py:21 #: perms/models/application_permission.py:21 #: perms/serializers/application/user_permission.py:33 @@ -323,9 +323,9 @@ msgstr "可以查看应用账号密码" msgid "Category" msgstr "类别" -#: applications/models/application.py:217 +#: applications/models/application.py:218 #: applications/serializers/application.py:101 assets/models/backup.py:49 -#: assets/models/cmd_filter.py:82 assets/models/user.py:233 +#: assets/models/cmd_filter.py:82 assets/models/user.py:246 #: perms/models/application_permission.py:24 #: perms/serializers/application/user_permission.py:34 #: terminal/models/storage.py:55 terminal/models/storage.py:119 @@ -336,21 +336,21 @@ msgstr "类别" msgid "Type" msgstr "类型" -#: applications/models/application.py:221 assets/models/asset.py:217 +#: applications/models/application.py:222 assets/models/asset.py:217 #: assets/models/domain.py:29 assets/models/domain.py:63 msgid "Domain" msgstr "网域" -#: applications/models/application.py:223 xpack/plugins/cloud/models.py:33 +#: applications/models/application.py:224 xpack/plugins/cloud/models.py:33 #: xpack/plugins/cloud/serializers/account.py:58 msgid "Attrs" msgstr "属性" -#: applications/models/application.py:233 +#: applications/models/application.py:234 msgid "Can match application" msgstr "匹配应用" -#: applications/models/application.py:281 +#: applications/models/application.py:282 msgid "Application user" msgstr "应用用户" @@ -379,7 +379,7 @@ msgstr "类型名称" #: assets/serializers/cmd_filter.py:49 common/db/models.py:113 #: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30 #: orgs/models.py:67 orgs/models.py:217 perms/models/base.py:92 -#: users/models/group.py:18 users/models/user.py:841 +#: users/models/group.py:18 users/models/user.py:912 #: xpack/plugins/cloud/models.py:125 msgid "Date created" msgstr "创建日期" @@ -598,7 +598,7 @@ msgstr "主机名原始" msgid "Protocols" msgstr "协议组" -#: assets/models/asset.py:218 assets/models/user.py:225 +#: assets/models/asset.py:218 assets/models/user.py:238 #: perms/models/asset_permission.py:24 #: xpack/plugins/change_auth_plan/models/asset.py:43 #: xpack/plugins/gathered_user/models.py:24 @@ -611,7 +611,7 @@ msgid "Is active" msgstr "激活" #: assets/models/asset.py:222 assets/models/cluster.py:19 -#: assets/models/user.py:222 assets/models/user.py:377 +#: assets/models/user.py:235 assets/models/user.py:390 msgid "Admin user" msgstr "特权用户" @@ -631,7 +631,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:111 common/mixins/models.py:49 orgs/models.py:66 -#: orgs/models.py:219 perms/models/base.py:91 users/models/user.py:629 +#: orgs/models.py:219 perms/models/base.py:91 users/models/user.py:700 #: 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 @@ -812,7 +812,7 @@ msgstr "带宽" msgid "Contact" msgstr "联系人" -#: assets/models/cluster.py:22 users/models/user.py:604 +#: assets/models/cluster.py:22 users/models/user.py:675 msgid "Phone" msgstr "手机" @@ -838,7 +838,7 @@ msgid "Default" msgstr "默认" #: assets/models/cluster.py:36 assets/models/label.py:14 rbac/const.py:6 -#: users/models/user.py:826 +#: users/models/user.py:897 msgid "System" msgstr "系统" @@ -847,7 +847,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:590 +#: users/models/group.py:31 users/models/user.py:661 #: users/templates/users/_select_user_modal.html:16 #: users/templates/users/user_asset_permission.html:39 #: users/templates/users/user_asset_permission.html:67 @@ -993,77 +993,77 @@ msgstr "节点" msgid "Can match node" msgstr "可以匹配节点" -#: assets/models/user.py:216 +#: assets/models/user.py:229 msgid "Automatic managed" msgstr "托管密码" -#: assets/models/user.py:217 +#: assets/models/user.py:230 msgid "Manually input" msgstr "手动输入" -#: assets/models/user.py:221 +#: assets/models/user.py:234 msgid "Common user" msgstr "普通用户" -#: assets/models/user.py:224 +#: assets/models/user.py:237 msgid "Username same with user" msgstr "用户名与用户相同" -#: assets/models/user.py:227 assets/serializers/domain.py:29 +#: assets/models/user.py:240 assets/serializers/domain.py:29 #: terminal/templates/terminal/_msg_command_execute_alert.html:16 #: xpack/plugins/change_auth_plan/models/asset.py:39 msgid "Assets" msgstr "资产" -#: assets/models/user.py:231 users/apps.py:9 +#: assets/models/user.py:244 users/apps.py:9 msgid "Users" msgstr "用户管理" -#: assets/models/user.py:232 +#: assets/models/user.py:245 msgid "User groups" msgstr "用户组" -#: assets/models/user.py:236 +#: assets/models/user.py:249 msgid "Auto push" msgstr "自动推送" -#: assets/models/user.py:237 +#: assets/models/user.py:250 msgid "Sudo" msgstr "Sudo" -#: assets/models/user.py:238 +#: assets/models/user.py:251 msgid "Shell" msgstr "Shell" -#: assets/models/user.py:239 +#: assets/models/user.py:252 msgid "Login mode" msgstr "认证方式" -#: assets/models/user.py:240 +#: assets/models/user.py:253 msgid "SFTP Root" msgstr "SFTP根路径" -#: assets/models/user.py:241 authentication/models.py:48 +#: assets/models/user.py:254 authentication/models.py:48 msgid "Token" msgstr "" -#: assets/models/user.py:242 +#: assets/models/user.py:255 msgid "Home" msgstr "家目录" -#: assets/models/user.py:243 +#: assets/models/user.py:256 msgid "System groups" msgstr "用户组" -#: assets/models/user.py:246 +#: assets/models/user.py:259 msgid "User switch" msgstr "用户切换" -#: assets/models/user.py:247 +#: assets/models/user.py:260 msgid "Switch from" msgstr "切换自" -#: assets/models/user.py:327 +#: assets/models/user.py:340 msgid "Can match system user" msgstr "可以匹配系统用户" @@ -1502,7 +1502,7 @@ msgstr "用户代理" #: audits/models.py:124 #: authentication/templates/authentication/_mfa_confirm_modal.html:14 -#: users/forms/profile.py:64 users/models/user.py:607 +#: users/forms/profile.py:64 users/models/user.py:678 #: users/serializers/profile.py:121 msgid "MFA" msgstr "MFA" @@ -1580,13 +1580,13 @@ msgstr "认证令牌" #: audits/signal_handlers.py:71 authentication/notifications.py:73 #: authentication/views/login.py:164 authentication/views/wecom.py:158 -#: notifications/backends/__init__.py:11 users/models/user.py:643 +#: notifications/backends/__init__.py:11 users/models/user.py:714 msgid "WeCom" msgstr "企业微信" #: audits/signal_handlers.py:72 authentication/views/dingtalk.py:160 #: authentication/views/login.py:170 notifications/backends/__init__.py:12 -#: users/models/user.py:644 +#: users/models/user.py:715 msgid "DingTalk" msgstr "钉钉" @@ -2117,14 +2117,14 @@ msgid "Show" msgstr "显示" #: authentication/templates/authentication/_access_key_modal.html:66 -#: settings/serializers/security.py:39 users/models/user.py:479 +#: settings/serializers/security.py:39 users/models/user.py:550 #: users/serializers/profile.py:111 users/templates/users/mfa_setting.html:61 #: users/templates/users/user_verify_mfa.html:36 msgid "Disable" msgstr "禁用" #: authentication/templates/authentication/_access_key_modal.html:67 -#: users/models/user.py:480 users/serializers/profile.py:112 +#: users/models/user.py:551 users/serializers/profile.py:112 #: users/templates/users/mfa_setting.html:26 #: users/templates/users/mfa_setting.html:68 msgid "Enable" @@ -2373,7 +2373,7 @@ msgid "The FeiShu is already bound to another user" msgstr "该飞书已经绑定其他用户" #: authentication/views/feishu.py:148 authentication/views/login.py:176 -#: notifications/backends/__init__.py:14 users/models/user.py:645 +#: notifications/backends/__init__.py:14 users/models/user.py:716 msgid "FeiShu" msgstr "飞书" @@ -2668,7 +2668,7 @@ msgid "Notifications" msgstr "通知" #: notifications/backends/__init__.py:10 users/forms/profile.py:101 -#: users/models/user.py:586 +#: users/models/user.py:657 msgid "Email" msgstr "邮件" @@ -2880,7 +2880,7 @@ msgid "App organizations" msgstr "组织管理" #: orgs/mixins/models.py:46 orgs/mixins/serializers.py:25 orgs/models.py:80 -#: orgs/models.py:211 rbac/const.py:7 rbac/models/rolebinding.py:46 +#: orgs/models.py:211 rbac/const.py:7 rbac/models/rolebinding.py:47 #: rbac/serializers/rolebinding.py:40 tickets/serializers/ticket/ticket.py:77 msgid "Organization" msgstr "组织" @@ -2893,8 +2893,8 @@ msgstr "全局组织" msgid "Can view root org" msgstr "可以查看全局组织" -#: orgs/models.py:216 rbac/models/role.py:46 rbac/models/rolebinding.py:42 -#: users/models/user.py:594 users/templates/users/_select_user_modal.html:15 +#: orgs/models.py:216 rbac/models/role.py:46 rbac/models/rolebinding.py:43 +#: users/models/user.py:665 users/templates/users/_select_user_modal.html:15 msgid "Role" msgstr "角色" @@ -2981,7 +2981,7 @@ msgstr "剪贴板复制粘贴" #: perms/models/base.py:90 #: tickets/serializers/ticket/meta/ticket_type/apply_application.py:58 #: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:60 -#: users/models/user.py:626 +#: users/models/user.py:697 msgid "Date expired" msgstr "失效日期" @@ -3024,15 +3024,15 @@ msgstr "组织 ({}) 的应用授权" #: perms/serializers/application/permission.py:20 #: perms/serializers/application/permission.py:41 #: perms/serializers/asset/permission.py:19 -#: perms/serializers/asset/permission.py:45 users/serializers/user.py:137 +#: perms/serializers/asset/permission.py:45 users/serializers/user.py:139 msgid "Is valid" msgstr "账号是否有效" #: perms/serializers/application/permission.py:21 #: perms/serializers/application/permission.py:40 #: perms/serializers/asset/permission.py:20 -#: perms/serializers/asset/permission.py:44 users/serializers/user.py:83 -#: users/serializers/user.py:139 +#: perms/serializers/asset/permission.py:44 users/serializers/user.py:85 +#: users/serializers/user.py:141 msgid "Is expired" msgstr "已过期" @@ -3166,7 +3166,7 @@ msgstr "文件管理" msgid "Permission" msgstr "权限" -#: rbac/models/role.py:31 rbac/models/rolebinding.py:36 +#: rbac/models/role.py:31 rbac/models/rolebinding.py:37 msgid "Scope" msgstr "范围" @@ -3178,29 +3178,29 @@ msgstr "授权" msgid "Built-in" msgstr "内置" -#: rbac/models/role.py:127 +#: rbac/models/role.py:130 msgid "System role" msgstr "系统角色" -#: rbac/models/role.py:135 +#: rbac/models/role.py:138 msgid "Organization role" msgstr "组织角色" -#: rbac/models/rolebinding.py:51 +#: rbac/models/rolebinding.py:52 msgid "Role binding" msgstr "角色绑定" -#: rbac/models/rolebinding.py:123 +#: rbac/models/rolebinding.py:128 msgid "" "User last role in org, can not be delete, you can remove user from org " "instead" msgstr "用户最后一个角色,不能删除,你可以将用户从组织移除" -#: rbac/models/rolebinding.py:130 +#: rbac/models/rolebinding.py:135 msgid "Organization role binding" msgstr "组织角色绑定" -#: rbac/models/rolebinding.py:145 +#: rbac/models/rolebinding.py:150 msgid "System role binding" msgstr "系统角色绑定" @@ -4176,36 +4176,64 @@ msgstr "" "提示:如果你使用其它认证方式,如 AD/LDAP,你应该禁用此项,以避免第三方系统删" "除后,还可以登录" -#: settings/serializers/terminal.py:25 +#: settings/serializers/terminal.py:26 msgid "List sort by" msgstr "资产列表排序" -#: settings/serializers/terminal.py:27 +#: settings/serializers/terminal.py:29 msgid "List page size" msgstr "资产列表每页数量" -#: settings/serializers/terminal.py:29 +#: settings/serializers/terminal.py:32 msgid "Telnet login regex" msgstr "Telnet 成功正则表达式" -#: settings/serializers/terminal.py:30 +#: settings/serializers/terminal.py:33 msgid "" "The login success message varies with devices. if you cannot log in to the " "device through Telnet, set this parameter" msgstr "不同设备登录成功提示不一样,所以如果 telnet 不能正常登录,可以这里设置" -#: settings/serializers/terminal.py:34 +#: settings/serializers/terminal.py:37 msgid "RDP address" msgstr "RDP 地址" -#: settings/serializers/terminal.py:35 +#: settings/serializers/terminal.py:38 msgid "RDP visit address, eg: dev.jumpserver.org:3389" msgstr "RDP 访问地址, 如: dev.jumpserver.org:3389" -#: settings/serializers/terminal.py:38 +#: settings/serializers/terminal.py:40 msgid "Enable XRDP" msgstr "启用 XRDP 服务" +#: settings/serializers/terminal.py:42 +msgid "Enable database proxy" +msgstr "启用数据库组件" + +#: settings/serializers/terminal.py:44 +msgid "Database proxy host" +msgstr "数据库主机地址" + +#: settings/serializers/terminal.py:45 +msgid "Database proxy host, eg: dev.jumpserver.org" +msgstr "数据库组件地址, 如: dev.jumpserver.org (没有端口, 不同协议端口不同)" + +#: settings/serializers/terminal.py:48 +msgid "MySQL port" +msgstr "MySQL 协议端口" + +#: settings/serializers/terminal.py:49 +msgid "Database proxy MySQL protocol port" +msgstr "数据库组件 MySQL 协议监听的端口" + +#: settings/serializers/terminal.py:52 +msgid "PostgreSQL port" +msgstr "PostgreSQL 端口" + +#: settings/serializers/terminal.py:53 +msgid "Database proxy PostgreSQL port" +msgstr "数据库组件 PostgreSQL 协议监听的端口" + #: settings/utils/ldap.py:417 msgid "ldap:// or ldaps:// protocol is used." msgstr "使用 ldap:// 或 ldaps:// 协议" @@ -5023,7 +5051,7 @@ msgstr "端点无效: 移除路径 `{}`" msgid "Bucket" msgstr "桶名称" -#: terminal/serializers/storage.py:34 users/models/user.py:618 +#: terminal/serializers/storage.py:34 users/models/user.py:689 msgid "Secret key" msgstr "密钥" @@ -5081,7 +5109,7 @@ msgstr "忽略证书认证" msgid "Load status" msgstr "负载状态" -#: terminal/serializers/terminal.py:83 terminal/serializers/terminal.py:91 +#: terminal/serializers/terminal.py:81 terminal/serializers/terminal.py:89 msgid "Not found" msgstr "没有发现" @@ -5519,7 +5547,7 @@ msgstr "当前组织已存在该类型" msgid "Click here to review" msgstr "点击查看" -#: users/api/user.py:180 +#: users/api/user.py:183 msgid "Could not reset self otp, use profile reset instead" msgstr "不能在该页面重置 MFA 多因子认证, 请去个人信息页面重置" @@ -5626,68 +5654,68 @@ msgstr "不能和原来的密钥相同" msgid "Not a valid ssh public key" msgstr "SSH密钥不合法" -#: users/forms/profile.py:160 users/models/user.py:615 +#: users/forms/profile.py:160 users/models/user.py:686 #: users/templates/users/user_password_update.html:48 msgid "Public key" msgstr "SSH公钥" -#: users/models/user.py:481 +#: users/models/user.py:552 msgid "Force enable" msgstr "强制启用" -#: users/models/user.py:548 +#: users/models/user.py:619 msgid "Local" msgstr "数据库" -#: users/models/user.py:596 users/serializers/user.py:138 +#: users/models/user.py:667 users/serializers/user.py:140 msgid "Is service account" msgstr "服务账号" -#: users/models/user.py:598 +#: users/models/user.py:669 msgid "Avatar" msgstr "头像" -#: users/models/user.py:601 +#: users/models/user.py:672 msgid "Wechat" msgstr "微信" -#: users/models/user.py:612 +#: users/models/user.py:683 msgid "Private key" msgstr "ssh私钥" -#: users/models/user.py:634 +#: users/models/user.py:705 msgid "Source" msgstr "来源" -#: users/models/user.py:638 +#: users/models/user.py:709 msgid "Date password last updated" msgstr "最后更新密码日期" -#: users/models/user.py:641 +#: users/models/user.py:712 msgid "Need update password" msgstr "需要更新密码" -#: users/models/user.py:811 +#: users/models/user.py:882 msgid "Can invite user" msgstr "可以邀请用户" -#: users/models/user.py:812 +#: users/models/user.py:883 msgid "Can remove user" msgstr "可以移除用户" -#: users/models/user.py:813 +#: users/models/user.py:884 msgid "Can match user" msgstr "可以匹配用户" -#: users/models/user.py:822 +#: users/models/user.py:893 msgid "Administrator" msgstr "管理员" -#: users/models/user.py:825 +#: users/models/user.py:896 msgid "Administrator is the super user of system" msgstr "Administrator是初始的超级管理员" -#: users/models/user.py:850 +#: users/models/user.py:921 msgid "User password history" msgstr "用户密码历史" @@ -5738,7 +5766,7 @@ msgstr "新密码不能是最近 {} 次的密码" msgid "The newly set password is inconsistent" msgstr "两次密码不一致" -#: users/serializers/profile.py:142 users/serializers/user.py:136 +#: users/serializers/profile.py:142 users/serializers/user.py:138 msgid "Is first login" msgstr "首次登录" @@ -5750,85 +5778,85 @@ msgstr "系统角色" msgid "Org roles" msgstr "组织角色" -#: users/serializers/user.py:75 +#: users/serializers/user.py:77 #: xpack/plugins/change_auth_plan/models/base.py:35 #: xpack/plugins/change_auth_plan/serializers/base.py:22 msgid "Password strategy" msgstr "密码策略" -#: users/serializers/user.py:77 +#: users/serializers/user.py:79 msgid "MFA enabled" msgstr "MFA" -#: users/serializers/user.py:78 +#: users/serializers/user.py:80 msgid "MFA force enabled" msgstr "强制 MFA" -#: users/serializers/user.py:80 +#: users/serializers/user.py:82 msgid "MFA level display" msgstr "MFA 等级名称" -#: users/serializers/user.py:82 +#: users/serializers/user.py:84 msgid "Login blocked" msgstr "登录被阻塞" -#: users/serializers/user.py:85 +#: users/serializers/user.py:87 msgid "Can public key authentication" msgstr "能否公钥认证" -#: users/serializers/user.py:140 +#: users/serializers/user.py:142 msgid "Avatar url" msgstr "头像路径" -#: users/serializers/user.py:142 +#: users/serializers/user.py:144 msgid "Groups name" msgstr "用户组名" -#: users/serializers/user.py:143 +#: users/serializers/user.py:145 msgid "Source name" msgstr "用户来源名" -#: users/serializers/user.py:144 +#: users/serializers/user.py:146 msgid "Organization role name" msgstr "组织角色名称" -#: users/serializers/user.py:145 +#: users/serializers/user.py:147 msgid "Super role name" msgstr "超级角色名称" -#: users/serializers/user.py:146 +#: users/serializers/user.py:148 msgid "Total role name" msgstr "汇总角色名称" -#: users/serializers/user.py:148 +#: users/serializers/user.py:150 msgid "Is wecom bound" msgstr "是否绑定了企业微信" -#: users/serializers/user.py:149 +#: users/serializers/user.py:151 msgid "Is dingtalk bound" msgstr "是否绑定了钉钉" -#: users/serializers/user.py:150 +#: users/serializers/user.py:152 msgid "Is feishu bound" msgstr "是否绑定了飞书" -#: users/serializers/user.py:151 +#: users/serializers/user.py:153 msgid "Is OTP bound" msgstr "是否绑定了虚拟 MFA" -#: users/serializers/user.py:153 +#: users/serializers/user.py:155 msgid "System role name" msgstr "系统角色名称" -#: users/serializers/user.py:245 +#: users/serializers/user.py:247 msgid "Select users" msgstr "选择用户" -#: users/serializers/user.py:246 +#: users/serializers/user.py:248 msgid "For security, only list several users" msgstr "为了安全,仅列出几个用户" -#: users/serializers/user.py:279 +#: users/serializers/user.py:281 msgid "name not unique" msgstr "名称重复" diff --git a/apps/settings/api/public.py b/apps/settings/api/public.py index 314b7c9fa..f45e5a4e9 100644 --- a/apps/settings/api/public.py +++ b/apps/settings/api/public.py @@ -30,19 +30,15 @@ class PublicSettingApi(generics.RetrieveAPIView): def get_object(self): instance = { "data": { + # Security "WINDOWS_SKIP_ALL_MANUAL_PASSWORD": settings.WINDOWS_SKIP_ALL_MANUAL_PASSWORD, + "OLD_PASSWORD_HISTORY_LIMIT_COUNT": settings.OLD_PASSWORD_HISTORY_LIMIT_COUNT, "SECURITY_MAX_IDLE_TIME": settings.SECURITY_MAX_IDLE_TIME, - "XPACK_ENABLED": settings.XPACK_ENABLED, "SECURITY_VIEW_AUTH_NEED_MFA": settings.SECURITY_VIEW_AUTH_NEED_MFA, "SECURITY_MFA_VERIFY_TTL": settings.SECURITY_MFA_VERIFY_TTL, - "OLD_PASSWORD_HISTORY_LIMIT_COUNT": settings.OLD_PASSWORD_HISTORY_LIMIT_COUNT, "SECURITY_COMMAND_EXECUTION": settings.SECURITY_COMMAND_EXECUTION, "SECURITY_PASSWORD_EXPIRATION_TIME": settings.SECURITY_PASSWORD_EXPIRATION_TIME, "SECURITY_LUNA_REMEMBER_AUTH": settings.SECURITY_LUNA_REMEMBER_AUTH, - "XPACK_LICENSE_IS_VALID": has_valid_xpack_license(), - "XPACK_LICENSE_INFO": get_xpack_license_info(), - "LOGIN_TITLE": self.get_login_title(), - "LOGO_URLS": self.get_logo_urls(), "PASSWORD_RULE": { 'SECURITY_PASSWORD_MIN_LENGTH': settings.SECURITY_PASSWORD_MIN_LENGTH, 'SECURITY_ADMIN_USER_PASSWORD_MIN_LENGTH': settings.SECURITY_ADMIN_USER_PASSWORD_MIN_LENGTH, @@ -51,16 +47,30 @@ class PublicSettingApi(generics.RetrieveAPIView): 'SECURITY_PASSWORD_NUMBER': settings.SECURITY_PASSWORD_NUMBER, 'SECURITY_PASSWORD_SPECIAL_CHAR': settings.SECURITY_PASSWORD_SPECIAL_CHAR, }, + 'SECURITY_WATERMARK_ENABLED': settings.SECURITY_WATERMARK_ENABLED, + 'SECURITY_SESSION_SHARE': settings.SECURITY_SESSION_SHARE, + # XPACK + "XPACK_ENABLED": settings.XPACK_ENABLED, + "XPACK_LICENSE_IS_VALID": has_valid_xpack_license(), + "XPACK_LICENSE_INFO": get_xpack_license_info(), + # Performance + "LOGIN_TITLE": self.get_login_title(), + "LOGO_URLS": self.get_logo_urls(), + "HELP_DOCUMENT_URL": settings.HELP_DOCUMENT_URL, + "HELP_SUPPORT_URL": settings.HELP_SUPPORT_URL, + # Auth "AUTH_WECOM": settings.AUTH_WECOM, "AUTH_DINGTALK": settings.AUTH_DINGTALK, "AUTH_FEISHU": settings.AUTH_FEISHU, - 'SECURITY_WATERMARK_ENABLED': settings.SECURITY_WATERMARK_ENABLED, - 'SECURITY_SESSION_SHARE': settings.SECURITY_SESSION_SHARE, + # Terminal "XRDP_ENABLED": settings.XRDP_ENABLED, + "TERMINAL_MAGNUS_ENABLED": settings.TERMINAL_MAGNUS_ENABLED, + "TERMINAL_MAGNUS_HOST": settings.TERMINAL_MAGNUS_HOST, + "TERMINAL_MAGNUS_MYSQL_PORT": settings.TERMINAL_MAGNUS_MYSQL_PORT, + "TERMINAL_MAGNUS_POSTGRE_PORT": settings.TERMINAL_MAGNUS_POSTGRE_PORT, + # Announcement "ANNOUNCEMENT_ENABLED": settings.ANNOUNCEMENT_ENABLED, "ANNOUNCEMENT": settings.ANNOUNCEMENT, - "HELP_DOCUMENT_URL": settings.HELP_DOCUMENT_URL, - "HELP_SUPPORT_URL": settings.HELP_SUPPORT_URL, } } return instance diff --git a/apps/settings/serializers/terminal.py b/apps/settings/serializers/terminal.py index 12858913d..aad5c3e92 100644 --- a/apps/settings/serializers/terminal.py +++ b/apps/settings/serializers/terminal.py @@ -22,9 +22,12 @@ class TerminalSettingSerializer(serializers.Serializer): help_text=_('Tips: If use other auth method, like AD/LDAP, you should disable this to ' 'avoid being able to log in after deleting') ) - TERMINAL_ASSET_LIST_SORT_BY = serializers.ChoiceField(SORT_BY_CHOICES, required=False, label=_('List sort by')) - TERMINAL_ASSET_LIST_PAGE_SIZE = serializers.ChoiceField(PAGE_SIZE_CHOICES, required=False, - label=_('List page size')) + TERMINAL_ASSET_LIST_SORT_BY = serializers.ChoiceField( + SORT_BY_CHOICES, required=False, label=_('List sort by') + ) + TERMINAL_ASSET_LIST_PAGE_SIZE = serializers.ChoiceField( + PAGE_SIZE_CHOICES, required=False, label=_('List page size') + ) TERMINAL_TELNET_REGEX = serializers.CharField( allow_blank=True, max_length=1024, required=False, label=_('Telnet login regex'), help_text=_("The login success message varies with devices. " @@ -34,5 +37,19 @@ class TerminalSettingSerializer(serializers.Serializer): required=False, label=_("RDP address"), max_length=1024, allow_blank=True, help_text=_('RDP visit address, eg: dev.jumpserver.org:3389') ) - XRDP_ENABLED = serializers.BooleanField(label=_("Enable XRDP")) + + TERMINAL_MAGNUS_ENABLED = serializers.BooleanField(label=_("Enable database proxy")) + TERMINAL_MAGNUS_HOST = serializers.CharField( + required=False, label=_("Database proxy host"), max_length=1024, allow_blank=True, + help_text=_('Database proxy host, eg: dev.jumpserver.org') + ) + TERMINAL_MAGNUS_MYSQL_PORT = serializers.IntegerField( + required=False, label=_("MySQL port"), default=33060, + help_text=_('Database proxy MySQL protocol port') + ) + TERMINAL_MAGNUS_POSTGRE_PORT = serializers.IntegerField( + required=False, label=_("PostgreSQL port"), default=54320, + help_text=_('Database proxy PostgreSQL port') + ) + diff --git a/apps/settings/signal_handlers.py b/apps/settings/signal_handlers.py index f4163592c..8f585a2aa 100644 --- a/apps/settings/signal_handlers.py +++ b/apps/settings/signal_handlers.py @@ -3,6 +3,8 @@ import json import threading +from django.conf import LazySettings +from django.db.utils import ProgrammingError, OperationalError from django.dispatch import receiver from django.db.models.signals import post_save, pre_save from django.utils.functional import LazyObject @@ -85,3 +87,17 @@ def subscribe_settings_change(sender, **kwargs): t = threading.Thread(target=keep_subscribe_settings_change) t.daemon = True t.start() + + +@receiver(django_ready) +def monkey_patch_settings(sender, **kwargs): + def monkey_patch_getattr(self, name): + val = getattr(self._wrapped, name) + if callable(val): + val = val() + return val + + try: + LazySettings.__getattr__ = monkey_patch_getattr + except (ProgrammingError, OperationalError): + pass diff --git a/apps/terminal/serializers/terminal.py b/apps/terminal/serializers/terminal.py index 626529a5e..be991d8a8 100644 --- a/apps/terminal/serializers/terminal.py +++ b/apps/terminal/serializers/terminal.py @@ -8,7 +8,7 @@ from common.utils import get_request_ip from .. import const from ..models import ( - Terminal, Status, Session, Task, CommandStorage, ReplayStorage + Terminal, Status, Task, CommandStorage, ReplayStorage ) @@ -53,13 +53,11 @@ class TerminalSerializer(BulkModelSerializer): 'type', 'remote_addr', 'http_port', 'ssh_port', 'session_online', 'command_storage', 'replay_storage', 'is_accepted', "is_active", 'is_alive', - 'date_created', - 'comment', + 'date_created', 'comment', ] fields_fk = ['status', 'status_display', 'stat'] fields = fields_small + fields_fk read_only_fields = ['type', 'date_created'] - extra_kwargs = { 'command_storage': {'required': True, }, 'replay_storage': {'required': True, }, @@ -134,7 +132,7 @@ class TerminalRegistrationSerializer(serializers.ModelSerializer): if request: instance.remote_addr = get_request_ip(request) sa = self.service_account.create(validated_data) - sa.set_component_role() + sa.system_roles.add_role_system_component() instance.user = sa instance.command_storage = CommandStorage.default().name instance.replay_storage = ReplayStorage.default().name diff --git a/apps/users/models/user.py b/apps/users/models/user.py index f9335e40f..b98e401fa 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -12,17 +12,18 @@ from django.db import models from django.conf import settings from django.utils import timezone from django.core.cache import cache -from django.shortcuts import reverse from django.contrib.auth.models import AbstractUser from django.contrib.auth.hashers import check_password from django.utils.translation import ugettext_lazy as _ - +from django.shortcuts import reverse from orgs.utils import current_org from orgs.models import Organization from rbac.const import Scope from common import fields -from common.utils import date_expired_default, get_logger, lazyproperty, random_string +from common.utils import ( + date_expired_default, get_logger, lazyproperty, random_string, bulk_create_with_signal +) from ..signals import post_user_change_password, post_user_leave_org, pre_user_leave_org __all__ = ['User', 'UserPasswordHistory'] @@ -173,17 +174,17 @@ class RoleManager(models.Manager): def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) self.user = user - self.role_binding_cls = self.get_role_binding_cls() - self.role_cls = self.get_role_cls() - def get_role_binding_cls(self): + @lazyproperty + def role_binding_cls(self): from rbac.models import SystemRoleBinding, OrgRoleBinding if self.scope == Scope.org: return OrgRoleBinding else: return SystemRoleBinding - def get_role_cls(self): + @lazyproperty + def role_cls(self): from rbac.models import SystemRole, OrgRole if self.scope == Scope.org: return OrgRole @@ -240,17 +241,18 @@ class RoleManager(models.Manager): items = [] for role in need_adds: - kwargs = { - 'role': role, - 'user': self.user, - 'scope': self.scope - } - if self.scope == Scope.org and not current_org.is_root(): - kwargs['org_id'] = current_org.id + kwargs = {'role': role, 'user': self.user, 'scope': self.scope} + if self.scope == Scope.org: + if current_org.is_root(): + continue + else: + kwargs['org_id'] = current_org.id items.append(self.role_binding_cls(**kwargs)) try: - self.role_binding_cls.objects.bulk_create(items, ignore_conflicts=True) + result = bulk_create_with_signal(self.role_binding_cls, items, ignore_conflicts=True) + self.user.expire_users_rbac_perms_cache() + return result except Exception as e: logger.error('Create role binding error: {}'.format(e)) @@ -273,25 +275,15 @@ class RoleManager(models.Manager): if not roles: return roles = self._clean_roles(roles) - return self.role_bindings.filter(role__in=roles).delete() + deleted = self.role_bindings.filter(role__in=roles).delete() + self.user.expire_users_rbac_perms_cache() + return deleted def cache_set(self, roles): query = self._get_queryset() query._result_cache = roles self._cache = query - def remove_role_system_admin(self): - role = self.builtin_role.system_admin.get_role() - return self.remove(role) - - def add_role_system_admin(self): - role = self.builtin_role.system_admin.get_role() - return self.add(role) - - def add_role_system_user(self): - role = self.builtin_role.system_user.get_role() - return self.add(role) - @property def builtin_role(self): from rbac.builtin import BuiltinRole @@ -311,6 +303,22 @@ class SystemRoleManager(RoleManager): self.scope = Scope.system super().__init__(*args, **kwargs) + def remove_role_system_admin(self): + role = self.builtin_role.system_admin.get_role() + return self.remove(role) + + def add_role_system_admin(self): + role = self.builtin_role.system_admin.get_role() + return self.add(role) + + def add_role_system_user(self): + role = self.builtin_role.system_user.get_role() + return self.add(role) + + def add_role_system_component(self): + role = self.builtin_role.system_component.get_role() + self.add(role) + class RoleMixin: objects: models.Manager @@ -403,11 +411,6 @@ class RoleMixin: access_key = app.create_access_key() return app, access_key - def set_component_role(self): - from rbac.models import Role - role = Role.BuiltinRole.system_component.get_role() - self.system_roles.add(role) - def remove(self): if current_org.is_root(): return From b7b1d81ea001a5ea50fd205854868af796277ba8 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 25 Mar 2022 16:46:36 +0800 Subject: [PATCH 26/59] fix: magenus bug (#7977) Co-authored-by: feng626 <1304903146@qq.com> --- apps/jumpserver/settings/custom.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index d8495e0ba..37e6d2e95 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -171,5 +171,6 @@ HELP_SUPPORT_URL = CONFIG.HELP_SUPPORT_URL # Magnus MAGNUS_ENABLED = CONFIG.MAGNUS_ENABLED TERMINAL_MAGNUS_HOST = CONFIG.TERMINAL_MAGNUS_HOST +TERMINAL_MAGNUS_ENABLED = CONFIG.TERMINAL_MAGNUS_ENABLED TERMINAL_MAGNUS_MYSQL_PORT = CONFIG.TERMINAL_MAGNUS_MYSQL_PORT TERMINAL_MAGNUS_POSTGRE_PORT = CONFIG.TERMINAL_MAGNUS_POSTGRE_PORT From 03fdaa03e4f3a360d9cc0e32cb137808cdd70a08 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Fri, 25 Mar 2022 15:15:20 +0800 Subject: [PATCH 27/59] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E6=97=A5?= =?UTF-8?q?=E8=AF=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/authentication/login.html | 7 +- apps/locale/ja/LC_MESSAGES/django.mo | 3 + apps/locale/ja/LC_MESSAGES/django.po | 6837 +++++++++++++++++ apps/locale/ja/LC_MESSAGES/djangojs.mo | 3 + apps/locale/ja/LC_MESSAGES/djangojs.po | 158 + apps/locale/zh/LC_MESSAGES/django.po | 26 +- apps/templates/_header_bar.html | 6 + 7 files changed, 7025 insertions(+), 15 deletions(-) create mode 100644 apps/locale/ja/LC_MESSAGES/django.mo create mode 100644 apps/locale/ja/LC_MESSAGES/django.po create mode 100644 apps/locale/ja/LC_MESSAGES/djangojs.mo create mode 100644 apps/locale/ja/LC_MESSAGES/djangojs.po diff --git a/apps/authentication/templates/authentication/login.html b/apps/authentication/templates/authentication/login.html index 3e24aa610..677ee70d4 100644 --- a/apps/authentication/templates/authentication/login.html +++ b/apps/authentication/templates/authentication/login.html @@ -142,15 +142,18 @@ diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo new file mode 100644 index 000000000..15d633efa --- /dev/null +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc8a3e50aa2a43b3a9ea415e1f8b2e106cc7b4f8e653629958a0e28cc7c5f193 +size 128364 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po new file mode 100644 index 000000000..eb20c66d2 --- /dev/null +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -0,0 +1,6837 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-03-22 15:28+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: acls/apps.py:7 +msgid "Acls" +msgstr "Acls" + +#: acls/models/base.py:25 acls/serializers/login_asset_acl.py:47 +#: applications/models/application.py:212 assets/models/asset.py:138 +#: assets/models/base.py:175 assets/models/cluster.py:18 +#: assets/models/cmd_filter.py:27 assets/models/domain.py:23 +#: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24 +#: orgs/models.py:65 perms/models/base.py:83 rbac/models/role.py:29 +#: settings/models.py:29 settings/serializers/sms.py:6 +#: terminal/models/storage.py:23 terminal/models/task.py:16 +#: terminal/models/terminal.py:100 users/forms/profile.py:32 +#: users/models/group.py:15 users/models/user.py:655 +#: users/templates/users/_select_user_modal.html:13 +#: users/templates/users/user_asset_permission.html:37 +#: users/templates/users/user_asset_permission.html:154 +#: users/templates/users/user_database_app_permission.html:36 +#: xpack/plugins/cloud/models.py:28 +msgid "Name" +msgstr "名前" + +#: acls/models/base.py:27 assets/models/cmd_filter.py:84 +#: assets/models/user.py:234 +msgid "Priority" +msgstr "優先順位" + +#: acls/models/base.py:28 assets/models/cmd_filter.py:84 +#: assets/models/user.py:234 +msgid "1-100, the lower the value will be match first" +msgstr "1-100、低い値は最初に一致します" + +#: acls/models/base.py:31 authentication/models.py:17 +#: authentication/templates/authentication/_access_key_modal.html:32 +#: perms/models/base.py:88 terminal/models/sharing.py:26 +#: users/templates/users/_select_user_modal.html:18 +msgid "Active" +msgstr "アクティブ" + +#: acls/models/base.py:32 applications/models/application.py:225 +#: assets/models/asset.py:143 assets/models/asset.py:231 +#: assets/models/backup.py:54 assets/models/base.py:180 +#: assets/models/cluster.py:29 assets/models/cmd_filter.py:48 +#: assets/models/cmd_filter.py:96 assets/models/domain.py:24 +#: assets/models/domain.py:64 assets/models/group.py:23 +#: assets/models/label.py:23 ops/models/adhoc.py:38 orgs/models.py:68 +#: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34 +#: terminal/models/storage.py:26 terminal/models/terminal.py:114 +#: tickets/models/comment.py:24 tickets/models/ticket.py:154 +#: users/models/group.py:16 users/models/user.py:692 +#: 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 +msgid "Comment" +msgstr "コメント" + +#: acls/models/login_acl.py:18 tickets/const.py:38 +msgid "Reject" +msgstr "拒否" + +#: acls/models/login_acl.py:19 assets/models/cmd_filter.py:75 +msgid "Allow" +msgstr "許可" + +#: acls/models/login_acl.py:20 acls/models/login_acl.py:117 +#: acls/models/login_asset_acl.py:17 tickets/const.py:9 +msgid "Login confirm" +msgstr "ログイン確認" + +#: acls/models/login_acl.py:24 acls/models/login_asset_acl.py:20 +#: assets/models/cmd_filter.py:30 assets/models/label.py:15 audits/models.py:37 +#: audits/models.py:60 audits/models.py:85 audits/serializers.py:100 +#: authentication/models.py:50 orgs/models.py:214 perms/models/base.py:84 +#: rbac/builtin.py:101 rbac/models/rolebinding.py:40 templates/index.html:78 +#: terminal/backends/command/models.py:19 +#: terminal/backends/command/serializers.py:12 terminal/models/session.py:42 +#: terminal/notifications.py:91 terminal/notifications.py:139 +#: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:880 +#: users/models/user.py:911 users/serializers/group.py:19 +#: users/templates/users/user_asset_permission.html:38 +#: users/templates/users/user_asset_permission.html:64 +#: users/templates/users/user_database_app_permission.html:37 +#: users/templates/users/user_database_app_permission.html:58 +msgid "User" +msgstr "ユーザー" + +#: acls/models/login_acl.py:28 +msgid "Rule" +msgstr "ルール" + +#: acls/models/login_acl.py:31 acls/models/login_asset_acl.py:26 +#: acls/serializers/login_acl.py:17 acls/serializers/login_asset_acl.py:75 +#: assets/models/cmd_filter.py:89 audits/models.py:61 audits/serializers.py:51 +#: authentication/templates/authentication/_access_key_modal.html:34 +#: users/templates/users/_granted_assets.html:29 +#: users/templates/users/user_asset_permission.html:44 +#: users/templates/users/user_asset_permission.html:79 +#: users/templates/users/user_database_app_permission.html:42 +msgid "Action" +msgstr "アクション" + +#: acls/models/login_acl.py:35 acls/models/login_asset_acl.py:32 +#: acls/serializers/login_acl.py:16 assets/models/cmd_filter.py:94 +msgid "Reviewers" +msgstr "レビュー担当者" + +#: acls/models/login_acl.py:42 +msgid "Login acl" +msgstr "ログインacl" + +#: acls/models/login_asset_acl.py:21 +#: applications/serializers/application.py:122 +#: applications/serializers/application.py:167 +msgid "System User" +msgstr "システムユーザー" + +#: acls/models/login_asset_acl.py:22 +#: applications/serializers/attrs/application_category/remote_app.py:36 +#: assets/models/asset.py:355 assets/models/authbook.py:19 +#: assets/models/backup.py:31 assets/models/cmd_filter.py:38 +#: assets/models/gathered_user.py:14 assets/serializers/label.py:30 +#: assets/serializers/system_user.py:264 audits/models.py:39 +#: perms/models/asset_permission.py:23 templates/index.html:82 +#: terminal/backends/command/models.py:20 +#: terminal/backends/command/serializers.py:13 terminal/models/session.py:44 +#: terminal/notifications.py:90 +#: users/templates/users/user_asset_permission.html:40 +#: users/templates/users/user_asset_permission.html:70 +#: xpack/plugins/change_auth_plan/models/asset.py:199 +#: xpack/plugins/change_auth_plan/serializers/asset.py:180 +#: xpack/plugins/cloud/models.py:223 +msgid "Asset" +msgstr "資産" + +#: acls/models/login_asset_acl.py:40 +msgid "Login asset acl" +msgstr "ログインasset acl" + +#: acls/models/login_asset_acl.py:90 tickets/const.py:12 +msgid "Login asset confirm" +msgstr "ログイン資産の確認" + +#: acls/serializers/login_acl.py:11 acls/serializers/login_asset_acl.py:12 +msgid "Format for comma-delimited string, with * indicating a match all. " +msgstr "コンマ区切り文字列の形式。* はすべて一致することを示します。" + +#: acls/serializers/login_acl.py:15 acls/serializers/login_asset_acl.py:17 +#: acls/serializers/login_asset_acl.py:51 assets/models/base.py:176 +#: assets/models/gathered_user.py:15 audits/models.py:119 +#: authentication/forms.py:15 authentication/forms.py:17 +#: 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:31 users/models/user.py:653 +#: users/templates/users/_msg_user_created.html:12 +#: users/templates/users/_select_user_modal.html:14 +#: xpack/plugins/change_auth_plan/models/asset.py:34 +#: xpack/plugins/change_auth_plan/models/asset.py:195 +#: xpack/plugins/cloud/serializers/account_attrs.py:22 +msgid "Username" +msgstr "ユーザー名" + +#: acls/serializers/login_asset_acl.py:24 +msgid "" +"Format for comma-delimited string, with * indicating a match all. Such as: " +"192.168.10.1, 192.168.1.0/24, 10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:" +"db8:1a:1110::/64 (Domain name support)" +msgstr "" +"コンマ区切り文字列の形式。* はすべて一致することを示します。例: " +"192.168.10.1、192.168.1.0/24、10.1.1.1-10.1.1.20、2001:db8:2de::e13、2001:" +"db8:1a:1110:::/64 (ドメイン名サポート)" + +#: acls/serializers/login_asset_acl.py:31 acls/serializers/rules/rules.py:33 +#: applications/serializers/attrs/application_type/mysql_workbench.py:17 +#: assets/models/asset.py:210 assets/models/domain.py:60 +#: assets/serializers/account.py:13 +#: authentication/templates/authentication/_msg_oauth_bind.html:12 +#: authentication/templates/authentication/_msg_rest_password_success.html:8 +#: authentication/templates/authentication/_msg_rest_public_key_success.html:8 +#: settings/serializers/terminal.py:8 +#: users/templates/users/_granted_assets.html:26 +#: users/templates/users/user_asset_permission.html:156 +msgid "IP" +msgstr "IP" + +#: acls/serializers/login_asset_acl.py:35 assets/models/asset.py:211 +#: assets/serializers/account.py:14 assets/serializers/gathered_user.py:23 +#: settings/serializers/terminal.py:7 +#: users/templates/users/_granted_assets.html:25 +#: users/templates/users/user_asset_permission.html:157 +msgid "Hostname" +msgstr "ホスト名" + +#: acls/serializers/login_asset_acl.py:42 +msgid "" +"Format for comma-delimited string, with * indicating a match all. Protocol " +"options: {}" +msgstr "" +"コンマ区切り文字列の形式。* はすべて一致することを示します。プロトコル" +"オプション: {}" + +#: acls/serializers/login_asset_acl.py:55 assets/models/asset.py:213 +#: assets/models/domain.py:62 assets/models/user.py:235 +#: terminal/serializers/session.py:30 terminal/serializers/storage.py:69 +msgid "Protocol" +msgstr "プロトコル" + +#: acls/serializers/login_asset_acl.py:65 +msgid "Unsupported protocols: {}" +msgstr "サポートされていないプロトコル: {}" + +#: acls/serializers/login_asset_acl.py:98 +#: tickets/serializers/ticket/ticket.py:105 +msgid "The organization `{}` does not exist" +msgstr "組織 '{}'は存在しません" + +#: acls/serializers/login_asset_acl.py:103 +msgid "None of the reviewers belong to Organization `{}`" +msgstr "いずれのレビューアも組織 '{}' に属していません" + +#: acls/serializers/rules/rules.py:20 +#: xpack/plugins/cloud/serializers/task.py:23 +msgid "IP address invalid: `{}`" +msgstr "IPアドレスが無効: '{}'" + +#: acls/serializers/rules/rules.py:25 +msgid "" +"Format for comma-delimited string, with * indicating a match all. Such as: " +"192.168.10.1, 192.168.1.0/24, 10.1.1.1-10.1.1.20, 2001:db8:2de::e13, 2001:" +"db8:1a:1110::/64 " +msgstr "" +"コンマ区切り文字列の形式。* はすべて一致することを示します。例: " +"192.168.10.1、192.168.1.0/24、10.1.1.1-10.1.1.20、2001:db8:2de::e13、2001:" +"db8:1a:1110::/64" + +#: acls/serializers/rules/rules.py:35 +msgid "Time Period" +msgstr "期間" + +#: applications/api/mixin.py:28 +msgid "My applications" +msgstr "私のアプリケーション" + +#: applications/apps.py:9 applications/models/application.py:61 +msgid "Applications" +msgstr "アプリケーション" + +#: applications/const.py:8 +#: applications/serializers/attrs/application_category/db.py:14 +#: applications/serializers/attrs/application_type/mysql_workbench.py:25 +#: xpack/plugins/change_auth_plan/models/app.py:32 +msgid "Database" +msgstr "データベース" + +#: applications/const.py:9 +msgid "Remote app" +msgstr "リモートアプリ" + +#: applications/const.py:35 +msgid "Custom" +msgstr "カスタム" + +#: applications/models/account.py:12 applications/models/application.py:229 +#: assets/models/backup.py:32 assets/models/cmd_filter.py:45 +#: perms/models/application_permission.py:28 +msgid "Application" +msgstr "アプリケーション" + +#: applications/models/account.py:15 assets/models/authbook.py:20 +#: assets/models/cmd_filter.py:42 assets/models/user.py:325 audits/models.py:40 +#: perms/models/application_permission.py:33 +#: perms/models/asset_permission.py:25 terminal/backends/command/models.py:21 +#: terminal/backends/command/serializers.py:14 terminal/models/session.py:46 +#: users/templates/users/_granted_assets.html:27 +#: users/templates/users/user_asset_permission.html:42 +#: users/templates/users/user_asset_permission.html:76 +#: users/templates/users/user_asset_permission.html:159 +#: users/templates/users/user_database_app_permission.html:40 +#: users/templates/users/user_database_app_permission.html:67 +#: xpack/plugins/change_auth_plan/models/app.py:36 +#: xpack/plugins/change_auth_plan/models/app.py:147 +#: xpack/plugins/change_auth_plan/serializers/app.py:65 +msgid "System user" +msgstr "システムユーザー" + +#: applications/models/account.py:17 assets/models/authbook.py:21 +#: settings/serializers/auth/cas.py:15 +msgid "Version" +msgstr "バージョン" + +#: applications/models/account.py:23 +msgid "Application account" +msgstr "アプリケーションアカウント" + +#: applications/models/account.py:26 +msgid "Can view application account secret" +msgstr "アプリケーションアカウントの秘密を表示できます" + +#: applications/models/account.py:27 +msgid "Can change application account secret" +msgstr "アプリケーションアカウントの秘密を変更できます" + +#: applications/models/application.py:214 +#: applications/serializers/application.py:99 assets/models/label.py:21 +#: perms/models/application_permission.py:21 +#: perms/serializers/application/user_permission.py:33 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:22 +#: xpack/plugins/change_auth_plan/models/app.py:25 +msgid "Category" +msgstr "カテゴリ" + +#: applications/models/application.py:217 +#: applications/serializers/application.py:101 assets/models/backup.py:49 +#: assets/models/cmd_filter.py:82 assets/models/user.py:233 +#: perms/models/application_permission.py:24 +#: perms/serializers/application/user_permission.py:34 +#: terminal/models/storage.py:55 terminal/models/storage.py:119 +#: tickets/models/flow.py:56 tickets/models/ticket.py:131 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:29 +#: xpack/plugins/change_auth_plan/models/app.py:28 +#: xpack/plugins/change_auth_plan/models/app.py:153 +msgid "Type" +msgstr "タイプ" + +#: applications/models/application.py:221 assets/models/asset.py:217 +#: assets/models/domain.py:29 assets/models/domain.py:63 +msgid "Domain" +msgstr "ドメイン" + +#: applications/models/application.py:223 xpack/plugins/cloud/models.py:33 +#: xpack/plugins/cloud/serializers/account.py:58 +msgid "Attrs" +msgstr "ツールバーの" + +#: applications/models/application.py:233 +msgid "Can match application" +msgstr "アプリケーションを一致させることができます" + +#: applications/models/application.py:281 +msgid "Application user" +msgstr "アプリケーションユーザー" + +#: applications/serializers/application.py:70 +#: applications/serializers/application.py:100 assets/serializers/label.py:13 +#: perms/serializers/application/permission.py:18 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:26 +msgid "Category display" +msgstr "カテゴリ表示" + +#: applications/serializers/application.py:71 +#: applications/serializers/application.py:102 +#: assets/serializers/system_user.py:27 audits/serializers.py:29 +#: perms/serializers/application/permission.py:19 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:33 +#: tickets/serializers/ticket/ticket.py:21 +#: tickets/serializers/ticket/ticket.py:173 +msgid "Type display" +msgstr "タイプ表示" + +#: applications/serializers/application.py:103 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 +#: assets/serializers/account.py:18 assets/serializers/cmd_filter.py:28 +#: assets/serializers/cmd_filter.py:49 common/db/models.py:113 +#: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30 +#: orgs/models.py:67 orgs/models.py:217 perms/models/base.py:92 +#: users/models/group.py:18 users/models/user.py:912 +#: xpack/plugins/cloud/models.py:125 +msgid "Date created" +msgstr "作成された日付" + +#: applications/serializers/application.py:104 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:50 +#: common/db/models.py:114 common/mixins/models.py:51 ops/models/adhoc.py:40 +#: orgs/models.py:218 +msgid "Date updated" +msgstr "更新日" + +#: applications/serializers/application.py:121 +#: applications/serializers/application.py:166 +msgid "Application display" +msgstr "アプリケーション表示" + +#: applications/serializers/application.py:123 +msgid "account" +msgstr "アカウント" + +#: applications/serializers/attrs/application_category/cloud.py:8 +#: assets/models/cluster.py:40 +msgid "Cluster" +msgstr "クラスター" + +#: applications/serializers/attrs/application_category/db.py:11 +#: ops/models/adhoc.py:157 settings/serializers/auth/radius.py:14 +#: xpack/plugins/cloud/serializers/account_attrs.py:68 +msgid "Host" +msgstr "ホスト" + +#: applications/serializers/attrs/application_category/db.py:12 +#: applications/serializers/attrs/application_type/mongodb.py:10 +#: applications/serializers/attrs/application_type/mysql.py:10 +#: applications/serializers/attrs/application_type/mysql_workbench.py:21 +#: applications/serializers/attrs/application_type/oracle.py:10 +#: applications/serializers/attrs/application_type/pgsql.py:10 +#: 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:61 +#: settings/serializers/auth/radius.py:15 +#: xpack/plugins/cloud/serializers/account_attrs.py:69 +msgid "Port" +msgstr "ポート" + +#: applications/serializers/attrs/application_category/remote_app.py:39 +#: applications/serializers/attrs/application_type/chrome.py:13 +#: applications/serializers/attrs/application_type/mysql_workbench.py:13 +#: applications/serializers/attrs/application_type/vmware_client.py:17 +msgid "Application path" +msgstr "アプリケーションパス" + +#: applications/serializers/attrs/application_category/remote_app.py:44 +#: assets/serializers/system_user.py:163 +#: xpack/plugins/change_auth_plan/serializers/asset.py:66 +#: xpack/plugins/change_auth_plan/serializers/asset.py:69 +#: xpack/plugins/change_auth_plan/serializers/asset.py:72 +#: xpack/plugins/change_auth_plan/serializers/asset.py:103 +#: xpack/plugins/cloud/serializers/account_attrs.py:52 +msgid "This field is required." +msgstr "このフィールドは必須です。" + +#: applications/serializers/attrs/application_type/chrome.py:16 +#: applications/serializers/attrs/application_type/vmware_client.py:21 +msgid "Target URL" +msgstr "ターゲットURL" + +#: applications/serializers/attrs/application_type/chrome.py:19 +msgid "Chrome username" +msgstr "Chromeユーザー名" + +#: applications/serializers/attrs/application_type/chrome.py:22 +#: applications/serializers/attrs/application_type/chrome.py:29 +msgid "Chrome password" +msgstr "Chromeパスワード" + +#: applications/serializers/attrs/application_type/custom.py:11 +msgid "Operating parameter" +msgstr "操作パラメータ" + +#: applications/serializers/attrs/application_type/custom.py:15 +msgid "Target url" +msgstr "ターゲットURL" + +#: applications/serializers/attrs/application_type/custom.py:19 +msgid "Custom Username" +msgstr "カスタムユーザー名" + +#: applications/serializers/attrs/application_type/custom.py:23 +#: applications/serializers/attrs/application_type/custom.py:30 +#: xpack/plugins/change_auth_plan/models/base.py:27 +msgid "Custom password" +msgstr "カスタムパスワード" + +#: applications/serializers/attrs/application_type/mysql_workbench.py:29 +msgid "Mysql workbench username" +msgstr "Mysql workbench のユーザー名" + +#: applications/serializers/attrs/application_type/mysql_workbench.py:33 +#: applications/serializers/attrs/application_type/mysql_workbench.py:40 +msgid "Mysql workbench password" +msgstr "Mysql workbench パスワード" + +#: applications/serializers/attrs/application_type/vmware_client.py:25 +msgid "Vmware username" +msgstr "Vmware ユーザー名" + +#: applications/serializers/attrs/application_type/vmware_client.py:29 +#: applications/serializers/attrs/application_type/vmware_client.py:36 +msgid "Vmware password" +msgstr "Vmware パスワード" + +#: assets/api/domain.py:52 +msgid "Number required" +msgstr "必要な数" + +#: assets/api/node.py:61 +msgid "You can't update the root node name" +msgstr "ルートノード名を更新できません" + +#: assets/api/node.py:68 +msgid "You can't delete the root node ({})" +msgstr "ルートノード ({}) を削除できません。" + +#: assets/api/node.py:71 +msgid "Deletion failed and the node contains assets" +msgstr "削除に失敗し、ノードにアセットが含まれています。" + +#: assets/apps.py:9 +msgid "App assets" +msgstr "アプリ資産" + +#: assets/models/asset.py:139 +msgid "Base" +msgstr "ベース" + +#: assets/models/asset.py:140 +msgid "Charset" +msgstr "シャーセット" + +#: assets/models/asset.py:141 assets/serializers/asset.py:176 +#: tickets/models/ticket.py:133 +msgid "Meta" +msgstr "メタ" + +#: assets/models/asset.py:142 +msgid "Internal" +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 +msgid "Platform" +msgstr "プラットフォーム" + +#: assets/models/asset.py:168 +msgid "Vendor" +msgstr "ベンダー" + +#: assets/models/asset.py:169 +msgid "Model" +msgstr "モデル" + +#: assets/models/asset.py:170 tickets/models/ticket.py:159 +msgid "Serial number" +msgstr "シリアル番号" + +#: assets/models/asset.py:172 +msgid "CPU model" +msgstr "CPU モデル" + +#: assets/models/asset.py:173 +msgid "CPU count" +msgstr "CPU カウント" + +#: assets/models/asset.py:174 +msgid "CPU cores" +msgstr "CPU カラー" + +#: assets/models/asset.py:175 +msgid "CPU vcpus" +msgstr "CPU 合計" + +#: assets/models/asset.py:176 +msgid "Memory" +msgstr "メモリ" + +#: assets/models/asset.py:177 +msgid "Disk total" +msgstr "ディスクの合計" + +#: assets/models/asset.py:178 +msgid "Disk info" +msgstr "ディスク情報" + +#: assets/models/asset.py:180 +msgid "OS" +msgstr "OS" + +#: assets/models/asset.py:181 +msgid "OS version" +msgstr "システムバージョン" + +#: assets/models/asset.py:182 +msgid "OS arch" +msgstr "システムアーキテクチャ" + +#: assets/models/asset.py:183 +msgid "Hostname raw" +msgstr "ホスト名生" + +#: assets/models/asset.py:215 assets/serializers/account.py:16 +#: assets/serializers/asset.py:65 perms/serializers/asset/user_permission.py:41 +#: xpack/plugins/cloud/models.py:107 xpack/plugins/cloud/serializers/task.py:42 +msgid "Protocols" +msgstr "プロトコル" + +#: assets/models/asset.py:218 assets/models/user.py:225 +#: perms/models/asset_permission.py:24 +#: xpack/plugins/change_auth_plan/models/asset.py:43 +#: xpack/plugins/gathered_user/models.py:24 +msgid "Nodes" +msgstr "ノード" + +#: assets/models/asset.py:219 assets/models/cmd_filter.py:47 +#: assets/models/domain.py:65 assets/models/label.py:22 +msgid "Is active" +msgstr "アクティブです。" + +#: assets/models/asset.py:222 assets/models/cluster.py:19 +#: assets/models/user.py:222 assets/models/user.py:377 +msgid "Admin user" +msgstr "管理ユーザー" + +#: assets/models/asset.py:225 +msgid "Public IP" +msgstr "パブリックIP" + +#: assets/models/asset.py:226 +msgid "Asset number" +msgstr "資産番号" + +#: assets/models/asset.py:228 +msgid "Labels" +msgstr "ラベル" + +#: assets/models/asset.py:229 assets/models/base.py:183 +#: assets/models/cluster.py:28 assets/models/cmd_filter.py:52 +#: assets/models/cmd_filter.py:99 assets/models/group.py:21 +#: common/db/models.py:111 common/mixins/models.py:49 orgs/models.py:66 +#: orgs/models.py:219 perms/models/base.py:91 users/models/user.py:700 +#: 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 +msgid "Created by" +msgstr "によって作成された" + +#: assets/models/asset.py:358 +msgid "Can refresh asset hardware info" +msgstr "資産ハードウェア情報を更新できます" + +#: assets/models/asset.py:359 +msgid "Can test asset connectivity" +msgstr "資産接続をテストできます" + +#: assets/models/asset.py:360 +msgid "Can push system user to asset" +msgstr "システムユーザーを資産にプッシュできます" + +#: assets/models/asset.py:361 +msgid "Can match asset" +msgstr "アセットを一致させることができます" + +#: assets/models/asset.py:362 +msgid "Add asset to node" +msgstr "ノードにアセットを追加する" + +#: assets/models/asset.py:363 +msgid "Move asset to node" +msgstr "アセットをノードに移動する" + +#: assets/models/authbook.py:27 +msgid "AuthBook" +msgstr "資産アカウント" + +#: assets/models/authbook.py:30 +msgid "Can test asset account connectivity" +msgstr "アセットアカウントの接続性をテストできます" + +#: assets/models/authbook.py:31 +msgid "Can view asset account secret" +msgstr "資産アカウントの秘密を表示できます" + +#: assets/models/authbook.py:32 +msgid "Can change asset account secret" +msgstr "資産口座の秘密を変更できます" + +#: assets/models/backup.py:30 perms/models/base.py:54 +#: settings/serializers/terminal.py:12 +msgid "All" +msgstr "すべて" + +#: assets/models/backup.py:52 assets/serializers/backup.py:32 +#: xpack/plugins/change_auth_plan/models/app.py:41 +#: xpack/plugins/change_auth_plan/models/asset.py:62 +#: xpack/plugins/change_auth_plan/serializers/base.py:44 +msgid "Recipient" +msgstr "受信者" + +#: assets/models/backup.py:62 assets/models/backup.py:124 +msgid "Account backup plan" +msgstr "アカウントバックアップ計画" + +#: assets/models/backup.py:100 +#: xpack/plugins/change_auth_plan/models/base.py:107 +msgid "Manual trigger" +msgstr "手動トリガー" + +#: assets/models/backup.py:101 +#: xpack/plugins/change_auth_plan/models/base.py:108 +msgid "Timing trigger" +msgstr "タイミングトリガー" + +#: assets/models/backup.py:105 audits/models.py:44 ops/models/command.py:31 +#: perms/models/base.py:89 terminal/models/session.py:56 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:55 +#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:57 +#: xpack/plugins/change_auth_plan/models/base.py:112 +#: xpack/plugins/change_auth_plan/models/base.py:203 +#: xpack/plugins/gathered_user/models.py:76 +msgid "Date start" +msgstr "開始日" + +#: assets/models/backup.py:108 +#: authentication/templates/authentication/_msg_oauth_bind.html:11 +#: notifications/notifications.py:187 ops/models/adhoc.py:258 +#: xpack/plugins/change_auth_plan/models/base.py:115 +#: xpack/plugins/change_auth_plan/models/base.py:204 +#: xpack/plugins/gathered_user/models.py:79 +msgid "Time" +msgstr "時間" + +#: assets/models/backup.py:112 +msgid "Account backup snapshot" +msgstr "アカウントのバックアップスナップショット" + +#: assets/models/backup.py:116 assets/serializers/backup.py:40 +#: xpack/plugins/change_auth_plan/models/base.py:125 +#: xpack/plugins/change_auth_plan/serializers/base.py:73 +msgid "Trigger mode" +msgstr "トリガーモード" + +#: assets/models/backup.py:119 audits/models.py:125 +#: terminal/models/sharing.py:94 +#: xpack/plugins/change_auth_plan/models/base.py:201 +#: xpack/plugins/change_auth_plan/serializers/app.py:66 +#: xpack/plugins/change_auth_plan/serializers/asset.py:179 +#: xpack/plugins/cloud/models.py:179 +msgid "Reason" +msgstr "理由" + +#: assets/models/backup.py:121 audits/serializers.py:82 +#: audits/serializers.py:97 ops/models/adhoc.py:260 +#: terminal/serializers/session.py:35 +#: xpack/plugins/change_auth_plan/models/base.py:202 +#: xpack/plugins/change_auth_plan/serializers/app.py:67 +#: xpack/plugins/change_auth_plan/serializers/asset.py:181 +msgid "Is success" +msgstr "成功は" + +#: assets/models/backup.py:128 +msgid "Account backup execution" +msgstr "アカウントバックアップの実行" + +#: assets/models/base.py:30 assets/tasks/const.py:51 audits/const.py:5 +msgid "Unknown" +msgstr "不明" + +#: assets/models/base.py:31 +msgid "Ok" +msgstr "OK" + +#: assets/models/base.py:32 audits/models.py:116 +#: xpack/plugins/change_auth_plan/serializers/app.py:88 +#: xpack/plugins/change_auth_plan/serializers/asset.py:198 +#: xpack/plugins/cloud/const.py:30 +msgid "Failed" +msgstr "失敗しました" + +#: assets/models/base.py:38 +msgid "Connectivity" +msgstr "接続性" + +#: assets/models/base.py:40 +msgid "Date verified" +msgstr "確認済みの日付" + +#: assets/models/base.py:177 audits/signal_handlers.py:68 +#: authentication/forms.py:22 +#: authentication/templates/authentication/login.html:178 +#: settings/serializers/auth/ldap.py:44 users/forms/profile.py:21 +#: users/templates/users/_msg_user_created.html:13 +#: users/templates/users/user_password_update.html:43 +#: users/templates/users/user_password_verify.html:18 +#: xpack/plugins/change_auth_plan/models/base.py:42 +#: xpack/plugins/change_auth_plan/models/base.py:121 +#: xpack/plugins/change_auth_plan/models/base.py:196 +#: xpack/plugins/cloud/serializers/account_attrs.py:24 +msgid "Password" +msgstr "パスワード" + +#: assets/models/base.py:178 xpack/plugins/change_auth_plan/models/asset.py:53 +#: xpack/plugins/change_auth_plan/models/asset.py:130 +#: xpack/plugins/change_auth_plan/models/asset.py:206 +msgid "SSH private key" +msgstr "SSH秘密鍵" + +#: assets/models/base.py:179 xpack/plugins/change_auth_plan/models/asset.py:56 +#: xpack/plugins/change_auth_plan/models/asset.py:126 +#: xpack/plugins/change_auth_plan/models/asset.py:202 +msgid "SSH public key" +msgstr "SSHパブリックキー" + +#: assets/models/cluster.py:20 +msgid "Bandwidth" +msgstr "帯域幅" + +#: assets/models/cluster.py:21 +msgid "Contact" +msgstr "連絡先" + +#: assets/models/cluster.py:22 users/models/user.py:675 +msgid "Phone" +msgstr "電話" + +#: assets/models/cluster.py:23 +msgid "Address" +msgstr "アドレス" + +#: assets/models/cluster.py:24 +msgid "Intranet" +msgstr "イントラネット" + +#: assets/models/cluster.py:25 +msgid "Extranet" +msgstr "エクストラネット" + +#: assets/models/cluster.py:27 +msgid "Operator" +msgstr "オペレーター" + +#: assets/models/cluster.py:36 assets/models/group.py:34 +#: xpack/plugins/cloud/providers/nutanix.py:30 +msgid "Default" +msgstr "デフォルト" + +#: assets/models/cluster.py:36 assets/models/label.py:14 rbac/const.py:6 +#: users/models/user.py:897 +msgid "System" +msgstr "システム" + +#: assets/models/cluster.py:36 +msgid "Default Cluster" +msgstr "デフォルトクラスター" + +#: assets/models/cmd_filter.py:34 perms/models/base.py:86 +#: users/models/group.py:31 users/models/user.py:661 +#: users/templates/users/_select_user_modal.html:16 +#: users/templates/users/user_asset_permission.html:39 +#: users/templates/users/user_asset_permission.html:67 +#: users/templates/users/user_database_app_permission.html:38 +#: users/templates/users/user_database_app_permission.html:61 +msgid "User group" +msgstr "ユーザーグループ" + +#: assets/models/cmd_filter.py:60 assets/serializers/system_user.py:54 +msgid "Command filter" +msgstr "コマンドフィルター" + +#: assets/models/cmd_filter.py:67 +msgid "Regex" +msgstr "正規情報" + +#: assets/models/cmd_filter.py:68 ops/models/command.py:26 +#: terminal/backends/command/serializers.py:15 terminal/models/session.py:53 +#: terminal/templates/terminal/_msg_command_alert.html:12 +#: terminal/templates/terminal/_msg_command_execute_alert.html:10 +msgid "Command" +msgstr "コマンド" + +#: assets/models/cmd_filter.py:74 +msgid "Deny" +msgstr "拒否" + +#: assets/models/cmd_filter.py:76 +msgid "Reconfirm" +msgstr "再確認" + +#: assets/models/cmd_filter.py:80 +msgid "Filter" +msgstr "フィルター" + +#: assets/models/cmd_filter.py:87 settings/serializers/basic.py:10 +#: xpack/plugins/license/models.py:29 +msgid "Content" +msgstr "コンテンツ" + +#: assets/models/cmd_filter.py:87 +msgid "One line one command" +msgstr "1行1コマンド" + +#: assets/models/cmd_filter.py:88 +msgid "Ignore case" +msgstr "家を無視する" + +#: assets/models/cmd_filter.py:103 +msgid "Command filter rule" +msgstr "コマンドフィルタルール" + +#: assets/models/cmd_filter.py:144 +msgid "The generated regular expression is incorrect: {}" +msgstr "生成された正規表現が正しくありません: {}" + +#: assets/models/cmd_filter.py:170 tickets/const.py:13 +msgid "Command confirm" +msgstr "コマンドの確認" + +#: assets/models/domain.py:72 +msgid "Gateway" +msgstr "ゲートウェイ" + +#: assets/models/domain.py:74 +msgid "Test gateway" +msgstr "テストゲートウェイ" + +#: assets/models/domain.py:130 +#, python-brace-format +msgid "Unable to connect to port {port} on {ip}" +msgstr "{ip} でポート {port} に接続できません" + +#: assets/models/domain.py:133 +msgid "Authentication failed" +msgstr "認証に失敗しました" + +#: assets/models/domain.py:135 assets/models/domain.py:157 +msgid "Connect failed" +msgstr "接続に失敗しました" + +#: assets/models/gathered_user.py:16 +msgid "Present" +msgstr "プレゼント" + +#: assets/models/gathered_user.py:17 +msgid "Date last login" +msgstr "最終ログイン日" + +#: assets/models/gathered_user.py:18 +msgid "IP last login" +msgstr "IP最終ログイン" + +#: assets/models/gathered_user.py:31 +msgid "GatherUser" +msgstr "収集ユーザー" + +#: assets/models/group.py:30 +msgid "Asset group" +msgstr "資産グループ" + +#: assets/models/group.py:34 +msgid "Default asset group" +msgstr "デフォルトアセットグループ" + +#: assets/models/label.py:19 assets/models/node.py:546 settings/models.py:30 +msgid "Value" +msgstr "値" + +#: assets/models/label.py:40 settings/serializers/sms.py:7 +msgid "Label" +msgstr "ラベル" + +#: assets/models/node.py:151 +msgid "New node" +msgstr "新しいノード" + +#: assets/models/node.py:474 users/templates/users/_granted_assets.html:130 +msgid "empty" +msgstr "空" + +#: assets/models/node.py:545 perms/models/asset_permission.py:101 +msgid "Key" +msgstr "キー" + +#: assets/models/node.py:547 assets/serializers/node.py:20 +msgid "Full value" +msgstr "フルバリュー" + +#: assets/models/node.py:550 perms/models/asset_permission.py:102 +msgid "Parent key" +msgstr "親キー" + +#: assets/models/node.py:559 assets/serializers/system_user.py:263 +#: users/templates/users/user_asset_permission.html:41 +#: users/templates/users/user_asset_permission.html:73 +#: users/templates/users/user_asset_permission.html:158 +#: xpack/plugins/cloud/models.py:96 xpack/plugins/cloud/serializers/task.py:69 +msgid "Node" +msgstr "ノード" + +#: assets/models/node.py:562 +msgid "Can match node" +msgstr "ノードを一致させることができます" + +#: assets/models/user.py:216 +msgid "Automatic managed" +msgstr "自動管理" + +#: assets/models/user.py:217 +msgid "Manually input" +msgstr "手動入力" + +#: assets/models/user.py:221 +msgid "Common user" +msgstr "共通ユーザー" + +#: assets/models/user.py:224 +msgid "Username same with user" +msgstr "ユーザーと同じユーザー名" + +#: assets/models/user.py:227 assets/serializers/domain.py:29 +#: terminal/templates/terminal/_msg_command_execute_alert.html:16 +#: xpack/plugins/change_auth_plan/models/asset.py:39 +msgid "Assets" +msgstr "資産" + +#: assets/models/user.py:231 users/apps.py:9 +msgid "Users" +msgstr "ユーザー" + +#: assets/models/user.py:232 +msgid "User groups" +msgstr "ユーザーグループ" + +#: assets/models/user.py:236 +msgid "Auto push" +msgstr "オートプッシュ" + +#: assets/models/user.py:237 +msgid "Sudo" +msgstr "すど" + +#: assets/models/user.py:238 +msgid "Shell" +msgstr "シェル" + +#: assets/models/user.py:239 +msgid "Login mode" +msgstr "ログインモード" + +#: assets/models/user.py:240 +msgid "SFTP Root" +msgstr "SFTPルート" + +#: assets/models/user.py:241 authentication/models.py:48 +msgid "Token" +msgstr "トークン" + +#: assets/models/user.py:242 +msgid "Home" +msgstr "ホーム" + +#: assets/models/user.py:243 +msgid "System groups" +msgstr "システムグループ" + +#: assets/models/user.py:246 +msgid "User switch" +msgstr "ユーザースイッチ" + +#: assets/models/user.py:247 +msgid "Switch from" +msgstr "から切り替え" + +#: assets/models/user.py:327 +msgid "Can match system user" +msgstr "システムユーザーに一致できます" + +#: assets/models/utils.py:35 +#, python-format +msgid "%(value)s is not an even number" +msgstr "%(value)s は偶数ではありません" + +#: assets/notifications.py:8 +msgid "Notification of account backup route task results" +msgstr "アカウントバックアップルートタスクの結果の通知" + +#: assets/notifications.py:18 +msgid "" +"{} - The account backup passage task has been completed. See the attachment " +"for details" +msgstr "{} -アカウントバックアップの通過タスクが完了しました。詳細は添付ファイルをご覧ください" + +#: assets/notifications.py:19 +msgid "" +"{} - The account backup passage task has been completed: the encryption " +"password has not been set - please go to personal information -> file " +"encryption password to set the encryption password" +msgstr "{} -アカウントのバックアップ通過タスクが完了しました: 暗号化パスワードが設定されていません-個人情報にアクセスしてください-> ファイル暗号化パスワードを設定してください暗号化パスワード" + +#: assets/serializers/account.py:40 assets/serializers/account.py:83 +msgid "System user display" +msgstr "システムユーザー表示" + +#: assets/serializers/asset.py:20 +msgid "Protocol format should {}/{}" +msgstr "プロトコル形式は {}/{}" + +#: assets/serializers/asset.py:37 +msgid "Protocol duplicate: {}" +msgstr "プロトコル重複: {}" + +#: assets/serializers/asset.py:66 +msgid "Domain name" +msgstr "ドメイン名" + +#: assets/serializers/asset.py:68 +msgid "Nodes name" +msgstr "ノード名" + +#: assets/serializers/asset.py:71 +msgid "Labels name" +msgstr "ラベル名" + +#: assets/serializers/asset.py:105 +msgid "Hardware info" +msgstr "ハードウェア情報" + +#: assets/serializers/asset.py:106 +msgid "Admin user display" +msgstr "管理者ユーザー表示" + +#: assets/serializers/asset.py:107 +msgid "CPU info" +msgstr "CPU情報" + +#: assets/serializers/backup.py:20 perms/models/base.py:87 +#: perms/serializers/application/permission.py:17 +#: perms/serializers/application/permission.py:42 +#: perms/serializers/asset/permission.py:18 +#: perms/serializers/asset/permission.py:46 +msgid "Actions" +msgstr "アクション" + +#: assets/serializers/backup.py:31 ops/mixin.py:106 ops/mixin.py:147 +#: settings/serializers/auth/ldap.py:59 +#: xpack/plugins/change_auth_plan/serializers/base.py:42 +msgid "Periodic perform" +msgstr "定期的なパフォーマンス" + +#: assets/serializers/backup.py:33 +#: xpack/plugins/change_auth_plan/serializers/base.py:45 +msgid "Currently only mail sending is supported" +msgstr "現在、メール送信のみがサポートされています" + +#: assets/serializers/base.py:36 +msgid "Key password" +msgstr "キーパスワード" + +#: assets/serializers/base.py:49 +msgid "private key invalid or passphrase error" +msgstr "秘密鍵が無効またはpassphraseエラー" + +#: assets/serializers/cmd_filter.py:51 +msgid "Action display" +msgstr "アクション表示" + +#: assets/serializers/domain.py:13 assets/serializers/label.py:12 +#: assets/serializers/system_user.py:59 +#: perms/serializers/asset/permission.py:49 +msgid "Assets amount" +msgstr "資産額" + +#: assets/serializers/domain.py:14 +msgid "Applications amount" +msgstr "申し込み金額" + +#: assets/serializers/domain.py:15 +msgid "Gateways count" +msgstr "ゲートウェイ数" + +#: assets/serializers/node.py:17 +msgid "value" +msgstr "値" + +#: assets/serializers/node.py:31 +msgid "Can't contains: /" +msgstr "含まれない:/" + +#: assets/serializers/node.py:41 +msgid "The same level node name cannot be the same" +msgstr "同じレベルのノード名を同じにすることはできません。" + +#: assets/serializers/system_user.py:28 +msgid "SSH key fingerprint" +msgstr "SSHキー指紋" + +#: assets/serializers/system_user.py:30 +#: perms/serializers/application/permission.py:46 +msgid "Apps amount" +msgstr "アプリの量" + +#: assets/serializers/system_user.py:58 +#: perms/serializers/asset/permission.py:50 +msgid "Nodes amount" +msgstr "ノード量" + +#: assets/serializers/system_user.py:60 assets/serializers/system_user.py:265 +msgid "Login mode display" +msgstr "ログインモード表示" + +#: assets/serializers/system_user.py:62 +msgid "Ad domain" +msgstr "広告ドメイン" + +#: assets/serializers/system_user.py:63 +msgid "Is asset protocol" +msgstr "資産プロトコルです" + +#: assets/serializers/system_user.py:64 +msgid "Only ssh and automatic login system users are supported" +msgstr "sshと自動ログインシステムのユーザーのみがサポートされています" + +#: assets/serializers/system_user.py:104 +msgid "Username same with user with protocol {} only allow 1" +msgstr "プロトコル {} のユーザーと同じユーザー名は1のみ許可します" + +#: assets/serializers/system_user.py:117 common/validators.py:14 +msgid "Special char not allowed" +msgstr "特別なcharは許可されていません" + +#: assets/serializers/system_user.py:127 +msgid "* Automatic login mode must fill in the username." +msgstr "* 自動ログインモードはユーザー名を入力する必要があります。" + +#: assets/serializers/system_user.py:142 +msgid "Path should starts with /" +msgstr "パスは/で始まる必要があります" + +#: assets/serializers/system_user.py:154 +msgid "Password or private key required" +msgstr "パスワードまたは秘密鍵が必要" + +#: assets/serializers/system_user.py:168 +msgid "Only ssh protocol system users are allowed" +msgstr "Sshプロトコルシステムユーザーのみが許可されています" + +#: assets/serializers/system_user.py:172 +msgid "The protocol must be consistent with the current user: {}" +msgstr "プロトコルは現在のユーザーと一致している必要があります: {}" + +#: assets/serializers/system_user.py:176 +msgid "Only system users with automatic login are allowed" +msgstr "自動ログインを持つシステムユーザーのみが許可されます" + +#: assets/serializers/system_user.py:281 +msgid "System user name" +msgstr "システムユーザー名" + +#: assets/serializers/system_user.py:282 orgs/mixins/serializers.py:26 +#: rbac/serializers/rolebinding.py:23 +msgid "Org name" +msgstr "組織名" + +#: assets/serializers/system_user.py:291 +msgid "Asset hostname" +msgstr "資産ホスト名" + +#: assets/serializers/utils.py:9 +msgid "Password can not contains `{{` " +msgstr "パスワードには '{{' を含まない" + +#: assets/tasks/account_connectivity.py:30 +msgid "The asset {} system platform {} does not support run Ansible tasks" +msgstr "資産 {} システムプラットフォーム {} はAnsibleタスクの実行をサポートしていません。" + +#: assets/tasks/account_connectivity.py:107 +msgid "Test account connectivity: " +msgstr "テストアカウント接続:" + +#: assets/tasks/asset_connectivity.py:49 +msgid "Test assets connectivity. " +msgstr "資産の接続性をテストします。" + +#: assets/tasks/asset_connectivity.py:91 assets/tasks/asset_connectivity.py:102 +msgid "Test assets connectivity: " +msgstr "資産の接続性のテスト:" + +#: assets/tasks/asset_connectivity.py:113 +msgid "Test if the assets under the node are connectable: " +msgstr "ノードの下のアセットが接続可能かどうかをテストします。" + +#: assets/tasks/const.py:49 +msgid "Unreachable" +msgstr "達成できない" + +#: assets/tasks/const.py:50 +msgid "Reachable" +msgstr "接続可能" + +#: assets/tasks/gather_asset_hardware_info.py:46 +msgid "Get asset info failed: {}" +msgstr "資産情報の取得に失敗しました: {}" + +#: assets/tasks/gather_asset_hardware_info.py:97 +msgid "Update some assets hardware info. " +msgstr "一部の資産ハードウェア情報を更新します。" + +#: assets/tasks/gather_asset_hardware_info.py:114 +msgid "Update asset hardware info: " +msgstr "資産ハードウェア情報の更新:" + +#: assets/tasks/gather_asset_hardware_info.py:120 +msgid "Update assets hardware info: " +msgstr "資産のハードウェア情報を更新する:" + +#: assets/tasks/gather_asset_hardware_info.py:137 +msgid "Update node asset hardware information: " +msgstr "ノード資産のハードウェア情報を更新します。" + +#: assets/tasks/gather_asset_users.py:111 +msgid "Gather assets users" +msgstr "資産ユーザーの収集" + +#: assets/tasks/nodes_amount.py:27 +msgid "" +"The task of self-checking is already running and cannot be started repeatedly" +msgstr "セルフチェックのタスクはすでに実行されており、繰り返し開始することはできません" + +#: assets/tasks/push_system_user.py:200 +msgid "System user is dynamic: {}" +msgstr "システムユーザーは動的です: {}" + +#: assets/tasks/push_system_user.py:241 +msgid "Start push system user for platform: [{}]" +msgstr "プラットフォームのプッシュシステムユーザーを開始: [{}]" + +#: assets/tasks/push_system_user.py:242 +#: assets/tasks/system_user_connectivity.py:106 +msgid "Hosts count: {}" +msgstr "ホスト数: {}" + +#: assets/tasks/push_system_user.py:259 assets/tasks/push_system_user.py:292 +msgid "Push system users to assets: " +msgstr "システムユーザーを資産にプッシュする:" + +#: assets/tasks/push_system_user.py:271 +msgid "Push system users to asset: " +msgstr "システムユーザーをアセットにプッシュする:" + +#: assets/tasks/system_user_connectivity.py:56 +msgid "Dynamic system user not support test" +msgstr "動的システムユーザーがテストをサポートしていない" + +#: assets/tasks/system_user_connectivity.py:105 +msgid "Start test system user connectivity for platform: [{}]" +msgstr "プラットフォームのテストシステムのユーザー接続を開始: [{}]" + +#: assets/tasks/system_user_connectivity.py:118 +#: assets/tasks/system_user_connectivity.py:129 +msgid "Test system user connectivity: " +msgstr "テストシステムユーザー接続:" + +#: assets/tasks/system_user_connectivity.py:148 +msgid "Test system user connectivity period: " +msgstr "テストシステムユーザー接続期间:" + +#: assets/tasks/utils.py:17 +msgid "Asset has been disabled, skipped: {}" +msgstr "資産が無効化されました。スキップ: {}" + +#: assets/tasks/utils.py:21 +msgid "Asset may not be support ansible, skipped: {}" +msgstr "資産はサポートできない場合があります。スキップ: {}" + +#: assets/tasks/utils.py:39 +msgid "For security, do not push user {}" +msgstr "セキュリティのために、ユーザー {} をプッシュしないでください" + +#: assets/tasks/utils.py:55 +msgid "No assets matched, stop task" +msgstr "一致する資産がない、タスクを停止" + +#: audits/apps.py:9 +msgid "Audits" +msgstr "監査" + +#: audits/models.py:27 audits/models.py:57 +#: authentication/templates/authentication/_access_key_modal.html:65 +#: rbac/tree.py:166 users/templates/users/user_asset_permission.html:128 +#: users/templates/users/user_database_app_permission.html:111 +msgid "Delete" +msgstr "削除" + +#: audits/models.py:28 +msgid "Upload" +msgstr "アップロード" + +#: audits/models.py:29 +msgid "Download" +msgstr "ダウンロード" + +#: audits/models.py:30 +msgid "Rmdir" +msgstr "Rmdir" + +#: audits/models.py:31 +msgid "Rename" +msgstr "名前の変更" + +#: audits/models.py:32 +msgid "Mkdir" +msgstr "Mkdir" + +#: audits/models.py:33 +msgid "Symlink" +msgstr "Symlink" + +#: audits/models.py:38 audits/models.py:64 audits/models.py:87 +#: terminal/models/session.py:49 terminal/models/sharing.py:82 +msgid "Remote addr" +msgstr "リモートaddr" + +#: audits/models.py:41 +msgid "Operate" +msgstr "操作" + +#: audits/models.py:42 +msgid "Filename" +msgstr "ファイル名" + +#: audits/models.py:43 audits/models.py:115 terminal/models/sharing.py:90 +#: xpack/plugins/change_auth_plan/serializers/app.py:87 +#: xpack/plugins/change_auth_plan/serializers/asset.py:197 +msgid "Success" +msgstr "成功" + +#: audits/models.py:47 +msgid "File transfer log" +msgstr "ファイル転送ログ" + +#: audits/models.py:55 +#: authentication/templates/authentication/_access_key_modal.html:22 +#: rbac/tree.py:163 +msgid "Create" +msgstr "作成" + +#: audits/models.py:56 rbac/tree.py:165 templates/_csv_import_export.html:18 +#: templates/_csv_update_modal.html:6 +#: users/templates/users/user_asset_permission.html:127 +#: users/templates/users/user_database_app_permission.html:110 +msgid "Update" +msgstr "更新" + +#: audits/models.py:62 audits/serializers.py:63 +msgid "Resource Type" +msgstr "リソースタイプ" + +#: audits/models.py:63 +msgid "Resource" +msgstr "リソース" + +#: audits/models.py:65 audits/models.py:88 +msgid "Datetime" +msgstr "時間" + +#: audits/models.py:80 +msgid "Operate log" +msgstr "ログの操作" + +#: audits/models.py:86 +msgid "Change by" +msgstr "による変更" + +#: audits/models.py:94 +msgid "Password change log" +msgstr "パスワード変更ログ" + +#: audits/models.py:109 +msgid "Disabled" +msgstr "無効" + +#: audits/models.py:110 settings/models.py:33 +msgid "Enabled" +msgstr "有効化" + +#: audits/models.py:111 +msgid "-" +msgstr "-" + +#: audits/models.py:120 +msgid "Login type" +msgstr "ログインタイプ" + +#: audits/models.py:121 +#: tickets/serializers/ticket/meta/ticket_type/login_confirm.py:14 +msgid "Login ip" +msgstr "ログインIP" + +#: audits/models.py:122 +#: authentication/templates/authentication/_msg_different_city.html:11 +#: tickets/serializers/ticket/meta/ticket_type/login_confirm.py:17 +msgid "Login city" +msgstr "ログイン都市" + +#: audits/models.py:123 audits/serializers.py:44 +msgid "User agent" +msgstr "ユーザーエージェント" + +#: audits/models.py:124 +#: authentication/templates/authentication/_mfa_confirm_modal.html:14 +#: users/forms/profile.py:64 users/models/user.py:678 +#: users/serializers/profile.py:121 +msgid "MFA" +msgstr "MFA" + +#: audits/models.py:126 terminal/models/status.py:33 +#: tickets/models/ticket.py:140 xpack/plugins/cloud/models.py:175 +#: xpack/plugins/cloud/models.py:227 +msgid "Status" +msgstr "ステータス" + +#: audits/models.py:127 +msgid "Date login" +msgstr "日付ログイン" + +#: audits/models.py:128 audits/serializers.py:46 +msgid "Authentication backend" +msgstr "認証バックエンド" + +#: audits/models.py:167 +msgid "User login log" +msgstr "ユーザーログインログ" + +#: audits/serializers.py:14 +msgid "Operate display" +msgstr "ディスプレイを操作する" + +#: audits/serializers.py:30 tickets/serializers/ticket/ticket.py:22 +msgid "Status display" +msgstr "ステータス表示" + +#: audits/serializers.py:31 +msgid "MFA display" +msgstr "MFAディスプレイ" + +#: audits/serializers.py:45 +msgid "Reason display" +msgstr "理由表示" + +#: audits/serializers.py:84 +msgid "Hosts display" +msgstr "ホスト表示" + +#: audits/serializers.py:96 ops/models/command.py:27 +#: xpack/plugins/cloud/models.py:173 +msgid "Result" +msgstr "結果" + +#: audits/serializers.py:98 terminal/serializers/storage.py:161 +msgid "Hosts" +msgstr "ホスト" + +#: audits/serializers.py:99 +msgid "Run as" +msgstr "として実行" + +#: audits/serializers.py:101 +msgid "Run as display" +msgstr "ディスプレイとして実行する" + +#: audits/serializers.py:102 rbac/serializers/rolebinding.py:21 +msgid "User display" +msgstr "ユーザー表示" + +#: audits/signal_handlers.py:67 +msgid "SSH Key" +msgstr "SSHキー" + +#: audits/signal_handlers.py:69 +msgid "SSO" +msgstr "SSO" + +#: audits/signal_handlers.py:70 +msgid "Auth Token" +msgstr "認証トークン" + +#: audits/signal_handlers.py:71 authentication/notifications.py:73 +#: authentication/views/login.py:164 authentication/views/wecom.py:158 +#: notifications/backends/__init__.py:11 users/models/user.py:714 +msgid "WeCom" +msgstr "企業微信" + +#: audits/signal_handlers.py:72 authentication/views/dingtalk.py:160 +#: authentication/views/login.py:170 notifications/backends/__init__.py:12 +#: users/models/user.py:715 +msgid "DingTalk" +msgstr "DingTalk" + +#: audits/signal_handlers.py:106 +msgid "User and Group" +msgstr "ユーザーとグループ" + +#: audits/signal_handlers.py:107 +#, python-brace-format +msgid "{User} JOINED {UserGroup}" +msgstr "{User} に参加 {UserGroup}" + +#: audits/signal_handlers.py:108 +#, python-brace-format +msgid "{User} LEFT {UserGroup}" +msgstr "{User} のそばを通る {UserGroup}" + +#: audits/signal_handlers.py:111 +msgid "Asset and SystemUser" +msgstr "資産およびシステム・ユーザー" + +#: audits/signal_handlers.py:112 +#, python-brace-format +msgid "{Asset} ADD {SystemUser}" +msgstr "{Asset} 追加 {SystemUser}" + +#: audits/signal_handlers.py:113 +#, python-brace-format +msgid "{Asset} REMOVE {SystemUser}" +msgstr "{Asset} 削除 {SystemUser}" + +#: audits/signal_handlers.py:116 +msgid "Node and Asset" +msgstr "ノードと資産" + +#: audits/signal_handlers.py:117 +#, python-brace-format +msgid "{Node} ADD {Asset}" +msgstr "{Node} 追加 {Asset}" + +#: audits/signal_handlers.py:118 +#, python-brace-format +msgid "{Node} REMOVE {Asset}" +msgstr "{Node} 削除 {Asset}" + +#: audits/signal_handlers.py:121 +msgid "User asset permissions" +msgstr "ユーザー資産の権限" + +#: audits/signal_handlers.py:122 +#, python-brace-format +msgid "{AssetPermission} ADD {User}" +msgstr "{AssetPermission} 追加 {User}" + +#: audits/signal_handlers.py:123 +#, python-brace-format +msgid "{AssetPermission} REMOVE {User}" +msgstr "{AssetPermission} 削除 {User}" + +#: audits/signal_handlers.py:126 +msgid "User group asset permissions" +msgstr "ユーザーグループの資産権限" + +#: audits/signal_handlers.py:127 +#, python-brace-format +msgid "{AssetPermission} ADD {UserGroup}" +msgstr "{AssetPermission} 追加 {UserGroup}" + +#: audits/signal_handlers.py:128 +#, python-brace-format +msgid "{AssetPermission} REMOVE {UserGroup}" +msgstr "{AssetPermission} 削除 {UserGroup}" + +#: audits/signal_handlers.py:131 perms/models/asset_permission.py:29 +#: users/templates/users/_user_detail_nav_header.html:31 +msgid "Asset permission" +msgstr "資産権限" + +#: audits/signal_handlers.py:132 +#, python-brace-format +msgid "{AssetPermission} ADD {Asset}" +msgstr "{AssetPermission} 追加 {Asset}" + +#: audits/signal_handlers.py:133 +#, python-brace-format +msgid "{AssetPermission} REMOVE {Asset}" +msgstr "{AssetPermission} 削除 {Asset}" + +#: audits/signal_handlers.py:136 +msgid "Node permission" +msgstr "ノード権限" + +#: audits/signal_handlers.py:137 +#, python-brace-format +msgid "{AssetPermission} ADD {Node}" +msgstr "{AssetPermission} 追加 {Node}" + +#: audits/signal_handlers.py:138 +#, python-brace-format +msgid "{AssetPermission} REMOVE {Node}" +msgstr "{AssetPermission} 削除 {Node}" + +#: audits/signal_handlers.py:141 +msgid "Asset permission and SystemUser" +msgstr "資産権限とSystemUser" + +#: audits/signal_handlers.py:142 +#, python-brace-format +msgid "{AssetPermission} ADD {SystemUser}" +msgstr "{AssetPermission} 追加 {SystemUser}" + +#: audits/signal_handlers.py:143 +#, python-brace-format +msgid "{AssetPermission} REMOVE {SystemUser}" +msgstr "{AssetPermission} 削除 {SystemUser}" + +#: audits/signal_handlers.py:146 +msgid "User application permissions" +msgstr "ユーザーアプリケーションの権限" + +#: audits/signal_handlers.py:147 +#, python-brace-format +msgid "{ApplicationPermission} ADD {User}" +msgstr "{ApplicationPermission} 追加 {User}" + +#: audits/signal_handlers.py:148 +#, python-brace-format +msgid "{ApplicationPermission} REMOVE {User}" +msgstr "{ApplicationPermission} 削除 {User}" + +#: audits/signal_handlers.py:151 +msgid "User group application permissions" +msgstr "ユーザーグループアプリケーションの権限" + +#: audits/signal_handlers.py:152 +#, python-brace-format +msgid "{ApplicationPermission} ADD {UserGroup}" +msgstr "{ApplicationPermission} 追加 {UserGroup}" + +#: audits/signal_handlers.py:153 +#, python-brace-format +msgid "{ApplicationPermission} REMOVE {UserGroup}" +msgstr "{ApplicationPermission} 削除 {UserGroup}" + +#: audits/signal_handlers.py:156 perms/models/application_permission.py:38 +msgid "Application permission" +msgstr "申請許可" + +#: audits/signal_handlers.py:157 +#, python-brace-format +msgid "{ApplicationPermission} ADD {Application}" +msgstr "{ApplicationPermission} 追加 {Application}" + +#: audits/signal_handlers.py:158 +#, python-brace-format +msgid "{ApplicationPermission} REMOVE {Application}" +msgstr "{ApplicationPermission} 削除 {Application}" + +#: audits/signal_handlers.py:161 +msgid "Application permission and SystemUser" +msgstr "アプリケーション権限とSystemUser" + +#: audits/signal_handlers.py:162 +#, python-brace-format +msgid "{ApplicationPermission} ADD {SystemUser}" +msgstr "{ApplicationPermission} 追加 {SystemUser}" + +#: audits/signal_handlers.py:163 +#, python-brace-format +msgid "{ApplicationPermission} REMOVE {SystemUser}" +msgstr "{ApplicationPermission} 削除 {SystemUser}" + +#: authentication/api/connection_token.py:296 +msgid "Invalid token" +msgstr "無効なトークン" + +#: authentication/api/mfa.py:64 +msgid "Current user not support mfa type: {}" +msgstr "現在のユーザーはmfaタイプをサポートしていません: {}" + +#: authentication/api/mfa.py:111 +msgid "Code is invalid, {}" +msgstr "コードが無効です。{}" + +#: authentication/apps.py:7 +msgid "Authentication" +msgstr "認証" + +#: authentication/backends/drf.py:56 +msgid "Invalid signature header. No credentials provided." +msgstr "署名ヘッダーが無効です。資格情報は提供されていません。" + +#: authentication/backends/drf.py:59 +msgid "Invalid signature header. Signature string should not contain spaces." +msgstr "署名ヘッダーが無効です。署名文字列にはスペースを含まないでください。" + +#: authentication/backends/drf.py:66 +msgid "Invalid signature header. Format like AccessKeyId:Signature" +msgstr "署名ヘッダーが無効です。AccessKeyIdのような形式: Signature" + +#: authentication/backends/drf.py:70 +msgid "" +"Invalid signature header. Signature string should not contain invalid " +"characters." +msgstr "署名ヘッダーが無効です。署名文字列に無効な文字を含めることはできません。" + +#: authentication/backends/drf.py:90 authentication/backends/drf.py:106 +msgid "Invalid signature." +msgstr "署名が無効です。" + +#: authentication/backends/drf.py:97 +msgid "HTTP header: Date not provide or not %a, %d %b %Y %H:%M:%S GMT" +msgstr "" + +#: authentication/backends/drf.py:102 +msgid "Expired, more than 15 minutes" +msgstr "期限切れ、15分以上" + +#: authentication/backends/drf.py:109 +msgid "User disabled." +msgstr "ユーザーが無効になりました。" + +#: authentication/backends/drf.py:127 +msgid "Invalid token header. No credentials provided." +msgstr "無効なトークンヘッダー。資格情報は提供されていません。" + +#: authentication/backends/drf.py:130 +msgid "Invalid token header. Sign string should not contain spaces." +msgstr "無効なトークンヘッダー。記号文字列にはスペースを含めないでください。" + +#: authentication/backends/drf.py:137 +msgid "" +"Invalid token header. Sign string should not contain invalid characters." +msgstr "無効なトークンヘッダー。署名文字列に無効な文字を含めることはできません。" + +#: authentication/backends/drf.py:148 +msgid "Invalid token or cache refreshed." +msgstr "無効なトークンまたはキャッシュの更新。" + +#: authentication/errors.py:26 +msgid "Username/password check failed" +msgstr "ユーザー名/パスワードのチェックに失敗しました" + +#: authentication/errors.py:27 +msgid "Password decrypt failed" +msgstr "パスワードの復号化に失敗しました" + +#: authentication/errors.py:28 +msgid "MFA failed" +msgstr "MFAに失敗しました" + +#: authentication/errors.py:29 +msgid "MFA unset" +msgstr "MFAセットなし" + +#: authentication/errors.py:30 +msgid "Username does not exist" +msgstr "ユーザー名が存在しません" + +#: authentication/errors.py:31 +msgid "Password expired" +msgstr "パスワード期限切れ" + +#: authentication/errors.py:32 +msgid "Disabled or expired" +msgstr "無効または期限切れ" + +#: authentication/errors.py:33 +msgid "This account is inactive." +msgstr "このアカウントは非アクティブです。" + +#: authentication/errors.py:34 +msgid "This account is expired" +msgstr "このアカウントは期限切れです" + +#: authentication/errors.py:35 +msgid "Auth backend not match" +msgstr "Authバックエンドが一致しない" + +#: authentication/errors.py:36 +msgid "ACL is not allowed" +msgstr "ACLは許可されません" + +#: authentication/errors.py:37 +msgid "Only local users are allowed" +msgstr "ローカルユーザーのみが許可されています" + +#: authentication/errors.py:47 +msgid "No session found, check your cookie" +msgstr "セッションが見つかりませんでした。クッキーを確認してください" + +#: authentication/errors.py:49 +#, python-brace-format +msgid "" +"The username or password you entered is incorrect, please enter it again. " +"You can also try {times_try} times (The account will be temporarily locked " +"for {block_time} minutes)" +msgstr "入力したユーザー名またはパスワードが正しくありません。再度入力してください。 {times_try} 回試すこともできます (アカウントは {block_time} 分の間一時的にロックされます)" + +#: authentication/errors.py:55 authentication/errors.py:63 +msgid "" +"The account has been locked (please contact admin to unlock it or try again " +"after {} minutes)" +msgstr "アカウントがロックされています (管理者に連絡してロックを解除するか、 {} 分後にもう一度お試しください)" + +#: authentication/errors.py:59 +msgid "" +"The ip has been locked (please contact admin to unlock it or try again after " +"{} minutes)" +msgstr "IPがロックされています (管理者に連絡してロックを解除するか、 {} 分後にもう一度お試しください)" + +#: authentication/errors.py:67 +#, python-brace-format +msgid "" +"{error}, You can also try {times_try} times (The account will be temporarily " +"locked for {block_time} minutes)" +msgstr "{error},{times_try} 回も試すことができます (アカウントは {block_time} 分の間一時的にロックされます)" + +#: authentication/errors.py:71 +msgid "MFA required" +msgstr "MFAが必要" + +#: authentication/errors.py:72 +msgid "MFA not set, please set it first" +msgstr "MFAをセットしない、最初にセットしてください" + +#: authentication/errors.py:73 +msgid "Login confirm required" +msgstr "ログイン確認が必要" + +#: authentication/errors.py:74 +msgid "Wait login confirm ticket for accept" +msgstr "受け入れのためのログイン確認チケットを待つ" + +#: authentication/errors.py:75 +msgid "Login confirm ticket was {}" +msgstr "ログイン確認チケットは {} でした" + +#: authentication/errors.py:255 +msgid "IP is not allowed" +msgstr "IPは許可されていません" + +#: authentication/errors.py:262 +msgid "Time Period is not allowed" +msgstr "期間は許可されていません" + +#: authentication/errors.py:295 +msgid "SSO auth closed" +msgstr "SSO authは閉鎖されました" + +#: authentication/errors.py:300 authentication/mixins.py:372 +msgid "Your password is too simple, please change it for security" +msgstr "パスワードがシンプルすぎるので、セキュリティのために変更してください" + +#: authentication/errors.py:309 authentication/mixins.py:379 +msgid "You should to change your password before login" +msgstr "ログインする前にパスワードを変更する必要があります" + +#: authentication/errors.py:318 authentication/mixins.py:386 +msgid "Your password has expired, please reset before logging in" +msgstr "パスワードの有効期限が切れました。ログインする前にリセットしてください。" + +#: authentication/errors.py:352 +msgid "Your password is invalid" +msgstr "パスワードが無効です" + +#: authentication/errors.py:357 +msgid "Please enter MFA code" +msgstr "MFAコードを入力してください" + +#: authentication/errors.py:362 +msgid "Please enter SMS code" +msgstr "SMSコードを入力してください" + +#: authentication/errors.py:367 users/exceptions.py:15 +msgid "Phone not set" +msgstr "電話が設定されていない" + +#: authentication/forms.py:35 +msgid "{} days auto login" +msgstr "{} 日自動ログイン" + +#: authentication/forms.py:46 +msgid "MFA Code" +msgstr "MFAコード" + +#: authentication/forms.py:47 +msgid "MFA type" +msgstr "MFAタイプ" + +#: authentication/forms.py:60 users/forms/profile.py:27 +msgid "MFA code" +msgstr "MFAコード" + +#: authentication/forms.py:62 +msgid "Dynamic code" +msgstr "動的コード" + +#: authentication/mfa/base.py:7 +msgid "Please input security code" +msgstr "セキュリティコードを入力してください" + +#: authentication/mfa/otp.py:7 +msgid "OTP code invalid, or server time error" +msgstr "OTPコードが無効、またはサーバー時間エラー" + +#: authentication/mfa/otp.py:12 +msgid "OTP" +msgstr "OTP" + +#: authentication/mfa/otp.py:13 +msgid "OTP verification code" +msgstr "OTP検証コード" + +#: authentication/mfa/otp.py:48 +msgid "Virtual OTP based MFA" +msgstr "仮想OTPベースのMFA" + +#: authentication/mfa/radius.py:7 +msgid "Radius verify code invalid" +msgstr "Radius verifyコードが無効" + +#: authentication/mfa/radius.py:13 +msgid "Radius verification code" +msgstr "半径確認コード" + +#: authentication/mfa/radius.py:44 +msgid "Radius global enabled, cannot disable" +msgstr "Radius globalが有効になり、無効にできません" + +#: authentication/mfa/sms.py:7 +msgid "SMS verify code invalid" +msgstr "SMS検証コードが無効" + +#: authentication/mfa/sms.py:12 +msgid "SMS" +msgstr "SMS" + +#: authentication/mfa/sms.py:13 +msgid "SMS verification code" +msgstr "SMS確認コード" + +#: authentication/mfa/sms.py:57 +msgid "Set phone number to enable" +msgstr "電話番号を設定して有効にする" + +#: authentication/mfa/sms.py:61 +msgid "Clear phone number to disable" +msgstr "無効にする電話番号をクリアする" + +#: authentication/mixins.py:322 +msgid "The MFA type ({}) is not enabled" +msgstr "MFAタイプ ({}) が有効になっていない" + +#: authentication/mixins.py:362 +msgid "Please change your password" +msgstr "パスワードを変更してください" + +#: authentication/models.py:33 terminal/serializers/storage.py:30 +msgid "Access key" +msgstr "アクセスキー" + +#: authentication/models.py:40 +msgid "Private Token" +msgstr "プライベートトークン" + +#: authentication/models.py:49 +msgid "Expired" +msgstr "期限切れ" + +#: authentication/models.py:53 +msgid "SSO token" +msgstr "" + +#: authentication/models.py:61 +msgid "Connection token" +msgstr "接続トークン" + +#: authentication/models.py:63 +msgid "Can view connection token secret" +msgstr "接続トークンの秘密を表示できます" + +#: authentication/models.py:70 +msgid "Super connection token" +msgstr "スーパー接続トークン" + +#: authentication/notifications.py:19 +msgid "Different city login reminder" +msgstr "異なる都市ログインのリマインダー" + +#: authentication/notifications.py:52 +msgid "binding reminder" +msgstr "バインディングリマインダー" + +#: authentication/templates/authentication/_access_key_modal.html:6 +msgid "API key list" +msgstr "APIキーリスト" + +#: authentication/templates/authentication/_access_key_modal.html:18 +msgid "Using api key sign api header, every requests header difference" +msgstr "APIキー記号APIヘッダーを使用すると、すべてのリクエストヘッダーの違い" + +#: authentication/templates/authentication/_access_key_modal.html:19 +msgid "docs" +msgstr "ドキュメント" + +#: authentication/templates/authentication/_access_key_modal.html:30 +#: users/serializers/group.py:35 +msgid "ID" +msgstr "ID" + +#: authentication/templates/authentication/_access_key_modal.html:31 +#: settings/serializers/auth/radius.py:17 +msgid "Secret" +msgstr "秘密" + +#: authentication/templates/authentication/_access_key_modal.html:33 +#: terminal/notifications.py:93 terminal/notifications.py:141 +msgid "Date" +msgstr "日付" + +#: authentication/templates/authentication/_access_key_modal.html:48 +#: users/templates/users/_granted_assets.html:75 +msgid "Show" +msgstr "表示" + +#: authentication/templates/authentication/_access_key_modal.html:66 +#: settings/serializers/security.py:39 users/models/user.py:550 +#: users/serializers/profile.py:111 users/templates/users/mfa_setting.html:61 +#: users/templates/users/user_verify_mfa.html:36 +msgid "Disable" +msgstr "無効化" + +#: authentication/templates/authentication/_access_key_modal.html:67 +#: users/models/user.py:551 users/serializers/profile.py:112 +#: users/templates/users/mfa_setting.html:26 +#: users/templates/users/mfa_setting.html:68 +msgid "Enable" +msgstr "有効化" + +#: authentication/templates/authentication/_access_key_modal.html:147 +msgid "Delete success" +msgstr "削除成功" + +#: authentication/templates/authentication/_access_key_modal.html:155 +#: authentication/templates/authentication/_mfa_confirm_modal.html:53 +#: templates/_modal.html:22 tickets/const.py:36 +msgid "Close" +msgstr "閉じる" + +#: authentication/templates/authentication/_captcha_field.html:8 +msgid "Play CAPTCHA as audio file" +msgstr "CAPTCHAをオーディオファイルとして再生する" + +#: authentication/templates/authentication/_captcha_field.html:15 +#: users/forms/profile.py:102 +msgid "Captcha" +msgstr "キャプチャ" + +#: authentication/templates/authentication/_mfa_confirm_modal.html:5 +msgid "MFA confirm" +msgstr "MFA確認" + +#: authentication/templates/authentication/_mfa_confirm_modal.html:17 +msgid "Need MFA for view auth" +msgstr "ビューオートのためにMFAが必要" + +#: authentication/templates/authentication/_mfa_confirm_modal.html:20 +#: templates/_modal.html:23 templates/flash_message_standalone.html:34 +#: users/templates/users/user_password_verify.html:20 +msgid "Confirm" +msgstr "確認" + +#: authentication/templates/authentication/_mfa_confirm_modal.html:25 +msgid "Code error" +msgstr "コードエラー" + +#: authentication/templates/authentication/_msg_different_city.html:3 +#: authentication/templates/authentication/_msg_oauth_bind.html:3 +#: 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:293 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 +#: users/templates/users/_msg_account_expire_reminder.html:4 +#: users/templates/users/_msg_password_expire_reminder.html:4 +#: users/templates/users/_msg_reset_mfa.html:4 +#: users/templates/users/_msg_reset_ssh_key.html:4 +msgid "Hello" +msgstr "こんにちは" + +#: authentication/templates/authentication/_msg_different_city.html:6 +msgid "Your account has remote login behavior, please pay attention" +msgstr "アカウントにリモートログイン動作があります。注意してください" + +#: authentication/templates/authentication/_msg_different_city.html:10 +msgid "Login time" +msgstr "ログイン時間" + +#: authentication/templates/authentication/_msg_different_city.html:16 +msgid "" +"If you suspect that the login behavior is abnormal, please modify the " +"account password in time." +msgstr "ログイン動作が異常であると疑われる場合は、時間内にアカウントのパスワードを変更してください。" + +#: authentication/templates/authentication/_msg_oauth_bind.html:6 +msgid "Your account has just been bound to" +msgstr "アカウントはにバインドされています" + +#: authentication/templates/authentication/_msg_oauth_bind.html:17 +msgid "If the operation is not your own, unbind and change the password." +msgstr "操作が独自のものでない場合は、パスワードをバインド解除して変更します。" + +#: authentication/templates/authentication/_msg_reset_password.html:6 +msgid "" +"Please click the link below to reset your password, if not your request, " +"concern your account security" +msgstr "下のリンクをクリックしてパスワードをリセットしてください。リクエストがない場合は、アカウントのセキュリティに関係します。" + +#: authentication/templates/authentication/_msg_reset_password.html:10 +msgid "Click here reset password" +msgstr "ここをクリックしてパスワードをリセット" + +#: authentication/templates/authentication/_msg_reset_password.html:16 +#: users/templates/users/_msg_user_created.html:22 +msgid "This link is valid for 1 hour. After it expires" +msgstr "このリンクは1時間有効です。有効期限が切れた後" + +#: authentication/templates/authentication/_msg_reset_password.html:17 +#: users/templates/users/_msg_user_created.html:23 +msgid "request new one" +msgstr "新しいものを要求する" + +#: authentication/templates/authentication/_msg_rest_password_success.html:5 +msgid "Your password has just been successfully updated" +msgstr "パスワードが正常に更新されました" + +#: authentication/templates/authentication/_msg_rest_password_success.html:9 +#: authentication/templates/authentication/_msg_rest_public_key_success.html:9 +msgid "Browser" +msgstr "ブラウザ" + +#: authentication/templates/authentication/_msg_rest_password_success.html:13 +msgid "" +"If the password update was not initiated by you, your account may have " +"security issues" +msgstr "パスワードの更新が開始されなかった場合、アカウントにセキュリティ上の問題がある可能性があります" + +#: authentication/templates/authentication/_msg_rest_password_success.html:14 +#: authentication/templates/authentication/_msg_rest_public_key_success.html:14 +msgid "If you have any questions, you can contact the administrator" +msgstr "質問があれば、管理者に連絡できます" + +#: authentication/templates/authentication/_msg_rest_public_key_success.html:5 +msgid "Your public key has just been successfully updated" +msgstr "公開鍵が正常に更新されました" + +#: authentication/templates/authentication/_msg_rest_public_key_success.html:13 +msgid "" +"If the public key update was not initiated by you, your account may have " +"security issues" +msgstr "公開鍵の更新が開始されなかった場合、アカウントにセキュリティ上の問題がある可能性があります" + +#: authentication/templates/authentication/login.html:170 +msgid "Welcome back, please enter username and password to login" +msgstr "おかえりなさい、ログインするためにユーザー名とパスワードを入力してください" + +#: authentication/templates/authentication/login.html:206 +#: users/templates/users/forgot_password.html:15 +#: users/templates/users/forgot_password.html:16 +msgid "Forgot password" +msgstr "パスワードを忘れた" + +#: authentication/templates/authentication/login.html:213 +#: templates/_header_bar.html:83 +msgid "Login" +msgstr "ログイン" + +#: authentication/templates/authentication/login.html:220 +msgid "More login options" +msgstr "その他のログインオプション" + +#: authentication/templates/authentication/login_mfa.html:6 +msgid "MFA Auth" +msgstr "MFA マルチファクタ認証" + +#: authentication/templates/authentication/login_mfa.html:19 +#: users/templates/users/user_otp_check_password.html:12 +#: users/templates/users/user_otp_enable_bind.html:24 +#: users/templates/users/user_otp_enable_install_app.html:29 +#: users/templates/users/user_verify_mfa.html:30 +msgid "Next" +msgstr "次へ" + +#: authentication/templates/authentication/login_mfa.html:22 +msgid "Can't provide security? Please contact the administrator!" +msgstr "セキュリティを提供できませんか? 管理者に連絡してください!" + +#: authentication/templates/authentication/login_wait_confirm.html:41 +msgid "Refresh" +msgstr "リフレッシュ" + +#: authentication/templates/authentication/login_wait_confirm.html:46 +msgid "Copy link" +msgstr "リンクのコピー" + +#: authentication/templates/authentication/login_wait_confirm.html:51 +msgid "Return" +msgstr "返品" + +#: authentication/templates/authentication/login_wait_confirm.html:113 +msgid "Copy success" +msgstr "コピー成功" + +#: authentication/views/dingtalk.py:39 +msgid "DingTalk Error, Please contact your system administrator" +msgstr "DingTalkエラー、システム管理者に連絡してください" + +#: authentication/views/dingtalk.py:42 +msgid "DingTalk Error" +msgstr "DingTalkエラー" + +#: authentication/views/dingtalk.py:54 authentication/views/feishu.py:50 +#: authentication/views/wecom.py:54 +msgid "" +"The system configuration is incorrect. Please contact your administrator" +msgstr "システム設定が正しくありません。管理者に連絡してください" + +#: authentication/views/dingtalk.py:92 +msgid "DingTalk is already bound" +msgstr "DingTalkはすでにバインドされています" + +#: authentication/views/dingtalk.py:105 authentication/views/feishu.py:99 +#: authentication/views/wecom.py:104 +msgid "Please verify your password first" +msgstr "最初にパスワードを確認してください" + +#: authentication/views/dingtalk.py:129 authentication/views/wecom.py:128 +msgid "Invalid user_id" +msgstr "無効なuser_id" + +#: authentication/views/dingtalk.py:145 +msgid "DingTalk query user failed" +msgstr "DingTalkクエリユーザーが失敗しました" + +#: authentication/views/dingtalk.py:154 +msgid "The DingTalk is already bound to another user" +msgstr "DingTalkはすでに別のユーザーにバインドされています" + +#: authentication/views/dingtalk.py:161 +msgid "Binding DingTalk successfully" +msgstr "DingTalkのバインドに成功" + +#: authentication/views/dingtalk.py:213 +msgid "Failed to get user from DingTalk" +msgstr "DingTalkからユーザーを取得できませんでした" + +#: authentication/views/dingtalk.py:219 +msgid "DingTalk is not bound" +msgstr "DingTalkはバインドされていません" + +#: authentication/views/dingtalk.py:220 +msgid "Please login with a password and then bind the DingTalk" +msgstr "パスワードでログインし、DingTalkをバインドしてください" + +#: authentication/views/feishu.py:38 +msgid "FeiShu Error" +msgstr "FeiShuエラー" + +#: authentication/views/feishu.py:86 +msgid "FeiShu is already bound" +msgstr "FeiShuはすでにバインドされています" + +#: authentication/views/feishu.py:133 +msgid "FeiShu query user failed" +msgstr "FeiShuクエリユーザーが失敗しました" + +#: authentication/views/feishu.py:142 +msgid "The FeiShu is already bound to another user" +msgstr "FeiShuはすでに別のユーザーにバインドされています" + +#: authentication/views/feishu.py:148 authentication/views/login.py:176 +#: notifications/backends/__init__.py:14 users/models/user.py:716 +msgid "FeiShu" +msgstr "本を飛ばす" + +#: authentication/views/feishu.py:149 +msgid "Binding FeiShu successfully" +msgstr "本を飛ばすのバインドに成功" + +#: authentication/views/feishu.py:200 +msgid "Failed to get user from FeiShu" +msgstr "本を飛ばすからユーザーを取得できませんでした" + +#: authentication/views/feishu.py:206 +msgid "FeiShu is not bound" +msgstr "本を飛ばすは拘束されていません" + +#: authentication/views/feishu.py:207 +msgid "Please login with a password and then bind the FeiShu" +msgstr "パスワードでログインしてから本を飛ばすをバインドしてください" + +#: authentication/views/login.py:70 +msgid "Redirecting" +msgstr "リダイレクト" + +#: authentication/views/login.py:71 +msgid "Redirecting to {} authentication" +msgstr "{} 認証へのリダイレクト" + +#: authentication/views/login.py:94 +msgid "Please enable cookies and try again." +msgstr "クッキーを有効にして、もう一度お試しください。" + +#: authentication/views/login.py:263 +msgid "" +"Wait for {} confirm, You also can copy link to her/him
\n" +" Don't close this page" +msgstr "{} 確認を待ちます。彼女/彼へのリンクをコピーすることもできます
\n" +" このページを閉じないでください" + +#: authentication/views/login.py:268 +msgid "No ticket found" +msgstr "チケットが見つかりません" + +#: authentication/views/login.py:302 +msgid "Logout success" +msgstr "ログアウト成功" + +#: authentication/views/login.py:303 +msgid "Logout success, return login page" +msgstr "ログアウト成功、ログインページを返す" + +#: authentication/views/wecom.py:39 +msgid "WeCom Error, Please contact your system administrator" +msgstr "企業微信エラー、システム管理者に連絡してください" + +#: authentication/views/wecom.py:42 +msgid "WeCom Error" +msgstr "企業微信エラー" + +#: authentication/views/wecom.py:91 +msgid "WeCom is already bound" +msgstr "企業の微信はすでにバインドされています" + +#: authentication/views/wecom.py:143 +msgid "WeCom query user failed" +msgstr "企業微信ユーザーの問合せに失敗しました" + +#: authentication/views/wecom.py:152 +msgid "The WeCom is already bound to another user" +msgstr "この企業の微信はすでに他のユーザーをバインドしている。" + +#: authentication/views/wecom.py:159 +msgid "Binding WeCom successfully" +msgstr "企業の微信のバインドに成功" + +#: authentication/views/wecom.py:208 +msgid "Failed to get user from WeCom" +msgstr "企業の微信からユーザーを取得できませんでした" + +#: authentication/views/wecom.py:214 +msgid "WeCom is not bound" +msgstr "企業の微信をバインドしていません" + +#: authentication/views/wecom.py:215 +msgid "Please login with a password and then bind the WeCom" +msgstr "パスワードでログインしてからWeComをバインドしてください" + +#: common/const/__init__.py:6 +#, python-format +msgid "%(name)s was created successfully" +msgstr "%(name)s が正常に作成されました" + +#: common/const/__init__.py:7 +#, python-format +msgid "%(name)s was updated successfully" +msgstr "%(name)s は正常に更新されました" + +#: common/db/encoder.py:17 +msgid "ugettext_lazy" +msgstr "" + +#: common/db/models.py:112 +msgid "Updated by" +msgstr "によって更新" + +#: common/drf/exc_handlers.py:25 +msgid "Object" +msgstr "オブジェクト" + +#: common/drf/parsers/base.py:17 +msgid "The file content overflowed (The maximum length `{}` bytes)" +msgstr "ファイルの内容がオーバーフローしました (最大長 '{}' バイト)" + +#: common/drf/parsers/base.py:153 +msgid "Parse file error: {}" +msgstr "解析ファイルエラー: {}" + +#: common/exceptions.py:15 +#, python-format +msgid "%s object does not exist." +msgstr "%s オブジェクトは存在しません。" + +#: common/exceptions.py:25 +msgid "Someone else is doing this. Please wait for complete" +msgstr "他の誰かがこれをやっています。完了をお待ちください" + +#: common/exceptions.py:30 +msgid "Your request timeout" +msgstr "リクエストのタイムアウト" + +#: common/exceptions.py:35 +msgid "M2M reverse not allowed" +msgstr "M2Mリバースは許可されません" + +#: common/exceptions.py:41 +msgid "Is referenced by other objects and cannot be deleted" +msgstr "他のオブジェクトによって参照され、削除できません。" + +#: common/exceptions.py:47 +msgid "This action require verify your MFA" +msgstr "このアクションでは、MFAの確認が必要です。" + +#: common/exceptions.py:53 +msgid "Unexpect error occur" +msgstr "予期しないエラーが発生します" + +#: common/fields/model.py:80 +msgid "Marshal dict data to char field" +msgstr "チャーフィールドへのマーシャルディクトデータ" + +#: common/fields/model.py:84 +msgid "Marshal dict data to text field" +msgstr "テキストフィールドへのマーシャルディクトデータ" + +#: common/fields/model.py:96 +msgid "Marshal list data to char field" +msgstr "元帥リストデータをチャーフィールドに" + +#: common/fields/model.py:100 +msgid "Marshal list data to text field" +msgstr "マーシャルリストデータをテキストフィールドに" + +#: common/fields/model.py:104 +msgid "Marshal data to char field" +msgstr "チャーフィールドへのマーシャルデータ" + +#: common/fields/model.py:108 +msgid "Marshal data to text field" +msgstr "テキストフィールドへのマーシャルデータ" + +#: common/fields/model.py:150 +msgid "Encrypt field using Secret Key" +msgstr "Secret Keyを使用したフィールドの暗号化" + +#: common/mixins/api/action.py:52 +msgid "Request file format may be wrong" +msgstr "リクエストファイルの形式が間違っている可能性があります" + +#: common/mixins/models.py:33 +msgid "is discard" +msgstr "は破棄されます" + +#: common/mixins/models.py:34 +msgid "discard time" +msgstr "時間を捨てる" + +#: common/sdk/im/exceptions.py:23 +msgid "Network error, please contact system administrator" +msgstr "ネットワークエラー、システム管理者に連絡してください" + +#: common/sdk/im/wecom/__init__.py:15 +msgid "WeCom error, please contact system administrator" +msgstr "企業微信エラー、システム管理者に連絡してください" + +#: common/sdk/sms/alibaba.py:56 +msgid "Signature does not match" +msgstr "署名が一致しない" + +#: common/sdk/sms/endpoint.py:16 +msgid "Alibaba cloud" +msgstr "アリ雲" + +#: common/sdk/sms/endpoint.py:17 +msgid "Tencent cloud" +msgstr "テンセント雲" + +#: common/sdk/sms/endpoint.py:28 +msgid "SMS provider not support: {}" +msgstr "SMSプロバイダーはサポートしていません: {}" + +#: common/sdk/sms/endpoint.py:49 +msgid "SMS verification code signature or template invalid" +msgstr "SMS検証コードの署名またはテンプレートが無効" + +#: common/sdk/sms/utils.py:15 +msgid "The verification code has expired. Please resend it" +msgstr "確認コードの有効期限が切れています。再送信してください" + +#: common/sdk/sms/utils.py:20 +msgid "The verification code is incorrect" +msgstr "確認コードが正しくありません" + +#: common/sdk/sms/utils.py:25 +msgid "Please wait {} seconds before sending" +msgstr "{} 秒待ってから送信してください" + +#: common/utils/geoip/utils.py:17 common/utils/geoip/utils.py:30 +msgid "Invalid ip" +msgstr "無効なIP" + +#: common/utils/geoip/utils.py:28 +msgid "LAN" +msgstr "LAN" + +#: common/utils/geoip/utils.py:35 common/utils/geoip/utils.py:45 +msgid "Unknown ip" +msgstr "不明なip" + +#: common/validators.py:32 +msgid "This field must be unique." +msgstr "このフィールドは一意である必要があります。" + +#: common/validators.py:40 +msgid "Should not contains special characters" +msgstr "特殊文字を含むべきではない" + +#: common/validators.py:46 +msgid "The mobile phone number format is incorrect" +msgstr "携帯電話番号の形式が正しくありません" + +#: jumpserver/conf.py:292 +msgid "Create account successfully" +msgstr "アカウントを正常に作成" + +#: jumpserver/conf.py:294 +msgid "Your account has been created successfully" +msgstr "アカウントが正常に作成されました" + +#: jumpserver/context_processor.py:17 +msgid "JumpServer Open Source Bastion Host" +msgstr "JumpServer オープンソースの要塞ホスト" + +#: jumpserver/views/celery_flower.py:23 +msgid "

Flower service unavailable, check it

" +msgstr "

フラワーサービス利用不可、チェック

" + +#: jumpserver/views/other.py:26 +msgid "" +"
Luna is a separately deployed program, you need to deploy Luna, koko, " +"configure nginx for url distribution,
If you see this page, " +"prove that you are not accessing the nginx listening port. Good luck." +msgstr "
Lunaは個別にデプロイされたプログラムです。Luna、kokoをデプロイする必要があります。urlディストリビューションにnginxを設定します。
このページが表示されている場合は、nginxリスニングポートにアクセスしていないことを証明してください。頑張ってください。" + +#: jumpserver/views/other.py:70 +msgid "Websocket server run on port: {}, you should proxy it on nginx" +msgstr "Websocket サーバーはport: {}で実行されます。nginxでプロキシする必要があります。" + +#: jumpserver/views/other.py:84 +msgid "" +"
Koko is a separately deployed program, you need to deploy Koko, " +"configure nginx for url distribution,
If you see this page, " +"prove that you are not accessing the nginx listening port. Good luck." +msgstr "
Kokoは個別にデプロイされているプログラムです。Kokoをデプロイする必要があります。URL配布用にnginxを設定します。
このページが表示されている場合は、nginxリスニングポートにアクセスしていないことを証明してください。頑張ってください。" + +#: notifications/apps.py:7 +msgid "Notifications" +msgstr "通知" + +#: notifications/backends/__init__.py:10 users/forms/profile.py:101 +#: users/models/user.py:657 +msgid "Email" +msgstr "メール" + +#: notifications/backends/__init__.py:13 +msgid "Site message" +msgstr "サイトメッセージ" + +#: ops/api/celery.py:61 ops/api/celery.py:76 +msgid "Waiting task start" +msgstr "タスク開始待ち" + +#: ops/api/command.py:56 +msgid "Not has host {} permission" +msgstr "ホスト {} 権限がありません" + +#: ops/apps.py:9 ops/notifications.py:16 +msgid "App ops" +msgstr "アプリ操作" + +#: ops/mixin.py:29 ops/mixin.py:92 ops/mixin.py:162 +#: settings/serializers/auth/ldap.py:66 +msgid "Cycle perform" +msgstr "サイクル実行" + +#: ops/mixin.py:33 ops/mixin.py:90 ops/mixin.py:109 ops/mixin.py:150 +#: settings/serializers/auth/ldap.py:63 +msgid "Regularly perform" +msgstr "定期的に実行する" + +#: ops/mixin.py:112 +msgid "Interval" +msgstr "間隔" + +#: ops/mixin.py:122 +msgid "* Please enter a valid crontab expression" +msgstr "* 有効なcrontab式を入力してください" + +#: ops/mixin.py:129 +msgid "Range {} to {}" +msgstr "{} から {} までの範囲" + +#: ops/mixin.py:140 +msgid "Require periodic or regularly perform setting" +msgstr "定期的または定期的に設定を行う必要があります" + +#: ops/mixin.py:151 +msgid "" +"eg: Every Sunday 03:05 run <5 3 * * 0>
Tips: Using 5 digits linux " +"crontab expressions (Online tools)
Note: If both Regularly " +"perform and Cycle perform are set, give priority to Regularly perform" +msgstr "" +"eg:毎週日03:05<5 3**0>
ヒント:5ビットLinux crontab式<" +"分時日月曜日>(オンラインワーク" +")
注意:定期実行と周期実行を同時に設定した場合は、定期実行を優先します。" + +#: ops/mixin.py:162 +msgid "Unit: hour" +msgstr "単位: 時間" + +#: ops/models/adhoc.py:36 +msgid "Callback" +msgstr "コールバック" + +#: ops/models/adhoc.py:135 terminal/models/task.py:26 +#: xpack/plugins/gathered_user/models.py:73 +msgid "Task" +msgstr "タスク" + +#: ops/models/adhoc.py:138 +msgid "Can view task monitor" +msgstr "タスクモニターを表示できます" + +#: ops/models/adhoc.py:154 +msgid "Tasks" +msgstr "タスク" + +#: ops/models/adhoc.py:155 +msgid "Pattern" +msgstr "パターン" + +#: ops/models/adhoc.py:156 +msgid "Options" +msgstr "オプション" + +#: ops/models/adhoc.py:158 +msgid "Run as admin" +msgstr "再実行" + +#: ops/models/adhoc.py:161 +msgid "Become" +msgstr "になる" + +#: ops/models/adhoc.py:162 +msgid "Create by" +msgstr "による作成" + +#: ops/models/adhoc.py:243 +msgid "AdHoc" +msgstr "タスクの各バージョン" + +#: ops/models/adhoc.py:252 +msgid "Task display" +msgstr "タスク表示" + +#: ops/models/adhoc.py:254 +msgid "Host amount" +msgstr "ホスト量" + +#: ops/models/adhoc.py:256 +msgid "Start time" +msgstr "開始時間" + +#: ops/models/adhoc.py:257 +msgid "End time" +msgstr "終了時間" + +#: ops/models/adhoc.py:259 ops/models/command.py:29 +#: terminal/serializers/session.py:39 +msgid "Is finished" +msgstr "終了しました" + +#: ops/models/adhoc.py:261 +msgid "Adhoc raw result" +msgstr "アドホック生の結果" + +#: ops/models/adhoc.py:262 +msgid "Adhoc result summary" +msgstr "アドホック結果の概要" + +#: ops/models/adhoc.py:339 +msgid "AdHoc execution" +msgstr "アドホックエキューション" + +#: ops/models/command.py:32 +msgid "Date finished" +msgstr "終了日" + +#: ops/models/command.py:113 +msgid "Task start" +msgstr "タスクの開始" + +#: ops/models/command.py:147 +msgid "Command `{}` is forbidden ........" +msgstr "コマンド '{}' は禁止されています ........" + +#: ops/models/command.py:160 +msgid "Task end" +msgstr "タスク" + +#: ops/models/command.py:164 +msgid "Command execution" +msgstr "コマンド実行" + +#: ops/notifications.py:17 +msgid "Server performance" +msgstr "サーバーのパフォーマンス" + +#: ops/notifications.py:23 +msgid "Terminal health check warning" +msgstr "ターミナルヘルスチェックの警告" + +#: ops/notifications.py:68 +#, python-brace-format +msgid "The terminal is offline: {name}" +msgstr "ターミナルはオフラインです: {name}" + +#: ops/notifications.py:73 +#, python-brace-format +msgid "Disk used more than {max_threshold}%: => {value}" +msgstr "{max_threshold}%: => {value} を超えるディスクを使用" + +#: ops/notifications.py:78 +#, python-brace-format +msgid "Memory used more than {max_threshold}%: => {value}" +msgstr "{max_threshold}%: => {value} を超える使用メモリ" + +#: ops/notifications.py:83 +#, python-brace-format +msgid "CPU load more than {max_threshold}: => {value}" +msgstr "{max_threshold} を超えるCPUロード: => {value}" + +#: ops/tasks.py:72 +msgid "Clean task history period" +msgstr "クリーンなタスク履歴期間" + +#: ops/tasks.py:85 +msgid "Clean celery log period" +msgstr "きれいなセロリログ期間" + +#: ops/templates/ops/celery_task_log.html:4 +msgid "Task log" +msgstr "タスクログ" + +#: ops/utils.py:64 +msgid "Update task content: {}" +msgstr "タスク内容の更新: {}" + +#: orgs/api.py:68 +msgid "The current organization ({}) cannot be deleted" +msgstr "現在の組織 ({}) は削除できません" + +#: orgs/api.py:76 +msgid "The organization have resource ({}) cannot be deleted" +msgstr "組織のリソース ({}) は削除できません" + +#: orgs/apps.py:7 rbac/tree.py:112 +msgid "App organizations" +msgstr "アプリ組織" + +#: orgs/mixins/models.py:46 orgs/mixins/serializers.py:25 orgs/models.py:80 +#: orgs/models.py:211 rbac/const.py:7 rbac/models/rolebinding.py:47 +#: rbac/serializers/rolebinding.py:40 tickets/serializers/ticket/ticket.py:77 +msgid "Organization" +msgstr "組織" + +#: orgs/models.py:74 +msgid "GLOBAL" +msgstr "グローバル組織" + +#: orgs/models.py:82 +msgid "Can view root org" +msgstr "グローバル組織を表示できます" + +#: orgs/models.py:216 rbac/models/role.py:46 rbac/models/rolebinding.py:43 +#: users/models/user.py:665 users/templates/users/_select_user_modal.html:15 +msgid "Role" +msgstr "ロール" + +#: perms/apps.py:9 +msgid "App permissions" +msgstr "アプリの権限" + +#: perms/exceptions.py:9 +msgid "The administrator is modifying permissions. Please wait" +msgstr "管理者は権限を変更しています。お待ちください" + +#: perms/exceptions.py:14 +msgid "The authorization cannot be revoked for the time being" +msgstr "当分の間、承認を取り消すことはできません。" + +#: perms/models/application_permission.py:111 +msgid "Permed application" +msgstr "許可されたアプリケーション" + +#: perms/models/application_permission.py:114 +msgid "Can view my apps" +msgstr "自分のアプリを表示できます" + +#: perms/models/application_permission.py:115 +msgid "Can view user apps" +msgstr "ユーザーアプリを表示できます" + +#: perms/models/application_permission.py:116 +msgid "Can view usergroup apps" +msgstr "ユーザー・グループ認可の適用を表示できます" + +#: perms/models/asset_permission.py:134 +msgid "Ungrouped" +msgstr "グループ化されていません" + +#: perms/models/asset_permission.py:136 +msgid "Favorite" +msgstr "お気に入り" + +#: perms/models/asset_permission.py:183 +msgid "Permed asset" +msgstr "許可された資産" + +#: perms/models/asset_permission.py:185 +msgid "Can view my assets" +msgstr "私の資産を見ることができます" + +#: perms/models/asset_permission.py:186 +msgid "Can view user assets" +msgstr "ユーザー資産を表示できます" + +#: perms/models/asset_permission.py:187 +msgid "Can view usergroup assets" +msgstr "ユーザーグループの資産を表示できます" + +#: perms/models/base.py:55 +msgid "Connect" +msgstr "接続" + +#: perms/models/base.py:56 +msgid "Upload file" +msgstr "ファイルのアップロード" + +#: perms/models/base.py:57 +msgid "Download file" +msgstr "ファイルのダウンロード" + +#: perms/models/base.py:58 +msgid "Upload download" +msgstr "ダウンロードのアップロード" + +#: perms/models/base.py:59 +msgid "Clipboard copy" +msgstr "クリップボードのコピー" + +#: perms/models/base.py:60 +msgid "Clipboard paste" +msgstr "クリップボードペースト" + +#: perms/models/base.py:61 +msgid "Clipboard copy paste" +msgstr "クリップボードコピーペースト" + +#: perms/models/base.py:90 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:58 +#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:60 +#: users/models/user.py:697 +msgid "Date expired" +msgstr "期限切れの日付" + +#: perms/models/base.py:94 +msgid "From ticket" +msgstr "チケットから" + +#: perms/notifications.py:17 +msgid "You permed assets is about to expire" +msgstr "パーマ資産の有効期限が近づいています" + +#: perms/notifications.py:21 +msgid "permed assets" +msgstr "パーマ資産" + +#: perms/notifications.py:59 +msgid "Asset permissions is about to expire" +msgstr "資産権限の有効期限が近づいています" + +#: perms/notifications.py:63 +msgid "asset permissions of organization {}" +msgstr "組織 {} の資産権限" + +#: perms/notifications.py:89 +msgid "Your permed applications is about to expire" +msgstr "パーマアプリケーションの有効期限が近づいています" + +#: perms/notifications.py:92 +msgid "permed applications" +msgstr "Permedアプリケーション" + +#: perms/notifications.py:127 +msgid "Application permissions is about to expire" +msgstr "アプリケーション権限の有効期限が近づいています" + +#: perms/notifications.py:130 +msgid "application permissions of organization {}" +msgstr "Organization {} のアプリケーション権限" + +#: perms/serializers/application/permission.py:20 +#: perms/serializers/application/permission.py:41 +#: perms/serializers/asset/permission.py:19 +#: perms/serializers/asset/permission.py:45 users/serializers/user.py:137 +msgid "Is valid" +msgstr "有効です" + +#: perms/serializers/application/permission.py:21 +#: perms/serializers/application/permission.py:40 +#: perms/serializers/asset/permission.py:20 +#: perms/serializers/asset/permission.py:44 users/serializers/user.py:83 +#: users/serializers/user.py:139 +msgid "Is expired" +msgstr "期限切れです" + +#: perms/serializers/application/permission.py:43 +#: perms/serializers/asset/permission.py:47 rbac/serializers/role.py:26 +#: users/serializers/group.py:34 +msgid "Users amount" +msgstr "ユーザー数" + +#: perms/serializers/application/permission.py:44 +#: perms/serializers/asset/permission.py:48 +msgid "User groups amount" +msgstr "ユーザーグループの量" + +#: perms/serializers/application/permission.py:45 +#: perms/serializers/asset/permission.py:51 +msgid "System users amount" +msgstr "システムユーザー数" + +#: perms/serializers/application/permission.py:79 +msgid "" +"The application list contains applications that are different from the " +"permission type. ({})" +msgstr "アプリケーションリストには、権限タイプとは異なるアプリケーションが含まれています。({})" + +#: perms/serializers/asset/permission.py:21 +msgid "Users display" +msgstr "ユーザー表示" + +#: perms/serializers/asset/permission.py:22 +msgid "User groups display" +msgstr "ユーザーグループの表示" + +#: perms/serializers/asset/permission.py:23 +msgid "Assets display" +msgstr "資産表示" + +#: perms/serializers/asset/permission.py:24 +msgid "Nodes display" +msgstr "ノード表示" + +#: perms/serializers/asset/permission.py:25 +msgid "System users display" +msgstr "システムユーザーの表示" + +#: perms/templates/perms/_msg_item_permissions_expire.html:7 +#: perms/templates/perms/_msg_permed_items_expire.html:7 +#, python-format +msgid "" +"\n" +" The following %(item_type)s will expire in 3 days\n" +" " +msgstr "" +"\n" +" 次の %(item_type)s は3日以内に期限切れになります\n" +" " + +#: perms/templates/perms/_msg_permed_items_expire.html:21 +msgid "If you have any question, please contact the administrator" +msgstr "質問があったら、管理者に連絡して下さい" + +#: rbac/api/role.py:32 +msgid "Internal role, can't be destroy" +msgstr "内部の役割は、破壊することはできません" + +#: rbac/api/role.py:36 +msgid "The role has been bound to users, can't be destroy" +msgstr "ロールはユーザーにバインドされており、破壊することはできません" + +#: rbac/api/role.py:43 +msgid "Internal role, can't be update" +msgstr "内部ロール、更新できません" + +#: rbac/api/rolebinding.py:52 +msgid "{} at least one system role" +msgstr "{} 少なくとも1つのシステムロール" + +#: rbac/apps.py:7 +msgid "RBAC" +msgstr "RBAC" + +#: rbac/builtin.py:92 +msgid "SystemAdmin" +msgstr "システム管理者" + +#: rbac/builtin.py:95 +msgid "SystemAuditor" +msgstr "システム監査人" + +#: rbac/builtin.py:98 +msgid "SystemComponent" +msgstr "システムコンポーネント" + +#: rbac/builtin.py:104 +msgid "OrgAdmin" +msgstr "組織管理者" + +#: rbac/builtin.py:107 +msgid "OrgAuditor" +msgstr "監査員を組織する" + +#: rbac/builtin.py:110 +msgid "OrgUser" +msgstr "組織ユーザー" + +#: rbac/models/menu.py:13 +msgid "Menu permission" +msgstr "メニュー権限" + +#: rbac/models/menu.py:15 +msgid "Can view console view" +msgstr "コンソールビューを表示できます" + +#: rbac/models/menu.py:16 +msgid "Can view audit view" +msgstr "監査ビューを表示できます" + +#: rbac/models/menu.py:17 +msgid "Can view workspace view" +msgstr "ワークスペースビューを表示できます" + +#: rbac/models/menu.py:18 +msgid "Can view web terminal" +msgstr "Webターミナルを表示できます" + +#: rbac/models/menu.py:19 +msgid "Can view file manager" +msgstr "ファイルマネージャを表示できます" + +#: rbac/models/permission.py:26 +msgid "Permission" +msgstr "権限" + +#: rbac/models/role.py:31 rbac/models/rolebinding.py:37 +msgid "Scope" +msgstr "スコープ" + +#: rbac/models/role.py:34 +msgid "Permissions" +msgstr "権限" + +#: rbac/models/role.py:36 +msgid "Built-in" +msgstr "内蔵" + +#: rbac/models/role.py:130 +msgid "System role" +msgstr "システムの役割" + +#: rbac/models/role.py:138 +msgid "Organization role" +msgstr "組織の役割" + +#: rbac/models/rolebinding.py:52 +msgid "Role binding" +msgstr "ロールバインディング" + +#: rbac/models/rolebinding.py:128 +msgid "" +"User last role in org, can not be delete, you can remove user from org " +"instead" +msgstr "ユーザーの最後のロールは削除できません。ユーザーを組織から削除できます。" + +#: rbac/models/rolebinding.py:135 +msgid "Organization role binding" +msgstr "組織の役割バインディング" + +#: rbac/models/rolebinding.py:150 +msgid "System role binding" +msgstr "システムロールバインディング" + +#: rbac/serializers/permission.py:26 users/serializers/profile.py:126 +msgid "Perms" +msgstr "パーマ" + +#: rbac/serializers/role.py:11 +msgid "Scope display" +msgstr "スコープ表示" + +#: rbac/serializers/role.py:27 +msgid "Display name" +msgstr "表示名" + +#: rbac/serializers/rolebinding.py:22 +msgid "Role display" +msgstr "ロール表示" + +#: rbac/serializers/rolebinding.py:56 +msgid "Has bound this role" +msgstr "この役割をバインドしました" + +#: rbac/tree.py:19 rbac/tree.py:20 +msgid "All permissions" +msgstr "すべての権限" + +#: rbac/tree.py:26 +msgid "Console view" +msgstr "コンソールビュー" + +#: rbac/tree.py:27 +msgid "Workspace view" +msgstr "ワークスペースビュー" + +#: rbac/tree.py:28 +msgid "Audit view" +msgstr "監査ビュー" + +#: rbac/tree.py:29 settings/models.py:140 +msgid "System setting" +msgstr "システム設定" + +#: rbac/tree.py:30 +msgid "Other" +msgstr "その他" + +#: rbac/tree.py:38 +msgid "Accounts" +msgstr "アカウント" + +#: rbac/tree.py:42 +msgid "Session audits" +msgstr "セッション監査" + +#: rbac/tree.py:52 +msgid "Cloud import" +msgstr "クラウドインポート" + +#: rbac/tree.py:53 +msgid "Backup account" +msgstr "バックアップアカウント" + +#: rbac/tree.py:54 +msgid "Gather account" +msgstr "アカウントを集める" + +#: rbac/tree.py:55 +msgid "App change auth" +msgstr "応用改密" + +#: rbac/tree.py:56 +msgid "Asset change auth" +msgstr "資産の改ざん" + +#: rbac/tree.py:57 +msgid "Terminal setting" +msgstr "ターミナル設定" + +#: rbac/tree.py:58 +msgid "My assets" +msgstr "私の資産" + +#: rbac/tree.py:59 +msgid "My apps" +msgstr "マイアプリ" + +#: rbac/tree.py:113 +msgid "Ticket comment" +msgstr "チケットコメント" + +#: rbac/tree.py:114 tickets/models/ticket.py:163 +msgid "Ticket" +msgstr "チケット" + +#: rbac/tree.py:115 +msgid "Common setting" +msgstr "共通設定" + +#: rbac/tree.py:116 +msgid "View permission tree" +msgstr "権限ツリーの表示" + +#: rbac/tree.py:117 +msgid "Execute batch command" +msgstr "バッチ実行コマンド" + +#: rbac/tree.py:164 +msgid "View" +msgstr "表示" + +#: settings/api/alibaba_sms.py:31 settings/api/tencent_sms.py:35 +msgid "test_phone is required" +msgstr "携帯番号をテストこのフィールドは必須です" + +#: settings/api/alibaba_sms.py:52 settings/api/dingtalk.py:31 +#: settings/api/feishu.py:36 settings/api/tencent_sms.py:57 +#: settings/api/wecom.py:37 +msgid "Test success" +msgstr "テストの成功" + +#: settings/api/email.py:20 +msgid "Test mail sent to {}, please check" +msgstr "{}に送信されたテストメールを確認してください" + +#: settings/api/ldap.py:166 +msgid "Synchronization start, please wait." +msgstr "同期開始、お待ちください。" + +#: settings/api/ldap.py:170 +msgid "Synchronization is running, please wait." +msgstr "同期が実行中です。しばらくお待ちください。" + +#: settings/api/ldap.py:175 +msgid "Synchronization error: {}" +msgstr "同期エラー: {}" + +#: settings/api/ldap.py:211 +msgid "Get ldap users is None" +msgstr "Ldapユーザーを取得するにはNone" + +#: settings/api/ldap.py:220 +msgid "Imported {} users successfully (Organization: {})" +msgstr "{} 人のユーザーを正常にインポートしました (組織: {})" + +#: settings/apps.py:7 +msgid "Settings" +msgstr "設定" + +#: settings/models.py:142 +msgid "Can change email setting" +msgstr "メール設定を変更できます" + +#: settings/models.py:143 +msgid "Can change auth setting" +msgstr "資格認定の設定" + +#: settings/models.py:144 +msgid "Can change system msg sub setting" +msgstr "システムmsgサブ设定を変更できます" + +#: settings/models.py:145 +msgid "Can change sms setting" +msgstr "Smsの設定を変えることができます" + +#: settings/models.py:146 +msgid "Can change security setting" +msgstr "セキュリティ設定を変更できます" + +#: settings/models.py:147 +msgid "Can change clean setting" +msgstr "きれいな設定を変えることができます" + +#: settings/models.py:148 +msgid "Can change interface setting" +msgstr "インターフェイスの設定を変えることができます" + +#: settings/models.py:149 +msgid "Can change license setting" +msgstr "ライセンス設定を変更できます" + +#: settings/models.py:150 +msgid "Can change terminal setting" +msgstr "ターミナルの設定を変えることができます" + +#: settings/models.py:151 +msgid "Can change other setting" +msgstr "他の設定を変えることができます" + +#: settings/serializers/auth/base.py:10 +msgid "CAS Auth" +msgstr "CAS 認証" + +#: settings/serializers/auth/base.py:11 +msgid "OPENID Auth" +msgstr "OPENID 認証" + +#: settings/serializers/auth/base.py:12 +msgid "RADIUS Auth" +msgstr "RADIUS 認証" + +#: settings/serializers/auth/base.py:13 +msgid "DingTalk Auth" +msgstr "くぎ 認証" + +#: settings/serializers/auth/base.py:14 +msgid "FeiShu Auth" +msgstr "飛本 認証" + +#: settings/serializers/auth/base.py:15 +msgid "WeCom Auth" +msgstr "企業微信 認証" + +#: settings/serializers/auth/base.py:16 +msgid "SSO Auth" +msgstr "SSO Token 認証" + +#: settings/serializers/auth/base.py:17 +msgid "SAML2 Auth" +msgstr "SAML2 認証" + +#: settings/serializers/auth/base.py:20 settings/serializers/basic.py:36 +msgid "Forgot password url" +msgstr "パスワードのURLを忘れた" + +#: settings/serializers/auth/base.py:26 +msgid "Enable login redirect msg" +msgstr "ログインリダイレクトの有効化msg" + +#: settings/serializers/auth/cas.py:11 +msgid "Enable CAS Auth" +msgstr "CAS 認証の有効化" + +#: settings/serializers/auth/cas.py:12 settings/serializers/auth/oidc.py:32 +msgid "Server url" +msgstr "サービス側アドレス" + +#: settings/serializers/auth/cas.py:13 +msgid "Proxy server url" +msgstr "コールバックアドレス" + +#: settings/serializers/auth/cas.py:14 settings/serializers/auth/saml2.py:32 +msgid "Logout completely" +msgstr "同期ログアウト" + +#: settings/serializers/auth/cas.py:16 +msgid "Username attr" +msgstr "ユーザー名のプロパティ" + +#: settings/serializers/auth/cas.py:17 +msgid "Enable attributes map" +msgstr "属性マップの有効化" + +#: settings/serializers/auth/cas.py:18 settings/serializers/auth/saml2.py:31 +msgid "Rename attr" +msgstr "マッピングのプロパティ" + +#: settings/serializers/auth/cas.py:19 +msgid "Create user if not" +msgstr "そうでない場合はユーザーを作成" + +#: settings/serializers/auth/dingtalk.py:11 +msgid "Enable DingTalk Auth" +msgstr "ピン認証の有効化" + +#: settings/serializers/auth/feishu.py:10 +msgid "Enable FeiShu Auth" +msgstr "飛本認証の有効化" + +#: settings/serializers/auth/ldap.py:39 +msgid "LDAP server" +msgstr "LDAPサーバー" + +#: settings/serializers/auth/ldap.py:40 +msgid "eg: ldap://localhost:389" +msgstr "例: ldap://localhost:389" + +#: settings/serializers/auth/ldap.py:42 +msgid "Bind DN" +msgstr "DN のバインド" + +#: settings/serializers/auth/ldap.py:46 +msgid "User OU" +msgstr "ユーザー OU" + +#: settings/serializers/auth/ldap.py:47 +msgid "Use | split multi OUs" +msgstr "使用 | splitマルチ OU" + +#: settings/serializers/auth/ldap.py:50 +msgid "User search filter" +msgstr "ユーザー検索フィルター" + +#: settings/serializers/auth/ldap.py:51 +#, python-format +msgid "Choice may be (cn|uid|sAMAccountName)=%(user)s)" +msgstr "選択は (cnまたはuidまたはsAMAccountName)=%(user)s)" + +#: settings/serializers/auth/ldap.py:54 +msgid "User attr map" +msgstr "ユーザー属性マッピング" + +#: settings/serializers/auth/ldap.py:55 +msgid "" +"User attr map present how to map LDAP user attr to jumpserver, username,name," +"email is jumpserver attr" +msgstr "" +"ユーザー属性マッピングは、LDAPのユーザー属性をjumpserverユーザーにマッピングする方法、username, name," +"emailはjumpserverのユーザーが必要とする属性です" + +#: settings/serializers/auth/ldap.py:70 +msgid "Connect timeout" +msgstr "接続タイムアウト" + +#: settings/serializers/auth/ldap.py:72 +msgid "Search paged size" +msgstr "ページサイズを検索" + +#: settings/serializers/auth/ldap.py:74 +msgid "Enable LDAP auth" +msgstr "LDAP認証の有効化" + +#: settings/serializers/auth/oidc.py:12 +msgid "Base site url" +msgstr "ベースサイトのアドレス" + +#: settings/serializers/auth/oidc.py:15 +msgid "Client Id" +msgstr "クライアントID" + +#: settings/serializers/auth/oidc.py:18 +#: xpack/plugins/cloud/serializers/account_attrs.py:34 +msgid "Client Secret" +msgstr "クライアント秘密" + +#: settings/serializers/auth/oidc.py:20 +msgid "Share session" +msgstr "セッションの共有" + +#: settings/serializers/auth/oidc.py:22 +msgid "Ignore ssl verification" +msgstr "Ssl検証を無視する" + +#: settings/serializers/auth/oidc.py:29 +msgid "Use Keycloak" +msgstr "Keycloakを使用する" + +#: settings/serializers/auth/oidc.py:35 +msgid "Realm name" +msgstr "レルム名" + +#: settings/serializers/auth/oidc.py:41 +msgid "Enable OPENID Auth" +msgstr "OIDC認証の有効化" + +#: settings/serializers/auth/oidc.py:43 +msgid "Provider endpoint" +msgstr "プロバイダーエンドポイント" + +#: settings/serializers/auth/oidc.py:46 +msgid "Provider auth endpoint" +msgstr "認証エンドポイントアドレス" + +#: settings/serializers/auth/oidc.py:49 +msgid "Provider token endpoint" +msgstr "プロバイダートークンエンドポイント" + +#: settings/serializers/auth/oidc.py:52 +msgid "Provider jwks endpoint" +msgstr "プロバイダーjwksエンドポイント" + +#: settings/serializers/auth/oidc.py:55 +msgid "Provider userinfo endpoint" +msgstr "プロバイダーuserinfoエンドポイント" + +#: settings/serializers/auth/oidc.py:58 +msgid "Provider end session endpoint" +msgstr "プロバイダーのセッション終了エンドポイント" + +#: settings/serializers/auth/oidc.py:61 +msgid "Provider sign alg" +msgstr "プロビダーサインalg" + +#: settings/serializers/auth/oidc.py:64 +msgid "Provider sign key" +msgstr "プロバイダ署名キー" + +#: settings/serializers/auth/oidc.py:66 +msgid "Scopes" +msgstr "スコープ" + +#: settings/serializers/auth/oidc.py:68 +msgid "Id token max age" +msgstr "IDトークンの最大年齢" + +#: settings/serializers/auth/oidc.py:71 +msgid "Id token include claims" +msgstr "IDトークンにはクレームが含まれます" + +#: settings/serializers/auth/oidc.py:73 +msgid "Use state" +msgstr "使用状態" + +#: settings/serializers/auth/oidc.py:74 +msgid "Use nonce" +msgstr "Nonceを使用" + +#: settings/serializers/auth/oidc.py:76 settings/serializers/auth/saml2.py:33 +msgid "Always update user" +msgstr "常にユーザーを更新" + +#: settings/serializers/auth/radius.py:13 +msgid "Enable Radius Auth" +msgstr "Radius認証の有効化" + +#: settings/serializers/auth/radius.py:19 +msgid "OTP in Radius" +msgstr "Radius のOTP" + +#: settings/serializers/auth/saml2.py:12 +msgid "Enable SAML2 Auth" +msgstr "SAML2認証の有効化" + +#: settings/serializers/auth/saml2.py:15 +msgid "IDP metadata URL" +msgstr "IDP metadata アドレス" + +#: settings/serializers/auth/saml2.py:18 +msgid "IDP metadata XML" +msgstr "IDP metadata XML" + +#: settings/serializers/auth/saml2.py:21 +msgid "SP advanced settings" +msgstr "詳細設定" + +#: settings/serializers/auth/saml2.py:25 +msgid "SP private key" +msgstr "SP プライベートキー" + +#: settings/serializers/auth/saml2.py:29 +msgid "SP cert" +msgstr "SP 証明書" + +#: settings/serializers/auth/sms.py:10 +msgid "Enable SMS" +msgstr "SMSの有効化" + +#: settings/serializers/auth/sms.py:12 +msgid "SMS provider" +msgstr "SMSプロバイダ" + +#: settings/serializers/auth/sms.py:17 settings/serializers/auth/sms.py:35 +#: settings/serializers/auth/sms.py:43 settings/serializers/email.py:63 +msgid "Signature" +msgstr "署名" + +#: settings/serializers/auth/sms.py:18 settings/serializers/auth/sms.py:36 +#: settings/serializers/auth/sms.py:44 +msgid "Template code" +msgstr "テンプレートコード" + +#: settings/serializers/auth/sms.py:22 +msgid "Test phone" +msgstr "テスト電話" + +#: settings/serializers/auth/sso.py:12 +msgid "Enable SSO auth" +msgstr "SSO Token認証の有効化" + +#: settings/serializers/auth/sso.py:13 +msgid "Other service can using SSO token login to JumpServer without password" +msgstr "他のサービスはパスワードなしでJumpServerへのSSOトークンログインを使用できます" + +#: settings/serializers/auth/sso.py:16 +msgid "SSO auth key TTL" +msgstr "Token有効期間" + +#: settings/serializers/auth/sso.py:16 +msgid "Unit: second" +msgstr "単位: 秒" + +#: settings/serializers/auth/wecom.py:11 +msgid "Enable WeCom Auth" +msgstr "企業微信認証の有効化" + +#: settings/serializers/basic.py:9 +msgid "Subject" +msgstr "件名" + +#: settings/serializers/basic.py:13 +msgid "More url" +msgstr "もっとURL" + +#: settings/serializers/basic.py:28 +msgid "Site url" +msgstr "サイトURL" + +#: settings/serializers/basic.py:29 +msgid "eg: http://dev.jumpserver.org:8080" +msgstr "例えば: http://dev.jumpserver.org:8080" + +#: settings/serializers/basic.py:32 +msgid "User guide url" +msgstr "ユーザーガイドurl" + +#: settings/serializers/basic.py:33 +msgid "User first login update profile done redirect to it" +msgstr "ユーザーの最初のログイン更新プロファイルがリダイレクトされました" + +#: settings/serializers/basic.py:37 +msgid "" +"The forgot password url on login page, If you use ldap or cas external " +"authentication, you can set it" +msgstr "ログインページでパスワードのURLを忘れてしまいました。ldapまたはcasの外部認証を使用している場合は、設定できます。" + +#: settings/serializers/basic.py:41 +msgid "Global organization name" +msgstr "グローバル組織名" + +#: settings/serializers/basic.py:42 +msgid "The name of global organization to display" +msgstr "表示するグローバル組織の名前" + +#: settings/serializers/basic.py:44 +msgid "Enable announcement" +msgstr "アナウンスの有効化" + +#: settings/serializers/basic.py:45 +msgid "Announcement" +msgstr "発表" + +#: settings/serializers/cleaning.py:10 +msgid "Login log keep days" +msgstr "ログインログは日数を保持します" + +#: settings/serializers/cleaning.py:10 settings/serializers/cleaning.py:14 +#: settings/serializers/cleaning.py:18 settings/serializers/cleaning.py:22 +#: settings/serializers/cleaning.py:26 +msgid "Unit: day" +msgstr "単位: 日" + +#: settings/serializers/cleaning.py:14 +msgid "Task log keep days" +msgstr "タスクログは日数を保持します" + +#: settings/serializers/cleaning.py:18 +msgid "Operate log keep days" +msgstr "ログ管理日を操作する" + +#: settings/serializers/cleaning.py:22 +msgid "FTP log keep days" +msgstr "ダウンロードのアップロード" + +#: settings/serializers/cleaning.py:26 +msgid "Cloud sync record keep days" +msgstr "クラウド同期レコードは日数を保持します" + +#: settings/serializers/cleaning.py:29 +msgid "Session keep duration" +msgstr "セッション維持期間" + +#: settings/serializers/cleaning.py:30 +msgid "" +"Unit: days, Session, record, command will be delete if more than duration, " +"only in database" +msgstr "" +"単位:日。セッション、録画、コマンドレコードがそれを超えると削除されます(データベースストレージにのみ影響します。ossなどは影響しません」" +"影響を受ける)" + +#: settings/serializers/email.py:18 +msgid "SMTP host" +msgstr "SMTPホスト" + +#: settings/serializers/email.py:19 +msgid "SMTP port" +msgstr "SMTPポート" + +#: settings/serializers/email.py:20 +msgid "SMTP account" +msgstr "SMTPアカウント" + +#: settings/serializers/email.py:22 +msgid "SMTP password" +msgstr "SMTPパスワード" + +#: settings/serializers/email.py:23 +msgid "Tips: Some provider use token except password" +msgstr "ヒント: 一部のプロバイダーはパスワード以外のトークンを使用します" + +#: settings/serializers/email.py:26 +msgid "Send user" +msgstr "ユーザーを送信" + +#: settings/serializers/email.py:27 +msgid "Tips: Send mail account, default SMTP account as the send account" +msgstr "ヒント: 送信メールアカウント、送信アカウントとしてのデフォルトのSMTPアカウント" + +#: settings/serializers/email.py:30 +msgid "Test recipient" +msgstr "テスト受信者" + +#: settings/serializers/email.py:31 +msgid "Tips: Used only as a test mail recipient" +msgstr "ヒント: テストメールの受信者としてのみ使用" + +#: settings/serializers/email.py:34 +msgid "Use SSL" +msgstr "SSLの使用" + +#: settings/serializers/email.py:35 +msgid "If SMTP port is 465, may be select" +msgstr "SMTPポートが465の場合は、" + +#: settings/serializers/email.py:38 +msgid "Use TLS" +msgstr "TLSの使用" + +#: settings/serializers/email.py:39 +msgid "If SMTP port is 587, may be select" +msgstr "SMTPポートが587の場合は、" + +#: settings/serializers/email.py:42 +msgid "Subject prefix" +msgstr "件名プレフィックス" + +#: settings/serializers/email.py:49 +msgid "Create user email subject" +msgstr "ユーザーメール件名の作成" + +#: settings/serializers/email.py:50 +msgid "" +"Tips: When creating a user, send the subject of the email (eg:Create account " +"successfully)" +msgstr "ヒント: ユーザーを作成するときに、メールの件名を送信します (例: アカウントを正常に作成)" + +#: settings/serializers/email.py:54 +msgid "Create user honorific" +msgstr "ユーザー敬語の作成" + +#: settings/serializers/email.py:55 +msgid "Tips: When creating a user, send the honorific of the email (eg:Hello)" +msgstr "ヒント: ユーザーを作成するときは、メールの敬語を送信します (例: こんにちは)" + +#: settings/serializers/email.py:59 +msgid "Create user email content" +msgstr "ユーザーのメールコンテンツを作成する" + +#: settings/serializers/email.py:60 +#, python-brace-format +msgid "" +"Tips: When creating a user, send the content of the email, support " +"{username} {name} {email} label" +msgstr "" +"ヒント:ユーザーの作成時にパスワード設定メールの内容を送信し、{username}{name}{email}ラベルをサポートします。" + +#: settings/serializers/email.py:64 +msgid "Tips: Email signature (eg:jumpserver)" +msgstr "ヒント: メール署名 (例: jumpserver)" + +#: settings/serializers/other.py:7 +msgid "Email suffix" +msgstr "メールのサフィックス" + +#: settings/serializers/other.py:8 +msgid "" +"This is used by default if no email is returned during SSO authentication" +msgstr "これは、SSO認証中にメールが返されない場合にデフォルトで使用されます。" + +#: settings/serializers/other.py:12 +msgid "OTP issuer name" +msgstr "OTP発行者名" + +#: settings/serializers/other.py:16 +msgid "OTP valid window" +msgstr "OTP有効なウィンドウ" + +#: settings/serializers/other.py:21 +msgid "CMD" +msgstr "CMD" + +#: settings/serializers/other.py:22 +msgid "PowerShell" +msgstr "PowerShell" + +#: settings/serializers/other.py:24 +msgid "Shell (Windows)" +msgstr "シェル (Windows)" + +#: settings/serializers/other.py:25 +msgid "The shell type used when Windows assets perform ansible tasks" +msgstr "Windowsアセットが実行可能なタスクを実行するときに使用されるシェルタイプ" + +#: settings/serializers/other.py:29 +msgid "Perm ungroup node" +msgstr "グループ化されていないノードを表示" + +#: settings/serializers/other.py:30 +msgid "Perm single to ungroup node" +msgstr "グループ化されていないノードに個別に許可された資産を配置し、資産が存在するノードが表示されないようにしますが、そのノードが許可されていないという質問に質問" + +#: settings/serializers/other.py:34 +msgid "Help Docs URL" +msgstr "ドキュメントリンク" + +#: settings/serializers/other.py:35 +msgid "default: http://docs.jumpserver.org" +msgstr "デフォルト: http://docs.jumpserver.org" + +#: settings/serializers/other.py:39 +msgid "Help Support URL" +msgstr "サポートリンク" + +#: settings/serializers/other.py:40 +msgid "default: http://www.jumpserver.org/support/" +msgstr "デフォルト: http://www.jumpserver.org/support/" + +#: settings/serializers/security.py:10 +msgid "Password minimum length" +msgstr "パスワードの最小長" + +#: settings/serializers/security.py:14 +msgid "Admin user password minimum length" +msgstr "管理者ユーザーパスワードの最小長" + +#: settings/serializers/security.py:17 +msgid "Must contain capital" +msgstr "資本を含める必要があります" + +#: settings/serializers/security.py:20 +msgid "Must contain lowercase" +msgstr "小文字を含める必要があります。" + +#: settings/serializers/security.py:23 +msgid "Must contain numeric" +msgstr "数値を含める必要があります" + +#: settings/serializers/security.py:26 +msgid "Must contain special" +msgstr "特別な" + +#: settings/serializers/security.py:31 +msgid "" +"Unit: minute, If the user has failed to log in for a limited number of " +"times, no login is allowed during this time interval." +msgstr "単位: 分。ユーザーが限られた回数だけログインできなかった場合、この時間間隔ではログインはできません。" + +#: settings/serializers/security.py:40 +msgid "All users" +msgstr "すべてのユーザー" + +#: settings/serializers/security.py:41 +msgid "Only admin users" +msgstr "管理者のみ" + +#: settings/serializers/security.py:43 +msgid "Global MFA auth" +msgstr "グローバル有効化MFA認証" + +#: settings/serializers/security.py:47 +msgid "Third-party login users perform MFA authentication" +msgstr "サードパーティのログインユーザーがMFA認証を実行" + +#: settings/serializers/security.py:48 +msgid "The third-party login modes include OIDC, CAS, and SAML2" +msgstr "サードパーティのログインモードには、OIDC、CAS、SAML2" + +#: settings/serializers/security.py:52 +msgid "Limit the number of user login failures" +msgstr "ユーザーログインの失敗数を制限する" + +#: settings/serializers/security.py:56 +msgid "Block user login interval" +msgstr "ユーザーのログイン間隔をブロックする" + +#: settings/serializers/security.py:61 +msgid "Limit the number of IP login failures" +msgstr "IPログイン失敗の数を制限する" + +#: settings/serializers/security.py:65 +msgid "Block IP login interval" +msgstr "IPログイン間隔をブロックする" + +#: settings/serializers/security.py:69 +msgid "Login IP White List" +msgstr "ログインIPホワイトリスト" + +#: settings/serializers/security.py:74 +msgid "Login IP Black List" +msgstr "ログインIPブラックリスト" + +#: settings/serializers/security.py:80 +msgid "User password expiration" +msgstr "ユーザーパスワードの有効期限" + +#: settings/serializers/security.py:82 +msgid "" +"Unit: day, If the user does not update the password during the time, the " +"user password will expire failure;The password expiration reminder mail will " +"be automatic sent to the user by system within 5 days (daily) before the " +"password expires" +msgstr "単位: 日。ユーザーがその期間中にパスワードを更新しなかった場合、ユーザーパスワードの有効期限が切れます。パスワードの有効期限が切れる前の5日 (毎日) 以内に、パスワードの有効期限が切れるリマインダーメールがシステムからユーザーに自動的に送信されます。" + +#: settings/serializers/security.py:89 +msgid "Number of repeated historical passwords" +msgstr "繰り返された履歴パスワードの数" + +#: settings/serializers/security.py:91 +msgid "" +"Tip: When the user resets the password, it cannot be the previous n " +"historical passwords of the user" +msgstr "ヒント: ユーザーがパスワードをリセットすると、ユーザーの前のnの履歴パスワードにすることはできません" + +#: settings/serializers/security.py:96 +msgid "Only single device login" +msgstr "単一デバイスログインのみ" + +#: settings/serializers/security.py:97 +msgid "Next device login, pre login will be logout" +msgstr "次のデバイスログイン、事前ログインはログアウトになります" + +#: settings/serializers/security.py:100 +msgid "Only exist user login" +msgstr "ユーザーログインのみ存在" + +#: settings/serializers/security.py:101 +msgid "If enable, CAS、OIDC auth will be failed, if user not exist yet" +msgstr "Enableの場合、ユーザーがまだ存在しない場合、CAS、OIDC authは失敗します" + +#: settings/serializers/security.py:104 +msgid "Only from source login" +msgstr "ソースログインからのみ" + +#: settings/serializers/security.py:105 +msgid "Only log in from the user source property" +msgstr "ユーザーソースのプロパティからのみログイン" + +#: settings/serializers/security.py:109 +msgid "MFA verify TTL" +msgstr "MFAはTTLを確認します" + +#: settings/serializers/security.py:111 +msgid "" +"Unit: second, The verification MFA takes effect only when you view the " +"account password" +msgstr "単位: 2番目に、検証MFAはアカウントのパスワードを表示したときにのみ有効になります。" + +#: settings/serializers/security.py:116 +msgid "Enable Login dynamic code" +msgstr "ログイン動的コードの有効化" + +#: settings/serializers/security.py:117 +msgid "" +"The password and additional code are sent to a third party authentication " +"system for verification" +msgstr "パスワードと追加コードは、検証のためにサードパーティの認証システムに送信されます" + +#: settings/serializers/security.py:122 +msgid "MFA in login page" +msgstr "ログインページのMFA" + +#: settings/serializers/security.py:123 +msgid "Eu security regulations(GDPR) require MFA to be on the login page" +msgstr "Euセキュリティ規制 (GDPR) では、MFAがログインページにある必要があります" + +#: settings/serializers/security.py:126 +msgid "Enable Login captcha" +msgstr "ログインcaptchaの有効化" + +#: settings/serializers/security.py:127 +msgid "Enable captcha to prevent robot authentication" +msgstr "Captchaを有効にしてロボット認証を防止する" + +#: settings/serializers/security.py:147 +msgid "Enable terminal register" +msgstr "ターミナルレジスタの有効化" + +#: settings/serializers/security.py:149 +msgid "" +"Allow terminal register, after all terminal setup, you should disable this " +"for security" +msgstr "ターミナルレジスタを許可し、すべてのターミナルセットアップの後、セキュリティのためにこれを無効にする必要があります" + +#: settings/serializers/security.py:153 +msgid "Enable watermark" +msgstr "透かしの有効化" + +#: settings/serializers/security.py:154 +msgid "Enabled, the web session and replay contains watermark information" +msgstr "Webセッションとリプレイには透かし情報が含まれています。" + +#: settings/serializers/security.py:158 +msgid "Connection max idle time" +msgstr "接続最大アイドル時間" + +#: settings/serializers/security.py:159 +msgid "If idle time more than it, disconnect connection Unit: minute" +msgstr "アイドル時間がそれ以上の場合は、接続単位を切断します: 分" + +#: settings/serializers/security.py:162 +msgid "Remember manual auth" +msgstr "手動入力パスワードの保存" + +#: settings/serializers/security.py:165 +msgid "Enable change auth secure mode" +msgstr "安全モードの変更を有効にする" + +#: settings/serializers/security.py:168 +msgid "Insecure command alert" +msgstr "安全でないコマンドアラート" + +#: settings/serializers/security.py:171 +msgid "Email recipient" +msgstr "メール受信者" + +#: settings/serializers/security.py:172 +msgid "Multiple user using , split" +msgstr "複数のユーザーを使用して、分割" + +#: settings/serializers/security.py:175 +msgid "Batch command execution" +msgstr "バッチコマンドの実行" + +#: settings/serializers/security.py:176 +msgid "Allow user run batch command or not using ansible" +msgstr "ユーザー実行バッチコマンドを許可するか、ansibleを使用しない" + +#: settings/serializers/security.py:179 +msgid "Session share" +msgstr "セッション共有" + +#: settings/serializers/security.py:180 +msgid "Enabled, Allows user active session to be shared with other users" +msgstr "ユーザーのアクティブなセッションを他のユーザーと共有できるようにします。" + +#: settings/serializers/security.py:183 +msgid "Remote Login Protection" +msgstr "リモートログイン保護" + +#: settings/serializers/security.py:185 +msgid "" +"The system determines whether the login IP address belongs to a common login " +"city. If the account is logged in from a common login city, the system sends " +"a remote login reminder" +msgstr "システムは、ログインIPアドレスが共通のログイン都市に属しているかどうかを判断します。アカウントが共通のログイン都市からログインしている場合、システムはリモートログインリマインダーを送信します" + +#: settings/serializers/terminal.py:13 +msgid "Auto" +msgstr "自動" + +#: settings/serializers/terminal.py:19 +msgid "Password auth" +msgstr "パスワード認証" + +#: settings/serializers/terminal.py:21 +msgid "Public key auth" +msgstr "鍵認証" + +#: settings/serializers/terminal.py:22 +msgid "" +"Tips: If use other auth method, like AD/LDAP, you should disable this to " +"avoid being able to log in after deleting" +msgstr "" +"ヒント: AD/LDAPなどの他の認証方法を使用する場合は、サードパーティ製システムの削除後にこの項目を無効にする必要があります, " +"ログインも可能" + +#: settings/serializers/terminal.py:25 +msgid "List sort by" +msgstr "リストの並べ替え" + +#: settings/serializers/terminal.py:27 +msgid "List page size" +msgstr "ページサイズを一覧表示" + +#: settings/serializers/terminal.py:29 +msgid "Telnet login regex" +msgstr "Telnetログインregex" + +#: settings/serializers/terminal.py:30 +msgid "" +"The login success message varies with devices. if you cannot log in to the " +"device through Telnet, set this parameter" +msgstr "ログイン成功メッセージはデバイスによって異なります。Telnet経由でデバイスにログインできない場合は、このパラメーターを設定します。" + +#: settings/serializers/terminal.py:34 +msgid "RDP address" +msgstr "RDPアドレス" + +#: settings/serializers/terminal.py:35 +msgid "RDP visit address, eg: dev.jumpserver.org:3389" +msgstr "RDP訪問先住所、例: dev.jumpserver.org:3389" + +#: settings/serializers/terminal.py:38 +msgid "Enable XRDP" +msgstr "XRDPの有効化" + +#: settings/utils/ldap.py:417 +msgid "ldap:// or ldaps:// protocol is used." +msgstr "ldap:// または ldaps:// プロトコルが使用されます。" + +#: settings/utils/ldap.py:428 +msgid "Host or port is disconnected: {}" +msgstr "ホストまたはポートが切断されました: {}" + +#: settings/utils/ldap.py:430 +msgid "The port is not the port of the LDAP service: {}" +msgstr "ポートはLDAPサービスのポートではありません: {}" + +#: settings/utils/ldap.py:432 +msgid "Please add certificate: {}" +msgstr "証明書を追加してください: {}" + +#: settings/utils/ldap.py:436 settings/utils/ldap.py:463 +#: settings/utils/ldap.py:493 settings/utils/ldap.py:521 +msgid "Unknown error: {}" +msgstr "不明なエラー: {}" + +#: settings/utils/ldap.py:450 +msgid "Bind DN or Password incorrect" +msgstr "DNまたはパスワードのバインドが正しくありません" + +#: settings/utils/ldap.py:457 +msgid "Please enter Bind DN: {}" +msgstr "バインドDN: {} を入力してください" + +#: settings/utils/ldap.py:459 +msgid "Please enter Password: {}" +msgstr "パスワードを入力してください: {}" + +#: settings/utils/ldap.py:461 +msgid "Please enter correct Bind DN and Password: {}" +msgstr "正しいバインドDNとパスワードを入力してください: {}" + +#: settings/utils/ldap.py:479 +msgid "Invalid User OU or User search filter: {}" +msgstr "無効なユーザー OU またはユーザー検索フィルター: {}" + +#: settings/utils/ldap.py:510 +msgid "LDAP User attr map not include: {}" +msgstr "LDAP ユーザーattrマップは含まれません: {}" + +#: settings/utils/ldap.py:517 +msgid "LDAP User attr map is not dict" +msgstr "LDAPユーザーattrマップはdictではありません" + +#: settings/utils/ldap.py:536 +msgid "LDAP authentication is not enabled" +msgstr "LDAP 認証が有効になっていない" + +#: settings/utils/ldap.py:554 +msgid "Error (Invalid LDAP server): {}" +msgstr "エラー (LDAPサーバーが無効): {}" + +#: settings/utils/ldap.py:556 +msgid "Error (Invalid Bind DN): {}" +msgstr "エラー (DNのバインドが無効): {}" + +#: settings/utils/ldap.py:558 +msgid "Error (Invalid LDAP User attr map): {}" +msgstr "エラー (LDAPユーザーattrマップが無効): {}" + +#: settings/utils/ldap.py:560 +msgid "Error (Invalid User OU or User search filter): {}" +msgstr "エラー (ユーザーOUまたはユーザー検索フィルターが無効): {}" + +#: settings/utils/ldap.py:562 +msgid "Error (Not enabled LDAP authentication): {}" +msgstr "エラー (LDAP認証が有効化されていません): {}" + +#: settings/utils/ldap.py:564 +msgid "Error (Unknown): {}" +msgstr "エラー (不明): {}" + +#: settings/utils/ldap.py:567 +msgid "Succeed: Match {} s user" +msgstr "成功: {} 人のユーザーに一致" + +#: settings/utils/ldap.py:600 +msgid "Authentication failed (configuration incorrect): {}" +msgstr "認証に失敗しました (設定が正しくありません): {}" + +#: settings/utils/ldap.py:602 +msgid "Authentication failed (before login check failed): {}" +msgstr "認証に失敗しました (ログインチェックが失敗する前): {}" + +#: settings/utils/ldap.py:604 +msgid "Authentication failed (username or password incorrect): {}" +msgstr "認証に失敗しました (ユーザー名またはパスワードが正しくありません): {}" + +#: settings/utils/ldap.py:606 +msgid "Authentication failed (Unknown): {}" +msgstr "認証に失敗しました (不明): {}" + +#: settings/utils/ldap.py:609 +msgid "Authentication success: {}" +msgstr "認証成功: {}" + +#: templates/_base_list.html:37 +msgid "Search" +msgstr "検索" + +#: templates/_csv_import_export.html:8 +msgid "Export" +msgstr "エクスポート" + +#: templates/_csv_import_export.html:13 templates/_csv_import_modal.html:5 +msgid "Import" +msgstr "インポート" + +#: templates/_csv_import_modal.html:12 +msgid "Download the imported template or use the exported CSV file format" +msgstr "インポートしたテンプレートをダウンロードするか、エクスポートしたCSVファイル形式を使用する" + +#: templates/_csv_import_modal.html:13 +msgid "Download the import template" +msgstr "インポートテンプレートのダウンロード" + +#: templates/_csv_import_modal.html:17 templates/_csv_update_modal.html:17 +msgid "Select the CSV file to import" +msgstr "インポートするCSVファイルの選択" + +#: templates/_csv_import_modal.html:39 templates/_csv_update_modal.html:42 +msgid "Please select file" +msgstr "ファイルを選択してください" + +#: templates/_csv_update_modal.html:12 +msgid "Download the update template or use the exported CSV file format" +msgstr "更新テンプレートをダウンロードするか、エクスポートしたCSVファイル形式を使用する" + +#: templates/_csv_update_modal.html:13 +msgid "Download the update template" +msgstr "更新テンプレートのダウンロード" + +#: templates/_header_bar.html:12 +msgid "Help" +msgstr "ヘルプ" + +#: templates/_header_bar.html:19 +msgid "Docs" +msgstr "ドキュメント" + +#: templates/_header_bar.html:25 +msgid "Commercial support" +msgstr "商用サポート" + +#: templates/_header_bar.html:70 users/forms/profile.py:43 +#: users/templates/users/user_password_update.html:39 +msgid "Profile" +msgstr "プロフィール" + +#: templates/_header_bar.html:73 +msgid "Admin page" +msgstr "ページの管理" + +#: templates/_header_bar.html:75 +msgid "User page" +msgstr "ユーザーページ" + +#: templates/_header_bar.html:78 +msgid "API Key" +msgstr "API Key" + +#: templates/_header_bar.html:79 +msgid "Logout" +msgstr "ログアウト" + +#: templates/_message.html:6 +msgid "" +"\n" +" Your account has expired, please contact the administrator.\n" +" " +msgstr "" +"\n" +" アカウントが期限切れになったので、管理者に連絡してください。 " + +#: templates/_message.html:13 +msgid "Your account will at" +msgstr "あなたのアカウントは" + +#: templates/_message.html:13 templates/_message.html:30 +msgid "expired. " +msgstr "期限切れです。" + +#: templates/_message.html:23 +#, python-format +msgid "" +"\n" +" Your password has expired, please click this link update password.\n" +" " +msgstr "" +"\n" +" パスワードが期限切れになりましたので、クリックしてください リンク パスワードの更新\n" +" " + +#: templates/_message.html:30 +msgid "Your password will at" +msgstr "あなたのパスワードは" + +#: templates/_message.html:31 +#, python-format +msgid "" +"\n" +" please click this " +"link to update your password.\n" +" " +msgstr "" +"\n" +" クリックしてください リンク パ" +"スワードの更新\n" +" " + +#: templates/_message.html:43 +#, python-format +msgid "" +"\n" +" Your information was incomplete. Please click this link to complete your information.\n" +" " +msgstr "" +"\n" +" あなたの情報が不完全なので、クリックしてください。 リンク " +" 補完\n" +" " + +#: templates/_message.html:56 +#, python-format +msgid "" +"\n" +" Your ssh public key not set or expired. Please click this link to update\n" +" " +msgstr "" +"\n" +" SSHキーが設定されていないか無効になっている場合は、 リンク 更新\n" +" " + +#: templates/_mfa_login_field.html:28 +msgid "Send verification code" +msgstr "確認コードを送信" + +#: templates/_mfa_login_field.html:106 +msgid "Wait: " +msgstr "待つ:" + +#: templates/_mfa_login_field.html:116 +msgid "The verification code has been sent" +msgstr "確認コードが送信されました" + +#: templates/_pagination.html:59 +msgid "" +"Displays the results of items _START_ to _END_; A total of _TOTAL_ entries" +msgstr "アイテムの結果を表示します _START_ to _END_; 合計 _TOTAL_ エントリ" + +#: templates/_without_nav_base.html:26 +msgid "Home page" +msgstr "ホームページ" + +#: templates/delete_confirm.html:6 +msgid "Confirm delete" +msgstr "削除の確認" + +#: templates/delete_confirm.html:11 +msgid "Are you sure delete" +msgstr "削除してもよろしいですか" + +#: templates/flash_message_standalone.html:25 +msgid "Cancel" +msgstr "キャンセル" + +#: templates/index.html:11 +msgid "Total users" +msgstr "合計ユーザー数" + +#: templates/index.html:23 +msgid "Total assets" +msgstr "総資産" + +#: templates/index.html:36 +msgid "Online users" +msgstr "オンラインユーザー" + +#: templates/index.html:49 +msgid "Online sessions" +msgstr "オンラインセッション" + +#: templates/index.html:61 +msgid "In the past week, a total of " +msgstr "過去1週間、共有 " + +#: templates/index.html:61 +msgid " users have logged in " +msgstr " ビットユーザーログイン." + +#: templates/index.html:61 +msgid " times asset." +msgstr " 次资产." + +#: templates/index.html:69 +msgid "Active user asset ratio" +msgstr "アクティブなユーザー資産比率" + +#: templates/index.html:72 +msgid "" +"The following graphs describe the percentage of active users per month and " +"assets per user host per month, respectively." +msgstr "次のグラフは、1か月あたりのアクティブユーザーの割合と、1か月あたりのユーザーホストあたりの資産の割合をそれぞれ示しています。" + +#: templates/index.html:97 templates/index.html:112 +msgid "Top 10 assets in a week" +msgstr "1週間でトップ10の資産" + +#: templates/index.html:113 +msgid "Login frequency and last login record." +msgstr "ログイン頻度と最後のログイン記録。" + +#: templates/index.html:122 +msgid "Last 10 login" +msgstr "最後の10ログイン" + +#: templates/index.html:128 +msgid "Login record" +msgstr "ログイン記録" + +#: templates/index.html:129 +msgid "Last 10 login records." +msgstr "最後の10件のログイン記録。" + +#: templates/index.html:143 templates/index.html:158 +msgid "Top 10 users in a week" +msgstr "1週間でトップ10のユーザー" + +#: templates/index.html:159 +msgid "User login frequency and last login record." +msgstr "ユーザーログイン頻度と最後のログインレコード。" + +#: templates/index.html:184 +msgid "Monthly data overview" +msgstr "毎月のデータ概要" + +#: templates/index.html:185 +msgid "History summary in one month" +msgstr "1ヶ月で履歴概要" + +#: templates/index.html:193 templates/index.html:217 +msgid "Login count" +msgstr "ログイン数" + +#: templates/index.html:193 templates/index.html:224 +msgid "Active users" +msgstr "アクティブユーザー" + +#: templates/index.html:193 templates/index.html:231 +msgid "Active assets" +msgstr "アクティブな資産" + +#: templates/index.html:262 templates/index.html:313 +msgid "Monthly active users" +msgstr "毎月のアクティブユーザー数" + +#: templates/index.html:262 templates/index.html:314 +msgid "Disable user" +msgstr "ユーザーを無効にする" + +#: templates/index.html:262 templates/index.html:315 +msgid "Month not logged in user" +msgstr "ユーザーにログインしていない月" + +#: templates/index.html:288 templates/index.html:368 +msgid "Access to the source" +msgstr "ソースへのアクセス" + +#: templates/index.html:342 +msgid "Month is logged into the asset" +msgstr "月が資産にログインされます" + +#: templates/index.html:342 templates/index.html:393 +msgid "Disable host" +msgstr "ホストの無効化" + +#: templates/index.html:342 templates/index.html:394 +msgid "Month not logged on host" +msgstr "月がホストにログオンしていない" + +#: templates/index.html:392 +msgid "Month is logged into the host" +msgstr "月がホストにログインされます" + +#: templates/index.html:466 +msgid " times/week" +msgstr " 時間/週" + +#: templates/index.html:491 templates/index.html:527 +msgid " times" +msgstr " 回数" + +#: templates/index.html:494 templates/index.html:530 +msgid "The time last logged in" +msgstr "最後にログインした時刻" + +#: templates/index.html:495 templates/index.html:531 +msgid "At" +msgstr "于" + +#: templates/index.html:510 templates/index.html:545 templates/index.html:580 +msgid "(No)" +msgstr "(しばらく)" + +#: templates/index.html:561 +msgid "Before" +msgstr "前" + +#: templates/index.html:562 +msgid "Login in " +msgstr "ログイン" + +#: templates/resource_download.html:18 templates/resource_download.html:24 +#: templates/resource_download.html:25 templates/resource_download.html:30 +msgid "Client" +msgstr "クライアント" + +#: templates/resource_download.html:20 +msgid "" +"JumpServer Client, currently used to launch the client, now only support " +"launch RDP client, The SSH client will next" +msgstr "現在クライアントの起動に使用されているJumpServerクライアントは、RDPクライアントの起動のみをサポートしています。" + +#: templates/resource_download.html:30 +msgid "Microsoft" +msgstr "マイクロソフト" + +#: templates/resource_download.html:30 +msgid "Official" +msgstr "公式" + +#: templates/resource_download.html:32 +msgid "" +"macOS needs to download the client to connect RDP asset, which comes with " +"Windows" +msgstr "MacOSは、Windowsに付属のRDPアセットを接続するためにクライアントをダウンロードする必要があります" + +#: templates/resource_download.html:41 +msgid "Windows Remote application publisher tools" +msgstr "Windowsリモートアプリケーション発行者ツール" + +#: templates/resource_download.html:42 +msgid "" +"Jmservisor is the program used to pull up remote applications in Windows " +"Remote Application publisher" +msgstr "Jmservisorはwindowsリモートアプリケーションパブリケーションサーバでリモートアプリケーションを引き出すためのプログラムです" + +#: templates/rest_framework/base.html:128 +msgid "Filters" +msgstr "フィルター" + +#: terminal/api/session.py:211 +msgid "Session does not exist: {}" +msgstr "セッションが存在しません: {}" + +#: terminal/api/session.py:214 +msgid "Session is finished or the protocol not supported" +msgstr "セッションが終了したか、プロトコルがサポートされていません" + +#: terminal/api/session.py:219 +msgid "User does not exist: {}" +msgstr "ユーザーが存在しない: {}" + +#: terminal/api/session.py:227 +msgid "User does not have permission" +msgstr "ユーザーに権限がありません" + +#: terminal/api/sharing.py:30 +msgid "Secure session sharing settings is disabled" +msgstr "安全なセッション共有設定が無効になっています" + +#: terminal/api/storage.py:28 +msgid "Deleting the default storage is not allowed" +msgstr "デフォルトのストレージの削除は許可されていません" + +#: terminal/api/storage.py:31 +msgid "Cannot delete storage that is being used" +msgstr "使用中のストレージを削除できません" + +#: terminal/api/storage.py:72 terminal/api/storage.py:73 +msgid "Command storages" +msgstr "コマンドストア" + +#: terminal/api/storage.py:79 +msgid "Invalid" +msgstr "無効" + +#: terminal/api/storage.py:119 +msgid "Test failure: {}" +msgstr "テスト失敗: {}" + +#: terminal/api/storage.py:122 +msgid "Test successful" +msgstr "テスト成功" + +#: terminal/api/storage.py:124 +msgid "Test failure: Account invalid" +msgstr "テスト失敗: アカウントが無効" + +#: terminal/api/terminal.py:39 +msgid "Have online sessions" +msgstr "オンラインセッションを持つ" + +#: terminal/apps.py:9 +msgid "Terminals" +msgstr "ターミナル管理" + +#: terminal/backends/command/es.py:27 +msgid "Invalid elasticsearch config" +msgstr "無効なElasticsearch構成" + +#: terminal/backends/command/models.py:15 +msgid "Ordinary" +msgstr "普通" + +#: terminal/backends/command/models.py:16 +msgid "Dangerous" +msgstr "危険" + +#: terminal/backends/command/models.py:22 +msgid "Input" +msgstr "入力" + +#: terminal/backends/command/models.py:23 +#: terminal/backends/command/serializers.py:16 +msgid "Output" +msgstr "出力" + +#: terminal/backends/command/models.py:24 terminal/models/replay.py:9 +#: terminal/models/sharing.py:17 terminal/models/sharing.py:64 +#: terminal/templates/terminal/_msg_command_alert.html:10 +msgid "Session" +msgstr "セッション" + +#: terminal/backends/command/models.py:25 +#: terminal/backends/command/serializers.py:18 +msgid "Risk level" +msgstr "リスクレベル" + +#: terminal/backends/command/serializers.py:17 +msgid "Session ID" +msgstr "セッションID" + +#: terminal/backends/command/serializers.py:19 +msgid "Risk level display" +msgstr "リスクレベル表示" + +#: terminal/backends/command/serializers.py:21 +msgid "Timestamp" +msgstr "タイムスタンプ" + +#: terminal/backends/command/serializers.py:22 terminal/models/terminal.py:105 +msgid "Remote Address" +msgstr "リモートアドレス" + +#: terminal/const.py:33 +msgid "Critical" +msgstr "クリティカル" + +#: terminal/const.py:34 +msgid "High" +msgstr "高い" + +#: terminal/const.py:35 users/templates/users/reset_password.html:50 +#: users/templates/users/user_password_update.html:104 +msgid "Normal" +msgstr "正常" + +#: terminal/const.py:36 +msgid "Offline" +msgstr "オフライン" + +#: terminal/exceptions.py:8 +msgid "Bulk create not support" +msgstr "一括作成非サポート" + +#: terminal/exceptions.py:13 +msgid "Storage is invalid" +msgstr "ストレージが無効です" + +#: terminal/models/command.py:24 +msgid "Command record" +msgstr "コマンドレコード" + +#: terminal/models/replay.py:12 +msgid "Session replay" +msgstr "セッション再生" + +#: terminal/models/replay.py:14 +msgid "Can upload session replay" +msgstr "セッションのリプレイをアップロードできます" + +#: terminal/models/replay.py:15 +msgid "Can download session replay" +msgstr "セッション再生をダウンロードできます" + +#: terminal/models/session.py:48 terminal/models/sharing.py:87 +msgid "Login from" +msgstr "ログイン元" + +#: terminal/models/session.py:52 +msgid "Replay" +msgstr "リプレイ" + +#: terminal/models/session.py:57 +msgid "Date end" +msgstr "終了日" + +#: terminal/models/session.py:242 +msgid "Session record" +msgstr "セッション記録" + +#: terminal/models/session.py:244 +msgid "Can monitor session" +msgstr "セッションを監視できます" + +#: terminal/models/session.py:245 +msgid "Can share session" +msgstr "セッションを共有できます" + +#: terminal/models/session.py:246 +msgid "Can terminate session" +msgstr "セッションを終了できます" + +#: terminal/models/session.py:247 +msgid "Can validate session action perm" +msgstr "セッションアクションのパーマを検証できます" + +#: terminal/models/sharing.py:22 +msgid "Creator" +msgstr "作成者" + +#: terminal/models/sharing.py:24 terminal/models/sharing.py:66 +msgid "Verify code" +msgstr "コードの確認" + +#: terminal/models/sharing.py:29 +msgid "Expired time (min)" +msgstr "期限切れ時間 (分)" + +#: terminal/models/sharing.py:34 terminal/models/sharing.py:69 +msgid "Session sharing" +msgstr "セッション共有" + +#: terminal/models/sharing.py:36 +msgid "Can add super session sharing" +msgstr "スーパーセッション共有を追加できます" + +#: terminal/models/sharing.py:54 +msgid "Link not active" +msgstr "リンクがアクティブでない" + +#: terminal/models/sharing.py:56 +msgid "Link expired" +msgstr "リンク期限切れ" + +#: terminal/models/sharing.py:73 terminal/serializers/sharing.py:49 +msgid "Joiner" +msgstr "ジョイナー" + +#: terminal/models/sharing.py:76 +msgid "Date joined" +msgstr "参加日" + +#: terminal/models/sharing.py:79 +msgid "Date left" +msgstr "日付が残っています" + +#: terminal/models/sharing.py:97 +#: xpack/plugins/change_auth_plan/models/base.py:192 +msgid "Finished" +msgstr "終了" + +#: terminal/models/sharing.py:102 +msgid "Session join record" +msgstr "セッション参加記録" + +#: terminal/models/sharing.py:118 +msgid "Invalid verification code" +msgstr "検証コードが無効" + +#: terminal/models/status.py:18 +msgid "Session Online" +msgstr "セッションオンライン" + +#: terminal/models/status.py:19 +msgid "CPU Load" +msgstr "CPUロード" + +#: terminal/models/status.py:20 +msgid "Memory Used" +msgstr "使用メモリ" + +#: terminal/models/status.py:21 +msgid "Disk Used" +msgstr "使用済みディスク" + +#: terminal/models/status.py:22 +msgid "Connections" +msgstr "接続" + +#: terminal/models/status.py:23 +msgid "Threads" +msgstr "スレッド" + +#: terminal/models/status.py:24 +msgid "Boot Time" +msgstr "ブート時間" + +#: terminal/models/storage.py:25 +msgid "Default storage" +msgstr "デフォルトのストレージ" + +#: terminal/models/storage.py:113 terminal/models/terminal.py:108 +msgid "Command storage" +msgstr "コマンドストレージ" + +#: terminal/models/storage.py:173 terminal/models/terminal.py:109 +msgid "Replay storage" +msgstr "再生ストレージ" + +#: terminal/models/task.py:17 +msgid "Args" +msgstr "アルグ" + +#: terminal/models/task.py:18 +msgid "Kwargs" +msgstr "クワーグ" + +#: terminal/models/terminal.py:103 +msgid "type" +msgstr "タイプ" + +#: terminal/models/terminal.py:106 +msgid "SSH Port" +msgstr "SSHポート" + +#: terminal/models/terminal.py:107 +msgid "HTTP Port" +msgstr "HTTPポート" + +#: terminal/models/terminal.py:183 terminal/serializers/session.py:38 +msgid "Terminal" +msgstr "ターミナル" + +#: terminal/models/terminal.py:185 +msgid "Can view terminal config" +msgstr "ターミナル構成を表示できます" + +#: terminal/notifications.py:22 +msgid "Sessions" +msgstr "セッション" + +#: terminal/notifications.py:68 +msgid "Danger command alert" +msgstr "危険コマンドアラート" + +#: terminal/notifications.py:92 terminal/notifications.py:140 +msgid "Level" +msgstr "レベル" + +#: terminal/notifications.py:110 +msgid "Batch danger command alert" +msgstr "一括危険コマンド警告" + +#: terminal/serializers/session.py:31 +msgid "User ID" +msgstr "ユーザーID" + +#: terminal/serializers/session.py:32 +msgid "Asset ID" +msgstr "資産ID" + +#: terminal/serializers/session.py:33 +msgid "System user ID" +msgstr "システムユーザーID" + +#: terminal/serializers/session.py:34 +msgid "Login from display" +msgstr "表示からのログイン" + +#: terminal/serializers/session.py:36 +msgid "Can replay" +msgstr "再生できます" + +#: terminal/serializers/session.py:37 +msgid "Can join" +msgstr "参加できます" + +#: terminal/serializers/session.py:40 +msgid "Can terminate" +msgstr "終了できます" + +#: terminal/serializers/session.py:45 +msgid "Command amount" +msgstr "コマンド量" + +#: terminal/serializers/storage.py:21 +msgid "Endpoint invalid: remove path `{}`" +msgstr "エンドポイントが無効: パス '{}' を削除" + +#: terminal/serializers/storage.py:27 +msgid "Bucket" +msgstr "バケット" + +#: terminal/serializers/storage.py:34 users/models/user.py:689 +msgid "Secret key" +msgstr "秘密キー" + +#: terminal/serializers/storage.py:39 terminal/serializers/storage.py:51 +#: terminal/serializers/storage.py:81 terminal/serializers/storage.py:91 +#: terminal/serializers/storage.py:99 +msgid "Endpoint" +msgstr "エンドポイント" + +#: terminal/serializers/storage.py:66 xpack/plugins/cloud/models.py:220 +msgid "Region" +msgstr "リージョン" + +#: terminal/serializers/storage.py:110 +msgid "Container name" +msgstr "コンテナー名" + +#: terminal/serializers/storage.py:112 +msgid "Account name" +msgstr "アカウント名" + +#: terminal/serializers/storage.py:113 +msgid "Account key" +msgstr "アカウントキー" + +#: terminal/serializers/storage.py:116 +msgid "Endpoint suffix" +msgstr "エンドポイントサフィックス" + +#: terminal/serializers/storage.py:138 +msgid "The address format is incorrect" +msgstr "アドレス形式が正しくありません" + +#: terminal/serializers/storage.py:145 +msgid "Host invalid" +msgstr "ホスト無効" + +#: terminal/serializers/storage.py:148 +msgid "Port invalid" +msgstr "ポートが無効" + +#: terminal/serializers/storage.py:164 +msgid "Index" +msgstr "インデックス" + +#: terminal/serializers/storage.py:166 +msgid "Doc type" +msgstr "Docタイプ" + +#: terminal/serializers/storage.py:168 +msgid "Ignore Certificate Verification" +msgstr "証明書の検証を無視する" + +#: terminal/serializers/terminal.py:44 +msgid "Load status" +msgstr "ロードステータス" + +#: terminal/serializers/terminal.py:83 terminal/serializers/terminal.py:91 +msgid "Not found" +msgstr "見つかりません" + +#: terminal/templates/terminal/_msg_command_alert.html:10 +msgid "view" +msgstr "表示" + +#: tickets/apps.py:7 +msgid "Tickets" +msgstr "チケット" + +#: tickets/const.py:8 +msgid "General" +msgstr "一般" + +#: tickets/const.py:10 +msgid "Apply for asset" +msgstr "資産の申請" + +#: tickets/const.py:11 +msgid "Apply for application" +msgstr "申し込み" + +#: tickets/const.py:17 tickets/const.py:30 tickets/const.py:35 +msgid "Open" +msgstr "オープン" + +#: tickets/const.py:18 tickets/const.py:25 +msgid "Approved" +msgstr "承認済み" + +#: tickets/const.py:19 tickets/const.py:26 +msgid "Rejected" +msgstr "拒否" + +#: tickets/const.py:20 tickets/const.py:31 +msgid "Closed" +msgstr "クローズ" + +#: tickets/const.py:24 +msgid "Notified" +msgstr "通知" + +#: tickets/const.py:37 +msgid "Approve" +msgstr "承認" + +#: tickets/const.py:42 +msgid "One level" +msgstr "1つのレベル" + +#: tickets/const.py:43 +msgid "Two level" +msgstr "2つのレベル" + +#: tickets/const.py:47 +msgid "Super admin" +msgstr "スーパー管理者" + +#: tickets/const.py:48 +msgid "Org admin" +msgstr "Org admin" + +#: tickets/const.py:49 +msgid "Super admin and org admin" +msgstr "スーパーadminとorg admin" + +#: tickets/const.py:50 +msgid "Custom user" +msgstr "カスタムユーザー" + +#: tickets/errors.py:9 +msgid "Ticket already closed" +msgstr "チケットはすでに閉じています" + +#: tickets/handler/apply_application.py:53 +msgid "Applied category" +msgstr "応用カテゴリ" + +#: tickets/handler/apply_application.py:54 +msgid "Applied type" +msgstr "応用タイプ" + +#: tickets/handler/apply_application.py:55 +msgid "Applied application group" +msgstr "応用アプリケーショングループ" + +#: tickets/handler/apply_application.py:56 tickets/handler/apply_asset.py:52 +msgid "Applied system user group" +msgstr "応用システムユーザーグループ" + +#: tickets/handler/apply_application.py:57 tickets/handler/apply_asset.py:54 +msgid "Applied date start" +msgstr "適用日開始" + +#: tickets/handler/apply_application.py:58 tickets/handler/apply_asset.py:55 +msgid "Applied date expired" +msgstr "適用期限が切れた" + +#: tickets/handler/apply_application.py:80 +msgid "" +"Created by the ticket, ticket title: {}, ticket applicant: {}, ticket " +"processor: {}, ticket ID: {}" +msgstr "チケットによって作成されたチケットタイトル: {}、チケット申請者: {}、チケット処理者: {}、チケットID: {}" + +#: tickets/handler/apply_asset.py:50 +msgid "Applied node group" +msgstr "適用ノードグループ" + +#: tickets/handler/apply_asset.py:51 +msgid "Applied hostname group" +msgstr "応用ホスト名グループ" + +#: tickets/handler/apply_asset.py:53 +msgid "Applied actions" +msgstr "応用アクション" + +#: tickets/handler/apply_asset.py:77 +msgid "" +"Created by the ticket ticket title: {} ticket applicant: {} ticket " +"processor: {} ticket ID: {}" +msgstr "チケットのタイトル: {} チケット申請者: {} チケットプロセッサ: {} チケットID: {}" + +#: tickets/handler/base.py:88 +msgid "{} {} the ticket" +msgstr "{} {} チケット" + +#: tickets/handler/base.py:116 +msgid "Ticket title" +msgstr "チケットタイトル" + +#: tickets/handler/base.py:117 +msgid "Ticket type" +msgstr "チケットタイプ" + +#: tickets/handler/base.py:118 +msgid "Ticket status" +msgstr "チケットのステータス" + +#: tickets/handler/base.py:119 +msgid "Ticket applicant" +msgstr "チケット申請者" + +#: tickets/handler/base.py:121 +msgid "Ticket basic info" +msgstr "チケット基本情報" + +#: tickets/handler/base.py:132 +msgid "No content" +msgstr "コンテンツなし" + +#: tickets/handler/base.py:134 +msgid "Ticket applied info" +msgstr "チケット適用情報" + +#: tickets/handler/command_confirm.py:25 +msgid "Applied run user" +msgstr "Applied runユーザー" + +#: tickets/handler/command_confirm.py:26 +msgid "Applied run asset" +msgstr "アプライドランアセット" + +#: tickets/handler/command_confirm.py:27 +msgid "Applied run system user" +msgstr "Applied runシステムユーザー" + +#: tickets/handler/command_confirm.py:28 +msgid "Applied run command" +msgstr "Applied runコマンド" + +#: tickets/handler/command_confirm.py:29 +msgid "Applied from session" +msgstr "セッションからの応用" + +#: tickets/handler/command_confirm.py:30 +msgid "Applied from command filter rules" +msgstr "コマンドフィルタルールから適用" + +#: tickets/handler/command_confirm.py:31 +msgid "Applied from command filter" +msgstr "コマンドフィルタからの応用" + +#: tickets/handler/login_asset_confirm.py:17 +msgid "Applied login user" +msgstr "応用ログインユーザー" + +#: tickets/handler/login_asset_confirm.py:18 +msgid "Applied login asset" +msgstr "アプライドログインアセット" + +#: tickets/handler/login_asset_confirm.py:19 +msgid "Applied login system user" +msgstr "応用ログインシステムユーザー" + +#: tickets/handler/login_confirm.py:17 +msgid "Applied login IP" +msgstr "応用ログインIP" + +#: tickets/handler/login_confirm.py:18 +msgid "Applied login city" +msgstr "応用ログイン都市" + +#: tickets/handler/login_confirm.py:19 +msgid "Applied login datetime" +msgstr "適用されたログインの日付時間" + +#: tickets/models/comment.py:19 +msgid "User display name" +msgstr "ユーザー表示名" + +#: tickets/models/comment.py:20 +msgid "Body" +msgstr "ボディ" + +#: tickets/models/flow.py:19 tickets/models/flow.py:61 +#: tickets/models/ticket.py:30 +msgid "Approve level" +msgstr "レベルを承認する" + +#: tickets/models/flow.py:24 tickets/serializers/ticket/ticket.py:141 +msgid "Approve strategy" +msgstr "戦略を承認する" + +#: tickets/models/flow.py:29 tickets/serializers/ticket/ticket.py:142 +msgid "Assignees" +msgstr "アシニーズ" + +#: tickets/models/flow.py:33 +msgid "Ticket flow approval rule" +msgstr "チケットフロー承認ルール" + +#: tickets/models/flow.py:66 +msgid "Ticket flow" +msgstr "チケットの流れ" + +#: tickets/models/relation.py:10 +msgid "Ticket session relation" +msgstr "チケットセッションの関係" + +#: tickets/models/ticket.py:35 +msgid "Ticket step" +msgstr "チケットステップ" + +#: tickets/models/ticket.py:46 +msgid "Ticket assignee" +msgstr "割り当てられたチケット" + +#: tickets/models/ticket.py:128 +msgid "Title" +msgstr "タイトル" + +#: tickets/models/ticket.py:136 +msgid "State" +msgstr "状態" + +#: tickets/models/ticket.py:144 +msgid "Approval step" +msgstr "承認ステップ" + +#: tickets/models/ticket.py:149 +msgid "Applicant" +msgstr "応募者" + +#: tickets/models/ticket.py:151 +msgid "Applicant display" +msgstr "応募者表示" + +#: tickets/models/ticket.py:152 +msgid "Process" +msgstr "プロセス" + +#: tickets/models/ticket.py:157 +msgid "TicketFlow" +msgstr "作業指示プロセス" + +#: tickets/models/ticket.py:311 +msgid "Please try again" +msgstr "もう一度お試しください" + +#: tickets/models/ticket.py:319 +msgid "Super ticket" +msgstr "スーパーチケット" + +#: tickets/notifications.py:63 +msgid "Your has a new ticket, applicant - {}" +msgstr "新しいチケットがあります- {}" + +#: tickets/notifications.py:69 +msgid "New Ticket - {} ({})" +msgstr "新しいチケット- {} ({})" + +#: tickets/notifications.py:91 +msgid "Your ticket has been processed, processor - {}" +msgstr "チケットが処理されました。プロセッサー- {}" + +#: tickets/notifications.py:95 +msgid "Ticket has processed - {} ({})" +msgstr "チケットが処理済み- {} ({})" + +#: tickets/serializers/super_ticket.py:11 +msgid "Processor" +msgstr "プロセッサ" + +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:18 +#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:19 +msgid "Apply name" +msgstr "名前を適用" + +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:37 +msgid "Apply applications" +msgstr "アプリケーションの適用" + +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:42 +msgid "Apply applications display" +msgstr "アプリケーション表示の適用" + +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:46 +#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:41 +msgid "Apply system users" +msgstr "システムユーザーの適用" + +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:51 +msgid "Apply system user display" +msgstr "システムユーザー表示の適用" + +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:71 +#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:73 +#: tickets/serializers/ticket/ticket.py:128 +msgid "Permission named `{}` already exists" +msgstr "'{}'という名前の権限は既に存在します" + +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:88 +#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:87 +msgid "The expiration date should be greater than the start date" +msgstr "有効期限は開始日より大きくする必要があります" + +#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:14 +msgid "Select at least one asset or node" +msgstr "少なくとも1つのアセットまたはノードを選択します。" + +#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:23 +msgid "Apply nodes" +msgstr "ノードの適用" + +#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:27 +msgid "Apply nodes display" +msgstr "Apply nodes display" + +#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:32 +msgid "Apply assets" +msgstr "資産の適用" + +#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:36 +#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:45 +#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:53 +msgid "Apply assets display" +msgstr "アセット表示の適用" + +#: tickets/serializers/ticket/meta/ticket_type/command_confirm.py:12 +msgid "Run user" +msgstr "ユーザーの実行" + +#: tickets/serializers/ticket/meta/ticket_type/command_confirm.py:13 +msgid "Run asset" +msgstr "アセットの実行" + +#: tickets/serializers/ticket/meta/ticket_type/command_confirm.py:15 +msgid "Run system user" +msgstr "システムユーザーの実行" + +#: tickets/serializers/ticket/meta/ticket_type/command_confirm.py:17 +msgid "Run command" +msgstr "実行コマンド" + +#: tickets/serializers/ticket/meta/ticket_type/command_confirm.py:18 +msgid "From session" +msgstr "セッションから" + +#: tickets/serializers/ticket/meta/ticket_type/command_confirm.py:20 +msgid "From cmd filter rule" +msgstr "コマンドフィルタ規則から" + +#: tickets/serializers/ticket/meta/ticket_type/command_confirm.py:22 +msgid "From cmd filter" +msgstr "コマンドフィルタ規則から" + +#: tickets/serializers/ticket/meta/ticket_type/common.py:11 +#: tickets/serializers/ticket/ticket.py:123 +msgid "Created by ticket ({}-{})" +msgstr "チケットで作成 ({}-{})" + +#: tickets/serializers/ticket/meta/ticket_type/login_asset_confirm.py:13 +msgid "Login user" +msgstr "ログインユーザー" + +#: tickets/serializers/ticket/meta/ticket_type/login_asset_confirm.py:14 +msgid "Login asset" +msgstr "ログイン資産" + +#: tickets/serializers/ticket/meta/ticket_type/login_asset_confirm.py:16 +msgid "Login system user" +msgstr "ログインシステムユーザー" + +#: tickets/serializers/ticket/meta/ticket_type/login_confirm.py:20 +msgid "Login datetime" +msgstr "ログイン日時" + +#: tickets/serializers/ticket/ticket.py:95 +msgid "" +"The `type` in the submission data (`{}`) is different from the type in the " +"request url (`{}`)" +msgstr "送信データ ('{}') の「タイプ」は、リクエストURL ('{}') のタイプとは異なります。" + +#: tickets/serializers/ticket/ticket.py:116 +msgid "The ticket flow `{}` does not exist" +msgstr "チケットフロー '{}'が存在しない" + +#: tickets/serializers/ticket/ticket.py:143 +msgid "Assignees display" +msgstr "受付者名" + +#: tickets/serializers/ticket/ticket.py:167 +msgid "Please select the Assignees" +msgstr "受付をお選びください" + +#: tickets/serializers/ticket/ticket.py:193 +msgid "The current organization type already exists" +msgstr "現在の組織タイプは既に存在します。" + +#: tickets/templates/tickets/_base_ticket_body.html:17 +#: tickets/templates/tickets/_msg_ticket.html:12 +msgid "Click here to review" +msgstr "こちらをクリックしてご覧ください" + +#: users/api/user.py:183 +msgid "Could not reset self otp, use profile reset instead" +msgstr "自己otpをリセットできませんでした、代わりにプロファイルリセットを使用" + +#: users/const.py:10 +msgid "System administrator" +msgstr "システム管理者" + +#: users/const.py:11 +msgid "System auditor" +msgstr "システム監査人" + +#: users/const.py:12 +msgid "Organization administrator" +msgstr "組織管理者" + +#: users/const.py:13 +msgid "Organization auditor" +msgstr "組織監査人" + +#: users/const.py:18 +msgid "Reset link will be generated and sent to the user" +msgstr "リセットリンクが生成され、ユーザーに送信されます" + +#: users/const.py:19 +msgid "Set password" +msgstr "パスワードの設定" + +#: users/exceptions.py:10 +msgid "MFA not enabled" +msgstr "MFAが有効化されていません" + +#: users/exceptions.py:20 +msgid "MFA method not support" +msgstr "MFAメソッドはサポートしていません" + +#: 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 " +"modification -> change MFA Settings\"!" +msgstr "" +"有効にすると、次回のログイン時にマルチファクタ認証バインドプロセスに入ります。(個人情報->クイック" +"修正->MFAマルチファクタ認証の設定)で直接バインド!" + +#: users/forms/profile.py:60 +msgid "* Enable MFA to make the account more secure." +msgstr "* アカウントをより安全にするためにMFAを有効にします。" + +#: 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 " +"password, enabling MFA)" +msgstr "あなたとあなたの会社を保護するために、アカウント、パスワード、キーの機密情報を適切に保管してください。(例: 複雑なパスワードの設定、MFAの有効化)" + +#: users/forms/profile.py:76 +msgid "Finish" +msgstr "仕上げ" + +#: users/forms/profile.py:83 +msgid "New password" +msgstr "新しいパスワード" + +#: users/forms/profile.py:88 +msgid "Confirm password" +msgstr "パスワードの確認" + +#: users/forms/profile.py:96 +msgid "Password does not match" +msgstr "パスワードが一致しない" + +#: users/forms/profile.py:108 +msgid "Old password" +msgstr "古いパスワード" + +#: users/forms/profile.py:118 +msgid "Old password error" +msgstr "古いパスワードエラー" + +#: users/forms/profile.py:128 +msgid "Automatically configure and download the SSH key" +msgstr "SSHキーの自動設定とダウンロード" + +#: users/forms/profile.py:130 +msgid "ssh public key" +msgstr "ssh公開キー" + +#: users/forms/profile.py:131 +msgid "ssh-rsa AAAA..." +msgstr "" + +#: users/forms/profile.py:132 +msgid "Paste your id_rsa.pub here." +msgstr "ここにid_rsa.pubを貼り付けます。" + +#: users/forms/profile.py:145 +msgid "Public key should not be the same as your old one." +msgstr "公開鍵は古いものと同じであってはなりません。" + +#: users/forms/profile.py:149 users/serializers/profile.py:95 +#: users/serializers/profile.py:176 users/serializers/profile.py:203 +msgid "Not a valid ssh public key" +msgstr "有効なssh公開鍵ではありません" + +#: users/forms/profile.py:160 users/models/user.py:686 +#: users/templates/users/user_password_update.html:48 +msgid "Public key" +msgstr "公開キー" + +#: users/models/user.py:552 +msgid "Force enable" +msgstr "強制有効" + +#: users/models/user.py:619 +msgid "Local" +msgstr "ローカル" + +#: users/models/user.py:667 users/serializers/user.py:138 +msgid "Is service account" +msgstr "サービスアカウントです" + +#: users/models/user.py:669 +msgid "Avatar" +msgstr "アバター" + +#: users/models/user.py:672 +msgid "Wechat" +msgstr "微信" + +#: users/models/user.py:683 +msgid "Private key" +msgstr "ssh秘密鍵" + +#: users/models/user.py:705 +msgid "Source" +msgstr "ソース" + +#: users/models/user.py:709 +msgid "Date password last updated" +msgstr "最終更新日パスワード" + +#: users/models/user.py:712 +msgid "Need update password" +msgstr "更新パスワードが必要" + +#: users/models/user.py:882 +msgid "Can invite user" +msgstr "ユーザーを招待できます" + +#: users/models/user.py:883 +msgid "Can remove user" +msgstr "ユーザーを削除できます" + +#: users/models/user.py:884 +msgid "Can match user" +msgstr "ユーザーに一致できます" + +#: users/models/user.py:893 +msgid "Administrator" +msgstr "管理者" + +#: users/models/user.py:896 +msgid "Administrator is the super user of system" +msgstr "管理者はシステムのスーパーユーザーです" + +#: users/models/user.py:921 +msgid "User password history" +msgstr "ユーザーパスワード履歴" + +#: users/notifications.py:55 +#: users/templates/users/_msg_password_expire_reminder.html:17 +#: users/templates/users/reset_password.html:5 +#: users/templates/users/reset_password.html:6 +msgid "Reset password" +msgstr "パスワードのリセット" + +#: users/notifications.py:85 users/views/profile/reset.py:127 +msgid "Reset password success" +msgstr "パスワードのリセット成功" + +#: users/notifications.py:117 +msgid "Reset public key success" +msgstr "公開鍵のリセット成功" + +#: users/notifications.py:143 +msgid "Password is about expire" +msgstr "パスワードの有効期限が近づいています" + +#: users/notifications.py:171 +msgid "Account is about expire" +msgstr "アカウントの有効期限が近づいています" + +#: users/notifications.py:193 +msgid "Reset SSH Key" +msgstr "SSHキーのリセット" + +#: users/notifications.py:214 +msgid "Reset MFA" +msgstr "MFAのリセット" + +#: users/serializers/profile.py:29 +msgid "The old password is incorrect" +msgstr "古いパスワードが正しくありません" + +#: users/serializers/profile.py:36 users/serializers/profile.py:190 +msgid "Password does not match security rules" +msgstr "パスワードがセキュリティルールと一致しない" + +#: users/serializers/profile.py:40 +msgid "The new password cannot be the last {} passwords" +msgstr "新しいパスワードを最後の {} 個のパスワードにすることはできません" + +#: users/serializers/profile.py:46 users/serializers/profile.py:66 +msgid "The newly set password is inconsistent" +msgstr "新しく設定されたパスワードが一致しない" + +#: users/serializers/profile.py:142 users/serializers/user.py:136 +msgid "Is first login" +msgstr "最初のログインです" + +#: users/serializers/user.py:24 users/serializers/user.py:31 +msgid "System roles" +msgstr "システムの役割" + +#: users/serializers/user.py:29 users/serializers/user.py:32 +msgid "Org roles" +msgstr "組織ロール" + +#: users/serializers/user.py:75 +#: xpack/plugins/change_auth_plan/models/base.py:35 +#: xpack/plugins/change_auth_plan/serializers/base.py:22 +msgid "Password strategy" +msgstr "パスワード戦略" + +#: users/serializers/user.py:77 +msgid "MFA enabled" +msgstr "MFA有効化" + +#: users/serializers/user.py:78 +msgid "MFA force enabled" +msgstr "MFAフォース有効化" + +#: users/serializers/user.py:80 +msgid "MFA level display" +msgstr "MFAレベル表示" + +#: users/serializers/user.py:82 +msgid "Login blocked" +msgstr "ログインブロック" + +#: users/serializers/user.py:85 +msgid "Can public key authentication" +msgstr "公開鍵認証が可能" + +#: users/serializers/user.py:140 +msgid "Avatar url" +msgstr "アバターURL" + +#: users/serializers/user.py:142 +msgid "Groups name" +msgstr "グループ名" + +#: users/serializers/user.py:143 +msgid "Source name" +msgstr "ソース名" + +#: users/serializers/user.py:144 +msgid "Organization role name" +msgstr "組織の役割名" + +#: users/serializers/user.py:145 +msgid "Super role name" +msgstr "スーパーロール名" + +#: users/serializers/user.py:146 +msgid "Total role name" +msgstr "合計ロール名" + +#: users/serializers/user.py:148 +msgid "Is wecom bound" +msgstr "企業の微信をバインドしているかどうか" + +#: users/serializers/user.py:149 +msgid "Is dingtalk bound" +msgstr "ピンをバインドしているかどうか" + +#: users/serializers/user.py:150 +msgid "Is feishu bound" +msgstr "飛本を縛ったかどうか" + +#: users/serializers/user.py:151 +msgid "Is OTP bound" +msgstr "仮想MFAがバインドされているか" + +#: users/serializers/user.py:153 +msgid "System role name" +msgstr "システムロール名" + +#: users/serializers/user.py:245 +msgid "Select users" +msgstr "ユーザーの選択" + +#: users/serializers/user.py:246 +msgid "For security, only list several users" +msgstr "セキュリティのために、複数のユーザーのみをリストします" + +#: users/serializers/user.py:279 +msgid "name not unique" +msgstr "名前が一意ではない" + +#: users/templates/users/_granted_assets.html:7 +msgid "Loading" +msgstr "読み込み中" + +#: users/templates/users/_msg_account_expire_reminder.html:7 +msgid "Your account will expire in" +msgstr "アカウントの有効期限は" + +#: users/templates/users/_msg_account_expire_reminder.html:8 +msgid "" +"In order not to affect your normal work, please contact the administrator " +"for confirmation." +msgstr "通常の作業に影響を与えないように、確認のために管理者に連絡してください。" + +#: users/templates/users/_msg_password_expire_reminder.html:7 +msgid "Your password will expire in" +msgstr "パスワードは" + +#: users/templates/users/_msg_password_expire_reminder.html:8 +msgid "" +"For your account security, please click on the link below to update your " +"password in time" +msgstr "アカウントのセキュリティについては、下のリンクをクリックしてパスワードを時間内に更新してください" + +#: users/templates/users/_msg_password_expire_reminder.html:11 +msgid "Click here update password" +msgstr "ここをクリック更新パスワード" + +#: users/templates/users/_msg_password_expire_reminder.html:16 +msgid "If your password has expired, please click the link below to" +msgstr "パスワードの有効期限が切れている場合は、以下のリンクをクリックしてください" + +#: users/templates/users/_msg_reset_mfa.html:7 +msgid "Your MFA has been reset by site administrator" +msgstr "MFAはサイト管理者によってリセットされました" + +#: users/templates/users/_msg_reset_mfa.html:8 +#: users/templates/users/_msg_reset_ssh_key.html:8 +msgid "Please click the link below to set" +msgstr "以下のリンクをクリックして設定してください" + +#: users/templates/users/_msg_reset_mfa.html:11 +#: users/templates/users/_msg_reset_ssh_key.html:11 +msgid "Click here set" +msgstr "ここをクリックセット" + +#: users/templates/users/_msg_reset_ssh_key.html:7 +msgid "Your ssh public key has been reset by site administrator" +msgstr "あなたのssh公開鍵はサイト管理者によってリセットされました" + +#: users/templates/users/_msg_user_created.html:15 +msgid "click here to set your password" +msgstr "ここをクリックしてパスワードを設定してください" + +#: users/templates/users/_select_user_modal.html:5 +msgid "Please Select User" +msgstr "ユーザーを選択してください" + +#: users/templates/users/_select_user_modal.html:17 +msgid "Asset num" +msgstr "資産num" + +#: users/templates/users/_user_detail_nav_header.html:11 +msgid "User detail" +msgstr "ユーザーの詳細" + +#: users/templates/users/_user_detail_nav_header.html:15 +msgid "User permissions" +msgstr "ユーザー権限" + +#: users/templates/users/_user_detail_nav_header.html:23 +msgid "Asset granted" +msgstr "付与された資産" + +#: users/templates/users/_user_detail_nav_header.html:40 +msgid "RemoteApp granted" +msgstr "承認されたリモートアプリケーション" + +#: users/templates/users/_user_detail_nav_header.html:47 +msgid "RemoteApp permission" +msgstr "リモートアプリケーションのライセンス" + +#: users/templates/users/_user_detail_nav_header.html:54 +msgid "DatabaseApp granted" +msgstr "認可されたデータベース・アプリケーション" + +#: users/templates/users/_user_detail_nav_header.html:61 +msgid "DatabaseApp permission" +msgstr "数据库应用授权" + +#: users/templates/users/_user_update_pk_modal.html:4 +msgid "Update User SSH Public Key" +msgstr "SSHキーの更新" + +#: users/templates/users/first_login.html:6 +#: users/templates/users/first_login_done.html:19 +msgid "First Login" +msgstr "最初のログイン" + +#: users/templates/users/first_login_done.html:31 +msgid "Welcome to use jumpserver, visit " +msgstr "JumpServer砦機へようこそ" + +#: users/templates/users/first_login_done.html:32 +msgid "Use guide" +msgstr "ガイド人" + +#: users/templates/users/first_login_done.html:32 +msgid " for more information" +msgstr "より多くの情報のため" + +#: users/templates/users/forgot_password.html:23 +msgid "Input your email, that will send a mail to your" +msgstr "あなたのメールを入力し、それはあなたにメールを送信します" + +#: users/templates/users/forgot_password.html:32 +#: users/templates/users/user_password_update.html:75 +msgid "Submit" +msgstr "送信" + +#: users/templates/users/mfa_setting.html:24 +msgid "Enable MFA" +msgstr "MFAの有効化" + +#: users/templates/users/mfa_setting.html:30 +msgid "MFA force enable, cannot disable" +msgstr "MFA強制有効化、無効化できません" + +#: users/templates/users/mfa_setting.html:48 +msgid "MFA setting" +msgstr "MFAの設定" + +#: users/templates/users/reset_password.html:23 +#: users/templates/users/user_password_update.html:64 +msgid "Your password must satisfy" +msgstr "パスワードを満たす必要があります" + +#: users/templates/users/reset_password.html:24 +#: users/templates/users/user_password_update.html:65 +msgid "Password strength" +msgstr "パスワードの強さ" + +#: users/templates/users/reset_password.html:29 +msgid "Setting" +msgstr "設定" + +#: users/templates/users/reset_password.html:48 +#: users/templates/users/user_password_update.html:102 +msgid "Very weak" +msgstr "非常に弱い" + +#: users/templates/users/reset_password.html:49 +#: users/templates/users/user_password_update.html:103 +msgid "Weak" +msgstr "弱い" + +#: users/templates/users/reset_password.html:51 +#: users/templates/users/user_password_update.html:105 +msgid "Medium" +msgstr "中" + +#: users/templates/users/reset_password.html:52 +#: users/templates/users/user_password_update.html:106 +msgid "Strong" +msgstr "強い" + +#: users/templates/users/reset_password.html:53 +#: users/templates/users/user_password_update.html:107 +msgid "Very strong" +msgstr "非常に強い" + +#: users/templates/users/user_asset_permission.html:43 +#: users/templates/users/user_asset_permission.html:155 +#: users/templates/users/user_database_app_permission.html:41 +#: xpack/plugins/cloud/models.py:34 +msgid "Validity" +msgstr "有効性" + +#: users/templates/users/user_asset_permission.html:160 +msgid "Inherit" +msgstr "継承" + +#: users/templates/users/user_asset_permission.html:161 +msgid "Include" +msgstr "含める" + +#: users/templates/users/user_asset_permission.html:162 +msgid "Exclude" +msgstr "除外" + +#: users/templates/users/user_database_app_permission.html:39 +#: users/templates/users/user_database_app_permission.html:64 +msgid "DatabaseApp" +msgstr "データベースの適用" + +#: users/templates/users/user_otp_check_password.html:6 +msgid "Enable OTP" +msgstr "OTPの有効化" + +#: users/templates/users/user_otp_enable_bind.html:6 +msgid "Bind one-time password authenticator" +msgstr "ワンタイムパスワード認証子のバインド" + +#: users/templates/users/user_otp_enable_bind.html:13 +msgid "" +"Use the MFA Authenticator application to scan the following qr code for a 6-" +"bit verification code" +msgstr "MFA Authenticatorアプリケーションを使用して、次のqrコードを6ビット検証コードでスキャンします。" + +#: users/templates/users/user_otp_enable_bind.html:22 +#: users/templates/users/user_verify_mfa.html:27 +msgid "Six figures" +msgstr "6つの数字" + +#: users/templates/users/user_otp_enable_install_app.html:6 +msgid "Install app" +msgstr "アプリのインストール" + +#: users/templates/users/user_otp_enable_install_app.html:13 +msgid "" +"Download and install the MFA Authenticator application on your phone or " +"applet of WeChat" +msgstr "携帯電話またはWeChatのアプレットにMFA Authenticatorアプリケーションをダウンロードしてインストールします" + +#: users/templates/users/user_otp_enable_install_app.html:18 +msgid "Android downloads" +msgstr "Androidのダウンロード" + +#: users/templates/users/user_otp_enable_install_app.html:23 +msgid "iPhone downloads" +msgstr "IPhoneのダウンロード" + +#: users/templates/users/user_otp_enable_install_app.html:26 +msgid "" +"After installation, click the next step to enter the binding page (if " +"installed, go to the next step directly)." +msgstr "インストール後、次のステップをクリックしてバインディングページに入ります (インストールされている場合は、次のステップに直接進みます)。" + +#: users/templates/users/user_password_update.html:74 +msgid "Reset" +msgstr "リセット" + +#: users/templates/users/user_password_verify.html:8 +#: users/templates/users/user_password_verify.html:9 +msgid "Verify password" +msgstr "パスワードの確認" + +#: users/templates/users/user_verify_mfa.html:9 +msgid "Authenticate" +msgstr "認証" + +#: users/templates/users/user_verify_mfa.html:15 +msgid "" +"The account protection has been opened, please complete the following " +"operations according to the prompts" +msgstr "アカウント保護が開始されました。プロンプトに従って次の操作を完了してください" + +#: users/templates/users/user_verify_mfa.html:17 +msgid "Open MFA Authenticator and enter the 6-bit dynamic code" +msgstr "MFA Authenticatorを開き、6ビットの動的コードを入力します" + +#: users/views/profile/otp.py:87 +msgid "Already bound" +msgstr "すでにバインド済み" + +#: users/views/profile/otp.py:88 +msgid "MFA already bound, disable first, then bound" +msgstr "MFAはすでにバインドされており、最初に無効にしてからバインドされています。" + +#: users/views/profile/otp.py:115 +msgid "OTP enable success" +msgstr "OTP有効化成功" + +#: users/views/profile/otp.py:116 +msgid "OTP enable success, return login page" +msgstr "OTP有効化成功、ログインページを返す" + +#: users/views/profile/otp.py:158 +msgid "Disable OTP" +msgstr "OTPの無効化" + +#: users/views/profile/otp.py:164 +msgid "OTP disable success" +msgstr "OTP無効化成功" + +#: users/views/profile/otp.py:165 +msgid "OTP disable success, return login page" +msgstr "OTP無効化成功、ログインページを返す" + +#: users/views/profile/password.py:36 users/views/profile/password.py:41 +msgid "Password invalid" +msgstr "パスワード無効" + +#: users/views/profile/reset.py:40 +msgid "Send reset password message" +msgstr "リセットパスワードメッセージを送信" + +#: users/views/profile/reset.py:41 +msgid "Send reset password mail success, login your mail box and follow it " +msgstr "リセットパスワードメールの成功を送信し、メールボックスにログインしてそれに従う" + +#: users/views/profile/reset.py:52 +msgid "Email address invalid, please input again" +msgstr "メールアドレスが無効です。再度入力してください" + +#: users/views/profile/reset.py:58 +msgid "" +"The user is from {}, please go to the corresponding system to change the " +"password" +msgstr "ユーザーは {}からです。対応するシステムにアクセスしてパスワードを変更してください。" + +#: users/views/profile/reset.py:84 users/views/profile/reset.py:95 +msgid "Token invalid or expired" +msgstr "トークンが無効または期限切れ" + +#: users/views/profile/reset.py:100 +msgid "User auth from {}, go there change password" +msgstr "ユーザー認証ソース {}, 対応するシステムにパスワードを変更してください" + +#: users/views/profile/reset.py:107 +msgid "* Your password does not meet the requirements" +msgstr "* パスワードが要件を満たしていない" + +#: users/views/profile/reset.py:113 +msgid "* The new password cannot be the last {} passwords" +msgstr "* 新しいパスワードを最後の {} パスワードにすることはできません" + +#: users/views/profile/reset.py:128 +msgid "Reset password success, return to login page" +msgstr "パスワードの成功をリセットし、ログインページに戻る" + +#: xpack/apps.py:8 +msgid "XPACK" +msgstr "" + +#: xpack/plugins/change_auth_plan/api/app.py:112 +#: xpack/plugins/change_auth_plan/api/asset.py:95 +msgid "The parameter 'action' must be [{}]" +msgstr "パラメータ 'action' は [{}] でなければなりません。" + +#: xpack/plugins/change_auth_plan/meta.py:9 +#: xpack/plugins/change_auth_plan/models/asset.py:123 +msgid "Change auth plan" +msgstr "密かな計画" + +#: xpack/plugins/change_auth_plan/models/app.py:46 +#: xpack/plugins/change_auth_plan/models/app.py:95 +msgid "Application change auth plan" +msgstr "改密計画の適用" + +#: xpack/plugins/change_auth_plan/models/app.py:99 +#: xpack/plugins/change_auth_plan/models/app.py:151 +msgid "Application change auth plan execution" +msgstr "改密計画実行の適用" + +#: xpack/plugins/change_auth_plan/models/app.py:144 +#: xpack/plugins/change_auth_plan/serializers/app.py:64 +msgid "App" +msgstr "適用" + +#: xpack/plugins/change_auth_plan/models/app.py:156 +msgid "Application change auth plan task" +msgstr "改密計画タスクの適用" + +#: xpack/plugins/change_auth_plan/models/app.py:180 +#: xpack/plugins/change_auth_plan/models/asset.py:263 +msgid "Password cannot be set to blank, exit. " +msgstr "パスワードを空白に設定することはできません。" + +#: xpack/plugins/change_auth_plan/models/asset.py:29 +msgid "Append SSH KEY" +msgstr "追加" + +#: xpack/plugins/change_auth_plan/models/asset.py:30 +msgid "Empty and append SSH KEY" +msgstr "すべてクリアして追加" + +#: xpack/plugins/change_auth_plan/models/asset.py:31 +msgid "Replace (The key generated by JumpServer) " +msgstr "置換(JumpServerによって生成された鍵)" + +#: xpack/plugins/change_auth_plan/models/asset.py:49 +#: xpack/plugins/change_auth_plan/serializers/asset.py:35 +msgid "SSH Key strategy" +msgstr "SSHキー戦略" + +#: xpack/plugins/change_auth_plan/models/asset.py:67 +msgid "Asset change auth plan" +msgstr "資産変更のオースプラン" + +#: xpack/plugins/change_auth_plan/models/asset.py:134 +msgid "Asset change auth plan execution" +msgstr "資産変更のオースプランの実行" + +#: xpack/plugins/change_auth_plan/models/asset.py:210 +msgid "Change auth plan execution" +msgstr "改密計画の実行" + +#: xpack/plugins/change_auth_plan/models/asset.py:217 +msgid "Asset change auth plan task" +msgstr "資産改密計画タスク" + +#: xpack/plugins/change_auth_plan/models/asset.py:252 +msgid "This asset does not have a privileged user set: " +msgstr "このアセットには特権ユーザーセットがありません。" + +#: xpack/plugins/change_auth_plan/models/asset.py:258 +msgid "" +"The password and key of the current asset privileged user cannot be changed: " +msgstr "現在のアセット特権ユーザーのパスワードとキーは変更できません。" + +#: xpack/plugins/change_auth_plan/models/asset.py:269 +msgid "Public key cannot be set to null, exit. " +msgstr "公開鍵をnull、exitに設定することはできません。" + +#: xpack/plugins/change_auth_plan/models/base.py:28 +msgid "All assets use the same random password" +msgstr "すべての資産は同じランダムパスワードを使用します" + +#: xpack/plugins/change_auth_plan/models/base.py:29 +msgid "All assets use different random password" +msgstr "すべての資産は異なるランダムパスワードを使用します" + +#: xpack/plugins/change_auth_plan/models/base.py:39 +msgid "Password rules" +msgstr "パスワードルール" + +#: xpack/plugins/change_auth_plan/models/base.py:118 +msgid "Change auth plan snapshot" +msgstr "計画スナップショットの暗号化" + +#: xpack/plugins/change_auth_plan/models/base.py:187 +msgid "Ready" +msgstr "の準備を" + +#: xpack/plugins/change_auth_plan/models/base.py:188 +msgid "Preflight check" +msgstr "プリフライトチェック" + +#: xpack/plugins/change_auth_plan/models/base.py:189 +msgid "Change auth" +msgstr "秘密を改める" + +#: xpack/plugins/change_auth_plan/models/base.py:190 +msgid "Verify auth" +msgstr "パスワード/キーの確認" + +#: xpack/plugins/change_auth_plan/models/base.py:191 +msgid "Keep auth" +msgstr "パスワード/キーの保存" + +#: xpack/plugins/change_auth_plan/models/base.py:199 +msgid "Step" +msgstr "ステップ" + +#: xpack/plugins/change_auth_plan/notifications.py:8 +msgid "Notification of implementation result of encryption change plan" +msgstr "暗号化変更プランの実装結果の通知" + +#: xpack/plugins/change_auth_plan/notifications.py:18 +msgid "" +"{} - The encryption change task has been completed. See the attachment for " +"details" +msgstr "{} -暗号化変更タスクが完了しました。詳細は添付ファイルをご覧ください" + +#: xpack/plugins/change_auth_plan/notifications.py:19 +msgid "" +"{} - The encryption change task has been completed: the encryption password " +"has not been set - please go to personal information -> file encryption " +"password to set the encryption password" +msgstr "{} -暗号化変更タスクが完了しました: 暗号化パスワードが設定されていません-個人情報にアクセスしてください-> ファイル暗号化パスワードを設定してください" + +#: xpack/plugins/change_auth_plan/serializers/asset.py:32 +msgid "Change Password" +msgstr "パスワードの変更" + +#: xpack/plugins/change_auth_plan/serializers/asset.py:33 +msgid "Change SSH Key" +msgstr "SSHキーの変更" + +#: xpack/plugins/change_auth_plan/serializers/base.py:43 +msgid "Run times" +msgstr "実行時間" + +#: xpack/plugins/change_auth_plan/serializers/base.py:57 +msgid "* Please enter the correct password length" +msgstr "* 正しいパスワードの長さを入力してください" + +#: xpack/plugins/change_auth_plan/serializers/base.py:60 +msgid "* Password length range 6-30 bits" +msgstr "* パスワードの長さの範囲6-30ビット" + +#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:236 +msgid "After many attempts to change the secret, it still failed" +msgstr "秘密を変更しようとする多くの試みの後、それはまだ失敗しました" + +#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:255 +msgid "Invalid/incorrect password" +msgstr "パスワードが無効/間違っている" + +#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:257 +msgid "Failed to connect to the host" +msgstr "ホストへの接続に失敗しました" + +#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:259 +msgid "Data could not be sent to remote" +msgstr "データをリモートに送信できませんでした" + +#: xpack/plugins/cloud/api.py:40 +msgid "Test connection successful" +msgstr "テスト接続成功" + +#: xpack/plugins/cloud/api.py:42 +msgid "Test connection failed: {}" +msgstr "テスト接続に失敗しました: {}" + +#: xpack/plugins/cloud/const.py:8 +msgid "Alibaba Cloud" +msgstr "アリ雲" + +#: xpack/plugins/cloud/const.py:9 +msgid "AWS (International)" +msgstr "AWS (国際)" + +#: xpack/plugins/cloud/const.py:10 +msgid "AWS (China)" +msgstr "AWS (中国)" + +#: xpack/plugins/cloud/const.py:11 +msgid "Azure (China)" +msgstr "Azure (中国)" + +#: xpack/plugins/cloud/const.py:12 +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 "百度雲" + +#: xpack/plugins/cloud/const.py:15 +msgid "Tencent Cloud" +msgstr "テンセント雲" + +#: xpack/plugins/cloud/const.py:16 +msgid "VMware" +msgstr "" + +#: xpack/plugins/cloud/const.py:17 xpack/plugins/cloud/providers/nutanix.py:13 +msgid "Nutanix" +msgstr "" + +#: xpack/plugins/cloud/const.py:18 +msgid "Huawei Private Cloud" +msgstr "華為私有雲" + +#: xpack/plugins/cloud/const.py:19 +msgid "Qingyun Private Cloud" +msgstr "青雲私有雲" + +#: xpack/plugins/cloud/const.py:20 +msgid "OpenStack" +msgstr "" + +#: xpack/plugins/cloud/const.py:21 +msgid "Google Cloud Platform" +msgstr "谷歌雲" + +#: xpack/plugins/cloud/const.py:25 +msgid "Instance name" +msgstr "インスタンス名" + +#: xpack/plugins/cloud/const.py:26 +msgid "Instance name and Partial IP" +msgstr "インスタンス名と部分IP" + +#: xpack/plugins/cloud/const.py:31 +msgid "Succeed" +msgstr "成功" + +#: xpack/plugins/cloud/const.py:35 +msgid "Unsync" +msgstr "同期していません" + +#: xpack/plugins/cloud/const.py:36 +msgid "New Sync" +msgstr "新しい同期" + +#: xpack/plugins/cloud/const.py:37 +msgid "Synced" +msgstr "同期済み" + +#: xpack/plugins/cloud/const.py:38 +msgid "Released" +msgstr "リリース済み" + +#: xpack/plugins/cloud/meta.py:9 +msgid "Cloud center" +msgstr "クラウドセンター" + +#: xpack/plugins/cloud/models.py:30 +msgid "Provider" +msgstr "プロバイダー" + +#: xpack/plugins/cloud/models.py:39 +msgid "Cloud account" +msgstr "クラウドアカウント" + +#: xpack/plugins/cloud/models.py:41 +msgid "Test cloud account" +msgstr "クラウドアカウントのテスト" + +#: xpack/plugins/cloud/models.py:85 xpack/plugins/cloud/serializers/task.py:66 +msgid "Account" +msgstr "アカウント" + +#: xpack/plugins/cloud/models.py:88 xpack/plugins/cloud/serializers/task.py:37 +msgid "Regions" +msgstr "リージョン" + +#: xpack/plugins/cloud/models.py:91 +msgid "Hostname strategy" +msgstr "ホスト名戦略" + +#: xpack/plugins/cloud/models.py:100 xpack/plugins/cloud/serializers/task.py:67 +msgid "Unix admin user" +msgstr "Unix adminユーザー" + +#: xpack/plugins/cloud/models.py:104 xpack/plugins/cloud/serializers/task.py:68 +msgid "Windows admin user" +msgstr "Windows管理者" + +#: xpack/plugins/cloud/models.py:110 xpack/plugins/cloud/serializers/task.py:45 +msgid "IP network segment group" +msgstr "IPネットワークセグメントグループ" + +#: xpack/plugins/cloud/models.py:113 xpack/plugins/cloud/serializers/task.py:71 +msgid "Always update" +msgstr "常に更新" + +#: xpack/plugins/cloud/models.py:119 +msgid "Date last sync" +msgstr "最終同期日" + +#: xpack/plugins/cloud/models.py:130 xpack/plugins/cloud/models.py:171 +msgid "Sync instance task" +msgstr "インスタンスの同期タスク" + +#: xpack/plugins/cloud/models.py:182 xpack/plugins/cloud/models.py:230 +msgid "Date sync" +msgstr "日付の同期" + +#: xpack/plugins/cloud/models.py:186 +msgid "Sync instance task execution" +msgstr "インスタンスタスクの同期実行" + +#: xpack/plugins/cloud/models.py:210 +msgid "Sync task" +msgstr "同期タスク" + +#: xpack/plugins/cloud/models.py:214 +msgid "Sync instance task history" +msgstr "インスタンスタスク履歴の同期" + +#: xpack/plugins/cloud/models.py:217 +msgid "Instance" +msgstr "インスタンス" + +#: xpack/plugins/cloud/models.py:234 +msgid "Sync instance detail" +msgstr "同期インスタンスの詳細" + +#: xpack/plugins/cloud/providers/aws_international.py:17 +msgid "China (Beijing)" +msgstr "中国 (北京)" + +#: xpack/plugins/cloud/providers/aws_international.py:18 +msgid "China (Ningxia)" +msgstr "中国 (寧夏)" + +#: xpack/plugins/cloud/providers/aws_international.py:21 +msgid "US East (Ohio)" +msgstr "米国東部 (オハイオ州)" + +#: xpack/plugins/cloud/providers/aws_international.py:22 +msgid "US East (N. Virginia)" +msgstr "米国東部 (N. バージニア州)" + +#: xpack/plugins/cloud/providers/aws_international.py:23 +msgid "US West (N. California)" +msgstr "米国西部 (N. カリフォルニア州)" + +#: xpack/plugins/cloud/providers/aws_international.py:24 +msgid "US West (Oregon)" +msgstr "米国西部 (オレゴン州)" + +#: xpack/plugins/cloud/providers/aws_international.py:25 +msgid "Africa (Cape Town)" +msgstr "アフリカ (ケープタウン)" + +#: xpack/plugins/cloud/providers/aws_international.py:26 +msgid "Asia Pacific (Hong Kong)" +msgstr "アジアパシフィック (香港)" + +#: xpack/plugins/cloud/providers/aws_international.py:27 +msgid "Asia Pacific (Mumbai)" +msgstr "アジア太平洋 (ムンバイ)" + +#: xpack/plugins/cloud/providers/aws_international.py:28 +msgid "Asia Pacific (Osaka-Local)" +msgstr "アジアパシフィック (大阪-ローカル)" + +#: xpack/plugins/cloud/providers/aws_international.py:29 +msgid "Asia Pacific (Seoul)" +msgstr "アジア太平洋地域 (ソウル)" + +#: xpack/plugins/cloud/providers/aws_international.py:30 +msgid "Asia Pacific (Singapore)" +msgstr "アジア太平洋 (シンガポール)" + +#: xpack/plugins/cloud/providers/aws_international.py:31 +msgid "Asia Pacific (Sydney)" +msgstr "アジア太平洋 (シドニー)" + +#: xpack/plugins/cloud/providers/aws_international.py:32 +msgid "Asia Pacific (Tokyo)" +msgstr "アジアパシフィック (東京)" + +#: xpack/plugins/cloud/providers/aws_international.py:33 +msgid "Canada (Central)" +msgstr "カナダ (中央)" + +#: xpack/plugins/cloud/providers/aws_international.py:34 +msgid "Europe (Frankfurt)" +msgstr "ヨーロッパ (フランクフルト)" + +#: xpack/plugins/cloud/providers/aws_international.py:35 +msgid "Europe (Ireland)" +msgstr "ヨーロッパ (アイルランド)" + +#: xpack/plugins/cloud/providers/aws_international.py:36 +msgid "Europe (London)" +msgstr "ヨーロッパ (ロンドン)" + +#: xpack/plugins/cloud/providers/aws_international.py:37 +msgid "Europe (Milan)" +msgstr "ヨーロッパ (ミラノ)" + +#: xpack/plugins/cloud/providers/aws_international.py:38 +msgid "Europe (Paris)" +msgstr "ヨーロッパ (パリ)" + +#: xpack/plugins/cloud/providers/aws_international.py:39 +msgid "Europe (Stockholm)" +msgstr "ヨーロッパ (ストックホルム)" + +#: xpack/plugins/cloud/providers/aws_international.py:40 +msgid "Middle East (Bahrain)" +msgstr "中东 (バーレーン)" + +#: xpack/plugins/cloud/providers/aws_international.py:41 +msgid "South America (São Paulo)" +msgstr "南米 (サンパウロ)" + +#: xpack/plugins/cloud/providers/baiducloud.py:54 +msgid "CN North-Beijing" +msgstr "華北-北京" + +#: xpack/plugins/cloud/providers/baiducloud.py:55 +#: xpack/plugins/cloud/providers/huaweicloud.py:40 +msgid "CN South-Guangzhou" +msgstr "華南-広州" + +#: xpack/plugins/cloud/providers/baiducloud.py:56 +msgid "CN East-Suzhou" +msgstr "華東-蘇州" + +#: xpack/plugins/cloud/providers/baiducloud.py:57 +#: xpack/plugins/cloud/providers/huaweicloud.py:48 +msgid "CN-Hong Kong" +msgstr "中国-香港" + +#: xpack/plugins/cloud/providers/baiducloud.py:58 +msgid "CN Center-Wuhan" +msgstr "華中-武漢" + +#: xpack/plugins/cloud/providers/baiducloud.py:59 +msgid "CN North-Baoding" +msgstr "華北-保定" + +#: xpack/plugins/cloud/providers/baiducloud.py:60 +msgid "CN East-Shanghai" +msgstr "華東-上海" + +#: xpack/plugins/cloud/providers/baiducloud.py:61 +#: xpack/plugins/cloud/providers/huaweicloud.py:47 +msgid "AP-Singapore" +msgstr "アジア太平洋-シンガポール" + +#: xpack/plugins/cloud/providers/huaweicloud.py:35 +msgid "AF-Johannesburg" +msgstr "アフリカ-ヨハネスブルク" + +#: xpack/plugins/cloud/providers/huaweicloud.py:36 +msgid "CN North-Beijing4" +msgstr "華北-北京4" + +#: xpack/plugins/cloud/providers/huaweicloud.py:37 +msgid "CN North-Beijing1" +msgstr "華北-北京1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:38 +msgid "CN East-Shanghai2" +msgstr "華東-上海2" + +#: xpack/plugins/cloud/providers/huaweicloud.py:39 +msgid "CN East-Shanghai1" +msgstr "華東-上海1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:41 +msgid "LA-Mexico City1" +msgstr "LA-メキシコCity1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:42 +msgid "LA-Santiago" +msgstr "ラテンアメリカ-サンディエゴ" + +#: xpack/plugins/cloud/providers/huaweicloud.py:43 +msgid "LA-Sao Paulo1" +msgstr "ラミー・サンパウロ1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:44 +msgid "EU-Paris" +msgstr "ヨーロッパ-パリ" + +#: xpack/plugins/cloud/providers/huaweicloud.py:45 +msgid "CN Southwest-Guiyang1" +msgstr "南西-貴陽1" + +#: xpack/plugins/cloud/providers/huaweicloud.py:46 +msgid "AP-Bangkok" +msgstr "アジア太平洋-バンコク" + +#: xpack/plugins/cloud/providers/huaweicloud.py:50 +msgid "CN Northeast-Dalian" +msgstr "华北-大连" + +#: xpack/plugins/cloud/providers/huaweicloud.py:51 +msgid "CN North-Ulanqab1" +msgstr "華北-ウランチャブ一" + +#: xpack/plugins/cloud/providers/huaweicloud.py:52 +msgid "CN South-Guangzhou-InvitationOnly" +msgstr "華南-広州-友好ユーザー環境" + +#: xpack/plugins/cloud/serializers/account.py:59 +msgid "Validity display" +msgstr "有効表示" + +#: xpack/plugins/cloud/serializers/account.py:60 +msgid "Provider display" +msgstr "プロバイダ表示" + +#: xpack/plugins/cloud/serializers/account_attrs.py:13 +msgid "AccessKey ID" +msgstr "" + +#: xpack/plugins/cloud/serializers/account_attrs.py:16 +msgid "AccessKey Secret" +msgstr "" + +#: xpack/plugins/cloud/serializers/account_attrs.py:31 +msgid "Client ID" +msgstr "クライアントID" + +#: xpack/plugins/cloud/serializers/account_attrs.py:37 +msgid "Tenant ID" +msgstr "テナントID" + +#: xpack/plugins/cloud/serializers/account_attrs.py:40 +msgid "Subscription ID" +msgstr "サブスクリプションID" + +#: xpack/plugins/cloud/serializers/account_attrs.py:91 +#: xpack/plugins/cloud/serializers/account_attrs.py:96 +msgid "API Endpoint" +msgstr "APIエンドポイント" + +#: xpack/plugins/cloud/serializers/account_attrs.py:102 +msgid "Auth url" +msgstr "認証アドレス" + +#: xpack/plugins/cloud/serializers/account_attrs.py:103 +msgid "eg: http://openstack.example.com:5000/v3" +msgstr "例えば: http://openstack.example.com:5000/v3" + +#: xpack/plugins/cloud/serializers/account_attrs.py:106 +msgid "User domain" +msgstr "ユーザードメイン" + +#: xpack/plugins/cloud/serializers/account_attrs.py:113 +msgid "Service account key" +msgstr "サービスアカウントキー" + +#: xpack/plugins/cloud/serializers/account_attrs.py:114 +msgid "The file is in JSON format" +msgstr "ファイルはJSON形式です。" + +#: xpack/plugins/cloud/serializers/task.py:29 +msgid "" +"The IP address that is first matched to will be used as the IP of the " +"created asset.
The default * indicates a random match.
Format for " +"comma-delimited string, Such as: 192.168.1.0/24, 10.1.1.1-10.1.1.20" +msgstr "" +"最初に一致するIPアドレスは、作成された資産のIPとして使用されます。
デフォルト*はランダムマッチングを表します。" +"
カンマで区切られた文字列で書式設定,たとえば:192.168.1.0/24,10.1.1.1-10.1.1.20" + +#: xpack/plugins/cloud/serializers/task.py:35 +msgid "History count" +msgstr "実行回数" + +#: xpack/plugins/cloud/serializers/task.py:36 +msgid "Instance count" +msgstr "インスタンス数" + +#: xpack/plugins/cloud/serializers/task.py:65 +msgid "Linux admin user" +msgstr "Linux管理者" + +#: xpack/plugins/cloud/serializers/task.py:70 +#: xpack/plugins/gathered_user/serializers.py:20 +msgid "Periodic display" +msgstr "定期的な表示" + +#: xpack/plugins/cloud/utils.py:68 +msgid "Account unavailable" +msgstr "利用できないアカウント" + +#: xpack/plugins/gathered_user/meta.py:11 +msgid "Gathered user" +msgstr "収集されたユーザー" + +#: xpack/plugins/gathered_user/models.py:39 +msgid "Gather user task" +msgstr "ユーザータスクの収集" + +#: xpack/plugins/gathered_user/models.py:85 +msgid "gather user task execution" +msgstr "ユーザータスクの実行を収集" + +#: xpack/plugins/gathered_user/models.py:91 +msgid "Assets is empty, please change nodes" +msgstr "資産は空です。ノードを変更してください" + +#: xpack/plugins/gathered_user/serializers.py:21 +msgid "Executed times" +msgstr "実行時間" + +#: xpack/plugins/interface/api.py:50 +msgid "It is already in the default setting state!" +msgstr "すでにデフォルトの設定状態です!" + +#: xpack/plugins/interface/api.py:53 +msgid "Restore default successfully." +msgstr "デフォルトの復元に成功しました。" + +#: xpack/plugins/interface/meta.py:10 +msgid "Interface settings" +msgstr "インターフェイスの設定" + +#: xpack/plugins/interface/models.py:16 +msgid "Title of login page" +msgstr "ログインページのタイトル" + +#: xpack/plugins/interface/models.py:20 +msgid "Image of login page" +msgstr "ログインページのイメージ" + +#: xpack/plugins/interface/models.py:24 +msgid "Website icon" +msgstr "ウェブサイトのアイコン" + +#: xpack/plugins/interface/models.py:28 +msgid "Logo of management page" +msgstr "管理ページのロゴ" + +#: xpack/plugins/interface/models.py:32 +msgid "Logo of logout page" +msgstr "ログアウトページのロゴ" + +#: xpack/plugins/interface/models.py:36 +msgid "Interface setting" +msgstr "インターフェイスの設定" + +#: xpack/plugins/license/api.py:43 +msgid "License import successfully" +msgstr "ライセンスのインポートに成功" + +#: xpack/plugins/license/api.py:44 +msgid "License is invalid" +msgstr "ライセンスが無効です" + +#: xpack/plugins/license/meta.py:11 xpack/plugins/license/models.py:127 +msgid "License" +msgstr "ライセンス" + +#: xpack/plugins/license/models.py:71 +msgid "Standard edition" +msgstr "標準版" + +#: xpack/plugins/license/models.py:73 +msgid "Enterprise edition" +msgstr "エンタープライズ版" + +#: xpack/plugins/license/models.py:75 +msgid "Ultimate edition" +msgstr "究極のエディション" + +#: xpack/plugins/license/models.py:77 +msgid "Community edition" +msgstr "コミュニティ版" diff --git a/apps/locale/ja/LC_MESSAGES/djangojs.mo b/apps/locale/ja/LC_MESSAGES/djangojs.mo new file mode 100644 index 000000000..fe05f6a5d --- /dev/null +++ b/apps/locale/ja/LC_MESSAGES/djangojs.mo @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1c4a4fa3abb21fea213011d50fd62455fb1ddf73538401dc8cd9c03f4f4bbc77 +size 3322 diff --git a/apps/locale/ja/LC_MESSAGES/djangojs.po b/apps/locale/ja/LC_MESSAGES/djangojs.po new file mode 100644 index 000000000..482394a7b --- /dev/null +++ b/apps/locale/ja/LC_MESSAGES/djangojs.po @@ -0,0 +1,158 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-03-22 15:29+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: static/js/jumpserver.js:260 +msgid "Update is successful!" +msgstr "アップデートは成功しました!" + +#: static/js/jumpserver.js:262 +msgid "An unknown error occurred while updating.." +msgstr "更新中に不明なエラーが発生しました。" + +#: static/js/jumpserver.js:333 +msgid "Not found" +msgstr "見つかりません" + +#: static/js/jumpserver.js:335 +msgid "Server error" +msgstr "サーバーエラー" + +#: static/js/jumpserver.js:337 static/js/jumpserver.js:375 +#: static/js/jumpserver.js:377 +msgid "Error" +msgstr "エラー" + +#: static/js/jumpserver.js:343 static/js/jumpserver.js:384 +msgid "Delete the success" +msgstr "成功を削除する" + +#: static/js/jumpserver.js:350 +msgid "Are you sure about deleting it?" +msgstr "削除してもよろしいですか?" + +#: static/js/jumpserver.js:354 static/js/jumpserver.js:395 +msgid "Cancel" +msgstr "キャンセル" + +#: static/js/jumpserver.js:356 static/js/jumpserver.js:397 +msgid "Confirm" +msgstr "確認" + +#: static/js/jumpserver.js:375 +msgid "" +"The organization contains undeleted information. Please try again after " +"deleting" +msgstr "組織には削除されていない情報が含まれています。削除後にもう一度お試しください" + +#: static/js/jumpserver.js:377 +msgid "" +"Do not perform this operation under this organization. Try again after " +"switching to another organization" +msgstr "この組織ではこの操作を実行しないでください。別の組織に切り替えた後にもう一度お試しください" + +#: static/js/jumpserver.js:391 +msgid "" +"Please ensure that the following information in the organization has been " +"deleted" +msgstr "組織内の次の情報が削除されていることを確認してください" + +#: static/js/jumpserver.js:392 +msgid "" +"User list、User group、Asset list、Domain list、Admin user、System user、" +"Labels、Asset permission" +msgstr "ユーザーリスト、ユーザーグループ、資産リスト、ドメインリスト、管理ユーザー、システムユーザー、ラベル、資産権限" + +#: static/js/jumpserver.js:469 +msgid "Loading" +msgstr "読み込み中" + +#: static/js/jumpserver.js:470 +msgid "Search" +msgstr "検索" + +#: static/js/jumpserver.js:473 +#, javascript-format +msgid "Selected item %d" +msgstr "選択したアイテム % d" + +#: static/js/jumpserver.js:477 +msgid "Per page _MENU_" +msgstr "各ページ _MENU_" + +#: static/js/jumpserver.js:478 +msgid "" +"Displays the results of items _START_ to _END_; A total of _TOTAL_ entries" +msgstr "アイテムの結果を表示します _START_ に着く _END_; 合計 _TOTAL_ エントリ" + +#: static/js/jumpserver.js:481 +msgid "No match" +msgstr "一致しません" + +#: static/js/jumpserver.js:482 +msgid "No record" +msgstr "記録なし" + +#: static/js/jumpserver.js:662 +msgid "Unknown error occur" +msgstr "不明なエラーが発生" + +#: static/js/jumpserver.js:915 +msgid "Password minimum length {N} bits" +msgstr "最小パスワード長 {N} ビット" + +#: static/js/jumpserver.js:916 +msgid "Must contain capital letters" +msgstr "大文字を含める必要があります" + +#: static/js/jumpserver.js:917 +msgid "Must contain lowercase letters" +msgstr "小文字を含める必要があります" + +#: static/js/jumpserver.js:918 +msgid "Must contain numeric characters" +msgstr "数字を含める必要があります。" + +#: static/js/jumpserver.js:919 +msgid "Must contain special characters" +msgstr "特殊文字を含める必要があります" + +#: static/js/jumpserver.js:1098 static/js/jumpserver.js:1122 +msgid "Export failed" +msgstr "エクスポートに失敗しました" + +#: static/js/jumpserver.js:1139 +msgid "Import Success" +msgstr "インポートの成功" + +#: static/js/jumpserver.js:1144 +msgid "Update Success" +msgstr "更新の成功" + +#: static/js/jumpserver.js:1145 +msgid "Count" +msgstr "カウント" + +#: static/js/jumpserver.js:1174 +msgid "Import failed" +msgstr "インポートに失敗しました" + +#: static/js/jumpserver.js:1179 +msgid "Update failed" +msgstr "更新に失敗しました" diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 13f102da7..4d1f7fae3 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -1795,7 +1795,7 @@ msgstr "" #: authentication/backends/drf.py:90 authentication/backends/drf.py:106 msgid "Invalid signature." -msgstr "" +msgstr "签名无效" #: authentication/backends/drf.py:97 msgid "HTTP header: Date not provide or not %a, %d %b %Y %H:%M:%S GMT" @@ -1803,7 +1803,7 @@ msgstr "" #: authentication/backends/drf.py:102 msgid "Expired, more than 15 minutes" -msgstr "" +msgstr "已过期,超过15分钟" #: authentication/backends/drf.py:109 msgid "User disabled." @@ -1811,20 +1811,20 @@ msgstr "用户已禁用" #: authentication/backends/drf.py:127 msgid "Invalid token header. No credentials provided." -msgstr "" +msgstr "无效的令牌头。没有提供任何凭据。" #: authentication/backends/drf.py:130 msgid "Invalid token header. Sign string should not contain spaces." -msgstr "" +msgstr "无效的令牌头。符号字符串不应包含空格。" #: authentication/backends/drf.py:137 msgid "" "Invalid token header. Sign string should not contain invalid characters." -msgstr "" +msgstr "无效的令牌头。符号字符串不应包含无效字符。" #: authentication/backends/drf.py:148 msgid "Invalid token or cache refreshed." -msgstr "" +msgstr "刷新的令牌或缓存无效。" #: authentication/errors.py:26 msgid "Username/password check failed" @@ -2518,7 +2518,7 @@ msgstr "这个操作需要验证 MFA" #: common/exceptions.py:53 msgid "Unexpect error occur" -msgstr "" +msgstr "发生意外错误" #: common/fields/model.py:80 msgid "Marshal dict data to char field" @@ -2606,7 +2606,7 @@ msgstr "无效IP" #: common/utils/geoip/utils.py:28 msgid "LAN" -msgstr "" +msgstr "LAN" #: common/utils/geoip/utils.py:35 common/utils/geoip/utils.py:45 msgid "Unknown ip" @@ -3626,11 +3626,11 @@ msgstr "启用 SAML2 认证" #: settings/serializers/auth/saml2.py:15 msgid "IDP metadata URL" -msgstr "" +msgstr "IDP metadata 地址" #: settings/serializers/auth/saml2.py:18 msgid "IDP metadata XML" -msgstr "" +msgstr "IDP metadata XML" #: settings/serializers/auth/saml2.py:21 msgid "SP advanced settings" @@ -3881,11 +3881,11 @@ msgstr "OTP 延迟有效次数" #: settings/serializers/other.py:21 msgid "CMD" -msgstr "" +msgstr "CMD" #: settings/serializers/other.py:22 msgid "PowerShell" -msgstr "" +msgstr "PowerShell" #: settings/serializers/other.py:24 msgid "Shell (Windows)" @@ -4671,7 +4671,7 @@ msgstr "" #: templates/resource_download.html:30 msgid "Microsoft" -msgstr "" +msgstr "微软" #: templates/resource_download.html:30 msgid "Official" diff --git a/apps/templates/_header_bar.html b/apps/templates/_header_bar.html index 63ee1bbfc..62ddb52c4 100644 --- a/apps/templates/_header_bar.html +++ b/apps/templates/_header_bar.html @@ -52,6 +52,12 @@ English +
  • + + + 日本語 + +
  • From e303b4f5710ae9a1c69f78544515da5ed61a3836 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 28 Mar 2022 11:27:35 +0800 Subject: [PATCH 28/59] =?UTF-8?q?perf:=20=E4=BF=AE=E5=A4=8D=20settings=20p?= =?UTF-8?q?atch=20=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/settings/signal_handlers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/settings/signal_handlers.py b/apps/settings/signal_handlers.py index 8f585a2aa..818b7ba03 100644 --- a/apps/settings/signal_handlers.py +++ b/apps/settings/signal_handlers.py @@ -93,7 +93,8 @@ def subscribe_settings_change(sender, **kwargs): def monkey_patch_settings(sender, **kwargs): def monkey_patch_getattr(self, name): val = getattr(self._wrapped, name) - if callable(val): + # 只解析 defaults 中的 callable + if callable(val) and val.__module__ == 'jumpserver.conf': val = val() return val From a20de3df16ab306a9d0cfc0e5c097af659330d7d Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 28 Mar 2022 17:06:06 +0800 Subject: [PATCH 29/59] =?UTF-8?q?perf:=20app=20tree=20=E6=B7=BB=E5=8A=A0at?= =?UTF-8?q?trs=EF=BC=8Cluna=20=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/applications/api/mixin.py | 6 +++++- apps/applications/models/application.py | 11 +++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/apps/applications/api/mixin.py b/apps/applications/api/mixin.py index e17755ea8..35ec0fdb6 100644 --- a/apps/applications/api/mixin.py +++ b/apps/applications/api/mixin.py @@ -48,20 +48,24 @@ class SerializeApplicationToTreeNodeMixin: root_node = self.create_root_node() tree_nodes.append(root_node) organizations = self.filter_organizations(applications) + for i, org in enumerate(organizations): tree_id = urlencode({'org_id': str(org.id)}) apps = applications.filter(org_id=org.id) + # 组织节点 org_node = org.as_tree_node(oid=tree_id, pid=root_node.id) org_node.name += '({})'.format(apps.count()) tree_nodes.append(org_node) + + # 类别节点 category_type_nodes = Application.create_category_type_tree_nodes( apps, tree_id, show_empty=False ) tree_nodes += category_type_nodes for app in apps: - app_node = app.as_tree_node(tree_id, is_luna=True) + app_node = app.as_tree_node(tree_id, k8s_as_tree=True) tree_nodes.append(app_node) return tree_nodes diff --git a/apps/applications/models/application.py b/apps/applications/models/application.py index d9b3efe23..a3c50e960 100644 --- a/apps/applications/models/application.py +++ b/apps/applications/models/application.py @@ -20,6 +20,7 @@ class ApplicationTreeNodeMixin: name: str type: str category: str + attrs: dict @staticmethod def create_tree_id(pid, type, v): @@ -173,13 +174,18 @@ class ApplicationTreeNodeMixin: pid = self.create_tree_id(pid, 'type', self.type) return pid - def as_tree_node(self, pid, is_luna=False): - if is_luna and self.type == const.AppType.k8s: + def as_tree_node(self, pid, k8s_as_tree=False): + if self.type == const.AppType.k8s and k8s_as_tree: node = KubernetesTree(pid).as_tree_node(self) else: node = self._as_tree_node(pid) return node + def _attrs_to_tree(self): + if self.category == const.AppCategory.db: + return {'database': self.attrs.get('database')} + return {} + def _as_tree_node(self, pid): icon_skin_category_mapper = { 'remote_app': 'chrome', @@ -201,6 +207,7 @@ class ApplicationTreeNodeMixin: 'data': { 'category': self.category, 'type': self.type, + 'attrs': self._attrs_to_tree() } } }) From 52709d2efa7fd6c5afba0b20da5198819d6b11f4 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 29 Mar 2022 13:19:13 +0800 Subject: [PATCH 30/59] =?UTF-8?q?feat:=20=E4=BC=81=E4=B8=9A=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E3=80=81=E9=92=89=E9=92=89=20=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E5=8F=B0=E5=85=8D=E5=AF=86=E7=99=BB=E5=BD=95(=E9=A3=9E?= =?UTF-8?q?=E4=B9=A6=E5=B7=B2=E5=AE=9E=E7=8E=B0)=20(#7855)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 添加oauth接口 * feat: 企业微信支持OAuth认证,工作台免密登录 * feat: 钉钉支持OAuth认证,工作台免密登录 * fix: 修复参数错误 Co-authored-by: halo --- apps/authentication/urls/view_urls.py | 4 + apps/authentication/views/dingtalk.py | 106 ++++++++++++++++++++---- apps/authentication/views/wecom.py | 105 +++++++++++++++++++---- apps/common/sdk/im/dingtalk/__init__.py | 1 + apps/common/sdk/im/wecom/__init__.py | 1 + 5 files changed, 188 insertions(+), 29 deletions(-) diff --git a/apps/authentication/urls/view_urls.py b/apps/authentication/urls/view_urls.py index ce0d3c647..2d0749470 100644 --- a/apps/authentication/urls/view_urls.py +++ b/apps/authentication/urls/view_urls.py @@ -27,12 +27,16 @@ urlpatterns = [ path('wecom/qr/login/', views.WeComQRLoginView.as_view(), name='wecom-qr-login'), path('wecom/qr/bind//callback/', views.WeComQRBindCallbackView.as_view(), name='wecom-qr-bind-callback'), path('wecom/qr/login/callback/', views.WeComQRLoginCallbackView.as_view(), name='wecom-qr-login-callback'), + path('wecom/oauth/login/', views.WeComOAuthLoginView.as_view(), name='wecom-oauth-login'), + path('wecom/oauth/login/callback/', views.WeComOAuthLoginCallbackView.as_view(), name='wecom-oauth-login-callback'), path('dingtalk/bind/start/', views.DingTalkEnableStartView.as_view(), name='dingtalk-bind-start'), path('dingtalk/qr/bind/', views.DingTalkQRBindView.as_view(), name='dingtalk-qr-bind'), path('dingtalk/qr/login/', views.DingTalkQRLoginView.as_view(), name='dingtalk-qr-login'), path('dingtalk/qr/bind//callback/', views.DingTalkQRBindCallbackView.as_view(), name='dingtalk-qr-bind-callback'), path('dingtalk/qr/login/callback/', views.DingTalkQRLoginCallbackView.as_view(), name='dingtalk-qr-login-callback'), + path('dingtalk/oauth/login/', views.DingTalkOAuthLoginView.as_view(), name='dingtalk-oauth-login'), + path('dingtalk/oauth/login/callback/', views.DingTalkOAuthLoginCallbackView.as_view(), name='dingtalk-oauth-login-callback'), path('feishu/bind/start/', views.FeiShuEnableStartView.as_view(), name='feishu-bind-start'), path('feishu/qr/bind/', views.FeiShuQRBindView.as_view(), name='feishu-qr-bind'), diff --git a/apps/authentication/views/dingtalk.py b/apps/authentication/views/dingtalk.py index e42e7ff81..b4fd2cede 100644 --- a/apps/authentication/views/dingtalk.py +++ b/apps/authentication/views/dingtalk.py @@ -28,7 +28,7 @@ logger = get_logger(__file__) DINGTALK_STATE_SESSION_KEY = '_dingtalk_state' -class DingTalkQRMixin(PermissionsMixin, View): +class DingTalkBaseMixin(PermissionsMixin, View): def dispatch(self, request, *args, **kwargs): try: return super().dispatch(request, *args, **kwargs) @@ -54,20 +54,6 @@ class DingTalkQRMixin(PermissionsMixin, View): msg = _("The system configuration is incorrect. Please contact your administrator") return self.get_failed_response(redirect_uri, msg, msg) - def get_qr_url(self, redirect_uri): - state = random_string(16) - self.request.session[DINGTALK_STATE_SESSION_KEY] = state - - params = { - 'appid': settings.DINGTALK_APPKEY, - 'response_type': 'code', - 'scope': 'snsapi_login', - 'state': state, - 'redirect_uri': redirect_uri, - } - url = URL.QR_CONNECT + '?' + urlencode(params) - return url - @staticmethod def get_success_response(redirect_url, title, msg): message_data = { @@ -94,6 +80,42 @@ class DingTalkQRMixin(PermissionsMixin, View): return response +class DingTalkQRMixin(DingTalkBaseMixin, View): + + def get_qr_url(self, redirect_uri): + state = random_string(16) + self.request.session[DINGTALK_STATE_SESSION_KEY] = state + + params = { + 'appid': settings.DINGTALK_APPKEY, + 'response_type': 'code', + 'scope': 'snsapi_login', + 'state': state, + 'redirect_uri': redirect_uri, + } + url = URL.QR_CONNECT + '?' + urlencode(params) + return url + + +class DingTalkOAuthMixin(DingTalkBaseMixin, View): + + def get_oauth_url(self, redirect_uri): + if not settings.AUTH_DINGTALK: + return reverse('authentication:login') + state = random_string(16) + self.request.session[DINGTALK_STATE_SESSION_KEY] = state + + params = { + 'appid': settings.DINGTALK_APPKEY, + 'response_type': 'code', + 'scope': 'snsapi_auth', + 'state': state, + 'redirect_uri': redirect_uri, + } + url = URL.OAUTH_CONNECT + '?' + urlencode(params) + return url + + class DingTalkQRBindView(DingTalkQRMixin, View): permission_classes = (IsAuthenticated,) @@ -230,3 +252,57 @@ class DingTalkQRLoginCallbackView(AuthMixin, DingTalkQRMixin, View): return response return self.redirect_to_guard_view() + + +class DingTalkOAuthLoginView(DingTalkOAuthMixin, View): + permission_classes = (AllowAny,) + + def get(self, request: HttpRequest): + redirect_url = request.GET.get('redirect_url') + + redirect_uri = reverse('authentication:dingtalk-oauth-login-callback', external=True) + redirect_uri += '?' + urlencode({'redirect_url': redirect_url}) + + url = self.get_oauth_url(redirect_uri) + return HttpResponseRedirect(url) + + +class DingTalkOAuthLoginCallbackView(AuthMixin, DingTalkOAuthMixin, View): + permission_classes = (AllowAny,) + + def get(self, request: HttpRequest): + code = request.GET.get('code') + redirect_url = request.GET.get('redirect_url') + login_url = reverse('authentication:login') + + if not self.verify_state(): + return self.get_verify_state_failed_response(redirect_url) + + dingtalk = DingTalk( + appid=settings.DINGTALK_APPKEY, + appsecret=settings.DINGTALK_APPSECRET, + agentid=settings.DINGTALK_AGENTID + ) + userid = dingtalk.get_userid_by_code(code) + if not userid: + # 正常流程不会出这个错误,hack 行为 + msg = _('Failed to get user from DingTalk') + response = self.get_failed_response(login_url, title=msg, msg=msg) + return response + + user = get_object_or_none(User, dingtalk_id=userid) + if user is None: + title = _('DingTalk is not bound') + msg = _('Please login with a password and then bind the DingTalk') + response = self.get_failed_response(login_url, title=title, msg=msg) + return response + + try: + self.check_oauth2_auth(user, settings.AUTH_BACKEND_DINGTALK) + except errors.AuthFailedError as e: + self.set_login_failed_mark() + msg = e.msg + response = self.get_failed_response(login_url, title=msg, msg=msg) + return response + + return self.redirect_to_guard_view() \ No newline at end of file diff --git a/apps/authentication/views/wecom.py b/apps/authentication/views/wecom.py index 3ac1df686..87afd08ea 100644 --- a/apps/authentication/views/wecom.py +++ b/apps/authentication/views/wecom.py @@ -28,7 +28,7 @@ logger = get_logger(__file__) WECOM_STATE_SESSION_KEY = '_wecom_state' -class WeComQRMixin(PermissionsMixin, View): +class WeComBaseMixin(PermissionsMixin, View): def dispatch(self, request, *args, **kwargs): try: return super().dispatch(request, *args, **kwargs) @@ -54,19 +54,6 @@ class WeComQRMixin(PermissionsMixin, View): msg = _("The system configuration is incorrect. Please contact your administrator") return self.get_failed_response(redirect_uri, msg, msg) - def get_qr_url(self, redirect_uri): - state = random_string(16) - self.request.session[WECOM_STATE_SESSION_KEY] = state - - params = { - 'appid': settings.WECOM_CORPID, - 'agentid': settings.WECOM_AGENTID, - 'state': state, - 'redirect_uri': redirect_uri, - } - url = URL.QR_CONNECT + '?' + urlencode(params) - return url - @staticmethod def get_success_response(redirect_url, title, msg): message_data = { @@ -93,6 +80,42 @@ class WeComQRMixin(PermissionsMixin, View): return response +class WeComQRMixin(WeComBaseMixin, View): + + def get_qr_url(self, redirect_uri): + state = random_string(16) + self.request.session[WECOM_STATE_SESSION_KEY] = state + + params = { + 'appid': settings.WECOM_CORPID, + 'agentid': settings.WECOM_AGENTID, + 'state': state, + 'redirect_uri': redirect_uri, + } + url = URL.QR_CONNECT + '?' + urlencode(params) + return url + + +class WeComOAuthMixin(WeComBaseMixin, View): + + def get_oauth_url(self, redirect_uri): + if not settings.AUTH_WECOM: + return reverse('authentication:login') + state = random_string(16) + self.request.session[WECOM_STATE_SESSION_KEY] = state + + params = { + 'appid': settings.WECOM_CORPID, + 'agentid': settings.WECOM_AGENTID, + 'state': state, + 'redirect_uri': redirect_uri, + 'response_type': 'code', + 'scope': 'snsapi_base', + } + url = URL.OAUTH_CONNECT + '?' + urlencode(params) + '#wechat_redirect' + return url + + class WeComQRBindView(WeComQRMixin, View): permission_classes = (IsAuthenticated,) @@ -225,3 +248,57 @@ class WeComQRLoginCallbackView(AuthMixin, WeComQRMixin, View): return response return self.redirect_to_guard_view() + + +class WeComOAuthLoginView(WeComOAuthMixin, View): + permission_classes = (AllowAny,) + + def get(self, request: HttpRequest): + redirect_url = request.GET.get('redirect_url') + + redirect_uri = reverse('authentication:wecom-oauth-login-callback', external=True) + redirect_uri += '?' + urlencode({'redirect_url': redirect_url}) + + url = self.get_oauth_url(redirect_uri) + return HttpResponseRedirect(url) + + +class WeComOAuthLoginCallbackView(AuthMixin, WeComOAuthMixin, View): + permission_classes = (AllowAny,) + + def get(self, request: HttpRequest): + code = request.GET.get('code') + redirect_url = request.GET.get('redirect_url') + login_url = reverse('authentication:login') + + if not self.verify_state(): + return self.get_verify_state_failed_response(redirect_url) + + wecom = WeCom( + corpid=settings.WECOM_CORPID, + corpsecret=settings.WECOM_SECRET, + agentid=settings.WECOM_AGENTID + ) + wecom_userid, __ = wecom.get_user_id_by_code(code) + if not wecom_userid: + # 正常流程不会出这个错误,hack 行为 + msg = _('Failed to get user from WeCom') + response = self.get_failed_response(login_url, title=msg, msg=msg) + return response + + user = get_object_or_none(User, wecom_id=wecom_userid) + if user is None: + title = _('WeCom is not bound') + msg = _('Please login with a password and then bind the WeCom') + response = self.get_failed_response(login_url, title=title, msg=msg) + return response + + try: + self.check_oauth2_auth(user, settings.AUTH_BACKEND_WECOM) + except errors.AuthFailedError as e: + self.set_login_failed_mark() + msg = e.msg + response = self.get_failed_response(login_url, title=msg, msg=msg) + return response + + return self.redirect_to_guard_view() \ No newline at end of file diff --git a/apps/common/sdk/im/dingtalk/__init__.py b/apps/common/sdk/im/dingtalk/__init__.py index f18cd4b35..d41e73221 100644 --- a/apps/common/sdk/im/dingtalk/__init__.py +++ b/apps/common/sdk/im/dingtalk/__init__.py @@ -28,6 +28,7 @@ class ErrorCode: class URL: QR_CONNECT = 'https://oapi.dingtalk.com/connect/qrconnect' + OAUTH_CONNECT = 'https://oapi.dingtalk.com/connect/oauth2/sns_authorize' GET_USER_INFO_BY_CODE = 'https://oapi.dingtalk.com/sns/getuserinfo_bycode' GET_TOKEN = 'https://oapi.dingtalk.com/gettoken' SEND_MESSAGE_BY_TEMPLATE = 'https://oapi.dingtalk.com/topapi/message/corpconversation/sendbytemplate' diff --git a/apps/common/sdk/im/wecom/__init__.py b/apps/common/sdk/im/wecom/__init__.py index ceda292c7..bc925508e 100644 --- a/apps/common/sdk/im/wecom/__init__.py +++ b/apps/common/sdk/im/wecom/__init__.py @@ -19,6 +19,7 @@ class URL: GET_TOKEN = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken' SEND_MESSAGE = 'https://qyapi.weixin.qq.com/cgi-bin/message/send' QR_CONNECT = 'https://open.work.weixin.qq.com/wwopen/sso/qrConnect' + OAUTH_CONNECT = 'https://open.weixin.qq.com/connect/oauth2/authorize' # https://open.work.weixin.qq.com/api/doc/90000/90135/91437 GET_USER_ID_BY_CODE = 'https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo' From d856f1364afa70e4f31e6fc9013733ce191e9b00 Mon Sep 17 00:00:00 2001 From: feng626 <1304903146@qq.com> Date: Mon, 28 Mar 2022 19:52:48 +0800 Subject: [PATCH 31/59] =?UTF-8?q?feat:=20=E6=8B=89=E8=B5=B7ssh=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/api/connection_token.py | 26 +- apps/jumpserver/conf.py | 2 + apps/jumpserver/settings/custom.py | 3 + apps/locale/ja/LC_MESSAGES/django.po | 560 +++++++++++++------- apps/locale/zh/LC_MESSAGES/django.po | 142 ++--- apps/settings/api/public.py | 2 + apps/settings/serializers/terminal.py | 3 + 7 files changed, 465 insertions(+), 273 deletions(-) diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index fd3d20e1a..7fbe5bac4 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -159,6 +159,25 @@ class ClientProtocolMixin: content += f'{k}:{v}\n' return name, content + def get_ssh_token(self, serializer): + asset, application, system_user, user = self.get_request_resource(serializer) + token, secret = self.create_token(user, asset, application, system_user) + if asset: + name = asset.hostname + elif application: + name = application.name + else: + name = '*' + + content = { + 'ip': settings.TERMINAL_KOKO_HOST, + 'port': str(settings.TERMINAL_KOKO_SSH_PORT), + 'username': f'JMS-{token}', + 'password': secret + } + token = json.dumps(content) + return name, token + def get_encrypt_cmdline(self, app: Application): parameters = app.get_rdp_remote_app_setting()['parameters'] parameters = parameters.encode('ascii') @@ -200,13 +219,11 @@ class ClientProtocolMixin: asset, application, system_user, user = self.get_request_resource(serializer) protocol = system_user.protocol username = user.username - + config, token = '', '' if protocol == 'rdp': name, config = self.get_rdp_file_content(serializer) elif protocol == 'ssh': - # Todo: - name = '' - config = 'ssh://system_user@asset@user@jumpserver-ssh' + name, token = self.get_ssh_token(serializer) else: raise ValueError('Protocol not support: {}'.format(protocol)) @@ -215,6 +232,7 @@ class ClientProtocolMixin: "filename": filename, "protocol": system_user.protocol, "username": username, + "token": token, "config": config } return data diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index d3625e156..3625f2a41 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -311,6 +311,8 @@ class Config(dict): 'TERMINAL_COMMAND_STORAGE': {}, 'TERMINAL_RDP_ADDR': lambda: urlparse(settings.SITE_URL).hostname + ':3389', 'XRDP_ENABLED': True, + 'TERMINAL_KOKO_HOST': lambda: urlparse(settings.SITE_URL).hostname, + 'TERMINAL_KOKO_SSH_PORT': 2222, 'TERMINAL_MAGNUS_ENABLED': True, 'TERMINAL_MAGNUS_HOST': lambda: urlparse(settings.SITE_URL).hostname, diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index 37e6d2e95..4d720349f 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -140,6 +140,9 @@ CLOUD_SYNC_TASK_EXECUTION_KEEP_DAYS = CONFIG.CLOUD_SYNC_TASK_EXECUTION_KEEP_DAYS XRDP_ENABLED = CONFIG.XRDP_ENABLED +TERMINAL_KOKO_HOST = CONFIG.TERMINAL_KOKO_HOST +TERMINAL_KOKO_SSH_PORT = CONFIG.TERMINAL_KOKO_SSH_PORT + # SMS enabled SMS_ENABLED = CONFIG.SMS_ENABLED SMS_BACKEND = CONFIG.SMS_BACKEND diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index eb20c66d2..b67d81397 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-03-22 15:28+0800\n" +"POT-Creation-Date: 2022-03-29 12:58+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -23,7 +23,7 @@ msgid "Acls" msgstr "Acls" #: acls/models/base.py:25 acls/serializers/login_asset_acl.py:47 -#: applications/models/application.py:212 assets/models/asset.py:138 +#: applications/models/application.py:211 assets/models/asset.py:138 #: assets/models/base.py:175 assets/models/cluster.py:18 #: assets/models/cmd_filter.py:27 assets/models/domain.py:23 #: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24 @@ -31,7 +31,7 @@ msgstr "Acls" #: settings/models.py:29 settings/serializers/sms.py:6 #: terminal/models/storage.py:23 terminal/models/task.py:16 #: terminal/models/terminal.py:100 users/forms/profile.py:32 -#: users/models/group.py:15 users/models/user.py:655 +#: users/models/group.py:15 users/models/user.py:659 #: users/templates/users/_select_user_modal.html:13 #: users/templates/users/user_asset_permission.html:37 #: users/templates/users/user_asset_permission.html:154 @@ -41,12 +41,12 @@ msgid "Name" msgstr "名前" #: acls/models/base.py:27 assets/models/cmd_filter.py:84 -#: assets/models/user.py:234 +#: assets/models/user.py:247 msgid "Priority" msgstr "優先順位" #: acls/models/base.py:28 assets/models/cmd_filter.py:84 -#: assets/models/user.py:234 +#: assets/models/user.py:247 msgid "1-100, the lower the value will be match first" msgstr "1-100、低い値は最初に一致します" @@ -57,7 +57,7 @@ msgstr "1-100、低い値は最初に一致します" msgid "Active" msgstr "アクティブ" -#: acls/models/base.py:32 applications/models/application.py:225 +#: acls/models/base.py:32 applications/models/application.py:224 #: assets/models/asset.py:143 assets/models/asset.py:231 #: assets/models/backup.py:54 assets/models/base.py:180 #: assets/models/cluster.py:29 assets/models/cmd_filter.py:48 @@ -67,7 +67,7 @@ msgstr "アクティブ" #: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34 #: terminal/models/storage.py:26 terminal/models/terminal.py:114 #: tickets/models/comment.py:24 tickets/models/ticket.py:154 -#: users/models/group.py:16 users/models/user.py:692 +#: users/models/group.py:16 users/models/user.py:696 #: 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 @@ -95,8 +95,8 @@ msgstr "ログイン確認" #: terminal/backends/command/models.py:19 #: terminal/backends/command/serializers.py:12 terminal/models/session.py:42 #: terminal/notifications.py:91 terminal/notifications.py:139 -#: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:880 -#: users/models/user.py:911 users/serializers/group.py:19 +#: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:884 +#: users/models/user.py:915 users/serializers/group.py:19 #: users/templates/users/user_asset_permission.html:38 #: users/templates/users/user_asset_permission.html:64 #: users/templates/users/user_database_app_permission.html:37 @@ -170,7 +170,7 @@ msgstr "コンマ区切り文字列の形式。* はすべて一致すること #: authentication/forms.py:15 authentication/forms.py:17 #: 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:31 users/models/user.py:653 +#: ops/models/adhoc.py:159 users/forms/profile.py:31 users/models/user.py:657 #: users/templates/users/_msg_user_created.html:12 #: users/templates/users/_select_user_modal.html:14 #: xpack/plugins/change_auth_plan/models/asset.py:34 @@ -215,11 +215,11 @@ msgid "" "Format for comma-delimited string, with * indicating a match all. Protocol " "options: {}" msgstr "" -"コンマ区切り文字列の形式。* はすべて一致することを示します。プロトコル" -"オプション: {}" +"コンマ区切り文字列の形式。* はすべて一致することを示します。プロトコルオプ" +"ション: {}" #: acls/serializers/login_asset_acl.py:55 assets/models/asset.py:213 -#: assets/models/domain.py:62 assets/models/user.py:235 +#: assets/models/domain.py:62 assets/models/user.py:248 #: terminal/serializers/session.py:30 terminal/serializers/storage.py:69 msgid "Protocol" msgstr "プロトコル" @@ -260,7 +260,7 @@ msgstr "期間" msgid "My applications" msgstr "私のアプリケーション" -#: applications/apps.py:9 applications/models/application.py:61 +#: applications/apps.py:9 applications/models/application.py:62 msgid "Applications" msgstr "アプリケーション" @@ -279,14 +279,14 @@ msgstr "リモートアプリ" msgid "Custom" msgstr "カスタム" -#: applications/models/account.py:12 applications/models/application.py:229 +#: applications/models/account.py:12 applications/models/application.py:228 #: assets/models/backup.py:32 assets/models/cmd_filter.py:45 #: perms/models/application_permission.py:28 msgid "Application" msgstr "アプリケーション" #: applications/models/account.py:15 assets/models/authbook.py:20 -#: assets/models/cmd_filter.py:42 assets/models/user.py:325 audits/models.py:40 +#: assets/models/cmd_filter.py:42 assets/models/user.py:338 audits/models.py:40 #: perms/models/application_permission.py:33 #: perms/models/asset_permission.py:25 terminal/backends/command/models.py:21 #: terminal/backends/command/serializers.py:14 terminal/models/session.py:46 @@ -319,7 +319,7 @@ msgstr "アプリケーションアカウントの秘密を表示できます" msgid "Can change application account secret" msgstr "アプリケーションアカウントの秘密を変更できます" -#: applications/models/application.py:214 +#: applications/models/application.py:213 #: applications/serializers/application.py:99 assets/models/label.py:21 #: perms/models/application_permission.py:21 #: perms/serializers/application/user_permission.py:33 @@ -328,9 +328,9 @@ msgstr "アプリケーションアカウントの秘密を変更できます" msgid "Category" msgstr "カテゴリ" -#: applications/models/application.py:217 +#: applications/models/application.py:216 #: applications/serializers/application.py:101 assets/models/backup.py:49 -#: assets/models/cmd_filter.py:82 assets/models/user.py:233 +#: assets/models/cmd_filter.py:82 assets/models/user.py:246 #: perms/models/application_permission.py:24 #: perms/serializers/application/user_permission.py:34 #: terminal/models/storage.py:55 terminal/models/storage.py:119 @@ -341,21 +341,21 @@ msgstr "カテゴリ" msgid "Type" msgstr "タイプ" -#: applications/models/application.py:221 assets/models/asset.py:217 +#: applications/models/application.py:220 assets/models/asset.py:217 #: assets/models/domain.py:29 assets/models/domain.py:63 msgid "Domain" msgstr "ドメイン" -#: applications/models/application.py:223 xpack/plugins/cloud/models.py:33 +#: applications/models/application.py:222 xpack/plugins/cloud/models.py:33 #: xpack/plugins/cloud/serializers/account.py:58 msgid "Attrs" msgstr "ツールバーの" -#: applications/models/application.py:233 +#: applications/models/application.py:232 msgid "Can match application" msgstr "アプリケーションを一致させることができます" -#: applications/models/application.py:281 +#: applications/models/application.py:280 msgid "Application user" msgstr "アプリケーションユーザー" @@ -384,7 +384,7 @@ msgstr "タイプ表示" #: assets/serializers/cmd_filter.py:49 common/db/models.py:113 #: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30 #: orgs/models.py:67 orgs/models.py:217 perms/models/base.py:92 -#: users/models/group.py:18 users/models/user.py:912 +#: users/models/group.py:18 users/models/user.py:916 #: xpack/plugins/cloud/models.py:125 msgid "Date created" msgstr "作成された日付" @@ -603,7 +603,7 @@ msgstr "ホスト名生" msgid "Protocols" msgstr "プロトコル" -#: assets/models/asset.py:218 assets/models/user.py:225 +#: assets/models/asset.py:218 assets/models/user.py:238 #: perms/models/asset_permission.py:24 #: xpack/plugins/change_auth_plan/models/asset.py:43 #: xpack/plugins/gathered_user/models.py:24 @@ -616,7 +616,7 @@ msgid "Is active" msgstr "アクティブです。" #: assets/models/asset.py:222 assets/models/cluster.py:19 -#: assets/models/user.py:222 assets/models/user.py:377 +#: assets/models/user.py:235 assets/models/user.py:390 msgid "Admin user" msgstr "管理ユーザー" @@ -636,7 +636,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:111 common/mixins/models.py:49 orgs/models.py:66 -#: orgs/models.py:219 perms/models/base.py:91 users/models/user.py:700 +#: orgs/models.py:219 perms/models/base.py:91 users/models/user.py:704 #: 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 @@ -785,7 +785,7 @@ msgstr "確認済みの日付" #: assets/models/base.py:177 audits/signal_handlers.py:68 #: authentication/forms.py:22 -#: authentication/templates/authentication/login.html:178 +#: authentication/templates/authentication/login.html:181 #: settings/serializers/auth/ldap.py:44 users/forms/profile.py:21 #: users/templates/users/_msg_user_created.html:13 #: users/templates/users/user_password_update.html:43 @@ -817,7 +817,7 @@ msgstr "帯域幅" msgid "Contact" msgstr "連絡先" -#: assets/models/cluster.py:22 users/models/user.py:675 +#: assets/models/cluster.py:22 users/models/user.py:679 msgid "Phone" msgstr "電話" @@ -843,7 +843,7 @@ msgid "Default" msgstr "デフォルト" #: assets/models/cluster.py:36 assets/models/label.py:14 rbac/const.py:6 -#: users/models/user.py:897 +#: users/models/user.py:901 msgid "System" msgstr "システム" @@ -852,7 +852,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:661 +#: users/models/group.py:31 users/models/user.py:665 #: users/templates/users/_select_user_modal.html:16 #: users/templates/users/user_asset_permission.html:39 #: users/templates/users/user_asset_permission.html:67 @@ -998,77 +998,77 @@ msgstr "ノード" msgid "Can match node" msgstr "ノードを一致させることができます" -#: assets/models/user.py:216 +#: assets/models/user.py:229 msgid "Automatic managed" msgstr "自動管理" -#: assets/models/user.py:217 +#: assets/models/user.py:230 msgid "Manually input" msgstr "手動入力" -#: assets/models/user.py:221 +#: assets/models/user.py:234 msgid "Common user" msgstr "共通ユーザー" -#: assets/models/user.py:224 +#: assets/models/user.py:237 msgid "Username same with user" msgstr "ユーザーと同じユーザー名" -#: assets/models/user.py:227 assets/serializers/domain.py:29 +#: assets/models/user.py:240 assets/serializers/domain.py:29 #: terminal/templates/terminal/_msg_command_execute_alert.html:16 #: xpack/plugins/change_auth_plan/models/asset.py:39 msgid "Assets" msgstr "資産" -#: assets/models/user.py:231 users/apps.py:9 +#: assets/models/user.py:244 users/apps.py:9 msgid "Users" msgstr "ユーザー" -#: assets/models/user.py:232 +#: assets/models/user.py:245 msgid "User groups" msgstr "ユーザーグループ" -#: assets/models/user.py:236 +#: assets/models/user.py:249 msgid "Auto push" msgstr "オートプッシュ" -#: assets/models/user.py:237 +#: assets/models/user.py:250 msgid "Sudo" msgstr "すど" -#: assets/models/user.py:238 +#: assets/models/user.py:251 msgid "Shell" msgstr "シェル" -#: assets/models/user.py:239 +#: assets/models/user.py:252 msgid "Login mode" msgstr "ログインモード" -#: assets/models/user.py:240 +#: assets/models/user.py:253 msgid "SFTP Root" msgstr "SFTPルート" -#: assets/models/user.py:241 authentication/models.py:48 +#: assets/models/user.py:254 authentication/models.py:48 msgid "Token" msgstr "トークン" -#: assets/models/user.py:242 +#: assets/models/user.py:255 msgid "Home" msgstr "ホーム" -#: assets/models/user.py:243 +#: assets/models/user.py:256 msgid "System groups" msgstr "システムグループ" -#: assets/models/user.py:246 +#: assets/models/user.py:259 msgid "User switch" msgstr "ユーザースイッチ" -#: assets/models/user.py:247 +#: assets/models/user.py:260 msgid "Switch from" msgstr "から切り替え" -#: assets/models/user.py:327 +#: assets/models/user.py:340 msgid "Can match system user" msgstr "システムユーザーに一致できます" @@ -1085,14 +1085,19 @@ msgstr "アカウントバックアップルートタスクの結果の通知" msgid "" "{} - The account backup passage task has been completed. See the attachment " "for details" -msgstr "{} -アカウントバックアップの通過タスクが完了しました。詳細は添付ファイルをご覧ください" +msgstr "" +"{} -アカウントバックアップの通過タスクが完了しました。詳細は添付ファイルをご" +"覧ください" #: assets/notifications.py:19 msgid "" "{} - The account backup passage task has been completed: the encryption " "password has not been set - please go to personal information -> file " "encryption password to set the encryption password" -msgstr "{} -アカウントのバックアップ通過タスクが完了しました: 暗号化パスワードが設定されていません-個人情報にアクセスしてください-> ファイル暗号化パスワードを設定してください暗号化パスワード" +msgstr "" +"{} -アカウントのバックアップ通過タスクが完了しました: 暗号化パスワードが設定" +"されていません-個人情報にアクセスしてください-> ファイル暗号化パスワードを設" +"定してください暗号化パスワード" #: assets/serializers/account.py:40 assets/serializers/account.py:83 msgid "System user display" @@ -1268,7 +1273,9 @@ msgstr "パスワードには '{{' を含まない" #: assets/tasks/account_connectivity.py:30 msgid "The asset {} system platform {} does not support run Ansible tasks" -msgstr "資産 {} システムプラットフォーム {} はAnsibleタスクの実行をサポートしていません。" +msgstr "" +"資産 {} システムプラットフォーム {} はAnsibleタスクの実行をサポートしていませ" +"ん。" #: assets/tasks/account_connectivity.py:107 msgid "Test account connectivity: " @@ -1321,7 +1328,9 @@ msgstr "資産ユーザーの収集" #: assets/tasks/nodes_amount.py:27 msgid "" "The task of self-checking is already running and cannot be started repeatedly" -msgstr "セルフチェックのタスクはすでに実行されており、繰り返し開始することはできません" +msgstr "" +"セルフチェックのタスクはすでに実行されており、繰り返し開始することはできませ" +"ん" #: assets/tasks/push_system_user.py:200 msgid "System user is dynamic: {}" @@ -1505,7 +1514,7 @@ msgstr "ユーザーエージェント" #: audits/models.py:124 #: authentication/templates/authentication/_mfa_confirm_modal.html:14 -#: users/forms/profile.py:64 users/models/user.py:678 +#: users/forms/profile.py:64 users/models/user.py:682 #: users/serializers/profile.py:121 msgid "MFA" msgstr "MFA" @@ -1583,13 +1592,13 @@ msgstr "認証トークン" #: audits/signal_handlers.py:71 authentication/notifications.py:73 #: authentication/views/login.py:164 authentication/views/wecom.py:158 -#: notifications/backends/__init__.py:11 users/models/user.py:714 +#: notifications/backends/__init__.py:11 users/models/user.py:718 msgid "WeCom" msgstr "企業微信" #: audits/signal_handlers.py:72 authentication/views/dingtalk.py:160 #: authentication/views/login.py:170 notifications/backends/__init__.py:12 -#: users/models/user.py:715 +#: users/models/user.py:719 msgid "DingTalk" msgstr "DingTalk" @@ -1762,7 +1771,7 @@ msgstr "{ApplicationPermission} 追加 {SystemUser}" msgid "{ApplicationPermission} REMOVE {SystemUser}" msgstr "{ApplicationPermission} 削除 {SystemUser}" -#: authentication/api/connection_token.py:296 +#: authentication/api/connection_token.py:313 msgid "Invalid token" msgstr "無効なトークン" @@ -1794,7 +1803,8 @@ msgstr "署名ヘッダーが無効です。AccessKeyIdのような形式: Signa msgid "" "Invalid signature header. Signature string should not contain invalid " "characters." -msgstr "署名ヘッダーが無効です。署名文字列に無効な文字を含めることはできません。" +msgstr "" +"署名ヘッダーが無効です。署名文字列に無効な文字を含めることはできません。" #: authentication/backends/drf.py:90 authentication/backends/drf.py:106 msgid "Invalid signature." @@ -1823,7 +1833,8 @@ msgstr "無効なトークンヘッダー。記号文字列にはスペースを #: authentication/backends/drf.py:137 msgid "" "Invalid token header. Sign string should not contain invalid characters." -msgstr "無効なトークンヘッダー。署名文字列に無効な文字を含めることはできません。" +msgstr "" +"無効なトークンヘッダー。署名文字列に無効な文字を含めることはできません。" #: authentication/backends/drf.py:148 msgid "Invalid token or cache refreshed." @@ -1887,26 +1898,35 @@ msgid "" "The username or password you entered is incorrect, please enter it again. " "You can also try {times_try} times (The account will be temporarily locked " "for {block_time} minutes)" -msgstr "入力したユーザー名またはパスワードが正しくありません。再度入力してください。 {times_try} 回試すこともできます (アカウントは {block_time} 分の間一時的にロックされます)" +msgstr "" +"入力したユーザー名またはパスワードが正しくありません。再度入力してください。 " +"{times_try} 回試すこともできます (アカウントは {block_time} 分の間一時的に" +"ロックされます)" #: authentication/errors.py:55 authentication/errors.py:63 msgid "" "The account has been locked (please contact admin to unlock it or try again " "after {} minutes)" -msgstr "アカウントがロックされています (管理者に連絡してロックを解除するか、 {} 分後にもう一度お試しください)" +msgstr "" +"アカウントがロックされています (管理者に連絡してロックを解除するか、 {} 分後" +"にもう一度お試しください)" #: authentication/errors.py:59 msgid "" "The ip has been locked (please contact admin to unlock it or try again after " "{} minutes)" -msgstr "IPがロックされています (管理者に連絡してロックを解除するか、 {} 分後にもう一度お試しください)" +msgstr "" +"IPがロックされています (管理者に連絡してロックを解除するか、 {} 分後にもう一" +"度お試しください)" #: authentication/errors.py:67 #, python-brace-format msgid "" "{error}, You can also try {times_try} times (The account will be temporarily " "locked for {block_time} minutes)" -msgstr "{error},{times_try} 回も試すことができます (アカウントは {block_time} 分の間一時的にロックされます)" +msgstr "" +"{error},{times_try} 回も試すことができます (アカウントは {block_time} 分の間" +"一時的にロックされます)" #: authentication/errors.py:71 msgid "MFA required" @@ -1950,7 +1970,8 @@ msgstr "ログインする前にパスワードを変更する必要がありま #: authentication/errors.py:318 authentication/mixins.py:386 msgid "Your password has expired, please reset before logging in" -msgstr "パスワードの有効期限が切れました。ログインする前にリセットしてください。" +msgstr "" +"パスワードの有効期限が切れました。ログインする前にリセットしてください。" #: authentication/errors.py:352 msgid "Your password is invalid" @@ -2117,14 +2138,14 @@ msgid "Show" msgstr "表示" #: authentication/templates/authentication/_access_key_modal.html:66 -#: settings/serializers/security.py:39 users/models/user.py:550 +#: settings/serializers/security.py:39 users/models/user.py:554 #: users/serializers/profile.py:111 users/templates/users/mfa_setting.html:61 #: users/templates/users/user_verify_mfa.html:36 msgid "Disable" msgstr "無効化" #: authentication/templates/authentication/_access_key_modal.html:67 -#: users/models/user.py:551 users/serializers/profile.py:112 +#: users/models/user.py:555 users/serializers/profile.py:112 #: users/templates/users/mfa_setting.html:26 #: users/templates/users/mfa_setting.html:68 msgid "Enable" @@ -2172,7 +2193,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:293 ops/tasks.py:145 ops/tasks.py:148 +#: jumpserver/conf.py:295 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 #: users/templates/users/_msg_account_expire_reminder.html:4 @@ -2194,7 +2215,9 @@ msgstr "ログイン時間" msgid "" "If you suspect that the login behavior is abnormal, please modify the " "account password in time." -msgstr "ログイン動作が異常であると疑われる場合は、時間内にアカウントのパスワードを変更してください。" +msgstr "" +"ログイン動作が異常であると疑われる場合は、時間内にアカウントのパスワードを変" +"更してください。" #: authentication/templates/authentication/_msg_oauth_bind.html:6 msgid "Your account has just been bound to" @@ -2208,7 +2231,9 @@ msgstr "操作が独自のものでない場合は、パスワードをバイン msgid "" "Please click the link below to reset your password, if not your request, " "concern your account security" -msgstr "下のリンクをクリックしてパスワードをリセットしてください。リクエストがない場合は、アカウントのセキュリティに関係します。" +msgstr "" +"下のリンクをクリックしてパスワードをリセットしてください。リクエストがない場" +"合は、アカウントのセキュリティに関係します。" #: authentication/templates/authentication/_msg_reset_password.html:10 msgid "Click here reset password" @@ -2237,7 +2262,9 @@ msgstr "ブラウザ" msgid "" "If the password update was not initiated by you, your account may have " "security issues" -msgstr "パスワードの更新が開始されなかった場合、アカウントにセキュリティ上の問題がある可能性があります" +msgstr "" +"パスワードの更新が開始されなかった場合、アカウントにセキュリティ上の問題があ" +"る可能性があります" #: authentication/templates/authentication/_msg_rest_password_success.html:14 #: authentication/templates/authentication/_msg_rest_public_key_success.html:14 @@ -2252,24 +2279,27 @@ msgstr "公開鍵が正常に更新されました" msgid "" "If the public key update was not initiated by you, your account may have " "security issues" -msgstr "公開鍵の更新が開始されなかった場合、アカウントにセキュリティ上の問題がある可能性があります" +msgstr "" +"公開鍵の更新が開始されなかった場合、アカウントにセキュリティ上の問題がある可" +"能性があります" -#: authentication/templates/authentication/login.html:170 +#: authentication/templates/authentication/login.html:173 msgid "Welcome back, please enter username and password to login" -msgstr "おかえりなさい、ログインするためにユーザー名とパスワードを入力してください" +msgstr "" +"おかえりなさい、ログインするためにユーザー名とパスワードを入力してください" -#: authentication/templates/authentication/login.html:206 +#: authentication/templates/authentication/login.html:209 #: users/templates/users/forgot_password.html:15 #: users/templates/users/forgot_password.html:16 msgid "Forgot password" msgstr "パスワードを忘れた" -#: authentication/templates/authentication/login.html:213 -#: templates/_header_bar.html:83 +#: authentication/templates/authentication/login.html:216 +#: templates/_header_bar.html:89 msgid "Login" msgstr "ログイン" -#: authentication/templates/authentication/login.html:220 +#: authentication/templates/authentication/login.html:223 msgid "More login options" msgstr "その他のログインオプション" @@ -2373,7 +2403,7 @@ msgid "The FeiShu is already bound to another user" msgstr "FeiShuはすでに別のユーザーにバインドされています" #: authentication/views/feishu.py:148 authentication/views/login.py:176 -#: notifications/backends/__init__.py:14 users/models/user.py:716 +#: notifications/backends/__init__.py:14 users/models/user.py:720 msgid "FeiShu" msgstr "本を飛ばす" @@ -2409,7 +2439,8 @@ msgstr "クッキーを有効にして、もう一度お試しください。" msgid "" "Wait for {} confirm, You also can copy link to her/him
    \n" " Don't close this page" -msgstr "{} 確認を待ちます。彼女/彼へのリンクをコピーすることもできます
    \n" +msgstr "" +"{} 確認を待ちます。彼女/彼へのリンクをコピーすることもできます
    \n" " このページを閉じないでください" #: authentication/views/login.py:268 @@ -2623,11 +2654,11 @@ msgstr "特殊文字を含むべきではない" msgid "The mobile phone number format is incorrect" msgstr "携帯電話番号の形式が正しくありません" -#: jumpserver/conf.py:292 +#: jumpserver/conf.py:294 msgid "Create account successfully" msgstr "アカウントを正常に作成" -#: jumpserver/conf.py:294 +#: jumpserver/conf.py:296 msgid "Your account has been created successfully" msgstr "アカウントが正常に作成されました" @@ -2644,25 +2675,35 @@ msgid "" "
    Luna is a separately deployed program, you need to deploy Luna, koko, " "configure nginx for url distribution,
    If you see this page, " "prove that you are not accessing the nginx listening port. Good luck." -msgstr "
    Lunaは個別にデプロイされたプログラムです。Luna、kokoをデプロイする必要があります。urlディストリビューションにnginxを設定します。
    このページが表示されている場合は、nginxリスニングポートにアクセスしていないことを証明してください。頑張ってください。" +msgstr "" +"
    Lunaは個別にデプロイされたプログラムです。Luna、kokoをデプロイする必要" +"があります。urlディストリビューションにnginxを設定します。
    この" +"ページが表示されている場合は、nginxリスニングポートにアクセスしていないことを" +"証明してください。頑張ってください。" #: jumpserver/views/other.py:70 msgid "Websocket server run on port: {}, you should proxy it on nginx" -msgstr "Websocket サーバーはport: {}で実行されます。nginxでプロキシする必要があります。" +msgstr "" +"Websocket サーバーはport: {}で実行されます。nginxでプロキシする必要がありま" +"す。" #: jumpserver/views/other.py:84 msgid "" "
    Koko is a separately deployed program, you need to deploy Koko, " "configure nginx for url distribution,
    If you see this page, " "prove that you are not accessing the nginx listening port. Good luck." -msgstr "
    Kokoは個別にデプロイされているプログラムです。Kokoをデプロイする必要があります。URL配布用にnginxを設定します。
    このページが表示されている場合は、nginxリスニングポートにアクセスしていないことを証明してください。頑張ってください。" +msgstr "" +"
    Kokoは個別にデプロイされているプログラムです。Kokoをデプロイする必要が" +"あります。URL配布用にnginxを設定します。
    このページが表示されて" +"いる場合は、nginxリスニングポートにアクセスしていないことを証明してください。" +"頑張ってください。" #: notifications/apps.py:7 msgid "Notifications" msgstr "通知" #: notifications/backends/__init__.py:10 users/forms/profile.py:101 -#: users/models/user.py:657 +#: users/models/user.py:661 msgid "Email" msgstr "メール" @@ -2715,9 +2756,9 @@ msgid "" "crontab/' target='_blank'>Online tools)
    Note: If both Regularly " "perform and Cycle perform are set, give priority to Regularly perform" msgstr "" -"eg:毎週日03:05<5 3**0>
    ヒント:5ビットLinux crontab式<" -"分時日月曜日>(オンラインワーク" -")
    注意:定期実行と周期実行を同時に設定した場合は、定期実行を優先します。" +"eg:毎週日03:05<5 3**0>
    ヒント:5ビットLinux crontab式<分時日月曜日>(オンラインワーク)
    注" +"意:定期実行と周期実行を同時に設定した場合は、定期実行を優先します。" #: ops/mixin.py:162 msgid "Unit: hour" @@ -2888,7 +2929,7 @@ msgid "Can view root org" msgstr "グローバル組織を表示できます" #: orgs/models.py:216 rbac/models/role.py:46 rbac/models/rolebinding.py:43 -#: users/models/user.py:665 users/templates/users/_select_user_modal.html:15 +#: users/models/user.py:669 users/templates/users/_select_user_modal.html:15 msgid "Role" msgstr "ロール" @@ -2975,7 +3016,7 @@ msgstr "クリップボードコピーペースト" #: perms/models/base.py:90 #: tickets/serializers/ticket/meta/ticket_type/apply_application.py:58 #: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:60 -#: users/models/user.py:697 +#: users/models/user.py:701 msgid "Date expired" msgstr "期限切れの日付" @@ -3018,15 +3059,15 @@ msgstr "Organization {} のアプリケーション権限" #: perms/serializers/application/permission.py:20 #: perms/serializers/application/permission.py:41 #: perms/serializers/asset/permission.py:19 -#: perms/serializers/asset/permission.py:45 users/serializers/user.py:137 +#: perms/serializers/asset/permission.py:45 users/serializers/user.py:139 msgid "Is valid" msgstr "有効です" #: perms/serializers/application/permission.py:21 #: perms/serializers/application/permission.py:40 #: perms/serializers/asset/permission.py:20 -#: perms/serializers/asset/permission.py:44 users/serializers/user.py:83 -#: users/serializers/user.py:139 +#: perms/serializers/asset/permission.py:44 users/serializers/user.py:85 +#: users/serializers/user.py:141 msgid "Is expired" msgstr "期限切れです" @@ -3050,7 +3091,9 @@ msgstr "システムユーザー数" msgid "" "The application list contains applications that are different from the " "permission type. ({})" -msgstr "アプリケーションリストには、権限タイプとは異なるアプリケーションが含まれています。({})" +msgstr "" +"アプリケーションリストには、権限タイプとは異なるアプリケーションが含まれてい" +"ます。({})" #: perms/serializers/asset/permission.py:21 msgid "Users display" @@ -3188,7 +3231,8 @@ msgstr "ロールバインディング" msgid "" "User last role in org, can not be delete, you can remove user from org " "instead" -msgstr "ユーザーの最後のロールは削除できません。ユーザーを組織から削除できます。" +msgstr "" +"ユーザーの最後のロールは削除できません。ユーザーを組織から削除できます。" #: rbac/models/rolebinding.py:135 msgid "Organization role binding" @@ -3502,8 +3546,8 @@ msgid "" "User attr map present how to map LDAP user attr to jumpserver, username,name," "email is jumpserver attr" msgstr "" -"ユーザー属性マッピングは、LDAPのユーザー属性をjumpserverユーザーにマッピングする方法、username, name," -"emailはjumpserverのユーザーが必要とする属性です" +"ユーザー属性マッピングは、LDAPのユーザー属性をjumpserverユーザーにマッピング" +"する方法、username, name,emailはjumpserverのユーザーが必要とする属性です" #: settings/serializers/auth/ldap.py:70 msgid "Connect timeout" @@ -3666,7 +3710,8 @@ msgstr "SSO Token認証の有効化" #: settings/serializers/auth/sso.py:13 msgid "Other service can using SSO token login to JumpServer without password" -msgstr "他のサービスはパスワードなしでJumpServerへのSSOトークンログインを使用できます" +msgstr "" +"他のサービスはパスワードなしでJumpServerへのSSOトークンログインを使用できます" #: settings/serializers/auth/sso.py:16 msgid "SSO auth key TTL" @@ -3708,7 +3753,9 @@ msgstr "ユーザーの最初のログイン更新プロファイルがリダイ msgid "" "The forgot password url on login page, If you use ldap or cas external " "authentication, you can set it" -msgstr "ログインページでパスワードのURLを忘れてしまいました。ldapまたはcasの外部認証を使用している場合は、設定できます。" +msgstr "" +"ログインページでパスワードのURLを忘れてしまいました。ldapまたはcasの外部認証" +"を使用している場合は、設定できます。" #: settings/serializers/basic.py:41 msgid "Global organization name" @@ -3761,8 +3808,8 @@ msgid "" "Unit: days, Session, record, command will be delete if more than duration, " "only in database" msgstr "" -"単位:日。セッション、録画、コマンドレコードがそれを超えると削除されます(データベースストレージにのみ影響します。ossなどは影響しません」" -"影響を受ける)" +"単位:日。セッション、録画、コマンドレコードがそれを超えると削除されます(デー" +"タベースストレージにのみ影響します。ossなどは影響しません」影響を受ける)" #: settings/serializers/email.py:18 msgid "SMTP host" @@ -3790,7 +3837,9 @@ msgstr "ユーザーを送信" #: settings/serializers/email.py:27 msgid "Tips: Send mail account, default SMTP account as the send account" -msgstr "ヒント: 送信メールアカウント、送信アカウントとしてのデフォルトのSMTPアカウント" +msgstr "" +"ヒント: 送信メールアカウント、送信アカウントとしてのデフォルトのSMTPアカウン" +"ト" #: settings/serializers/email.py:30 msgid "Test recipient" @@ -3828,7 +3877,9 @@ msgstr "ユーザーメール件名の作成" msgid "" "Tips: When creating a user, send the subject of the email (eg:Create account " "successfully)" -msgstr "ヒント: ユーザーを作成するときに、メールの件名を送信します (例: アカウントを正常に作成)" +msgstr "" +"ヒント: ユーザーを作成するときに、メールの件名を送信します (例: アカウントを" +"正常に作成)" #: settings/serializers/email.py:54 msgid "Create user honorific" @@ -3836,7 +3887,8 @@ msgstr "ユーザー敬語の作成" #: settings/serializers/email.py:55 msgid "Tips: When creating a user, send the honorific of the email (eg:Hello)" -msgstr "ヒント: ユーザーを作成するときは、メールの敬語を送信します (例: こんにちは)" +msgstr "" +"ヒント: ユーザーを作成するときは、メールの敬語を送信します (例: こんにちは)" #: settings/serializers/email.py:59 msgid "Create user email content" @@ -3848,7 +3900,8 @@ msgid "" "Tips: When creating a user, send the content of the email, support " "{username} {name} {email} label" msgstr "" -"ヒント:ユーザーの作成時にパスワード設定メールの内容を送信し、{username}{name}{email}ラベルをサポートします。" +"ヒント:ユーザーの作成時にパスワード設定メールの内容を送信し、{username}{name}" +"{email}ラベルをサポートします。" #: settings/serializers/email.py:64 msgid "Tips: Email signature (eg:jumpserver)" @@ -3885,7 +3938,8 @@ msgstr "シェル (Windows)" #: settings/serializers/other.py:25 msgid "The shell type used when Windows assets perform ansible tasks" -msgstr "Windowsアセットが実行可能なタスクを実行するときに使用されるシェルタイプ" +msgstr "" +"Windowsアセットが実行可能なタスクを実行するときに使用されるシェルタイプ" #: settings/serializers/other.py:29 msgid "Perm ungroup node" @@ -3893,7 +3947,10 @@ msgstr "グループ化されていないノードを表示" #: settings/serializers/other.py:30 msgid "Perm single to ungroup node" -msgstr "グループ化されていないノードに個別に許可された資産を配置し、資産が存在するノードが表示されないようにしますが、そのノードが許可されていないという質問に質問" +msgstr "" +"グループ化されていないノードに個別に許可された資産を配置し、資産が存在する" +"ノードが表示されないようにしますが、そのノードが許可されていないという質問に" +"質問" #: settings/serializers/other.py:34 msgid "Help Docs URL" @@ -3939,7 +3996,9 @@ msgstr "特別な" msgid "" "Unit: minute, If the user has failed to log in for a limited number of " "times, no login is allowed during this time interval." -msgstr "単位: 分。ユーザーが限られた回数だけログインできなかった場合、この時間間隔ではログインはできません。" +msgstr "" +"単位: 分。ユーザーが限られた回数だけログインできなかった場合、この時間間隔で" +"はログインはできません。" #: settings/serializers/security.py:40 msgid "All users" @@ -3995,7 +4054,11 @@ msgid "" "user password will expire failure;The password expiration reminder mail will " "be automatic sent to the user by system within 5 days (daily) before the " "password expires" -msgstr "単位: 日。ユーザーがその期間中にパスワードを更新しなかった場合、ユーザーパスワードの有効期限が切れます。パスワードの有効期限が切れる前の5日 (毎日) 以内に、パスワードの有効期限が切れるリマインダーメールがシステムからユーザーに自動的に送信されます。" +msgstr "" +"単位: 日。ユーザーがその期間中にパスワードを更新しなかった場合、ユーザーパス" +"ワードの有効期限が切れます。パスワードの有効期限が切れる前の5日 (毎日) 以内" +"に、パスワードの有効期限が切れるリマインダーメールがシステムからユーザーに自" +"動的に送信されます。" #: settings/serializers/security.py:89 msgid "Number of repeated historical passwords" @@ -4005,7 +4068,9 @@ msgstr "繰り返された履歴パスワードの数" msgid "" "Tip: When the user resets the password, it cannot be the previous n " "historical passwords of the user" -msgstr "ヒント: ユーザーがパスワードをリセットすると、ユーザーの前のnの履歴パスワードにすることはできません" +msgstr "" +"ヒント: ユーザーがパスワードをリセットすると、ユーザーの前のnの履歴パスワード" +"にすることはできません" #: settings/serializers/security.py:96 msgid "Only single device login" @@ -4039,7 +4104,9 @@ msgstr "MFAはTTLを確認します" msgid "" "Unit: second, The verification MFA takes effect only when you view the " "account password" -msgstr "単位: 2番目に、検証MFAはアカウントのパスワードを表示したときにのみ有効になります。" +msgstr "" +"単位: 2番目に、検証MFAはアカウントのパスワードを表示したときにのみ有効になり" +"ます。" #: settings/serializers/security.py:116 msgid "Enable Login dynamic code" @@ -4049,7 +4116,9 @@ msgstr "ログイン動的コードの有効化" msgid "" "The password and additional code are sent to a third party authentication " "system for verification" -msgstr "パスワードと追加コードは、検証のためにサードパーティの認証システムに送信されます" +msgstr "" +"パスワードと追加コードは、検証のためにサードパーティの認証システムに送信され" +"ます" #: settings/serializers/security.py:122 msgid "MFA in login page" @@ -4057,7 +4126,8 @@ msgstr "ログインページのMFA" #: settings/serializers/security.py:123 msgid "Eu security regulations(GDPR) require MFA to be on the login page" -msgstr "Euセキュリティ規制 (GDPR) では、MFAがログインページにある必要があります" +msgstr "" +"Euセキュリティ規制 (GDPR) では、MFAがログインページにある必要があります" #: settings/serializers/security.py:126 msgid "Enable Login captcha" @@ -4075,7 +4145,9 @@ msgstr "ターミナルレジスタの有効化" msgid "" "Allow terminal register, after all terminal setup, you should disable this " "for security" -msgstr "ターミナルレジスタを許可し、すべてのターミナルセットアップの後、セキュリティのためにこれを無効にする必要があります" +msgstr "" +"ターミナルレジスタを許可し、すべてのターミナルセットアップの後、セキュリティ" +"のためにこれを無効にする必要があります" #: settings/serializers/security.py:153 msgid "Enable watermark" @@ -4127,7 +4199,8 @@ msgstr "セッション共有" #: settings/serializers/security.py:180 msgid "Enabled, Allows user active session to be shared with other users" -msgstr "ユーザーのアクティブなセッションを他のユーザーと共有できるようにします。" +msgstr "" +"ユーザーのアクティブなセッションを他のユーザーと共有できるようにします。" #: settings/serializers/security.py:183 msgid "Remote Login Protection" @@ -4138,7 +4211,10 @@ msgid "" "The system determines whether the login IP address belongs to a common login " "city. If the account is logged in from a common login city, the system sends " "a remote login reminder" -msgstr "システムは、ログインIPアドレスが共通のログイン都市に属しているかどうかを判断します。アカウントが共通のログイン都市からログインしている場合、システムはリモートログインリマインダーを送信します" +msgstr "" +"システムは、ログインIPアドレスが共通のログイン都市に属しているかどうかを判断" +"します。アカウントが共通のログイン都市からログインしている場合、システムはリ" +"モートログインリマインダーを送信します" #: settings/serializers/terminal.py:13 msgid "Auto" @@ -4157,39 +4233,79 @@ msgid "" "Tips: If use other auth method, like AD/LDAP, you should disable this to " "avoid being able to log in after deleting" msgstr "" -"ヒント: AD/LDAPなどの他の認証方法を使用する場合は、サードパーティ製システムの削除後にこの項目を無効にする必要があります, " -"ログインも可能" +"ヒント: AD/LDAPなどの他の認証方法を使用する場合は、サードパーティ製システムの" +"削除後にこの項目を無効にする必要があります, ログインも可能" -#: settings/serializers/terminal.py:25 +#: settings/serializers/terminal.py:26 msgid "List sort by" msgstr "リストの並べ替え" -#: settings/serializers/terminal.py:27 +#: settings/serializers/terminal.py:29 msgid "List page size" msgstr "ページサイズを一覧表示" -#: settings/serializers/terminal.py:29 +#: settings/serializers/terminal.py:32 msgid "Telnet login regex" msgstr "Telnetログインregex" -#: settings/serializers/terminal.py:30 +#: settings/serializers/terminal.py:33 msgid "" "The login success message varies with devices. if you cannot log in to the " "device through Telnet, set this parameter" -msgstr "ログイン成功メッセージはデバイスによって異なります。Telnet経由でデバイスにログインできない場合は、このパラメーターを設定します。" +msgstr "" +"ログイン成功メッセージはデバイスによって異なります。Telnet経由でデバイスにロ" +"グインできない場合は、このパラメーターを設定します。" -#: settings/serializers/terminal.py:34 +#: settings/serializers/terminal.py:37 msgid "RDP address" msgstr "RDPアドレス" -#: settings/serializers/terminal.py:35 +#: settings/serializers/terminal.py:38 msgid "RDP visit address, eg: dev.jumpserver.org:3389" msgstr "RDP訪問先住所、例: dev.jumpserver.org:3389" -#: settings/serializers/terminal.py:38 +#: settings/serializers/terminal.py:40 msgid "Enable XRDP" msgstr "XRDPの有効化" +#: settings/serializers/terminal.py:42 +msgid "Koko host" +msgstr "KOKO ホストアドレス" + +#: settings/serializers/terminal.py:43 +msgid "Koko ssh port" +msgstr "KOKO ssh ポート" + +#: settings/serializers/terminal.py:45 +msgid "Enable database proxy" +msgstr "属性マップの有効化" + +#: settings/serializers/terminal.py:47 +#, fuzzy +#| msgid "DatabaseApp" +msgid "Database proxy host" +msgstr "データベースの適用" + +#: settings/serializers/terminal.py:48 +msgid "Database proxy host, eg: dev.jumpserver.org" +msgstr "RDP訪問先住所、例: dev.jumpserver.org:3389" + +#: settings/serializers/terminal.py:51 +msgid "MySQL port" +msgstr "SMTPポート" + +#: settings/serializers/terminal.py:52 +msgid "Database proxy MySQL protocol port" +msgstr "" + +#: settings/serializers/terminal.py:55 +msgid "PostgreSQL port" +msgstr "" + +#: settings/serializers/terminal.py:56 +msgid "Database proxy PostgreSQL port" +msgstr "" + #: settings/utils/ldap.py:417 msgid "ldap:// or ldaps:// protocol is used." msgstr "ldap:// または ldaps:// プロトコルが使用されます。" @@ -4305,7 +4421,9 @@ msgstr "インポート" #: templates/_csv_import_modal.html:12 msgid "Download the imported template or use the exported CSV file format" -msgstr "インポートしたテンプレートをダウンロードするか、エクスポートしたCSVファイル形式を使用する" +msgstr "" +"インポートしたテンプレートをダウンロードするか、エクスポートしたCSVファイル形" +"式を使用する" #: templates/_csv_import_modal.html:13 msgid "Download the import template" @@ -4321,7 +4439,9 @@ msgstr "ファイルを選択してください" #: templates/_csv_update_modal.html:12 msgid "Download the update template or use the exported CSV file format" -msgstr "更新テンプレートをダウンロードするか、エクスポートしたCSVファイル形式を使用する" +msgstr "" +"更新テンプレートをダウンロードするか、エクスポートしたCSVファイル形式を使用す" +"る" #: templates/_csv_update_modal.html:13 msgid "Download the update template" @@ -4339,24 +4459,24 @@ msgstr "ドキュメント" msgid "Commercial support" msgstr "商用サポート" -#: templates/_header_bar.html:70 users/forms/profile.py:43 +#: templates/_header_bar.html:76 users/forms/profile.py:43 #: users/templates/users/user_password_update.html:39 msgid "Profile" msgstr "プロフィール" -#: templates/_header_bar.html:73 +#: templates/_header_bar.html:79 msgid "Admin page" msgstr "ページの管理" -#: templates/_header_bar.html:75 +#: templates/_header_bar.html:81 msgid "User page" msgstr "ユーザーページ" -#: templates/_header_bar.html:78 +#: templates/_header_bar.html:84 msgid "API Key" msgstr "API Key" -#: templates/_header_bar.html:79 +#: templates/_header_bar.html:85 msgid "Logout" msgstr "ログアウト" @@ -4367,7 +4487,8 @@ msgid "" " " msgstr "" "\n" -" アカウントが期限切れになったので、管理者に連絡してください。 " +" アカウントが期限切れになったので、管理者に連絡してくださ" +"い。 " #: templates/_message.html:13 msgid "Your account will at" @@ -4386,8 +4507,8 @@ msgid "" " " msgstr "" "\n" -" パスワードが期限切れになりましたので、クリックしてください リンク パスワードの更新\n" +" パスワードが期限切れになりましたので、クリックしてください " +" リンク パスワードの更新\n" " " #: templates/_message.html:30 @@ -4403,8 +4524,8 @@ msgid "" " " msgstr "" "\n" -" クリックしてください リンク パ" -"スワードの更新\n" +" クリックしてください リンク パスワードの更新\n" " " #: templates/_message.html:43 @@ -4416,8 +4537,8 @@ msgid "" " " msgstr "" "\n" -" あなたの情報が不完全なので、クリックしてください。 リンク " -" 補完\n" +" あなたの情報が不完全なので、クリックしてください。 リンク 補完\n" " " #: templates/_message.html:56 @@ -4502,7 +4623,9 @@ msgstr "アクティブなユーザー資産比率" msgid "" "The following graphs describe the percentage of active users per month and " "assets per user host per month, respectively." -msgstr "次のグラフは、1か月あたりのアクティブユーザーの割合と、1か月あたりのユーザーホストあたりの資産の割合をそれぞれ示しています。" +msgstr "" +"次のグラフは、1か月あたりのアクティブユーザーの割合と、1か月あたりのユーザー" +"ホストあたりの資産の割合をそれぞれ示しています。" #: templates/index.html:97 templates/index.html:112 msgid "Top 10 assets in a week" @@ -4621,7 +4744,9 @@ msgstr "クライアント" msgid "" "JumpServer Client, currently used to launch the client, now only support " "launch RDP client, The SSH client will next" -msgstr "現在クライアントの起動に使用されているJumpServerクライアントは、RDPクライアントの起動のみをサポートしています。" +msgstr "" +"現在クライアントの起動に使用されているJumpServerクライアントは、RDPクライアン" +"トの起動のみをサポートしています。" #: templates/resource_download.html:30 msgid "Microsoft" @@ -4635,7 +4760,9 @@ msgstr "公式" msgid "" "macOS needs to download the client to connect RDP asset, which comes with " "Windows" -msgstr "MacOSは、Windowsに付属のRDPアセットを接続するためにクライアントをダウンロードする必要があります" +msgstr "" +"MacOSは、Windowsに付属のRDPアセットを接続するためにクライアントをダウンロード" +"する必要があります" #: templates/resource_download.html:41 msgid "Windows Remote application publisher tools" @@ -4645,7 +4772,9 @@ msgstr "Windowsリモートアプリケーション発行者ツール" msgid "" "Jmservisor is the program used to pull up remote applications in Windows " "Remote Application publisher" -msgstr "Jmservisorはwindowsリモートアプリケーションパブリケーションサーバでリモートアプリケーションを引き出すためのプログラムです" +msgstr "" +"Jmservisorはwindowsリモートアプリケーションパブリケーションサーバでリモートア" +"プリケーションを引き出すためのプログラムです" #: templates/rest_framework/base.html:128 msgid "Filters" @@ -5005,7 +5134,7 @@ msgstr "エンドポイントが無効: パス '{}' を削除" msgid "Bucket" msgstr "バケット" -#: terminal/serializers/storage.py:34 users/models/user.py:689 +#: terminal/serializers/storage.py:34 users/models/user.py:693 msgid "Secret key" msgstr "秘密キー" @@ -5063,7 +5192,7 @@ msgstr "証明書の検証を無視する" msgid "Load status" msgstr "ロードステータス" -#: terminal/serializers/terminal.py:83 terminal/serializers/terminal.py:91 +#: terminal/serializers/terminal.py:81 terminal/serializers/terminal.py:89 msgid "Not found" msgstr "見つかりません" @@ -5167,7 +5296,9 @@ msgstr "適用期限が切れた" msgid "" "Created by the ticket, ticket title: {}, ticket applicant: {}, ticket " "processor: {}, ticket ID: {}" -msgstr "チケットによって作成されたチケットタイトル: {}、チケット申請者: {}、チケット処理者: {}、チケットID: {}" +msgstr "" +"チケットによって作成されたチケットタイトル: {}、チケット申請者: {}、チケット" +"処理者: {}、チケットID: {}" #: tickets/handler/apply_asset.py:50 msgid "Applied node group" @@ -5185,7 +5316,9 @@ msgstr "応用アクション" msgid "" "Created by the ticket ticket title: {} ticket applicant: {} ticket " "processor: {} ticket ID: {}" -msgstr "チケットのタイトル: {} チケット申請者: {} チケットプロセッサ: {} チケットID: {}" +msgstr "" +"チケットのタイトル: {} チケット申請者: {} チケットプロセッサ: {} チケットID: " +"{}" #: tickets/handler/base.py:88 msgid "{} {} the ticket" @@ -5476,7 +5609,9 @@ msgstr "ログイン日時" msgid "" "The `type` in the submission data (`{}`) is different from the type in the " "request url (`{}`)" -msgstr "送信データ ('{}') の「タイプ」は、リクエストURL ('{}') のタイプとは異なります。" +msgstr "" +"送信データ ('{}') の「タイプ」は、リクエストURL ('{}') のタイプとは異なりま" +"す。" #: tickets/serializers/ticket/ticket.py:116 msgid "The ticket flow `{}` does not exist" @@ -5541,8 +5676,8 @@ msgid "" "in. you can also directly bind in \"personal information -> quick " "modification -> change MFA Settings\"!" msgstr "" -"有効にすると、次回のログイン時にマルチファクタ認証バインドプロセスに入ります。(個人情報->クイック" -"修正->MFAマルチファクタ認証の設定)で直接バインド!" +"有効にすると、次回のログイン時にマルチファクタ認証バインドプロセスに入りま" +"す。(個人情報->クイック修正->MFAマルチファクタ認証の設定)で直接バインド!" #: users/forms/profile.py:60 msgid "* Enable MFA to make the account more secure." @@ -5553,7 +5688,9 @@ msgid "" "In order to protect you and your company, please keep your account, password " "and key sensitive information properly. (for example: setting complex " "password, enabling MFA)" -msgstr "あなたとあなたの会社を保護するために、アカウント、パスワード、キーの機密情報を適切に保管してください。(例: 複雑なパスワードの設定、MFAの有効化)" +msgstr "" +"あなたとあなたの会社を保護するために、アカウント、パスワード、キーの機密情報" +"を適切に保管してください。(例: 複雑なパスワードの設定、MFAの有効化)" #: users/forms/profile.py:76 msgid "Finish" @@ -5604,68 +5741,68 @@ msgstr "公開鍵は古いものと同じであってはなりません。" msgid "Not a valid ssh public key" msgstr "有効なssh公開鍵ではありません" -#: users/forms/profile.py:160 users/models/user.py:686 +#: users/forms/profile.py:160 users/models/user.py:690 #: users/templates/users/user_password_update.html:48 msgid "Public key" msgstr "公開キー" -#: users/models/user.py:552 +#: users/models/user.py:556 msgid "Force enable" msgstr "強制有効" -#: users/models/user.py:619 +#: users/models/user.py:623 msgid "Local" msgstr "ローカル" -#: users/models/user.py:667 users/serializers/user.py:138 +#: users/models/user.py:671 users/serializers/user.py:140 msgid "Is service account" msgstr "サービスアカウントです" -#: users/models/user.py:669 +#: users/models/user.py:673 msgid "Avatar" msgstr "アバター" -#: users/models/user.py:672 +#: users/models/user.py:676 msgid "Wechat" msgstr "微信" -#: users/models/user.py:683 +#: users/models/user.py:687 msgid "Private key" msgstr "ssh秘密鍵" -#: users/models/user.py:705 +#: users/models/user.py:709 msgid "Source" msgstr "ソース" -#: users/models/user.py:709 +#: users/models/user.py:713 msgid "Date password last updated" msgstr "最終更新日パスワード" -#: users/models/user.py:712 +#: users/models/user.py:716 msgid "Need update password" msgstr "更新パスワードが必要" -#: users/models/user.py:882 +#: users/models/user.py:886 msgid "Can invite user" msgstr "ユーザーを招待できます" -#: users/models/user.py:883 +#: users/models/user.py:887 msgid "Can remove user" msgstr "ユーザーを削除できます" -#: users/models/user.py:884 +#: users/models/user.py:888 msgid "Can match user" msgstr "ユーザーに一致できます" -#: users/models/user.py:893 +#: users/models/user.py:897 msgid "Administrator" msgstr "管理者" -#: users/models/user.py:896 +#: users/models/user.py:900 msgid "Administrator is the super user of system" msgstr "管理者はシステムのスーパーユーザーです" -#: users/models/user.py:921 +#: users/models/user.py:925 msgid "User password history" msgstr "ユーザーパスワード履歴" @@ -5716,7 +5853,7 @@ msgstr "新しいパスワードを最後の {} 個のパスワードにする msgid "The newly set password is inconsistent" msgstr "新しく設定されたパスワードが一致しない" -#: users/serializers/profile.py:142 users/serializers/user.py:136 +#: users/serializers/profile.py:142 users/serializers/user.py:138 msgid "Is first login" msgstr "最初のログインです" @@ -5728,85 +5865,85 @@ msgstr "システムの役割" msgid "Org roles" msgstr "組織ロール" -#: users/serializers/user.py:75 +#: users/serializers/user.py:77 #: xpack/plugins/change_auth_plan/models/base.py:35 #: xpack/plugins/change_auth_plan/serializers/base.py:22 msgid "Password strategy" msgstr "パスワード戦略" -#: users/serializers/user.py:77 +#: users/serializers/user.py:79 msgid "MFA enabled" msgstr "MFA有効化" -#: users/serializers/user.py:78 +#: users/serializers/user.py:80 msgid "MFA force enabled" msgstr "MFAフォース有効化" -#: users/serializers/user.py:80 +#: users/serializers/user.py:82 msgid "MFA level display" msgstr "MFAレベル表示" -#: users/serializers/user.py:82 +#: users/serializers/user.py:84 msgid "Login blocked" msgstr "ログインブロック" -#: users/serializers/user.py:85 +#: users/serializers/user.py:87 msgid "Can public key authentication" msgstr "公開鍵認証が可能" -#: users/serializers/user.py:140 +#: users/serializers/user.py:142 msgid "Avatar url" msgstr "アバターURL" -#: users/serializers/user.py:142 +#: users/serializers/user.py:144 msgid "Groups name" msgstr "グループ名" -#: users/serializers/user.py:143 +#: users/serializers/user.py:145 msgid "Source name" msgstr "ソース名" -#: users/serializers/user.py:144 +#: users/serializers/user.py:146 msgid "Organization role name" msgstr "組織の役割名" -#: users/serializers/user.py:145 +#: users/serializers/user.py:147 msgid "Super role name" msgstr "スーパーロール名" -#: users/serializers/user.py:146 +#: users/serializers/user.py:148 msgid "Total role name" msgstr "合計ロール名" -#: users/serializers/user.py:148 +#: users/serializers/user.py:150 msgid "Is wecom bound" msgstr "企業の微信をバインドしているかどうか" -#: users/serializers/user.py:149 +#: users/serializers/user.py:151 msgid "Is dingtalk bound" msgstr "ピンをバインドしているかどうか" -#: users/serializers/user.py:150 +#: users/serializers/user.py:152 msgid "Is feishu bound" msgstr "飛本を縛ったかどうか" -#: users/serializers/user.py:151 +#: users/serializers/user.py:153 msgid "Is OTP bound" msgstr "仮想MFAがバインドされているか" -#: users/serializers/user.py:153 +#: users/serializers/user.py:155 msgid "System role name" msgstr "システムロール名" -#: users/serializers/user.py:245 +#: users/serializers/user.py:247 msgid "Select users" msgstr "ユーザーの選択" -#: users/serializers/user.py:246 +#: users/serializers/user.py:248 msgid "For security, only list several users" msgstr "セキュリティのために、複数のユーザーのみをリストします" -#: users/serializers/user.py:279 +#: users/serializers/user.py:281 msgid "name not unique" msgstr "名前が一意ではない" @@ -5822,7 +5959,8 @@ msgstr "アカウントの有効期限は" msgid "" "In order not to affect your normal work, please contact the administrator " "for confirmation." -msgstr "通常の作業に影響を与えないように、確認のために管理者に連絡してください。" +msgstr "" +"通常の作業に影響を与えないように、確認のために管理者に連絡してください。" #: users/templates/users/_msg_password_expire_reminder.html:7 msgid "Your password will expire in" @@ -5832,7 +5970,9 @@ msgstr "パスワードは" msgid "" "For your account security, please click on the link below to update your " "password in time" -msgstr "アカウントのセキュリティについては、下のリンクをクリックしてパスワードを時間内に更新してください" +msgstr "" +"アカウントのセキュリティについては、下のリンクをクリックしてパスワードを時間" +"内に更新してください" #: users/templates/users/_msg_password_expire_reminder.html:11 msgid "Click here update password" @@ -5840,7 +5980,8 @@ msgstr "ここをクリック更新パスワード" #: users/templates/users/_msg_password_expire_reminder.html:16 msgid "If your password has expired, please click the link below to" -msgstr "パスワードの有効期限が切れている場合は、以下のリンクをクリックしてください" +msgstr "" +"パスワードの有効期限が切れている場合は、以下のリンクをクリックしてください" #: users/templates/users/_msg_reset_mfa.html:7 msgid "Your MFA has been reset by site administrator" @@ -6017,7 +6158,9 @@ msgstr "ワンタイムパスワード認証子のバインド" msgid "" "Use the MFA Authenticator application to scan the following qr code for a 6-" "bit verification code" -msgstr "MFA Authenticatorアプリケーションを使用して、次のqrコードを6ビット検証コードでスキャンします。" +msgstr "" +"MFA Authenticatorアプリケーションを使用して、次のqrコードを6ビット検証コード" +"でスキャンします。" #: users/templates/users/user_otp_enable_bind.html:22 #: users/templates/users/user_verify_mfa.html:27 @@ -6032,7 +6175,9 @@ msgstr "アプリのインストール" msgid "" "Download and install the MFA Authenticator application on your phone or " "applet of WeChat" -msgstr "携帯電話またはWeChatのアプレットにMFA Authenticatorアプリケーションをダウンロードしてインストールします" +msgstr "" +"携帯電話またはWeChatのアプレットにMFA Authenticatorアプリケーションをダウン" +"ロードしてインストールします" #: users/templates/users/user_otp_enable_install_app.html:18 msgid "Android downloads" @@ -6046,7 +6191,9 @@ msgstr "IPhoneのダウンロード" msgid "" "After installation, click the next step to enter the binding page (if " "installed, go to the next step directly)." -msgstr "インストール後、次のステップをクリックしてバインディングページに入ります (インストールされている場合は、次のステップに直接進みます)。" +msgstr "" +"インストール後、次のステップをクリックしてバインディングページに入ります (イ" +"ンストールされている場合は、次のステップに直接進みます)。" #: users/templates/users/user_password_update.html:74 msgid "Reset" @@ -6065,7 +6212,8 @@ msgstr "認証" msgid "" "The account protection has been opened, please complete the following " "operations according to the prompts" -msgstr "アカウント保護が開始されました。プロンプトに従って次の操作を完了してください" +msgstr "" +"アカウント保護が開始されました。プロンプトに従って次の操作を完了してください" #: users/templates/users/user_verify_mfa.html:17 msgid "Open MFA Authenticator and enter the 6-bit dynamic code" @@ -6077,7 +6225,8 @@ msgstr "すでにバインド済み" #: users/views/profile/otp.py:88 msgid "MFA already bound, disable first, then bound" -msgstr "MFAはすでにバインドされており、最初に無効にしてからバインドされています。" +msgstr "" +"MFAはすでにバインドされており、最初に無効にしてからバインドされています。" #: users/views/profile/otp.py:115 msgid "OTP enable success" @@ -6109,7 +6258,9 @@ msgstr "リセットパスワードメッセージを送信" #: users/views/profile/reset.py:41 msgid "Send reset password mail success, login your mail box and follow it " -msgstr "リセットパスワードメールの成功を送信し、メールボックスにログインしてそれに従う" +msgstr "" +"リセットパスワードメールの成功を送信し、メールボックスにログインしてそれに従" +"う" #: users/views/profile/reset.py:52 msgid "Email address invalid, please input again" @@ -6119,7 +6270,9 @@ msgstr "メールアドレスが無効です。再度入力してください" msgid "" "The user is from {}, please go to the corresponding system to change the " "password" -msgstr "ユーザーは {}からです。対応するシステムにアクセスしてパスワードを変更してください。" +msgstr "" +"ユーザーは {}からです。対応するシステムにアクセスしてパスワードを変更してくだ" +"さい。" #: users/views/profile/reset.py:84 users/views/profile/reset.py:95 msgid "Token invalid or expired" @@ -6280,7 +6433,9 @@ msgid "" "{} - The encryption change task has been completed: the encryption password " "has not been set - please go to personal information -> file encryption " "password to set the encryption password" -msgstr "{} -暗号化変更タスクが完了しました: 暗号化パスワードが設定されていません-個人情報にアクセスしてください-> ファイル暗号化パスワードを設定してください" +msgstr "" +"{} -暗号化変更タスクが完了しました: 暗号化パスワードが設定されていません-個人" +"情報にアクセスしてください-> ファイル暗号化パスワードを設定してください" #: xpack/plugins/change_auth_plan/serializers/asset.py:32 msgid "Change Password" @@ -6728,8 +6883,9 @@ msgid "" "created asset.
    The default * indicates a random match.
    Format for " "comma-delimited string, Such as: 192.168.1.0/24, 10.1.1.1-10.1.1.20" msgstr "" -"最初に一致するIPアドレスは、作成された資産のIPとして使用されます。
    デフォルト*はランダムマッチングを表します。" -"
    カンマで区切られた文字列で書式設定,たとえば:192.168.1.0/24,10.1.1.1-10.1.1.20" +"最初に一致するIPアドレスは、作成された資産のIPとして使用されます。
    デフォ" +"ルト*はランダムマッチングを表します。
    カンマで区切られた文字列で書式設" +"定,たとえば:192.168.1.0/24,10.1.1.1-10.1.1.20" #: xpack/plugins/cloud/serializers/task.py:35 msgid "History count" diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 4d1f7fae3..e0e340828 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-03-23 15:35+0800\n" +"POT-Creation-Date: 2022-03-29 12:58+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -22,7 +22,7 @@ msgid "Acls" msgstr "访问控制" #: acls/models/base.py:25 acls/serializers/login_asset_acl.py:47 -#: applications/models/application.py:213 assets/models/asset.py:138 +#: applications/models/application.py:211 assets/models/asset.py:138 #: assets/models/base.py:175 assets/models/cluster.py:18 #: assets/models/cmd_filter.py:27 assets/models/domain.py:23 #: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24 @@ -30,7 +30,7 @@ msgstr "访问控制" #: settings/models.py:29 settings/serializers/sms.py:6 #: terminal/models/storage.py:23 terminal/models/task.py:16 #: terminal/models/terminal.py:100 users/forms/profile.py:32 -#: users/models/group.py:15 users/models/user.py:655 +#: users/models/group.py:15 users/models/user.py:659 #: users/templates/users/_select_user_modal.html:13 #: users/templates/users/user_asset_permission.html:37 #: users/templates/users/user_asset_permission.html:154 @@ -56,7 +56,7 @@ msgstr "优先级可选范围为 1-100 (数值越小越优先)" msgid "Active" msgstr "激活中" -#: acls/models/base.py:32 applications/models/application.py:226 +#: acls/models/base.py:32 applications/models/application.py:224 #: assets/models/asset.py:143 assets/models/asset.py:231 #: assets/models/backup.py:54 assets/models/base.py:180 #: assets/models/cluster.py:29 assets/models/cmd_filter.py:48 @@ -66,7 +66,7 @@ msgstr "激活中" #: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34 #: terminal/models/storage.py:26 terminal/models/terminal.py:114 #: tickets/models/comment.py:24 tickets/models/ticket.py:154 -#: users/models/group.py:16 users/models/user.py:692 +#: users/models/group.py:16 users/models/user.py:696 #: 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,8 +94,8 @@ msgstr "登录复核" #: terminal/backends/command/models.py:19 #: terminal/backends/command/serializers.py:12 terminal/models/session.py:42 #: terminal/notifications.py:91 terminal/notifications.py:139 -#: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:880 -#: users/models/user.py:911 users/serializers/group.py:19 +#: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:884 +#: users/models/user.py:915 users/serializers/group.py:19 #: users/templates/users/user_asset_permission.html:38 #: users/templates/users/user_asset_permission.html:64 #: users/templates/users/user_database_app_permission.html:37 @@ -169,7 +169,7 @@ msgstr "格式为逗号分隔的字符串, * 表示匹配所有. " #: authentication/forms.py:15 authentication/forms.py:17 #: 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:31 users/models/user.py:653 +#: ops/models/adhoc.py:159 users/forms/profile.py:31 users/models/user.py:657 #: users/templates/users/_msg_user_created.html:12 #: users/templates/users/_select_user_modal.html:14 #: xpack/plugins/change_auth_plan/models/asset.py:34 @@ -274,7 +274,7 @@ msgstr "远程应用" msgid "Custom" msgstr "自定义" -#: applications/models/account.py:12 applications/models/application.py:230 +#: applications/models/account.py:12 applications/models/application.py:228 #: assets/models/backup.py:32 assets/models/cmd_filter.py:45 #: perms/models/application_permission.py:28 msgid "Application" @@ -314,7 +314,7 @@ msgstr "可以查看应用账号密码" msgid "Can change application account secret" msgstr "可以查看应用账号密码" -#: applications/models/application.py:215 +#: applications/models/application.py:213 #: applications/serializers/application.py:99 assets/models/label.py:21 #: perms/models/application_permission.py:21 #: perms/serializers/application/user_permission.py:33 @@ -323,7 +323,7 @@ msgstr "可以查看应用账号密码" msgid "Category" msgstr "类别" -#: applications/models/application.py:218 +#: applications/models/application.py:216 #: applications/serializers/application.py:101 assets/models/backup.py:49 #: assets/models/cmd_filter.py:82 assets/models/user.py:246 #: perms/models/application_permission.py:24 @@ -336,21 +336,21 @@ msgstr "类别" msgid "Type" msgstr "类型" -#: applications/models/application.py:222 assets/models/asset.py:217 +#: applications/models/application.py:220 assets/models/asset.py:217 #: assets/models/domain.py:29 assets/models/domain.py:63 msgid "Domain" msgstr "网域" -#: applications/models/application.py:224 xpack/plugins/cloud/models.py:33 +#: applications/models/application.py:222 xpack/plugins/cloud/models.py:33 #: xpack/plugins/cloud/serializers/account.py:58 msgid "Attrs" msgstr "属性" -#: applications/models/application.py:234 +#: applications/models/application.py:232 msgid "Can match application" msgstr "匹配应用" -#: applications/models/application.py:282 +#: applications/models/application.py:280 msgid "Application user" msgstr "应用用户" @@ -379,7 +379,7 @@ msgstr "类型名称" #: assets/serializers/cmd_filter.py:49 common/db/models.py:113 #: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30 #: orgs/models.py:67 orgs/models.py:217 perms/models/base.py:92 -#: users/models/group.py:18 users/models/user.py:912 +#: users/models/group.py:18 users/models/user.py:916 #: xpack/plugins/cloud/models.py:125 msgid "Date created" msgstr "创建日期" @@ -631,7 +631,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:111 common/mixins/models.py:49 orgs/models.py:66 -#: orgs/models.py:219 perms/models/base.py:91 users/models/user.py:700 +#: orgs/models.py:219 perms/models/base.py:91 users/models/user.py:704 #: 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 @@ -780,7 +780,7 @@ msgstr "校验日期" #: assets/models/base.py:177 audits/signal_handlers.py:68 #: authentication/forms.py:22 -#: authentication/templates/authentication/login.html:178 +#: authentication/templates/authentication/login.html:181 #: settings/serializers/auth/ldap.py:44 users/forms/profile.py:21 #: users/templates/users/_msg_user_created.html:13 #: users/templates/users/user_password_update.html:43 @@ -812,7 +812,7 @@ msgstr "带宽" msgid "Contact" msgstr "联系人" -#: assets/models/cluster.py:22 users/models/user.py:675 +#: assets/models/cluster.py:22 users/models/user.py:679 msgid "Phone" msgstr "手机" @@ -838,7 +838,7 @@ msgid "Default" msgstr "默认" #: assets/models/cluster.py:36 assets/models/label.py:14 rbac/const.py:6 -#: users/models/user.py:897 +#: users/models/user.py:901 msgid "System" msgstr "系统" @@ -847,7 +847,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:661 +#: users/models/group.py:31 users/models/user.py:665 #: users/templates/users/_select_user_modal.html:16 #: users/templates/users/user_asset_permission.html:39 #: users/templates/users/user_asset_permission.html:67 @@ -1502,7 +1502,7 @@ msgstr "用户代理" #: audits/models.py:124 #: authentication/templates/authentication/_mfa_confirm_modal.html:14 -#: users/forms/profile.py:64 users/models/user.py:678 +#: users/forms/profile.py:64 users/models/user.py:682 #: users/serializers/profile.py:121 msgid "MFA" msgstr "MFA" @@ -1580,13 +1580,13 @@ msgstr "认证令牌" #: audits/signal_handlers.py:71 authentication/notifications.py:73 #: authentication/views/login.py:164 authentication/views/wecom.py:158 -#: notifications/backends/__init__.py:11 users/models/user.py:714 +#: notifications/backends/__init__.py:11 users/models/user.py:718 msgid "WeCom" msgstr "企业微信" #: audits/signal_handlers.py:72 authentication/views/dingtalk.py:160 #: authentication/views/login.py:170 notifications/backends/__init__.py:12 -#: users/models/user.py:715 +#: users/models/user.py:719 msgid "DingTalk" msgstr "钉钉" @@ -1759,7 +1759,7 @@ msgstr "{ApplicationPermission} 添加 {SystemUser}" msgid "{ApplicationPermission} REMOVE {SystemUser}" msgstr "{ApplicationPermission} 移除 {SystemUser}" -#: authentication/api/connection_token.py:296 +#: authentication/api/connection_token.py:313 msgid "Invalid token" msgstr "无效的令牌" @@ -2117,14 +2117,14 @@ msgid "Show" msgstr "显示" #: authentication/templates/authentication/_access_key_modal.html:66 -#: settings/serializers/security.py:39 users/models/user.py:550 +#: settings/serializers/security.py:39 users/models/user.py:554 #: users/serializers/profile.py:111 users/templates/users/mfa_setting.html:61 #: users/templates/users/user_verify_mfa.html:36 msgid "Disable" msgstr "禁用" #: authentication/templates/authentication/_access_key_modal.html:67 -#: users/models/user.py:551 users/serializers/profile.py:112 +#: users/models/user.py:555 users/serializers/profile.py:112 #: users/templates/users/mfa_setting.html:26 #: users/templates/users/mfa_setting.html:68 msgid "Enable" @@ -2172,7 +2172,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:293 ops/tasks.py:145 ops/tasks.py:148 +#: jumpserver/conf.py:295 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 #: users/templates/users/_msg_account_expire_reminder.html:4 @@ -2254,22 +2254,22 @@ msgid "" "security issues" msgstr "如果这次公钥更新不是由你发起的,那么你的账号可能存在安全问题" -#: authentication/templates/authentication/login.html:170 +#: authentication/templates/authentication/login.html:173 msgid "Welcome back, please enter username and password to login" msgstr "欢迎回来,请输入用户名和密码登录" -#: authentication/templates/authentication/login.html:206 +#: authentication/templates/authentication/login.html:209 #: users/templates/users/forgot_password.html:15 #: users/templates/users/forgot_password.html:16 msgid "Forgot password" msgstr "忘记密码" -#: authentication/templates/authentication/login.html:213 -#: templates/_header_bar.html:83 +#: authentication/templates/authentication/login.html:216 +#: templates/_header_bar.html:89 msgid "Login" msgstr "登录" -#: authentication/templates/authentication/login.html:220 +#: authentication/templates/authentication/login.html:223 msgid "More login options" msgstr "更多登录方式" @@ -2373,7 +2373,7 @@ msgid "The FeiShu is already bound to another user" msgstr "该飞书已经绑定其他用户" #: authentication/views/feishu.py:148 authentication/views/login.py:176 -#: notifications/backends/__init__.py:14 users/models/user.py:716 +#: notifications/backends/__init__.py:14 users/models/user.py:720 msgid "FeiShu" msgstr "飞书" @@ -2624,11 +2624,11 @@ msgstr "不能包含特殊字符" msgid "The mobile phone number format is incorrect" msgstr "手机号格式不正确" -#: jumpserver/conf.py:292 +#: jumpserver/conf.py:294 msgid "Create account successfully" msgstr "创建账号成功" -#: jumpserver/conf.py:294 +#: jumpserver/conf.py:296 msgid "Your account has been created successfully" msgstr "你的账号已创建成功" @@ -2668,7 +2668,7 @@ msgid "Notifications" msgstr "通知" #: notifications/backends/__init__.py:10 users/forms/profile.py:101 -#: users/models/user.py:657 +#: users/models/user.py:661 msgid "Email" msgstr "邮件" @@ -2894,7 +2894,7 @@ msgid "Can view root org" msgstr "可以查看全局组织" #: orgs/models.py:216 rbac/models/role.py:46 rbac/models/rolebinding.py:43 -#: users/models/user.py:665 users/templates/users/_select_user_modal.html:15 +#: users/models/user.py:669 users/templates/users/_select_user_modal.html:15 msgid "Role" msgstr "角色" @@ -2981,7 +2981,7 @@ msgstr "剪贴板复制粘贴" #: perms/models/base.py:90 #: tickets/serializers/ticket/meta/ticket_type/apply_application.py:58 #: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:60 -#: users/models/user.py:697 +#: users/models/user.py:701 msgid "Date expired" msgstr "失效日期" @@ -4207,30 +4207,38 @@ msgid "Enable XRDP" msgstr "启用 XRDP 服务" #: settings/serializers/terminal.py:42 +msgid "Koko host" +msgstr "KOKO 主机地址" + +#: settings/serializers/terminal.py:43 +msgid "Koko ssh port" +msgstr "KOKO ssh 端口" + +#: settings/serializers/terminal.py:45 msgid "Enable database proxy" msgstr "启用数据库组件" -#: settings/serializers/terminal.py:44 +#: settings/serializers/terminal.py:47 msgid "Database proxy host" msgstr "数据库主机地址" -#: settings/serializers/terminal.py:45 +#: settings/serializers/terminal.py:48 msgid "Database proxy host, eg: dev.jumpserver.org" msgstr "数据库组件地址, 如: dev.jumpserver.org (没有端口, 不同协议端口不同)" -#: settings/serializers/terminal.py:48 +#: settings/serializers/terminal.py:51 msgid "MySQL port" msgstr "MySQL 协议端口" -#: settings/serializers/terminal.py:49 +#: settings/serializers/terminal.py:52 msgid "Database proxy MySQL protocol port" msgstr "数据库组件 MySQL 协议监听的端口" -#: settings/serializers/terminal.py:52 +#: settings/serializers/terminal.py:55 msgid "PostgreSQL port" msgstr "PostgreSQL 端口" -#: settings/serializers/terminal.py:53 +#: settings/serializers/terminal.py:56 msgid "Database proxy PostgreSQL port" msgstr "数据库组件 PostgreSQL 协议监听的端口" @@ -4383,24 +4391,24 @@ msgstr "文档" msgid "Commercial support" msgstr "商业支持" -#: templates/_header_bar.html:70 users/forms/profile.py:43 +#: templates/_header_bar.html:76 users/forms/profile.py:43 #: users/templates/users/user_password_update.html:39 msgid "Profile" msgstr "个人信息" -#: templates/_header_bar.html:73 +#: templates/_header_bar.html:79 msgid "Admin page" msgstr "管理页面" -#: templates/_header_bar.html:75 +#: templates/_header_bar.html:81 msgid "User page" msgstr "用户页面" -#: templates/_header_bar.html:78 +#: templates/_header_bar.html:84 msgid "API Key" msgstr "API Key" -#: templates/_header_bar.html:79 +#: templates/_header_bar.html:85 msgid "Logout" msgstr "注销登录" @@ -5051,7 +5059,7 @@ msgstr "端点无效: 移除路径 `{}`" msgid "Bucket" msgstr "桶名称" -#: terminal/serializers/storage.py:34 users/models/user.py:689 +#: terminal/serializers/storage.py:34 users/models/user.py:693 msgid "Secret key" msgstr "密钥" @@ -5654,68 +5662,68 @@ msgstr "不能和原来的密钥相同" msgid "Not a valid ssh public key" msgstr "SSH密钥不合法" -#: users/forms/profile.py:160 users/models/user.py:686 +#: users/forms/profile.py:160 users/models/user.py:690 #: users/templates/users/user_password_update.html:48 msgid "Public key" msgstr "SSH公钥" -#: users/models/user.py:552 +#: users/models/user.py:556 msgid "Force enable" msgstr "强制启用" -#: users/models/user.py:619 +#: users/models/user.py:623 msgid "Local" msgstr "数据库" -#: users/models/user.py:667 users/serializers/user.py:140 +#: users/models/user.py:671 users/serializers/user.py:140 msgid "Is service account" msgstr "服务账号" -#: users/models/user.py:669 +#: users/models/user.py:673 msgid "Avatar" msgstr "头像" -#: users/models/user.py:672 +#: users/models/user.py:676 msgid "Wechat" msgstr "微信" -#: users/models/user.py:683 +#: users/models/user.py:687 msgid "Private key" msgstr "ssh私钥" -#: users/models/user.py:705 +#: users/models/user.py:709 msgid "Source" msgstr "来源" -#: users/models/user.py:709 +#: users/models/user.py:713 msgid "Date password last updated" msgstr "最后更新密码日期" -#: users/models/user.py:712 +#: users/models/user.py:716 msgid "Need update password" msgstr "需要更新密码" -#: users/models/user.py:882 +#: users/models/user.py:886 msgid "Can invite user" msgstr "可以邀请用户" -#: users/models/user.py:883 +#: users/models/user.py:887 msgid "Can remove user" msgstr "可以移除用户" -#: users/models/user.py:884 +#: users/models/user.py:888 msgid "Can match user" msgstr "可以匹配用户" -#: users/models/user.py:893 +#: users/models/user.py:897 msgid "Administrator" msgstr "管理员" -#: users/models/user.py:896 +#: users/models/user.py:900 msgid "Administrator is the super user of system" msgstr "Administrator是初始的超级管理员" -#: users/models/user.py:921 +#: users/models/user.py:925 msgid "User password history" msgstr "用户密码历史" diff --git a/apps/settings/api/public.py b/apps/settings/api/public.py index f45e5a4e9..af811cc72 100644 --- a/apps/settings/api/public.py +++ b/apps/settings/api/public.py @@ -64,6 +64,8 @@ class PublicSettingApi(generics.RetrieveAPIView): "AUTH_FEISHU": settings.AUTH_FEISHU, # Terminal "XRDP_ENABLED": settings.XRDP_ENABLED, + "TERMINAL_KOKO_HOST": settings.TERMINAL_KOKO_HOST, + "TERMINAL_KOKO_SSH_PORT": settings.TERMINAL_KOKO_SSH_PORT, "TERMINAL_MAGNUS_ENABLED": settings.TERMINAL_MAGNUS_ENABLED, "TERMINAL_MAGNUS_HOST": settings.TERMINAL_MAGNUS_HOST, "TERMINAL_MAGNUS_MYSQL_PORT": settings.TERMINAL_MAGNUS_MYSQL_PORT, diff --git a/apps/settings/serializers/terminal.py b/apps/settings/serializers/terminal.py index aad5c3e92..b96e5974b 100644 --- a/apps/settings/serializers/terminal.py +++ b/apps/settings/serializers/terminal.py @@ -39,6 +39,9 @@ class TerminalSettingSerializer(serializers.Serializer): ) XRDP_ENABLED = serializers.BooleanField(label=_("Enable XRDP")) + TERMINAL_KOKO_HOST = serializers.BooleanField(label=_("Koko host")) + TERMINAL_KOKO_SSH_PORT = serializers.BooleanField(label=_("Koko ssh port")) + TERMINAL_MAGNUS_ENABLED = serializers.BooleanField(label=_("Enable database proxy")) TERMINAL_MAGNUS_HOST = serializers.CharField( required=False, label=_("Database proxy host"), max_length=1024, allow_blank=True, From cddff9fd19135b149e7230b1fd9fda195113a801 Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" Date: Mon, 28 Mar 2022 19:48:55 +0800 Subject: [PATCH 32/59] =?UTF-8?q?feat:=20=E6=94=B9=E5=AF=86=E8=AE=A1?= =?UTF-8?q?=E5=88=92=E6=94=AF=E6=8C=81su=E5=88=87=E6=8D=A2=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=89=A7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat: 改密计划支持su切换用户执行 feat: 改密计划支持su切换用户执行 feat: 改密计划支持su切换用户执行 feat: 改密计划支持su切换用户执行 feat: 改密计划支持su切换用户执行 feat: 改密计划支持su切换用户执行 --- apps/assets/models/asset.py | 38 +++++++++++++++++++++++---- apps/assets/serializers/admin_user.py | 1 + apps/ops/inventory.py | 8 +----- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py index d846c6ce4..c4ecf9cfe 100644 --- a/apps/assets/models/asset.py +++ b/apps/assets/models/asset.py @@ -280,16 +280,44 @@ class Asset(AbsConnectivity, AbsHardwareInfo, ProtocolsMixin, NodesRelationMixin def is_support_ansible(self): return self.has_protocol('ssh') and self.platform_base not in ("Other",) - def get_auth_info(self): + def get_auth_info(self, with_become=False): if not self.admin_user: return {} - self.admin_user.load_asset_special_auth(self) + if self.is_unixlike() and self.admin_user.su_enabled and self.admin_user.su_from: + auth_user = self.admin_user.su_from + become_user = self.admin_user + else: + auth_user = self.admin_user + become_user = None + + auth_user.load_asset_special_auth(self) info = { - 'username': self.admin_user.username, - 'password': self.admin_user.password, - 'private_key': self.admin_user.private_key_file, + 'username': auth_user.username, + 'password': auth_user.password, + 'private_key': auth_user.private_key_file } + + if not with_become: + return info + + if become_user: + become_user.load_asset_special_auth(self) + become_method = 'su' + become_username = become_user.username + become_pass = become_user.password + else: + become_method = 'sudo' + become_username = 'root' + become_pass = auth_user.password + become_info = { + 'become': { + 'method': become_method, + 'username': become_username, + 'pass': become_pass + } + } + info.update(become_info) return info def nodes_display(self): diff --git a/apps/assets/serializers/admin_user.py b/apps/assets/serializers/admin_user.py index c72670ba8..b6ab18af3 100644 --- a/apps/assets/serializers/admin_user.py +++ b/apps/assets/serializers/admin_user.py @@ -15,6 +15,7 @@ class AdminUserSerializer(SuS): SuS.Meta.fields_m2m + \ [ 'type', 'protocol', "priority", 'sftp_root', 'ssh_key_fingerprint', + 'su_enabled', 'su_from', 'date_created', 'date_updated', 'comment', 'created_by', ] diff --git a/apps/ops/inventory.py b/apps/ops/inventory.py index fa077e903..b19ce8130 100644 --- a/apps/ops/inventory.py +++ b/apps/ops/inventory.py @@ -29,13 +29,7 @@ class JMSBaseInventory(BaseInventory): if asset.domain and asset.domain.has_gateway(): info["vars"].update(self.make_proxy_command(asset)) if run_as_admin: - info.update(asset.get_auth_info()) - if asset.is_unixlike(): - info["become"] = { - "method": 'sudo', - "user": 'root', - "pass": '' - } + info.update(asset.get_auth_info(with_become=True)) if asset.is_windows(): info["vars"].update({ "ansible_connection": "ssh", From b8e6bc932b05fff7aa927b09034f08c5c0296500 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 29 Mar 2022 17:22:59 +0800 Subject: [PATCH 33/59] =?UTF-8?q?perf:=20=E6=B7=BB=E5=8A=A0=20mariadb=20po?= =?UTF-8?q?rt=20(#7989)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 添加 mariadb port * perf: 优化 mariadb 树上天津更多信息 * perf: remove mixin Co-authored-by: ibuler --- apps/applications/api/__init__.py | 1 - apps/applications/models/application.py | 3 +- apps/jumpserver/conf.py | 1 + apps/jumpserver/settings/custom.py | 1 + .../user_permission_applications.py | 28 +++++--- apps/perms/tree/__init__.py | 0 .../api/mixin.py => perms/tree/app.py} | 72 +++++++++---------- apps/settings/api/public.py | 1 + apps/settings/serializers/terminal.py | 4 ++ 9 files changed, 60 insertions(+), 51 deletions(-) create mode 100644 apps/perms/tree/__init__.py rename apps/{applications/api/mixin.py => perms/tree/app.py} (61%) diff --git a/apps/applications/api/__init__.py b/apps/applications/api/__init__.py index 3258614fd..7a32ac0a0 100644 --- a/apps/applications/api/__init__.py +++ b/apps/applications/api/__init__.py @@ -1,4 +1,3 @@ from .application import * from .account import * -from .mixin import * from .remote_app import * diff --git a/apps/applications/models/application.py b/apps/applications/models/application.py index a3c50e960..aa2d56f70 100644 --- a/apps/applications/models/application.py +++ b/apps/applications/models/application.py @@ -145,7 +145,6 @@ class ApplicationTreeNodeMixin: pid, counts, show_empty=show_empty, show_count=show_count ) - return tree_nodes @classmethod @@ -183,7 +182,7 @@ class ApplicationTreeNodeMixin: def _attrs_to_tree(self): if self.category == const.AppCategory.db: - return {'database': self.attrs.get('database')} + return self.attrs return {} def _as_tree_node(self, pid): diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 3625f2a41..7aa8dc436 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -317,6 +317,7 @@ class Config(dict): 'TERMINAL_MAGNUS_ENABLED': True, 'TERMINAL_MAGNUS_HOST': lambda: urlparse(settings.SITE_URL).hostname, 'TERMINAL_MAGNUS_MYSQL_PORT': 33060, + 'TERMINAL_MAGNUS_MARIADB_PORT': 33061, 'TERMINAL_MAGNUS_POSTGRE_PORT': 54320, # 安全配置 diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index 4d720349f..2aa05afe5 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -176,4 +176,5 @@ MAGNUS_ENABLED = CONFIG.MAGNUS_ENABLED TERMINAL_MAGNUS_HOST = CONFIG.TERMINAL_MAGNUS_HOST TERMINAL_MAGNUS_ENABLED = CONFIG.TERMINAL_MAGNUS_ENABLED TERMINAL_MAGNUS_MYSQL_PORT = CONFIG.TERMINAL_MAGNUS_MYSQL_PORT +TERMINAL_MAGNUS_MARIADB_PORT = CONFIG.TERMINAL_MAGNUS_MARIADB_PORT TERMINAL_MAGNUS_POSTGRE_PORT = CONFIG.TERMINAL_MAGNUS_POSTGRE_PORT diff --git a/apps/perms/api/application/user_permission/user_permission_applications.py b/apps/perms/api/application/user_permission/user_permission_applications.py index f1f5e0e66..82b0ab025 100644 --- a/apps/perms/api/application/user_permission/user_permission_applications.py +++ b/apps/perms/api/application/user_permission/user_permission_applications.py @@ -1,18 +1,18 @@ # -*- coding: utf-8 -*- # +from typing import Callable + from rest_framework.generics import ListAPIView from rest_framework.response import Response from common.mixins.api import CommonApiMixin from common.tree import TreeNodeSerializer -from applications.api.mixin import ( - SerializeApplicationToTreeNodeMixin -) from perms import serializers -from .mixin import AppRoleAdminMixin, AppRoleUserMixin +from perms.tree.app import GrantedAppTreeUtil from perms.utils.application.user_permission import ( get_user_granted_all_applications ) +from .mixin import AppRoleAdminMixin, AppRoleUserMixin __all__ = [ @@ -23,7 +23,7 @@ __all__ = [ ] -class AllGrantedApplicationsMixin(CommonApiMixin, ListAPIView): +class AllGrantedApplicationsApi(CommonApiMixin, ListAPIView): only_fields = serializers.AppGrantedSerializer.Meta.only_fields serializer_class = serializers.AppGrantedSerializer filterset_fields = { @@ -41,28 +41,34 @@ class AllGrantedApplicationsMixin(CommonApiMixin, ListAPIView): return queryset.only(*self.only_fields) -class UserAllGrantedApplicationsApi(AppRoleAdminMixin, AllGrantedApplicationsMixin): +class UserAllGrantedApplicationsApi(AppRoleAdminMixin, AllGrantedApplicationsApi): pass -class MyAllGrantedApplicationsApi(AppRoleUserMixin, AllGrantedApplicationsMixin): +class MyAllGrantedApplicationsApi(AppRoleUserMixin, AllGrantedApplicationsApi): pass -class ApplicationsAsTreeMixin(SerializeApplicationToTreeNodeMixin): +class ApplicationsAsTreeMixin: """ 将应用序列化成树的结构返回 """ serializer_class = TreeNodeSerializer user: None + filter_queryset: Callable + get_queryset: Callable + get_serializer: Callable def list(self, request, *args, **kwargs): tree_id = request.query_params.get('tree_id', None) parent_info = request.query_params.get('parentInfo', None) queryset = self.filter_queryset(self.get_queryset()) - tree_nodes = self.serialize_applications_with_org( - queryset, tree_id, parent_info, self.user - ) + util = GrantedAppTreeUtil() + + if not tree_id: + tree_nodes = util.create_tree_nodes(queryset) + else: + tree_nodes = util.get_children_nodes(tree_id, parent_info, self.user) serializer = self.get_serializer(tree_nodes, many=True) return Response(data=serializer.data) diff --git a/apps/perms/tree/__init__.py b/apps/perms/tree/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/applications/api/mixin.py b/apps/perms/tree/app.py similarity index 61% rename from apps/applications/api/mixin.py rename to apps/perms/tree/app.py index 35ec0fdb6..e46d05473 100644 --- a/apps/applications/api/mixin.py +++ b/apps/perms/tree/app.py @@ -6,16 +6,12 @@ from rest_framework.generics import get_object_or_404 from common.tree import TreeNode from orgs.models import Organization from assets.models import SystemUser -from applications.utils import KubernetesClient, KubernetesTree +from applications.utils import KubernetesTree +from applications.models import Application from perms.utils.application.permission import get_application_system_user_ids -from ..models import Application - -__all__ = ['SerializeApplicationToTreeNodeMixin'] - - -class SerializeApplicationToTreeNodeMixin: +class GrantedAppTreeUtil: @staticmethod def filter_organizations(applications): organization_ids = set(applications.values_list('org_id', flat=True)) @@ -39,41 +35,15 @@ class SerializeApplicationToTreeNodeMixin: }) return node - def serialize_applications_with_org(self, applications, tree_id, parent_info, user): + @staticmethod + def get_children_nodes(tree_id, parent_info, user): tree_nodes = [] - if not applications: - return tree_nodes - - if not tree_id: - root_node = self.create_root_node() - tree_nodes.append(root_node) - organizations = self.filter_organizations(applications) - - for i, org in enumerate(organizations): - tree_id = urlencode({'org_id': str(org.id)}) - apps = applications.filter(org_id=org.id) - - # 组织节点 - org_node = org.as_tree_node(oid=tree_id, pid=root_node.id) - org_node.name += '({})'.format(apps.count()) - tree_nodes.append(org_node) - - # 类别节点 - category_type_nodes = Application.create_category_type_tree_nodes( - apps, tree_id, show_empty=False - ) - tree_nodes += category_type_nodes - - for app in apps: - app_node = app.as_tree_node(tree_id, k8s_as_tree=True) - tree_nodes.append(app_node) - return tree_nodes - parent_info = dict(parse_qsl(parent_info)) pod_name = parent_info.get('pod') app_id = parent_info.get('app_id') namespace = parent_info.get('namespace') system_user_id = parent_info.get('system_user_id') + if app_id and not any([pod_name, namespace, system_user_id]): app = get_object_or_404(Application, id=app_id) system_user_ids = get_application_system_user_ids(user, app) @@ -84,6 +54,34 @@ class SerializeApplicationToTreeNodeMixin: ) tree_nodes.append(system_user_node) return tree_nodes - tree_nodes = KubernetesTree(tree_id).async_tree_node(parent_info) return tree_nodes + + def create_tree_nodes(self, applications): + tree_nodes = [] + if not applications: + return tree_nodes + + root_node = self.create_root_node() + tree_nodes.append(root_node) + organizations = self.filter_organizations(applications) + + for i, org in enumerate(organizations): + tree_id = urlencode({'org_id': str(org.id)}) + apps = applications.filter(org_id=org.id) + + # 组织节点 + org_node = org.as_tree_node(oid=tree_id, pid=root_node.id) + org_node.name += '({})'.format(apps.count()) + tree_nodes.append(org_node) + + # 类别节点 + category_type_nodes = Application.create_category_type_tree_nodes( + apps, tree_id, show_empty=False + ) + tree_nodes += category_type_nodes + + for app in apps: + app_node = app.as_tree_node(tree_id, k8s_as_tree=True) + tree_nodes.append(app_node) + return tree_nodes diff --git a/apps/settings/api/public.py b/apps/settings/api/public.py index af811cc72..43acffaf0 100644 --- a/apps/settings/api/public.py +++ b/apps/settings/api/public.py @@ -69,6 +69,7 @@ class PublicSettingApi(generics.RetrieveAPIView): "TERMINAL_MAGNUS_ENABLED": settings.TERMINAL_MAGNUS_ENABLED, "TERMINAL_MAGNUS_HOST": settings.TERMINAL_MAGNUS_HOST, "TERMINAL_MAGNUS_MYSQL_PORT": settings.TERMINAL_MAGNUS_MYSQL_PORT, + "TERMINAL_MAGNUS_MARIADB_PORT": settings.TERMINAL_MAGNUS_MARIADB_PORT, "TERMINAL_MAGNUS_POSTGRE_PORT": settings.TERMINAL_MAGNUS_POSTGRE_PORT, # Announcement "ANNOUNCEMENT_ENABLED": settings.ANNOUNCEMENT_ENABLED, diff --git a/apps/settings/serializers/terminal.py b/apps/settings/serializers/terminal.py index b96e5974b..645c9bcfb 100644 --- a/apps/settings/serializers/terminal.py +++ b/apps/settings/serializers/terminal.py @@ -51,6 +51,10 @@ class TerminalSettingSerializer(serializers.Serializer): required=False, label=_("MySQL port"), default=33060, help_text=_('Database proxy MySQL protocol port') ) + TERMINAL_MAGNUS_MARIADB_PORT = serializers.IntegerField( + required=False, label=_("MariaDB port"), default=33061, + help_text=_('Database proxy MySQL protocol port') + ) TERMINAL_MAGNUS_POSTGRE_PORT = serializers.IntegerField( required=False, label=_("PostgreSQL port"), default=54320, help_text=_('Database proxy PostgreSQL port') From 59342a88c0813fd8669dcf2dac70e13f716e9b31 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 29 Mar 2022 18:27:28 +0800 Subject: [PATCH 34/59] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E5=90=84?= =?UTF-8?q?=E7=A7=8D=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 148 ++++++++++++----------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 162 ++++++++++++++------------ apps/settings/serializers/auth/cas.py | 18 ++- apps/settings/serializers/terminal.py | 6 +- 6 files changed, 186 insertions(+), 156 deletions(-) diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index 15d633efa..22c57dcbe 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cc8a3e50aa2a43b3a9ea415e1f8b2e106cc7b4f8e653629958a0e28cc7c5f193 -size 128364 +oid sha256:050a3fd63c1cf9b3dc60c8f138d58f029f2e8a32a71abd99fff6899b68c0f6d9 +size 129742 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index b67d81397..a6c716d25 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-03-29 12:58+0800\n" +"POT-Creation-Date: 2022-03-29 18:26+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -23,7 +23,7 @@ msgid "Acls" msgstr "Acls" #: acls/models/base.py:25 acls/serializers/login_asset_acl.py:47 -#: applications/models/application.py:211 assets/models/asset.py:138 +#: applications/models/application.py:217 assets/models/asset.py:138 #: assets/models/base.py:175 assets/models/cluster.py:18 #: assets/models/cmd_filter.py:27 assets/models/domain.py:23 #: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24 @@ -57,7 +57,7 @@ msgstr "1-100、低い値は最初に一致します" msgid "Active" msgstr "アクティブ" -#: acls/models/base.py:32 applications/models/application.py:224 +#: acls/models/base.py:32 applications/models/application.py:230 #: assets/models/asset.py:143 assets/models/asset.py:231 #: assets/models/backup.py:54 assets/models/base.py:180 #: assets/models/cluster.py:29 assets/models/cmd_filter.py:48 @@ -136,7 +136,7 @@ msgstr "システムユーザー" #: acls/models/login_asset_acl.py:22 #: applications/serializers/attrs/application_category/remote_app.py:36 -#: assets/models/asset.py:355 assets/models/authbook.py:19 +#: assets/models/asset.py:383 assets/models/authbook.py:19 #: assets/models/backup.py:31 assets/models/cmd_filter.py:38 #: assets/models/gathered_user.py:14 assets/serializers/label.py:30 #: assets/serializers/system_user.py:264 audits/models.py:39 @@ -256,11 +256,7 @@ msgstr "" msgid "Time Period" msgstr "期間" -#: applications/api/mixin.py:28 -msgid "My applications" -msgstr "私のアプリケーション" - -#: applications/apps.py:9 applications/models/application.py:62 +#: applications/apps.py:9 applications/models/application.py:63 msgid "Applications" msgstr "アプリケーション" @@ -279,7 +275,7 @@ msgstr "リモートアプリ" msgid "Custom" msgstr "カスタム" -#: applications/models/account.py:12 applications/models/application.py:228 +#: applications/models/account.py:12 applications/models/application.py:234 #: assets/models/backup.py:32 assets/models/cmd_filter.py:45 #: perms/models/application_permission.py:28 msgid "Application" @@ -303,7 +299,7 @@ msgid "System user" msgstr "システムユーザー" #: applications/models/account.py:17 assets/models/authbook.py:21 -#: settings/serializers/auth/cas.py:15 +#: settings/serializers/auth/cas.py:18 msgid "Version" msgstr "バージョン" @@ -319,7 +315,7 @@ msgstr "アプリケーションアカウントの秘密を表示できます" msgid "Can change application account secret" msgstr "アプリケーションアカウントの秘密を変更できます" -#: applications/models/application.py:213 +#: applications/models/application.py:219 #: applications/serializers/application.py:99 assets/models/label.py:21 #: perms/models/application_permission.py:21 #: perms/serializers/application/user_permission.py:33 @@ -328,7 +324,7 @@ msgstr "アプリケーションアカウントの秘密を変更できます" msgid "Category" msgstr "カテゴリ" -#: applications/models/application.py:216 +#: applications/models/application.py:222 #: applications/serializers/application.py:101 assets/models/backup.py:49 #: assets/models/cmd_filter.py:82 assets/models/user.py:246 #: perms/models/application_permission.py:24 @@ -341,21 +337,21 @@ msgstr "カテゴリ" msgid "Type" msgstr "タイプ" -#: applications/models/application.py:220 assets/models/asset.py:217 +#: applications/models/application.py:226 assets/models/asset.py:217 #: assets/models/domain.py:29 assets/models/domain.py:63 msgid "Domain" msgstr "ドメイン" -#: applications/models/application.py:222 xpack/plugins/cloud/models.py:33 +#: applications/models/application.py:228 xpack/plugins/cloud/models.py:33 #: xpack/plugins/cloud/serializers/account.py:58 msgid "Attrs" msgstr "ツールバーの" -#: applications/models/application.py:232 +#: applications/models/application.py:238 msgid "Can match application" msgstr "アプリケーションを一致させることができます" -#: applications/models/application.py:280 +#: applications/models/application.py:286 msgid "Application user" msgstr "アプリケーションユーザー" @@ -643,27 +639,27 @@ msgstr "ラベル" msgid "Created by" msgstr "によって作成された" -#: assets/models/asset.py:358 +#: assets/models/asset.py:386 msgid "Can refresh asset hardware info" msgstr "資産ハードウェア情報を更新できます" -#: assets/models/asset.py:359 +#: assets/models/asset.py:387 msgid "Can test asset connectivity" msgstr "資産接続をテストできます" -#: assets/models/asset.py:360 +#: assets/models/asset.py:388 msgid "Can push system user to asset" msgstr "システムユーザーを資産にプッシュできます" -#: assets/models/asset.py:361 +#: assets/models/asset.py:389 msgid "Can match asset" msgstr "アセットを一致させることができます" -#: assets/models/asset.py:362 +#: assets/models/asset.py:390 msgid "Add asset to node" msgstr "ノードにアセットを追加する" -#: assets/models/asset.py:363 +#: assets/models/asset.py:391 msgid "Move asset to node" msgstr "アセットをノードに移動する" @@ -1591,12 +1587,12 @@ msgid "Auth Token" msgstr "認証トークン" #: audits/signal_handlers.py:71 authentication/notifications.py:73 -#: authentication/views/login.py:164 authentication/views/wecom.py:158 +#: authentication/views/login.py:164 authentication/views/wecom.py:181 #: notifications/backends/__init__.py:11 users/models/user.py:718 msgid "WeCom" msgstr "企業微信" -#: audits/signal_handlers.py:72 authentication/views/dingtalk.py:160 +#: audits/signal_handlers.py:72 authentication/views/dingtalk.py:182 #: authentication/views/login.py:170 notifications/backends/__init__.py:12 #: users/models/user.py:719 msgid "DingTalk" @@ -1812,7 +1808,7 @@ msgstr "署名が無効です。" #: authentication/backends/drf.py:97 msgid "HTTP header: Date not provide or not %a, %d %b %Y %H:%M:%S GMT" -msgstr "" +msgstr "HTTP header: Date not provide or not" #: authentication/backends/drf.py:102 msgid "Expired, more than 15 minutes" @@ -2083,7 +2079,7 @@ msgstr "期限切れ" #: authentication/models.py:53 msgid "SSO token" -msgstr "" +msgstr "SSO token" #: authentication/models.py:61 msgid "Connection token" @@ -2349,40 +2345,40 @@ msgid "" "The system configuration is incorrect. Please contact your administrator" msgstr "システム設定が正しくありません。管理者に連絡してください" -#: authentication/views/dingtalk.py:92 +#: authentication/views/dingtalk.py:78 msgid "DingTalk is already bound" msgstr "DingTalkはすでにバインドされています" -#: authentication/views/dingtalk.py:105 authentication/views/feishu.py:99 -#: authentication/views/wecom.py:104 +#: authentication/views/dingtalk.py:127 authentication/views/feishu.py:99 +#: authentication/views/wecom.py:127 msgid "Please verify your password first" msgstr "最初にパスワードを確認してください" -#: authentication/views/dingtalk.py:129 authentication/views/wecom.py:128 +#: authentication/views/dingtalk.py:151 authentication/views/wecom.py:151 msgid "Invalid user_id" msgstr "無効なuser_id" -#: authentication/views/dingtalk.py:145 +#: authentication/views/dingtalk.py:167 msgid "DingTalk query user failed" msgstr "DingTalkクエリユーザーが失敗しました" -#: authentication/views/dingtalk.py:154 +#: authentication/views/dingtalk.py:176 msgid "The DingTalk is already bound to another user" msgstr "DingTalkはすでに別のユーザーにバインドされています" -#: authentication/views/dingtalk.py:161 +#: authentication/views/dingtalk.py:183 msgid "Binding DingTalk successfully" msgstr "DingTalkのバインドに成功" -#: authentication/views/dingtalk.py:213 +#: authentication/views/dingtalk.py:235 authentication/views/dingtalk.py:289 msgid "Failed to get user from DingTalk" msgstr "DingTalkからユーザーを取得できませんでした" -#: authentication/views/dingtalk.py:219 +#: authentication/views/dingtalk.py:241 authentication/views/dingtalk.py:295 msgid "DingTalk is not bound" msgstr "DingTalkはバインドされていません" -#: authentication/views/dingtalk.py:220 +#: authentication/views/dingtalk.py:242 authentication/views/dingtalk.py:296 msgid "Please login with a password and then bind the DingTalk" msgstr "パスワードでログインし、DingTalkをバインドしてください" @@ -2463,31 +2459,31 @@ msgstr "企業微信エラー、システム管理者に連絡してください msgid "WeCom Error" msgstr "企業微信エラー" -#: authentication/views/wecom.py:91 +#: authentication/views/wecom.py:78 msgid "WeCom is already bound" msgstr "企業の微信はすでにバインドされています" -#: authentication/views/wecom.py:143 +#: authentication/views/wecom.py:166 msgid "WeCom query user failed" msgstr "企業微信ユーザーの問合せに失敗しました" -#: authentication/views/wecom.py:152 +#: authentication/views/wecom.py:175 msgid "The WeCom is already bound to another user" msgstr "この企業の微信はすでに他のユーザーをバインドしている。" -#: authentication/views/wecom.py:159 +#: authentication/views/wecom.py:182 msgid "Binding WeCom successfully" msgstr "企業の微信のバインドに成功" -#: authentication/views/wecom.py:208 +#: authentication/views/wecom.py:231 authentication/views/wecom.py:285 msgid "Failed to get user from WeCom" msgstr "企業の微信からユーザーを取得できませんでした" -#: authentication/views/wecom.py:214 +#: authentication/views/wecom.py:237 authentication/views/wecom.py:291 msgid "WeCom is not bound" msgstr "企業の微信をバインドしていません" -#: authentication/views/wecom.py:215 +#: authentication/views/wecom.py:238 authentication/views/wecom.py:292 msgid "Please login with a password and then bind the WeCom" msgstr "パスワードでログインしてからWeComをバインドしてください" @@ -2503,7 +2499,7 @@ msgstr "%(name)s は正常に更新されました" #: common/db/encoder.py:17 msgid "ugettext_lazy" -msgstr "" +msgstr "ugettext_lazy" #: common/db/models.py:112 msgid "Updated by" @@ -3131,6 +3127,10 @@ msgstr "" msgid "If you have any question, please contact the administrator" msgstr "質問があったら、管理者に連絡して下さい" +#: perms/tree/app.py:24 +msgid "My applications" +msgstr "私のアプリケーション" + #: rbac/api/role.py:32 msgid "Internal role, can't be destroy" msgstr "内部の役割は、破壊することはできません" @@ -3468,35 +3468,35 @@ msgstr "パスワードのURLを忘れた" msgid "Enable login redirect msg" msgstr "ログインリダイレクトの有効化msg" -#: settings/serializers/auth/cas.py:11 +#: settings/serializers/auth/cas.py:10 msgid "Enable CAS Auth" msgstr "CAS 認証の有効化" -#: settings/serializers/auth/cas.py:12 settings/serializers/auth/oidc.py:32 +#: settings/serializers/auth/cas.py:11 settings/serializers/auth/oidc.py:32 msgid "Server url" msgstr "サービス側アドレス" -#: settings/serializers/auth/cas.py:13 +#: settings/serializers/auth/cas.py:14 msgid "Proxy server url" msgstr "コールバックアドレス" -#: settings/serializers/auth/cas.py:14 settings/serializers/auth/saml2.py:32 +#: settings/serializers/auth/cas.py:16 settings/serializers/auth/saml2.py:32 msgid "Logout completely" msgstr "同期ログアウト" -#: settings/serializers/auth/cas.py:16 +#: settings/serializers/auth/cas.py:21 msgid "Username attr" msgstr "ユーザー名のプロパティ" -#: settings/serializers/auth/cas.py:17 +#: settings/serializers/auth/cas.py:24 msgid "Enable attributes map" msgstr "属性マップの有効化" -#: settings/serializers/auth/cas.py:18 settings/serializers/auth/saml2.py:31 +#: settings/serializers/auth/cas.py:26 settings/serializers/auth/saml2.py:31 msgid "Rename attr" msgstr "マッピングのプロパティ" -#: settings/serializers/auth/cas.py:19 +#: settings/serializers/auth/cas.py:27 msgid "Create user if not" msgstr "そうでない場合はユーザーを作成" @@ -4274,17 +4274,15 @@ msgstr "KOKO ホストアドレス" #: settings/serializers/terminal.py:43 msgid "Koko ssh port" -msgstr "KOKO ssh ポート" +msgstr "Koko ssh ポート" #: settings/serializers/terminal.py:45 msgid "Enable database proxy" msgstr "属性マップの有効化" #: settings/serializers/terminal.py:47 -#, fuzzy -#| msgid "DatabaseApp" msgid "Database proxy host" -msgstr "データベースの適用" +msgstr "データベースエージェントホスト" #: settings/serializers/terminal.py:48 msgid "Database proxy host, eg: dev.jumpserver.org" @@ -4292,19 +4290,27 @@ msgstr "RDP訪問先住所、例: dev.jumpserver.org:3389" #: settings/serializers/terminal.py:51 msgid "MySQL port" -msgstr "SMTPポート" +msgstr "MySQLポート" #: settings/serializers/terminal.py:52 -msgid "Database proxy MySQL protocol port" -msgstr "" +msgid "MySQL protocol listen port" +msgstr "MySQLプロトコルリッスンポート" #: settings/serializers/terminal.py:55 -msgid "PostgreSQL port" -msgstr "" +msgid "MariaDB port" +msgstr "MariaDBポート" #: settings/serializers/terminal.py:56 -msgid "Database proxy PostgreSQL port" -msgstr "" +msgid "MariaDB protocol listen port" +msgstr "MariaDBプロトコルリッスンポート" + +#: settings/serializers/terminal.py:59 +msgid "PostgreSQL port" +msgstr "PostgreSQLポート" + +#: settings/serializers/terminal.py:60 +msgid "PostgreSQL protocol listen port" +msgstr "PostgreSQLプロトコルリッスンポート" #: settings/utils/ldap.py:417 msgid "ldap:// or ldaps:// protocol is used." @@ -5726,7 +5732,7 @@ msgstr "ssh公開キー" #: users/forms/profile.py:131 msgid "ssh-rsa AAAA..." -msgstr "" +msgstr "ssh-rsa AAAA.." #: users/forms/profile.py:132 msgid "Paste your id_rsa.pub here." @@ -6296,7 +6302,7 @@ msgstr "パスワードの成功をリセットし、ログインページに戻 #: xpack/apps.py:8 msgid "XPACK" -msgstr "" +msgstr "XPack" #: xpack/plugins/change_auth_plan/api/app.py:112 #: xpack/plugins/change_auth_plan/api/asset.py:95 @@ -6515,11 +6521,11 @@ msgstr "テンセント雲" #: xpack/plugins/cloud/const.py:16 msgid "VMware" -msgstr "" +msgstr "VMware" #: xpack/plugins/cloud/const.py:17 xpack/plugins/cloud/providers/nutanix.py:13 msgid "Nutanix" -msgstr "" +msgstr "Nutanix" #: xpack/plugins/cloud/const.py:18 msgid "Huawei Private Cloud" @@ -6531,7 +6537,7 @@ msgstr "青雲私有雲" #: xpack/plugins/cloud/const.py:20 msgid "OpenStack" -msgstr "" +msgstr "OpenStack" #: xpack/plugins/cloud/const.py:21 msgid "Google Cloud Platform" @@ -6834,11 +6840,11 @@ msgstr "プロバイダ表示" #: xpack/plugins/cloud/serializers/account_attrs.py:13 msgid "AccessKey ID" -msgstr "" +msgstr "アクセスキーID" #: xpack/plugins/cloud/serializers/account_attrs.py:16 msgid "AccessKey Secret" -msgstr "" +msgstr "アクセスキーシークレット" #: xpack/plugins/cloud/serializers/account_attrs.py:31 msgid "Client ID" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 2143cac3a..860a45eaa 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d545e79536feb40608d809a54b8b2140e235373acf331202131882e7af002dfb -size 105242 +oid sha256:1baa8c35aa2493c03c1fe7383a13ca4cfd9b18b44150770fb51f39433c18c74c +size 107492 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index e0e340828..ee4727335 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-03-29 12:58+0800\n" +"POT-Creation-Date: 2022-03-29 18:26+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -22,7 +22,7 @@ msgid "Acls" msgstr "访问控制" #: acls/models/base.py:25 acls/serializers/login_asset_acl.py:47 -#: applications/models/application.py:211 assets/models/asset.py:138 +#: applications/models/application.py:217 assets/models/asset.py:138 #: assets/models/base.py:175 assets/models/cluster.py:18 #: assets/models/cmd_filter.py:27 assets/models/domain.py:23 #: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24 @@ -56,7 +56,7 @@ msgstr "优先级可选范围为 1-100 (数值越小越优先)" msgid "Active" msgstr "激活中" -#: acls/models/base.py:32 applications/models/application.py:224 +#: acls/models/base.py:32 applications/models/application.py:230 #: assets/models/asset.py:143 assets/models/asset.py:231 #: assets/models/backup.py:54 assets/models/base.py:180 #: assets/models/cluster.py:29 assets/models/cmd_filter.py:48 @@ -135,7 +135,7 @@ msgstr "系统用户" #: acls/models/login_asset_acl.py:22 #: applications/serializers/attrs/application_category/remote_app.py:36 -#: assets/models/asset.py:355 assets/models/authbook.py:19 +#: assets/models/asset.py:383 assets/models/authbook.py:19 #: assets/models/backup.py:31 assets/models/cmd_filter.py:38 #: assets/models/gathered_user.py:14 assets/serializers/label.py:30 #: assets/serializers/system_user.py:264 audits/models.py:39 @@ -251,11 +251,7 @@ msgstr "" msgid "Time Period" msgstr "时段" -#: applications/api/mixin.py:28 -msgid "My applications" -msgstr "我的应用" - -#: applications/apps.py:9 applications/models/application.py:62 +#: applications/apps.py:9 applications/models/application.py:63 msgid "Applications" msgstr "应用管理" @@ -274,7 +270,7 @@ msgstr "远程应用" msgid "Custom" msgstr "自定义" -#: applications/models/account.py:12 applications/models/application.py:228 +#: applications/models/account.py:12 applications/models/application.py:234 #: assets/models/backup.py:32 assets/models/cmd_filter.py:45 #: perms/models/application_permission.py:28 msgid "Application" @@ -298,7 +294,7 @@ msgid "System user" msgstr "系统用户" #: applications/models/account.py:17 assets/models/authbook.py:21 -#: settings/serializers/auth/cas.py:15 +#: settings/serializers/auth/cas.py:18 msgid "Version" msgstr "版本" @@ -314,7 +310,7 @@ msgstr "可以查看应用账号密码" msgid "Can change application account secret" msgstr "可以查看应用账号密码" -#: applications/models/application.py:213 +#: applications/models/application.py:219 #: applications/serializers/application.py:99 assets/models/label.py:21 #: perms/models/application_permission.py:21 #: perms/serializers/application/user_permission.py:33 @@ -323,7 +319,7 @@ msgstr "可以查看应用账号密码" msgid "Category" msgstr "类别" -#: applications/models/application.py:216 +#: applications/models/application.py:222 #: applications/serializers/application.py:101 assets/models/backup.py:49 #: assets/models/cmd_filter.py:82 assets/models/user.py:246 #: perms/models/application_permission.py:24 @@ -336,21 +332,21 @@ msgstr "类别" msgid "Type" msgstr "类型" -#: applications/models/application.py:220 assets/models/asset.py:217 +#: applications/models/application.py:226 assets/models/asset.py:217 #: assets/models/domain.py:29 assets/models/domain.py:63 msgid "Domain" msgstr "网域" -#: applications/models/application.py:222 xpack/plugins/cloud/models.py:33 +#: applications/models/application.py:228 xpack/plugins/cloud/models.py:33 #: xpack/plugins/cloud/serializers/account.py:58 msgid "Attrs" msgstr "属性" -#: applications/models/application.py:232 +#: applications/models/application.py:238 msgid "Can match application" msgstr "匹配应用" -#: applications/models/application.py:280 +#: applications/models/application.py:286 msgid "Application user" msgstr "应用用户" @@ -638,27 +634,27 @@ msgstr "标签管理" msgid "Created by" msgstr "创建者" -#: assets/models/asset.py:358 +#: assets/models/asset.py:386 msgid "Can refresh asset hardware info" msgstr "可以更新资产硬件信息" -#: assets/models/asset.py:359 +#: assets/models/asset.py:387 msgid "Can test asset connectivity" msgstr "可以测试资产连接性" -#: assets/models/asset.py:360 +#: assets/models/asset.py:388 msgid "Can push system user to asset" msgstr "可以推送系统用户到资产" -#: assets/models/asset.py:361 +#: assets/models/asset.py:389 msgid "Can match asset" msgstr "可以匹配资产" -#: assets/models/asset.py:362 +#: assets/models/asset.py:390 msgid "Add asset to node" msgstr "添加资产到节点" -#: assets/models/asset.py:363 +#: assets/models/asset.py:391 msgid "Move asset to node" msgstr "移动资产到节点" @@ -1045,7 +1041,7 @@ msgstr "SFTP根路径" #: assets/models/user.py:254 authentication/models.py:48 msgid "Token" -msgstr "" +msgstr "Token" #: assets/models/user.py:255 msgid "Home" @@ -1479,7 +1475,7 @@ msgstr "启用" #: audits/models.py:111 msgid "-" -msgstr "" +msgstr "-" #: audits/models.py:120 msgid "Login type" @@ -1572,19 +1568,19 @@ msgstr "SSH 密钥" #: audits/signal_handlers.py:69 msgid "SSO" -msgstr "" +msgstr "SSO" #: audits/signal_handlers.py:70 msgid "Auth Token" msgstr "认证令牌" #: audits/signal_handlers.py:71 authentication/notifications.py:73 -#: authentication/views/login.py:164 authentication/views/wecom.py:158 +#: authentication/views/login.py:164 authentication/views/wecom.py:181 #: notifications/backends/__init__.py:11 users/models/user.py:718 msgid "WeCom" msgstr "企业微信" -#: audits/signal_handlers.py:72 authentication/views/dingtalk.py:160 +#: audits/signal_handlers.py:72 authentication/views/dingtalk.py:182 #: authentication/views/login.py:170 notifications/backends/__init__.py:12 #: users/models/user.py:719 msgid "DingTalk" @@ -1777,21 +1773,21 @@ msgstr "认证" #: authentication/backends/drf.py:56 msgid "Invalid signature header. No credentials provided." -msgstr "" +msgstr "不合法的签名头" #: authentication/backends/drf.py:59 msgid "Invalid signature header. Signature string should not contain spaces." -msgstr "" +msgstr "不合法的签名头" #: authentication/backends/drf.py:66 msgid "Invalid signature header. Format like AccessKeyId:Signature" -msgstr "" +msgstr "不合法的签名头" #: authentication/backends/drf.py:70 msgid "" "Invalid signature header. Signature string should not contain invalid " "characters." -msgstr "" +msgstr "不合法的签名头" #: authentication/backends/drf.py:90 authentication/backends/drf.py:106 msgid "Invalid signature." @@ -1799,7 +1795,7 @@ msgstr "签名无效" #: authentication/backends/drf.py:97 msgid "HTTP header: Date not provide or not %a, %d %b %Y %H:%M:%S GMT" -msgstr "" +msgstr "HTTP header not valid" #: authentication/backends/drf.py:102 msgid "Expired, more than 15 minutes" @@ -2062,7 +2058,7 @@ msgstr "过期时间" #: authentication/models.py:53 msgid "SSO token" -msgstr "" +msgstr "SSO token" #: authentication/models.py:61 msgid "Connection token" @@ -2319,40 +2315,40 @@ msgid "" "The system configuration is incorrect. Please contact your administrator" msgstr "企业配置错误,请联系系统管理员" -#: authentication/views/dingtalk.py:92 +#: authentication/views/dingtalk.py:78 msgid "DingTalk is already bound" msgstr "钉钉已经绑定" -#: authentication/views/dingtalk.py:105 authentication/views/feishu.py:99 -#: authentication/views/wecom.py:104 +#: authentication/views/dingtalk.py:127 authentication/views/feishu.py:99 +#: authentication/views/wecom.py:127 msgid "Please verify your password first" msgstr "请检查密码" -#: authentication/views/dingtalk.py:129 authentication/views/wecom.py:128 +#: authentication/views/dingtalk.py:151 authentication/views/wecom.py:151 msgid "Invalid user_id" msgstr "无效的 user_id" -#: authentication/views/dingtalk.py:145 +#: authentication/views/dingtalk.py:167 msgid "DingTalk query user failed" msgstr "钉钉查询用户失败" -#: authentication/views/dingtalk.py:154 +#: authentication/views/dingtalk.py:176 msgid "The DingTalk is already bound to another user" msgstr "该钉钉已经绑定其他用户" -#: authentication/views/dingtalk.py:161 +#: authentication/views/dingtalk.py:183 msgid "Binding DingTalk successfully" msgstr "绑定 钉钉 成功" -#: authentication/views/dingtalk.py:213 +#: authentication/views/dingtalk.py:235 authentication/views/dingtalk.py:289 msgid "Failed to get user from DingTalk" msgstr "从钉钉获取用户失败" -#: authentication/views/dingtalk.py:219 +#: authentication/views/dingtalk.py:241 authentication/views/dingtalk.py:295 msgid "DingTalk is not bound" msgstr "钉钉没有绑定" -#: authentication/views/dingtalk.py:220 +#: authentication/views/dingtalk.py:242 authentication/views/dingtalk.py:296 msgid "Please login with a password and then bind the DingTalk" msgstr "请使用密码登录,然后绑定钉钉" @@ -2433,31 +2429,31 @@ msgstr "企业微信错误,请联系系统管理员" msgid "WeCom Error" msgstr "企业微信错误" -#: authentication/views/wecom.py:91 +#: authentication/views/wecom.py:78 msgid "WeCom is already bound" msgstr "企业微信已经绑定" -#: authentication/views/wecom.py:143 +#: authentication/views/wecom.py:166 msgid "WeCom query user failed" msgstr "企业微信查询用户失败" -#: authentication/views/wecom.py:152 +#: authentication/views/wecom.py:175 msgid "The WeCom is already bound to another user" msgstr "该企业微信已经绑定其他用户" -#: authentication/views/wecom.py:159 +#: authentication/views/wecom.py:182 msgid "Binding WeCom successfully" msgstr "绑定 企业微信 成功" -#: authentication/views/wecom.py:208 +#: authentication/views/wecom.py:231 authentication/views/wecom.py:285 msgid "Failed to get user from WeCom" msgstr "从企业微信获取用户失败" -#: authentication/views/wecom.py:214 +#: authentication/views/wecom.py:237 authentication/views/wecom.py:291 msgid "WeCom is not bound" msgstr "没有绑定企业微信" -#: authentication/views/wecom.py:215 +#: authentication/views/wecom.py:238 authentication/views/wecom.py:292 msgid "Please login with a password and then bind the WeCom" msgstr "请使用密码登录,然后绑定企业微信" @@ -2473,7 +2469,7 @@ msgstr "%(name)s 更新成功" #: common/db/encoder.py:17 msgid "ugettext_lazy" -msgstr "" +msgstr "ugettext_lazy" #: common/db/models.py:112 msgid "Updated by" @@ -3094,6 +3090,10 @@ msgstr "" msgid "If you have any question, please contact the administrator" msgstr "如果有疑问或需求,请联系系统管理员" +#: perms/tree/app.py:24 +msgid "My applications" +msgstr "我的应用" + #: rbac/api/role.py:32 msgid "Internal role, can't be destroy" msgstr "内部角色,不能删除" @@ -3430,35 +3430,35 @@ msgstr "忘记密码 URL" msgid "Enable login redirect msg" msgstr "启用登录跳转提示" -#: settings/serializers/auth/cas.py:11 +#: settings/serializers/auth/cas.py:10 msgid "Enable CAS Auth" msgstr "启用 CAS 认证" -#: settings/serializers/auth/cas.py:12 settings/serializers/auth/oidc.py:32 +#: settings/serializers/auth/cas.py:11 settings/serializers/auth/oidc.py:32 msgid "Server url" msgstr "服务端地址" -#: settings/serializers/auth/cas.py:13 +#: settings/serializers/auth/cas.py:14 msgid "Proxy server url" msgstr "回调地址" -#: settings/serializers/auth/cas.py:14 settings/serializers/auth/saml2.py:32 +#: settings/serializers/auth/cas.py:16 settings/serializers/auth/saml2.py:32 msgid "Logout completely" msgstr "同步注销" -#: settings/serializers/auth/cas.py:16 +#: settings/serializers/auth/cas.py:21 msgid "Username attr" msgstr "用户名属性" -#: settings/serializers/auth/cas.py:17 +#: settings/serializers/auth/cas.py:24 msgid "Enable attributes map" msgstr "启用属性映射" -#: settings/serializers/auth/cas.py:18 settings/serializers/auth/saml2.py:31 +#: settings/serializers/auth/cas.py:26 settings/serializers/auth/saml2.py:31 msgid "Rename attr" msgstr "映射属性" -#: settings/serializers/auth/cas.py:19 +#: settings/serializers/auth/cas.py:27 msgid "Create user if not" msgstr "创建用户(如果不存在)" @@ -4231,16 +4231,24 @@ msgid "MySQL port" msgstr "MySQL 协议端口" #: settings/serializers/terminal.py:52 -msgid "Database proxy MySQL protocol port" -msgstr "数据库组件 MySQL 协议监听的端口" +msgid "MySQL protocol listen port" +msgstr "MySQL 协议监听端口" #: settings/serializers/terminal.py:55 +msgid "MariaDB port" +msgstr "MariaDB 端口" + +#: settings/serializers/terminal.py:56 +msgid "MariaDB protocol listen port" +msgstr "MariaDB 协议监听的端口" + +#: settings/serializers/terminal.py:59 msgid "PostgreSQL port" msgstr "PostgreSQL 端口" -#: settings/serializers/terminal.py:56 -msgid "Database proxy PostgreSQL port" -msgstr "数据库组件 PostgreSQL 协议监听的端口" +#: settings/serializers/terminal.py:60 +msgid "PostgreSQL protocol listen port" +msgstr "PostgreSQL 协议监听端口" #: settings/utils/ldap.py:417 msgid "ldap:// or ldaps:// protocol is used." @@ -4981,7 +4989,7 @@ msgstr "参数" #: terminal/models/task.py:18 msgid "Kwargs" -msgstr "" +msgstr "其它参数" #: terminal/models/terminal.py:103 msgid "type" @@ -5647,7 +5655,7 @@ msgstr "SSH公钥" #: users/forms/profile.py:131 msgid "ssh-rsa AAAA..." -msgstr "" +msgstr "ssh-rsa AAAA..." #: users/forms/profile.py:132 msgid "Paste your id_rsa.pub here." @@ -6204,7 +6212,7 @@ msgstr "重置密码成功,返回到登录页面" #: xpack/apps.py:8 msgid "XPACK" -msgstr "" +msgstr "XPack" #: xpack/plugins/change_auth_plan/api/app.py:112 #: xpack/plugins/change_auth_plan/api/asset.py:95 @@ -6423,11 +6431,11 @@ msgstr "腾讯云" #: xpack/plugins/cloud/const.py:16 msgid "VMware" -msgstr "" +msgstr "VMware" #: xpack/plugins/cloud/const.py:17 xpack/plugins/cloud/providers/nutanix.py:13 msgid "Nutanix" -msgstr "" +msgstr "Nutanix" #: xpack/plugins/cloud/const.py:18 msgid "Huawei Private Cloud" @@ -6742,11 +6750,11 @@ msgstr "服务商显示" #: xpack/plugins/cloud/serializers/account_attrs.py:13 msgid "AccessKey ID" -msgstr "" +msgstr "Access key ID" #: xpack/plugins/cloud/serializers/account_attrs.py:16 msgid "AccessKey Secret" -msgstr "" +msgstr "Access key secret" #: xpack/plugins/cloud/serializers/account_attrs.py:31 msgid "Client ID" @@ -6771,7 +6779,7 @@ msgstr "认证地址" #: xpack/plugins/cloud/serializers/account_attrs.py:103 msgid "eg: http://openstack.example.com:5000/v3" -msgstr "" +msgstr "如: http://openstack.example.com:5000/v3" #: xpack/plugins/cloud/serializers/account_attrs.py:106 msgid "User domain" @@ -6898,3 +6906,11 @@ msgstr "旗舰版" #: xpack/plugins/license/models.py:77 msgid "Community edition" msgstr "社区版" + +#~ msgid "Database proxy MySQL protocol listen port" +#~ msgstr "MySQL 协议监听的端口" + +#, fuzzy +#~| msgid "Database proxy PostgreSQL port" +#~ msgid "Database proxy PostgreSQL listen port" +#~ msgstr "数据库组件 PostgreSQL 协议监听的端口" diff --git a/apps/settings/serializers/auth/cas.py b/apps/settings/serializers/auth/cas.py index 7b6bb4373..bb1ab9c76 100644 --- a/apps/settings/serializers/auth/cas.py +++ b/apps/settings/serializers/auth/cas.py @@ -1,4 +1,3 @@ -import json from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers @@ -10,10 +9,19 @@ __all__ = [ class CASSettingSerializer(serializers.Serializer): AUTH_CAS = serializers.BooleanField(required=False, label=_('Enable CAS Auth')) CAS_SERVER_URL = serializers.CharField(required=False, max_length=1024, label=_('Server url')) - CAS_ROOT_PROXIED_AS = serializers.CharField(required=False, allow_null=True, allow_blank=True, max_length=1024, label=_('Proxy server url')) + CAS_ROOT_PROXIED_AS = serializers.CharField( + required=False, allow_null=True, allow_blank=True, + max_length=1024, label=_('Proxy server url') + ) CAS_LOGOUT_COMPLETELY = serializers.BooleanField(required=False, label=_('Logout completely')) - CAS_VERSION = serializers.IntegerField(required=False, label=_('Version'), min_value=1, max_value=3) - CAS_USERNAME_ATTRIBUTE = serializers.CharField(required=False, max_length=1024, label=_('Username attr')) - CAS_APPLY_ATTRIBUTES_TO_USER = serializers.BooleanField(required=False, label=_('Enable attributes map')) + CAS_VERSION = serializers.IntegerField( + required=False, label=_('Version'), min_value=1, max_value=3 + ) + CAS_USERNAME_ATTRIBUTE = serializers.CharField( + required=False, max_length=1024, label=_('Username attr') + ) + CAS_APPLY_ATTRIBUTES_TO_USER = serializers.BooleanField( + required=False, label=_('Enable attributes map') + ) CAS_RENAME_ATTRIBUTES = serializers.DictField(required=False, label=_('Rename attr')) CAS_CREATE_USER = serializers.BooleanField(required=False, label=_('Create user if not')) diff --git a/apps/settings/serializers/terminal.py b/apps/settings/serializers/terminal.py index 645c9bcfb..1ad5d9e75 100644 --- a/apps/settings/serializers/terminal.py +++ b/apps/settings/serializers/terminal.py @@ -49,14 +49,14 @@ class TerminalSettingSerializer(serializers.Serializer): ) TERMINAL_MAGNUS_MYSQL_PORT = serializers.IntegerField( required=False, label=_("MySQL port"), default=33060, - help_text=_('Database proxy MySQL protocol port') + help_text=_('MySQL protocol listen port') ) TERMINAL_MAGNUS_MARIADB_PORT = serializers.IntegerField( required=False, label=_("MariaDB port"), default=33061, - help_text=_('Database proxy MySQL protocol port') + help_text=_('MariaDB protocol listen port') ) TERMINAL_MAGNUS_POSTGRE_PORT = serializers.IntegerField( required=False, label=_("PostgreSQL port"), default=54320, - help_text=_('Database proxy PostgreSQL port') + help_text=_('PostgreSQL protocol listen port') ) From 71f8b40e21170df02d1ab7ea2229af88ca8d1f62 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Mar 2022 21:54:29 +0000 Subject: [PATCH 35/59] build(deps): bump paramiko from 2.7.2 to 2.10.1 in /requirements Bumps [paramiko](https://github.com/paramiko/paramiko) from 2.7.2 to 2.10.1. - [Release notes](https://github.com/paramiko/paramiko/releases) - [Changelog](https://github.com/paramiko/paramiko/blob/main/NEWS) - [Commits](https://github.com/paramiko/paramiko/compare/2.7.2...2.10.1) --- updated-dependencies: - dependency-name: paramiko dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 948774e7a..24aa5cf6a 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -47,7 +47,7 @@ MarkupSafe==1.1.1 mysqlclient==2.0.1 olefile==0.44 openapi-codec==1.3.2 -paramiko==2.7.2 +paramiko==2.10.1 passlib==1.7.1 Pillow==9.0.1 pyasn1==0.4.8 From 54d19965074053d7c056f3417e41c45b4e3c061b Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" Date: Wed, 30 Mar 2022 11:08:50 +0800 Subject: [PATCH 36/59] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E7=BB=AD?= =?UTF-8?q?=E6=9C=9FConnection=20Token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/api/connection_token.py | 66 +++++++++++++++++---- apps/users/models/user.py | 2 +- 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index 7fbe5bac4..f8c64e417 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -30,7 +30,7 @@ from common.http import is_true from perms.models.base import Action from perms.utils.application.permission import get_application_actions from perms.utils.asset.permission import get_asset_actions - +from common.const.http import PATCH from ..serializers import ( ConnectionTokenSerializer, ConnectionTokenSecretSerializer, ) @@ -344,18 +344,55 @@ class SecretDetailMixin: return Response(data=serializer.data, status=200) +class TokenCacheMixin: + CACHE_KEY_PREFIX = 'CONNECTION_TOKEN_{}' + + def get_token_cache_key(self, token): + return self.CACHE_KEY_PREFIX.format(token) + + def get_token_ttl(self, token): + key = self.get_token_cache_key(token) + return cache.ttl(key) + + def set_token_to_cache(self, token, value, ttl=5*60): + key = self.get_token_cache_key(token) + cache.set(key, value, timeout=ttl) + + def get_token_from_cache(self, token): + key = self.get_token_cache_key(token) + value = cache.get(key, None) + return value + + def renewal_token(self, token, ttl=5*60): + value = self.get_token_from_cache(token) + if value: + pre_ttl = self.get_token_ttl(token) + self.set_token_to_cache(token, value, ttl) + post_ttl = self.get_token_ttl(token) + ok = True + msg = f'{pre_ttl}s is renewed to {post_ttl}s.' + else: + ok = False + msg = 'Token is not found.' + data = { + 'ok': ok, + 'msg': msg + } + return data + + class UserConnectionTokenViewSet( RootOrgViewMixin, SerializerMixin, ClientProtocolMixin, - SecretDetailMixin, GenericViewSet + SecretDetailMixin, TokenCacheMixin, GenericViewSet ): serializer_classes = { 'default': ConnectionTokenSerializer, 'get_secret_detail': ConnectionTokenSecretSerializer, } - CACHE_KEY_PREFIX = 'CONNECTION_TOKEN_{}' rbac_perms = { 'GET': 'authentication.view_connectiontoken', 'create': 'authentication.add_connectiontoken', + 'renewal': 'authentication.add_superconnectiontoken', 'get_secret_detail': 'authentication.view_connectiontokensecret', 'get_rdp_file': 'authentication.add_connectiontoken', 'get_client_protocol_url': 'authentication.add_connectiontoken', @@ -376,7 +413,18 @@ class UserConnectionTokenViewSet( raise PermissionDenied(error) return True - def create_token(self, user, asset, application, system_user, ttl=5 * 60): + @action(methods=[PATCH], detail=False) + def renewal(self, request, *args, **kwargs): + """ 续期 Token """ + perm_required = 'authentication.add_superconnectiontoken' + if not request.user.has_perm(perm_required): + raise PermissionDenied('No permissions for authentication.add_superconnectiontoken') + token = request.data.get('token', '') + data = self.renewal_token(token) + status_code = 200 if data.get('ok') else 404 + return Response(data=data, status=status_code) + + def create_token(self, user, asset, application, system_user, ttl=5*60): # 再次强调一下权限 perm_required = 'authentication.add_superconnectiontoken' if user != self.request.user and not self.request.user.has_perm(perm_required): @@ -408,8 +456,7 @@ class UserConnectionTokenViewSet( 'application_name': str(application) }) - key = self.CACHE_KEY_PREFIX.format(token) - cache.set(key, value, timeout=ttl) + self.set_token_to_cache(token, value, ttl) return token, secret def create(self, request, *args, **kwargs): @@ -432,8 +479,7 @@ class UserConnectionTokenViewSet( from perms.utils.asset.permission import validate_permission as asset_validate_permission from perms.utils.application.permission import validate_permission as app_validate_permission - key = self.CACHE_KEY_PREFIX.format(token) - value = cache.get(key, None) + value = self.get_token_from_cache(token) if not value: raise serializers.ValidationError('Token not found') @@ -459,9 +505,7 @@ class UserConnectionTokenViewSet( def get(self, request): token = request.query_params.get('token') - key = self.CACHE_KEY_PREFIX.format(token) - value = cache.get(key, None) - + value = self.get_token_from_cache(token) if not value: return Response('', status=404) return Response(value) diff --git a/apps/users/models/user.py b/apps/users/models/user.py index b98e401fa..3aae3223b 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -366,7 +366,7 @@ class RoleMixin: """ 由于这里用了 cache ,所以不能改成 self.system_roles.filter().exists() 会查询的 """ - if not self._is_superuser: + if self._is_superuser is not None: return self._is_superuser from rbac.builtin import BuiltinRole From e7af0375131ec1beabe049ddf4149d8aad03e36c Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 30 Mar 2022 19:07:49 +0800 Subject: [PATCH 37/59] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=E5=91=BD?= =?UTF-8?q?=E4=BB=A4command=20input=20=E9=95=BF=E5=BA=A6=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20(#7996)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 修改命令command input max_length 1024 * perf: 修改命令command input 长度问题 * perf: 修改命令command input 长度问题 * perf: 修改命令command input 长度问题 * perf: 修改命令command input 长度问题 Co-authored-by: Jiangjie.Bai --- apps/common/utils/common.py | 21 +++++++++ apps/terminal/api/command.py | 2 +- apps/terminal/backends/command/db.py | 5 +- apps/terminal/backends/command/serializers.py | 46 ++++++++++--------- apps/terminal/models/command.py | 29 ++++++++++++ apps/terminal/serializers/__init__.py | 1 - apps/terminal/serializers/command.py | 11 ----- apps/terminal/serializers/terminal.py | 13 +++--- apps/users/models/user.py | 6 ++- apps/users/serializers/user.py | 8 +++- apps/users/utils.py | 16 ++++--- utils/generate_fake_data/generate.py | 2 + .../generate_fake_data/resources/terminal.py | 10 ++++ 13 files changed, 117 insertions(+), 53 deletions(-) delete mode 100644 apps/terminal/serializers/command.py create mode 100644 utils/generate_fake_data/resources/terminal.py diff --git a/apps/common/utils/common.py b/apps/common/utils/common.py index e5b9de4fd..d579eacfb 100644 --- a/apps/common/utils/common.py +++ b/apps/common/utils/common.py @@ -338,3 +338,24 @@ def get_file_by_arch(dir, filename): settings.BASE_DIR, dir, platform_name, arch, filename ) return file_path + + +def pretty_string(data: str, max_length=128, ellipsis_str='...'): + """ + params: + data: abcdefgh + max_length: 7 + ellipsis_str: ... + return: + ab...gh + """ + if len(data) < max_length: + return data + remain_length = max_length - len(ellipsis_str) + half = remain_length // 2 + if half <= 1: + return data[:max_length] + start = data[:half] + end = data[-half:] + data = f'{start}{ellipsis_str}{end}' + return data diff --git a/apps/terminal/api/command.py b/apps/terminal/api/command.py index 09ed27e30..22a2bb5c3 100644 --- a/apps/terminal/api/command.py +++ b/apps/terminal/api/command.py @@ -14,7 +14,7 @@ from terminal.filters import CommandFilter from orgs.utils import current_org from common.drf.api import JMSBulkModelViewSet from common.utils import get_logger -from terminal.serializers import InsecureCommandAlertSerializer +from terminal.backends.command.serializers import InsecureCommandAlertSerializer from terminal.exceptions import StorageInvalid from ..backends import ( get_command_storage, get_multi_command_storage, diff --git a/apps/terminal/backends/command/db.py b/apps/terminal/backends/command/db.py index bb4fa957a..8b11569e9 100644 --- a/apps/terminal/backends/command/db.py +++ b/apps/terminal/backends/command/db.py @@ -4,6 +4,7 @@ import datetime from django.db import transaction from django.utils import timezone from django.db.utils import OperationalError +from common.utils.common import pretty_string from .base import CommandBase @@ -32,9 +33,11 @@ class CommandStore(CommandBase): """ _commands = [] for c in commands: + cmd_input = pretty_string(c['input']) + cmd_output = pretty_string(c['output'], max_length=1024) _commands.append(self.model( user=c["user"], asset=c["asset"], system_user=c["system_user"], - input=c["input"], output=c["output"], session=c["session"], + input=cmd_input, output=cmd_output, session=c["session"], risk_level=c.get("risk_level", 0), org_id=c["org_id"], timestamp=c["timestamp"] )) diff --git a/apps/terminal/backends/command/serializers.py b/apps/terminal/backends/command/serializers.py index 8114ddbb1..625c4282e 100644 --- a/apps/terminal/backends/command/serializers.py +++ b/apps/terminal/backends/command/serializers.py @@ -4,27 +4,19 @@ from rest_framework import serializers from .models import AbstractSessionCommand +__all__ = ['SessionCommandSerializer', 'InsecureCommandAlertSerializer'] -class SessionCommandSerializer(serializers.Serializer): - """使用这个类作为基础Command Log Serializer类, 用来序列化""" - id = serializers.UUIDField(read_only=True) +class SimpleSessionCommandSerializer(serializers.Serializer): + """ 简单Session命令序列类, 用来提取公共字段 """ user = serializers.CharField(label=_("User")) # 限制 64 字符,见 validate_user asset = serializers.CharField(max_length=128, label=_("Asset")) - system_user = serializers.CharField(max_length=64, label=_("System user")) - input = serializers.CharField(max_length=128, label=_("Command")) - output = serializers.CharField(max_length=1024, allow_blank=True, label=_("Output")) + input = serializers.CharField(max_length=2048, label=_("Command")) session = serializers.CharField(max_length=36, label=_("Session ID")) - risk_level = serializers.ChoiceField(required=False, label=_("Risk level"), choices=AbstractSessionCommand.RISK_LEVEL_CHOICES) - risk_level_display = serializers.SerializerMethodField(label=_('Risk level display')) + risk_level = serializers.ChoiceField( + required=False, label=_("Risk level"), choices=AbstractSessionCommand.RISK_LEVEL_CHOICES + ) org_id = serializers.CharField(max_length=36, required=False, default='', allow_null=True, allow_blank=True) - timestamp = serializers.IntegerField(label=_('Timestamp')) - remote_addr = serializers.CharField(read_only=True, label=_('Remote Address')) - - @staticmethod - def get_risk_level_display(obj): - risk_mapper = dict(AbstractSessionCommand.RISK_LEVEL_CHOICES) - return risk_mapper.get(obj.risk_level) def validate_user(self, value): if len(value) > 64: @@ -32,9 +24,21 @@ class SessionCommandSerializer(serializers.Serializer): return value -class InsecureCommandAlertSerializer(serializers.Serializer): - input = serializers.CharField() - asset = serializers.CharField() - user = serializers.CharField() - risk_level = serializers.IntegerField() - session = serializers.UUIDField() +class InsecureCommandAlertSerializer(SimpleSessionCommandSerializer): + pass + + +class SessionCommandSerializer(SimpleSessionCommandSerializer): + """使用这个类作为基础Command Log Serializer类, 用来序列化""" + + id = serializers.UUIDField(read_only=True) + system_user = serializers.CharField(max_length=64, label=_("System user")) + output = serializers.CharField(max_length=2048, allow_blank=True, label=_("Output")) + risk_level_display = serializers.SerializerMethodField(label=_('Risk level display')) + timestamp = serializers.IntegerField(label=_('Timestamp')) + remote_addr = serializers.CharField(read_only=True, label=_('Remote Address')) + + @staticmethod + def get_risk_level_display(obj): + risk_mapper = dict(AbstractSessionCommand.RISK_LEVEL_CHOICES) + return risk_mapper.get(obj.risk_level) diff --git a/apps/terminal/models/command.py b/apps/terminal/models/command.py index 7609902f2..3e94740ff 100644 --- a/apps/terminal/models/command.py +++ b/apps/terminal/models/command.py @@ -1,5 +1,7 @@ from __future__ import unicode_literals +import time + from django.db import models from django.db.models.signals import post_save from django.utils.translation import ugettext_lazy as _ @@ -18,6 +20,33 @@ class CommandManager(models.Manager): class Command(AbstractSessionCommand): objects = CommandManager() + @classmethod + def generate_fake(cls, count=100, org=None): + import uuid + import datetime + from orgs.models import Organization + from common.utils import random_string + + if not org: + org = Organization.default() + + d = datetime.datetime.now() - datetime.timedelta(days=1) + commands = [ + cls(**{ + 'user': random_string(6), + 'asset': random_string(10), + 'system_user': random_string(6), + 'session': str(uuid.uuid4()), + 'input': random_string(16), + 'output': random_string(64), + 'timestamp': int(d.timestamp()), + 'org_id': str(org.id) + }) + for i in range(count) + ] + cls.objects.bulk_create(commands) + print(f'Create {len(commands)} commands of org ({org})') + class Meta: db_table = "terminal_command" ordering = ('-timestamp',) diff --git a/apps/terminal/serializers/__init__.py b/apps/terminal/serializers/__init__.py index a2a5bbf30..4e868cabc 100644 --- a/apps/terminal/serializers/__init__.py +++ b/apps/terminal/serializers/__init__.py @@ -3,5 +3,4 @@ from .terminal import * from .session import * from .storage import * -from .command import * from .sharing import * diff --git a/apps/terminal/serializers/command.py b/apps/terminal/serializers/command.py deleted file mode 100644 index 01343e825..000000000 --- a/apps/terminal/serializers/command.py +++ /dev/null @@ -1,11 +0,0 @@ -# ~*~ coding: utf-8 ~*~ -from rest_framework import serializers - - -class InsecureCommandAlertSerializer(serializers.Serializer): - input = serializers.CharField() - asset = serializers.CharField() - user = serializers.CharField() - risk_level = serializers.IntegerField() - session = serializers.UUIDField() - org_id = serializers.CharField() diff --git a/apps/terminal/serializers/terminal.py b/apps/terminal/serializers/terminal.py index be991d8a8..dd6565348 100644 --- a/apps/terminal/serializers/terminal.py +++ b/apps/terminal/serializers/terminal.py @@ -4,7 +4,7 @@ from django.utils.translation import ugettext_lazy as _ from common.drf.serializers import BulkModelSerializer, AdaptedBulkListSerializer from common.utils import is_uuid from users.serializers import ServiceAccountSerializer -from common.utils import get_request_ip +from common.utils import get_request_ip, pretty_string from .. import const from ..models import ( @@ -111,12 +111,11 @@ class TerminalRegistrationSerializer(serializers.ModelSerializer): valid = super().is_valid(raise_exception=raise_exception) if not valid: return valid - name = self.validated_data.get('name') - if len(name) > 128: - self.validated_data['comment'] = name - name = '{}...{}'.format(name[:32], name[-32:]) - self.validated_data['name'] = name - + raw_name = self.validated_data.get('name') + name = pretty_string(raw_name) + self.validated_data['name'] = name + if len(raw_name) > 128: + self.validated_data['comment'] = raw_name data = {'name': name} kwargs = {'data': data} if self.instance and self.instance.user: diff --git a/apps/users/models/user.py b/apps/users/models/user.py index 3aae3223b..1a5ce634c 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -401,10 +401,12 @@ class RoleMixin: def is_staff(self, value): pass + service_account_email_suffix = '@local.domain' + @classmethod - def create_service_account(cls, name, comment): + def create_service_account(cls, name, email, comment): app = cls.objects.create( - username=name, name=name, email='{}@local.domain'.format(name), + username=name, name=name, email=email, comment=comment, is_first_login=False, created_by='System', is_service_account=True, ) diff --git a/apps/users/serializers/user.py b/apps/users/serializers/user.py index b998e8f6d..56409addf 100644 --- a/apps/users/serializers/user.py +++ b/apps/users/serializers/user.py @@ -6,6 +6,7 @@ from rest_framework import serializers from common.mixins import CommonBulkSerializerMixin from common.validators import PhoneValidator +from common.utils import pretty_string from rbac.builtin import BuiltinRole from rbac.permissions import RBACPermission from rbac.models import OrgRoleBinding, SystemRoleBinding, Role @@ -268,7 +269,9 @@ class ServiceAccountSerializer(serializers.ModelSerializer): def get_email(self): name = self.initial_data.get('name') - return '{}@serviceaccount.local'.format(name) + name_max_length = 128 - len(User.service_account_email_suffix) + name = pretty_string(name, max_length=name_max_length, ellipsis_str='-') + return '{}{}'.format(name, User.service_account_email_suffix) def validate_name(self, name): email = self.get_email() @@ -283,6 +286,7 @@ class ServiceAccountSerializer(serializers.ModelSerializer): def create(self, validated_data): name = validated_data['name'] + email = self.get_email() comment = validated_data.get('comment', '') - user, ak = User.create_service_account(name, comment) + user, ak = User.create_service_account(name, email, comment) return user diff --git a/apps/users/utils.py b/apps/users/utils.py index 3602d67ee..b32b0c0e0 100644 --- a/apps/users/utils.py +++ b/apps/users/utils.py @@ -11,7 +11,7 @@ from django.conf import settings from django.core.cache import cache from common.tasks import send_mail_async -from common.utils import reverse, get_object_or_none, ip +from common.utils import reverse, get_object_or_none, ip, pretty_string from .models import User logger = logging.getLogger('jumpserver') @@ -229,12 +229,14 @@ class LoginIpBlockUtil(BlockGlobalIpUtilBase): BLOCK_KEY_TMPL = "_LOGIN_BLOCK_{}" -def construct_user_email(username, email): - if '@' not in email: - if '@' in username: - email = username - else: - email = '{}@{}'.format(username, settings.EMAIL_SUFFIX) +def construct_user_email(username, email, email_suffix=''): + if '@' in email: + return email + if '@' in username: + return username + if not email_suffix: + email_suffix = settings.EMAIL_SUFFIX + email = f'{username}@{email_suffix}' return email diff --git a/utils/generate_fake_data/generate.py b/utils/generate_fake_data/generate.py index 839295049..fb41d7e1d 100644 --- a/utils/generate_fake_data/generate.py +++ b/utils/generate_fake_data/generate.py @@ -15,6 +15,7 @@ django.setup() from resources.assets import AssetsGenerator, NodesGenerator, SystemUsersGenerator, AdminUsersGenerator from resources.users import UserGroupGenerator, UserGenerator from resources.perms import AssetPermissionGenerator +from resources.terminal import CommandGenerator # from resources.system import StatGenerator @@ -26,6 +27,7 @@ resource_generator_mapper = { 'user': UserGenerator, 'user_group': UserGroupGenerator, 'asset_permission': AssetPermissionGenerator, + 'command': CommandGenerator, # 'stat': StatGenerator } diff --git a/utils/generate_fake_data/resources/terminal.py b/utils/generate_fake_data/resources/terminal.py new file mode 100644 index 000000000..48d825b47 --- /dev/null +++ b/utils/generate_fake_data/resources/terminal.py @@ -0,0 +1,10 @@ +from .base import FakeDataGenerator +from terminal.models import Command + + +class CommandGenerator(FakeDataGenerator): + resource = 'command' + + def do_generate(self, batch, batch_size): + Command.generate_fake(len(batch), self.org) + From c58d2456363371d6fd05852a0e3de7bf522a6512 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 30 Mar 2022 19:51:56 +0800 Subject: [PATCH 38/59] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dkoko=20setting?= =?UTF-8?q?=20(#8005)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng626 <1304903146@qq.com> --- apps/settings/serializers/terminal.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/settings/serializers/terminal.py b/apps/settings/serializers/terminal.py index 1ad5d9e75..c6073aa28 100644 --- a/apps/settings/serializers/terminal.py +++ b/apps/settings/serializers/terminal.py @@ -39,8 +39,12 @@ class TerminalSettingSerializer(serializers.Serializer): ) XRDP_ENABLED = serializers.BooleanField(label=_("Enable XRDP")) - TERMINAL_KOKO_HOST = serializers.BooleanField(label=_("Koko host")) - TERMINAL_KOKO_SSH_PORT = serializers.BooleanField(label=_("Koko ssh port")) + TERMINAL_KOKO_HOST = serializers.CharField( + required=False, label=_("Koko host"), max_length=1024 + ) + TERMINAL_KOKO_SSH_PORT = serializers.CharField( + required=False, label=_("Koko ssh port"), max_length=1024 + ) TERMINAL_MAGNUS_ENABLED = serializers.BooleanField(label=_("Enable database proxy")) TERMINAL_MAGNUS_HOST = serializers.CharField( @@ -59,4 +63,3 @@ class TerminalSettingSerializer(serializers.Serializer): required=False, label=_("PostgreSQL port"), default=54320, help_text=_('PostgreSQL protocol listen port') ) - From 73cb5e10b414403b91b1acb3b34e7999153ccc65 Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" Date: Wed, 30 Mar 2022 19:30:27 +0800 Subject: [PATCH 39/59] =?UTF-8?q?fix:=20=E6=B7=BB=E5=8A=A0=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=B8=8D=E8=83=BD=E8=87=AA=E6=9B=B4=E6=96=B0=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E9=80=BB=E8=BE=91=20&=20=E4=BF=AE=E5=A4=8D=E7=94=A8?= =?UTF-8?q?=E6=88=B7is=5Factive=E5=88=9B=E5=BB=BA=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: 添加用户不能自更新字段逻辑 & 修复用户is_active创建失败的问题 fix: 添加用户不能自更新字段逻辑 & 修复用户is_active创建失败的问题 --- apps/users/serializers/user.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/apps/users/serializers/user.py b/apps/users/serializers/user.py index 56409addf..3014aa2d9 100644 --- a/apps/users/serializers/user.py +++ b/apps/users/serializers/user.py @@ -133,6 +133,7 @@ class UserSerializer(RolesSerializerMixin, CommonBulkSerializerMixin, serializer 'date_joined', 'last_login', 'created_by', 'is_first_login', 'wecom_id', 'dingtalk_id', 'feishu_id' ] + disallow_self_update_fields = ['is_active'] extra_kwargs = { 'password': {'write_only': True, 'required': False, 'allow_null': True, 'allow_blank': True}, 'public_key': {'write_only': True}, @@ -181,7 +182,23 @@ class UserSerializer(RolesSerializerMixin, CommonBulkSerializerMixin, serializer attrs.pop(field, None) return attrs + def check_disallow_self_update_fields(self, attrs): + request = self.context.get('request') + if not request or not request.user.is_authenticated: + return attrs + if not self.instance: + return attrs + if request.user.id != self.instance.id: + return attrs + disallow_fields = set(list(attrs.keys())) & set(self.Meta.disallow_self_update_fields) + if not disallow_fields: + return attrs + # 用户自己不能更新自己的一些字段 + error = 'User Cannot self-update fields: {}'.format(disallow_fields) + raise serializers.ValidationError(error) + def validate(self, attrs): + attrs = self.check_disallow_self_update_fields(attrs) attrs = self.change_password_to_raw(attrs) attrs = self.clean_auth_fields(attrs) attrs.pop('password_strategy', None) @@ -206,17 +223,6 @@ class UserSerializer(RolesSerializerMixin, CommonBulkSerializerMixin, serializer field.set(value) return instance - def validate_is_active(self, is_active): - request = self.context.get('request') - if not request or not request.user.is_authenticated: - return is_active - - user = request.user - if user.id == self.instance.id and not is_active: - # 用户自己不能禁用启用自己 - raise serializers.ValidationError("Cannot inactive self") - return is_active - def update(self, instance, validated_data): save_handler = partial(super().update, instance) instance = self.save_and_set_custom_m2m_fields(validated_data, save_handler, created=False) From eff562505e2480f4a8d7b8252e866a1ff705c477 Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" Date: Thu, 31 Mar 2022 11:22:48 +0800 Subject: [PATCH 40/59] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E7=BF=BB?= =?UTF-8?q?=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/ja/LC_MESSAGES/django.po | 170 ++++++++++++++------------- apps/locale/zh/LC_MESSAGES/django.po | 170 ++++++++++++++------------- apps/users/serializers/user.py | 2 +- 3 files changed, 175 insertions(+), 167 deletions(-) diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index a6c716d25..bc5707e14 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-03-29 18:26+0800\n" +"POT-Creation-Date: 2022-03-31 11:21+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -31,7 +31,7 @@ msgstr "Acls" #: settings/models.py:29 settings/serializers/sms.py:6 #: terminal/models/storage.py:23 terminal/models/task.py:16 #: terminal/models/terminal.py:100 users/forms/profile.py:32 -#: users/models/group.py:15 users/models/user.py:659 +#: users/models/group.py:15 users/models/user.py:661 #: users/templates/users/_select_user_modal.html:13 #: users/templates/users/user_asset_permission.html:37 #: users/templates/users/user_asset_permission.html:154 @@ -67,7 +67,7 @@ msgstr "アクティブ" #: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34 #: terminal/models/storage.py:26 terminal/models/terminal.py:114 #: tickets/models/comment.py:24 tickets/models/ticket.py:154 -#: users/models/group.py:16 users/models/user.py:696 +#: users/models/group.py:16 users/models/user.py:698 #: 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 @@ -95,8 +95,8 @@ msgstr "ログイン確認" #: terminal/backends/command/models.py:19 #: terminal/backends/command/serializers.py:12 terminal/models/session.py:42 #: terminal/notifications.py:91 terminal/notifications.py:139 -#: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:884 -#: users/models/user.py:915 users/serializers/group.py:19 +#: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:886 +#: users/models/user.py:917 users/serializers/group.py:19 #: users/templates/users/user_asset_permission.html:38 #: users/templates/users/user_asset_permission.html:64 #: users/templates/users/user_database_app_permission.html:37 @@ -170,7 +170,7 @@ msgstr "コンマ区切り文字列の形式。* はすべて一致すること #: authentication/forms.py:15 authentication/forms.py:17 #: 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:31 users/models/user.py:657 +#: ops/models/adhoc.py:159 users/forms/profile.py:31 users/models/user.py:659 #: users/templates/users/_msg_user_created.html:12 #: users/templates/users/_select_user_modal.html:14 #: xpack/plugins/change_auth_plan/models/asset.py:34 @@ -285,7 +285,7 @@ msgstr "アプリケーション" #: assets/models/cmd_filter.py:42 assets/models/user.py:338 audits/models.py:40 #: perms/models/application_permission.py:33 #: perms/models/asset_permission.py:25 terminal/backends/command/models.py:21 -#: terminal/backends/command/serializers.py:14 terminal/models/session.py:46 +#: terminal/backends/command/serializers.py:35 terminal/models/session.py:46 #: users/templates/users/_granted_assets.html:27 #: users/templates/users/user_asset_permission.html:42 #: users/templates/users/user_asset_permission.html:76 @@ -380,7 +380,7 @@ msgstr "タイプ表示" #: assets/serializers/cmd_filter.py:49 common/db/models.py:113 #: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30 #: orgs/models.py:67 orgs/models.py:217 perms/models/base.py:92 -#: users/models/group.py:18 users/models/user.py:916 +#: users/models/group.py:18 users/models/user.py:918 #: xpack/plugins/cloud/models.py:125 msgid "Date created" msgstr "作成された日付" @@ -632,7 +632,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:111 common/mixins/models.py:49 orgs/models.py:66 -#: orgs/models.py:219 perms/models/base.py:91 users/models/user.py:704 +#: orgs/models.py:219 perms/models/base.py:91 users/models/user.py:706 #: users/serializers/group.py:33 #: xpack/plugins/change_auth_plan/models/base.py:48 #: xpack/plugins/cloud/models.py:122 xpack/plugins/gathered_user/models.py:30 @@ -813,7 +813,7 @@ msgstr "帯域幅" msgid "Contact" msgstr "連絡先" -#: assets/models/cluster.py:22 users/models/user.py:679 +#: assets/models/cluster.py:22 users/models/user.py:681 msgid "Phone" msgstr "電話" @@ -839,7 +839,7 @@ msgid "Default" msgstr "デフォルト" #: assets/models/cluster.py:36 assets/models/label.py:14 rbac/const.py:6 -#: users/models/user.py:901 +#: users/models/user.py:903 msgid "System" msgstr "システム" @@ -848,7 +848,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:665 +#: users/models/group.py:31 users/models/user.py:667 #: users/templates/users/_select_user_modal.html:16 #: users/templates/users/user_asset_permission.html:39 #: users/templates/users/user_asset_permission.html:67 @@ -866,7 +866,7 @@ msgid "Regex" msgstr "正規情報" #: assets/models/cmd_filter.py:68 ops/models/command.py:26 -#: terminal/backends/command/serializers.py:15 terminal/models/session.py:53 +#: terminal/backends/command/serializers.py:14 terminal/models/session.py:53 #: terminal/templates/terminal/_msg_command_alert.html:12 #: terminal/templates/terminal/_msg_command_execute_alert.html:10 msgid "Command" @@ -1510,7 +1510,7 @@ msgstr "ユーザーエージェント" #: audits/models.py:124 #: authentication/templates/authentication/_mfa_confirm_modal.html:14 -#: users/forms/profile.py:64 users/models/user.py:682 +#: users/forms/profile.py:64 users/models/user.py:684 #: users/serializers/profile.py:121 msgid "MFA" msgstr "MFA" @@ -1588,13 +1588,13 @@ msgstr "認証トークン" #: audits/signal_handlers.py:71 authentication/notifications.py:73 #: authentication/views/login.py:164 authentication/views/wecom.py:181 -#: notifications/backends/__init__.py:11 users/models/user.py:718 +#: notifications/backends/__init__.py:11 users/models/user.py:720 msgid "WeCom" msgstr "企業微信" #: audits/signal_handlers.py:72 authentication/views/dingtalk.py:182 #: authentication/views/login.py:170 notifications/backends/__init__.py:12 -#: users/models/user.py:719 +#: users/models/user.py:721 msgid "DingTalk" msgstr "DingTalk" @@ -2134,14 +2134,14 @@ msgid "Show" msgstr "表示" #: authentication/templates/authentication/_access_key_modal.html:66 -#: settings/serializers/security.py:39 users/models/user.py:554 +#: settings/serializers/security.py:39 users/models/user.py:556 #: users/serializers/profile.py:111 users/templates/users/mfa_setting.html:61 #: users/templates/users/user_verify_mfa.html:36 msgid "Disable" msgstr "無効化" #: authentication/templates/authentication/_access_key_modal.html:67 -#: users/models/user.py:555 users/serializers/profile.py:112 +#: users/models/user.py:557 users/serializers/profile.py:112 #: users/templates/users/mfa_setting.html:26 #: users/templates/users/mfa_setting.html:68 msgid "Enable" @@ -2399,7 +2399,7 @@ msgid "The FeiShu is already bound to another user" msgstr "FeiShuはすでに別のユーザーにバインドされています" #: authentication/views/feishu.py:148 authentication/views/login.py:176 -#: notifications/backends/__init__.py:14 users/models/user.py:720 +#: notifications/backends/__init__.py:14 users/models/user.py:722 msgid "FeiShu" msgstr "本を飛ばす" @@ -2699,7 +2699,7 @@ msgid "Notifications" msgstr "通知" #: notifications/backends/__init__.py:10 users/forms/profile.py:101 -#: users/models/user.py:661 +#: users/models/user.py:663 msgid "Email" msgstr "メール" @@ -2925,7 +2925,7 @@ msgid "Can view root org" msgstr "グローバル組織を表示できます" #: orgs/models.py:216 rbac/models/role.py:46 rbac/models/rolebinding.py:43 -#: users/models/user.py:669 users/templates/users/_select_user_modal.html:15 +#: users/models/user.py:671 users/templates/users/_select_user_modal.html:15 msgid "Role" msgstr "ロール" @@ -3012,7 +3012,7 @@ msgstr "クリップボードコピーペースト" #: perms/models/base.py:90 #: tickets/serializers/ticket/meta/ticket_type/apply_application.py:58 #: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:60 -#: users/models/user.py:701 +#: users/models/user.py:703 msgid "Date expired" msgstr "期限切れの日付" @@ -3055,15 +3055,15 @@ msgstr "Organization {} のアプリケーション権限" #: perms/serializers/application/permission.py:20 #: perms/serializers/application/permission.py:41 #: perms/serializers/asset/permission.py:19 -#: perms/serializers/asset/permission.py:45 users/serializers/user.py:139 +#: perms/serializers/asset/permission.py:45 users/serializers/user.py:141 msgid "Is valid" msgstr "有効です" #: perms/serializers/application/permission.py:21 #: perms/serializers/application/permission.py:40 #: perms/serializers/asset/permission.py:20 -#: perms/serializers/asset/permission.py:44 users/serializers/user.py:85 -#: users/serializers/user.py:141 +#: perms/serializers/asset/permission.py:44 users/serializers/user.py:86 +#: users/serializers/user.py:143 msgid "Is expired" msgstr "期限切れです" @@ -4268,47 +4268,47 @@ msgstr "RDP訪問先住所、例: dev.jumpserver.org:3389" msgid "Enable XRDP" msgstr "XRDPの有効化" -#: settings/serializers/terminal.py:42 +#: settings/serializers/terminal.py:43 msgid "Koko host" msgstr "KOKO ホストアドレス" -#: settings/serializers/terminal.py:43 +#: settings/serializers/terminal.py:46 msgid "Koko ssh port" msgstr "Koko ssh ポート" -#: settings/serializers/terminal.py:45 +#: settings/serializers/terminal.py:49 msgid "Enable database proxy" msgstr "属性マップの有効化" -#: settings/serializers/terminal.py:47 +#: settings/serializers/terminal.py:51 msgid "Database proxy host" msgstr "データベースエージェントホスト" -#: settings/serializers/terminal.py:48 +#: settings/serializers/terminal.py:52 msgid "Database proxy host, eg: dev.jumpserver.org" msgstr "RDP訪問先住所、例: dev.jumpserver.org:3389" -#: settings/serializers/terminal.py:51 +#: settings/serializers/terminal.py:55 msgid "MySQL port" msgstr "MySQLポート" -#: settings/serializers/terminal.py:52 +#: settings/serializers/terminal.py:56 msgid "MySQL protocol listen port" msgstr "MySQLプロトコルリッスンポート" -#: settings/serializers/terminal.py:55 +#: settings/serializers/terminal.py:59 msgid "MariaDB port" msgstr "MariaDBポート" -#: settings/serializers/terminal.py:56 +#: settings/serializers/terminal.py:60 msgid "MariaDB protocol listen port" msgstr "MariaDBプロトコルリッスンポート" -#: settings/serializers/terminal.py:59 +#: settings/serializers/terminal.py:63 msgid "PostgreSQL port" msgstr "PostgreSQLポート" -#: settings/serializers/terminal.py:60 +#: settings/serializers/terminal.py:64 msgid "PostgreSQL protocol listen port" msgstr "PostgreSQLプロトコルリッスンポート" @@ -4859,7 +4859,7 @@ msgid "Input" msgstr "入力" #: terminal/backends/command/models.py:23 -#: terminal/backends/command/serializers.py:16 +#: terminal/backends/command/serializers.py:36 msgid "Output" msgstr "出力" @@ -4870,23 +4870,23 @@ msgid "Session" msgstr "セッション" #: terminal/backends/command/models.py:25 -#: terminal/backends/command/serializers.py:18 +#: terminal/backends/command/serializers.py:17 msgid "Risk level" msgstr "リスクレベル" -#: terminal/backends/command/serializers.py:17 +#: terminal/backends/command/serializers.py:15 msgid "Session ID" msgstr "セッションID" -#: terminal/backends/command/serializers.py:19 +#: terminal/backends/command/serializers.py:37 msgid "Risk level display" msgstr "リスクレベル表示" -#: terminal/backends/command/serializers.py:21 +#: terminal/backends/command/serializers.py:38 msgid "Timestamp" msgstr "タイムスタンプ" -#: terminal/backends/command/serializers.py:22 terminal/models/terminal.py:105 +#: terminal/backends/command/serializers.py:39 terminal/models/terminal.py:105 msgid "Remote Address" msgstr "リモートアドレス" @@ -4915,7 +4915,7 @@ msgstr "一括作成非サポート" msgid "Storage is invalid" msgstr "ストレージが無効です" -#: terminal/models/command.py:24 +#: terminal/models/command.py:53 msgid "Command record" msgstr "コマンドレコード" @@ -5140,7 +5140,7 @@ msgstr "エンドポイントが無効: パス '{}' を削除" msgid "Bucket" msgstr "バケット" -#: terminal/serializers/storage.py:34 users/models/user.py:693 +#: terminal/serializers/storage.py:34 users/models/user.py:695 msgid "Secret key" msgstr "秘密キー" @@ -5747,68 +5747,68 @@ msgstr "公開鍵は古いものと同じであってはなりません。" msgid "Not a valid ssh public key" msgstr "有効なssh公開鍵ではありません" -#: users/forms/profile.py:160 users/models/user.py:690 +#: users/forms/profile.py:160 users/models/user.py:692 #: users/templates/users/user_password_update.html:48 msgid "Public key" msgstr "公開キー" -#: users/models/user.py:556 +#: users/models/user.py:558 msgid "Force enable" msgstr "強制有効" -#: users/models/user.py:623 +#: users/models/user.py:625 msgid "Local" msgstr "ローカル" -#: users/models/user.py:671 users/serializers/user.py:140 +#: users/models/user.py:673 users/serializers/user.py:142 msgid "Is service account" msgstr "サービスアカウントです" -#: users/models/user.py:673 +#: users/models/user.py:675 msgid "Avatar" msgstr "アバター" -#: users/models/user.py:676 +#: users/models/user.py:678 msgid "Wechat" msgstr "微信" -#: users/models/user.py:687 +#: users/models/user.py:689 msgid "Private key" msgstr "ssh秘密鍵" -#: users/models/user.py:709 +#: users/models/user.py:711 msgid "Source" msgstr "ソース" -#: users/models/user.py:713 +#: users/models/user.py:715 msgid "Date password last updated" msgstr "最終更新日パスワード" -#: users/models/user.py:716 +#: users/models/user.py:718 msgid "Need update password" msgstr "更新パスワードが必要" -#: users/models/user.py:886 +#: users/models/user.py:888 msgid "Can invite user" msgstr "ユーザーを招待できます" -#: users/models/user.py:887 +#: users/models/user.py:889 msgid "Can remove user" msgstr "ユーザーを削除できます" -#: users/models/user.py:888 +#: users/models/user.py:890 msgid "Can match user" msgstr "ユーザーに一致できます" -#: users/models/user.py:897 +#: users/models/user.py:899 msgid "Administrator" msgstr "管理者" -#: users/models/user.py:900 +#: users/models/user.py:902 msgid "Administrator is the super user of system" msgstr "管理者はシステムのスーパーユーザーです" -#: users/models/user.py:925 +#: users/models/user.py:927 msgid "User password history" msgstr "ユーザーパスワード履歴" @@ -5859,97 +5859,101 @@ msgstr "新しいパスワードを最後の {} 個のパスワードにする msgid "The newly set password is inconsistent" msgstr "新しく設定されたパスワードが一致しない" -#: users/serializers/profile.py:142 users/serializers/user.py:138 +#: users/serializers/profile.py:142 users/serializers/user.py:140 msgid "Is first login" msgstr "最初のログインです" -#: users/serializers/user.py:24 users/serializers/user.py:31 +#: users/serializers/user.py:25 users/serializers/user.py:32 msgid "System roles" msgstr "システムの役割" -#: users/serializers/user.py:29 users/serializers/user.py:32 +#: users/serializers/user.py:30 users/serializers/user.py:33 msgid "Org roles" msgstr "組織ロール" -#: users/serializers/user.py:77 +#: users/serializers/user.py:78 #: xpack/plugins/change_auth_plan/models/base.py:35 #: xpack/plugins/change_auth_plan/serializers/base.py:22 msgid "Password strategy" msgstr "パスワード戦略" -#: users/serializers/user.py:79 +#: users/serializers/user.py:80 msgid "MFA enabled" msgstr "MFA有効化" -#: users/serializers/user.py:80 +#: users/serializers/user.py:81 msgid "MFA force enabled" msgstr "MFAフォース有効化" -#: users/serializers/user.py:82 +#: users/serializers/user.py:83 msgid "MFA level display" msgstr "MFAレベル表示" -#: users/serializers/user.py:84 +#: users/serializers/user.py:85 msgid "Login blocked" msgstr "ログインブロック" -#: users/serializers/user.py:87 +#: users/serializers/user.py:88 msgid "Can public key authentication" msgstr "公開鍵認証が可能" -#: users/serializers/user.py:142 +#: users/serializers/user.py:144 msgid "Avatar url" msgstr "アバターURL" -#: users/serializers/user.py:144 +#: users/serializers/user.py:146 msgid "Groups name" msgstr "グループ名" -#: users/serializers/user.py:145 +#: users/serializers/user.py:147 msgid "Source name" msgstr "ソース名" -#: users/serializers/user.py:146 +#: users/serializers/user.py:148 msgid "Organization role name" msgstr "組織の役割名" -#: users/serializers/user.py:147 +#: users/serializers/user.py:149 msgid "Super role name" msgstr "スーパーロール名" -#: users/serializers/user.py:148 +#: users/serializers/user.py:150 msgid "Total role name" msgstr "合計ロール名" -#: users/serializers/user.py:150 +#: users/serializers/user.py:152 msgid "Is wecom bound" msgstr "企業の微信をバインドしているかどうか" -#: users/serializers/user.py:151 +#: users/serializers/user.py:153 msgid "Is dingtalk bound" msgstr "ピンをバインドしているかどうか" -#: users/serializers/user.py:152 +#: users/serializers/user.py:154 msgid "Is feishu bound" msgstr "飛本を縛ったかどうか" -#: users/serializers/user.py:153 +#: users/serializers/user.py:155 msgid "Is OTP bound" msgstr "仮想MFAがバインドされているか" -#: users/serializers/user.py:155 +#: users/serializers/user.py:157 msgid "System role name" msgstr "システムロール名" -#: users/serializers/user.py:247 +#: users/serializers/user.py:197 +msgid "User cannot self-update fields: {}" +msgstr "ユーザーは自分のフィールドを更新できません: {}" + +#: users/serializers/user.py:254 msgid "Select users" msgstr "ユーザーの選択" -#: users/serializers/user.py:248 +#: users/serializers/user.py:255 msgid "For security, only list several users" msgstr "セキュリティのために、複数のユーザーのみをリストします" -#: users/serializers/user.py:281 +#: users/serializers/user.py:290 msgid "name not unique" msgstr "名前が一意ではない" diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index ee4727335..ffd8d4ba3 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-03-29 18:26+0800\n" +"POT-Creation-Date: 2022-03-31 11:19+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -30,7 +30,7 @@ msgstr "访问控制" #: settings/models.py:29 settings/serializers/sms.py:6 #: terminal/models/storage.py:23 terminal/models/task.py:16 #: terminal/models/terminal.py:100 users/forms/profile.py:32 -#: users/models/group.py:15 users/models/user.py:659 +#: users/models/group.py:15 users/models/user.py:661 #: users/templates/users/_select_user_modal.html:13 #: users/templates/users/user_asset_permission.html:37 #: users/templates/users/user_asset_permission.html:154 @@ -66,7 +66,7 @@ msgstr "激活中" #: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34 #: terminal/models/storage.py:26 terminal/models/terminal.py:114 #: tickets/models/comment.py:24 tickets/models/ticket.py:154 -#: users/models/group.py:16 users/models/user.py:696 +#: users/models/group.py:16 users/models/user.py:698 #: 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,8 +94,8 @@ msgstr "登录复核" #: terminal/backends/command/models.py:19 #: terminal/backends/command/serializers.py:12 terminal/models/session.py:42 #: terminal/notifications.py:91 terminal/notifications.py:139 -#: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:884 -#: users/models/user.py:915 users/serializers/group.py:19 +#: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:886 +#: users/models/user.py:917 users/serializers/group.py:19 #: users/templates/users/user_asset_permission.html:38 #: users/templates/users/user_asset_permission.html:64 #: users/templates/users/user_database_app_permission.html:37 @@ -169,7 +169,7 @@ msgstr "格式为逗号分隔的字符串, * 表示匹配所有. " #: authentication/forms.py:15 authentication/forms.py:17 #: 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:31 users/models/user.py:657 +#: ops/models/adhoc.py:159 users/forms/profile.py:31 users/models/user.py:659 #: users/templates/users/_msg_user_created.html:12 #: users/templates/users/_select_user_modal.html:14 #: xpack/plugins/change_auth_plan/models/asset.py:34 @@ -280,7 +280,7 @@ msgstr "应用程序" #: assets/models/cmd_filter.py:42 assets/models/user.py:338 audits/models.py:40 #: perms/models/application_permission.py:33 #: perms/models/asset_permission.py:25 terminal/backends/command/models.py:21 -#: terminal/backends/command/serializers.py:14 terminal/models/session.py:46 +#: terminal/backends/command/serializers.py:35 terminal/models/session.py:46 #: users/templates/users/_granted_assets.html:27 #: users/templates/users/user_asset_permission.html:42 #: users/templates/users/user_asset_permission.html:76 @@ -375,7 +375,7 @@ msgstr "类型名称" #: assets/serializers/cmd_filter.py:49 common/db/models.py:113 #: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30 #: orgs/models.py:67 orgs/models.py:217 perms/models/base.py:92 -#: users/models/group.py:18 users/models/user.py:916 +#: users/models/group.py:18 users/models/user.py:918 #: xpack/plugins/cloud/models.py:125 msgid "Date created" msgstr "创建日期" @@ -627,7 +627,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:111 common/mixins/models.py:49 orgs/models.py:66 -#: orgs/models.py:219 perms/models/base.py:91 users/models/user.py:704 +#: orgs/models.py:219 perms/models/base.py:91 users/models/user.py:706 #: users/serializers/group.py:33 #: xpack/plugins/change_auth_plan/models/base.py:48 #: xpack/plugins/cloud/models.py:122 xpack/plugins/gathered_user/models.py:30 @@ -808,7 +808,7 @@ msgstr "带宽" msgid "Contact" msgstr "联系人" -#: assets/models/cluster.py:22 users/models/user.py:679 +#: assets/models/cluster.py:22 users/models/user.py:681 msgid "Phone" msgstr "手机" @@ -834,7 +834,7 @@ msgid "Default" msgstr "默认" #: assets/models/cluster.py:36 assets/models/label.py:14 rbac/const.py:6 -#: users/models/user.py:901 +#: users/models/user.py:903 msgid "System" msgstr "系统" @@ -843,7 +843,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:665 +#: users/models/group.py:31 users/models/user.py:667 #: users/templates/users/_select_user_modal.html:16 #: users/templates/users/user_asset_permission.html:39 #: users/templates/users/user_asset_permission.html:67 @@ -861,7 +861,7 @@ msgid "Regex" msgstr "正则表达式" #: assets/models/cmd_filter.py:68 ops/models/command.py:26 -#: terminal/backends/command/serializers.py:15 terminal/models/session.py:53 +#: terminal/backends/command/serializers.py:14 terminal/models/session.py:53 #: terminal/templates/terminal/_msg_command_alert.html:12 #: terminal/templates/terminal/_msg_command_execute_alert.html:10 msgid "Command" @@ -1498,7 +1498,7 @@ msgstr "用户代理" #: audits/models.py:124 #: authentication/templates/authentication/_mfa_confirm_modal.html:14 -#: users/forms/profile.py:64 users/models/user.py:682 +#: users/forms/profile.py:64 users/models/user.py:684 #: users/serializers/profile.py:121 msgid "MFA" msgstr "MFA" @@ -1576,13 +1576,13 @@ msgstr "认证令牌" #: audits/signal_handlers.py:71 authentication/notifications.py:73 #: authentication/views/login.py:164 authentication/views/wecom.py:181 -#: notifications/backends/__init__.py:11 users/models/user.py:718 +#: notifications/backends/__init__.py:11 users/models/user.py:720 msgid "WeCom" msgstr "企业微信" #: audits/signal_handlers.py:72 authentication/views/dingtalk.py:182 #: authentication/views/login.py:170 notifications/backends/__init__.py:12 -#: users/models/user.py:719 +#: users/models/user.py:721 msgid "DingTalk" msgstr "钉钉" @@ -2113,14 +2113,14 @@ msgid "Show" msgstr "显示" #: authentication/templates/authentication/_access_key_modal.html:66 -#: settings/serializers/security.py:39 users/models/user.py:554 +#: settings/serializers/security.py:39 users/models/user.py:556 #: users/serializers/profile.py:111 users/templates/users/mfa_setting.html:61 #: users/templates/users/user_verify_mfa.html:36 msgid "Disable" msgstr "禁用" #: authentication/templates/authentication/_access_key_modal.html:67 -#: users/models/user.py:555 users/serializers/profile.py:112 +#: users/models/user.py:557 users/serializers/profile.py:112 #: users/templates/users/mfa_setting.html:26 #: users/templates/users/mfa_setting.html:68 msgid "Enable" @@ -2369,7 +2369,7 @@ msgid "The FeiShu is already bound to another user" msgstr "该飞书已经绑定其他用户" #: authentication/views/feishu.py:148 authentication/views/login.py:176 -#: notifications/backends/__init__.py:14 users/models/user.py:720 +#: notifications/backends/__init__.py:14 users/models/user.py:722 msgid "FeiShu" msgstr "飞书" @@ -2664,7 +2664,7 @@ msgid "Notifications" msgstr "通知" #: notifications/backends/__init__.py:10 users/forms/profile.py:101 -#: users/models/user.py:661 +#: users/models/user.py:663 msgid "Email" msgstr "邮件" @@ -2890,7 +2890,7 @@ msgid "Can view root org" msgstr "可以查看全局组织" #: orgs/models.py:216 rbac/models/role.py:46 rbac/models/rolebinding.py:43 -#: users/models/user.py:669 users/templates/users/_select_user_modal.html:15 +#: users/models/user.py:671 users/templates/users/_select_user_modal.html:15 msgid "Role" msgstr "角色" @@ -2977,7 +2977,7 @@ msgstr "剪贴板复制粘贴" #: perms/models/base.py:90 #: tickets/serializers/ticket/meta/ticket_type/apply_application.py:58 #: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:60 -#: users/models/user.py:701 +#: users/models/user.py:703 msgid "Date expired" msgstr "失效日期" @@ -3020,15 +3020,15 @@ msgstr "组织 ({}) 的应用授权" #: perms/serializers/application/permission.py:20 #: perms/serializers/application/permission.py:41 #: perms/serializers/asset/permission.py:19 -#: perms/serializers/asset/permission.py:45 users/serializers/user.py:139 +#: perms/serializers/asset/permission.py:45 users/serializers/user.py:141 msgid "Is valid" msgstr "账号是否有效" #: perms/serializers/application/permission.py:21 #: perms/serializers/application/permission.py:40 #: perms/serializers/asset/permission.py:20 -#: perms/serializers/asset/permission.py:44 users/serializers/user.py:85 -#: users/serializers/user.py:141 +#: perms/serializers/asset/permission.py:44 users/serializers/user.py:86 +#: users/serializers/user.py:143 msgid "Is expired" msgstr "已过期" @@ -4206,47 +4206,47 @@ msgstr "RDP 访问地址, 如: dev.jumpserver.org:3389" msgid "Enable XRDP" msgstr "启用 XRDP 服务" -#: settings/serializers/terminal.py:42 +#: settings/serializers/terminal.py:43 msgid "Koko host" msgstr "KOKO 主机地址" -#: settings/serializers/terminal.py:43 +#: settings/serializers/terminal.py:46 msgid "Koko ssh port" msgstr "KOKO ssh 端口" -#: settings/serializers/terminal.py:45 +#: settings/serializers/terminal.py:49 msgid "Enable database proxy" msgstr "启用数据库组件" -#: settings/serializers/terminal.py:47 +#: settings/serializers/terminal.py:51 msgid "Database proxy host" msgstr "数据库主机地址" -#: settings/serializers/terminal.py:48 +#: settings/serializers/terminal.py:52 msgid "Database proxy host, eg: dev.jumpserver.org" msgstr "数据库组件地址, 如: dev.jumpserver.org (没有端口, 不同协议端口不同)" -#: settings/serializers/terminal.py:51 +#: settings/serializers/terminal.py:55 msgid "MySQL port" msgstr "MySQL 协议端口" -#: settings/serializers/terminal.py:52 +#: settings/serializers/terminal.py:56 msgid "MySQL protocol listen port" msgstr "MySQL 协议监听端口" -#: settings/serializers/terminal.py:55 +#: settings/serializers/terminal.py:59 msgid "MariaDB port" msgstr "MariaDB 端口" -#: settings/serializers/terminal.py:56 +#: settings/serializers/terminal.py:60 msgid "MariaDB protocol listen port" msgstr "MariaDB 协议监听的端口" -#: settings/serializers/terminal.py:59 +#: settings/serializers/terminal.py:63 msgid "PostgreSQL port" msgstr "PostgreSQL 端口" -#: settings/serializers/terminal.py:60 +#: settings/serializers/terminal.py:64 msgid "PostgreSQL protocol listen port" msgstr "PostgreSQL 协议监听端口" @@ -4786,7 +4786,7 @@ msgid "Input" msgstr "输入" #: terminal/backends/command/models.py:23 -#: terminal/backends/command/serializers.py:16 +#: terminal/backends/command/serializers.py:36 msgid "Output" msgstr "输出" @@ -4797,23 +4797,23 @@ msgid "Session" msgstr "会话" #: terminal/backends/command/models.py:25 -#: terminal/backends/command/serializers.py:18 +#: terminal/backends/command/serializers.py:17 msgid "Risk level" msgstr "风险等级" -#: terminal/backends/command/serializers.py:17 +#: terminal/backends/command/serializers.py:15 msgid "Session ID" msgstr "会话ID" -#: terminal/backends/command/serializers.py:19 +#: terminal/backends/command/serializers.py:37 msgid "Risk level display" msgstr "风险等级名称" -#: terminal/backends/command/serializers.py:21 +#: terminal/backends/command/serializers.py:38 msgid "Timestamp" msgstr "时间戳" -#: terminal/backends/command/serializers.py:22 terminal/models/terminal.py:105 +#: terminal/backends/command/serializers.py:39 terminal/models/terminal.py:105 msgid "Remote Address" msgstr "远端地址" @@ -4842,7 +4842,7 @@ msgstr "不支持批量创建" msgid "Storage is invalid" msgstr "存储无效" -#: terminal/models/command.py:24 +#: terminal/models/command.py:53 msgid "Command record" msgstr "命令记录" @@ -5067,7 +5067,7 @@ msgstr "端点无效: 移除路径 `{}`" msgid "Bucket" msgstr "桶名称" -#: terminal/serializers/storage.py:34 users/models/user.py:693 +#: terminal/serializers/storage.py:34 users/models/user.py:695 msgid "Secret key" msgstr "密钥" @@ -5670,68 +5670,68 @@ msgstr "不能和原来的密钥相同" msgid "Not a valid ssh public key" msgstr "SSH密钥不合法" -#: users/forms/profile.py:160 users/models/user.py:690 +#: users/forms/profile.py:160 users/models/user.py:692 #: users/templates/users/user_password_update.html:48 msgid "Public key" msgstr "SSH公钥" -#: users/models/user.py:556 +#: users/models/user.py:558 msgid "Force enable" msgstr "强制启用" -#: users/models/user.py:623 +#: users/models/user.py:625 msgid "Local" msgstr "数据库" -#: users/models/user.py:671 users/serializers/user.py:140 +#: users/models/user.py:673 users/serializers/user.py:142 msgid "Is service account" msgstr "服务账号" -#: users/models/user.py:673 +#: users/models/user.py:675 msgid "Avatar" msgstr "头像" -#: users/models/user.py:676 +#: users/models/user.py:678 msgid "Wechat" msgstr "微信" -#: users/models/user.py:687 +#: users/models/user.py:689 msgid "Private key" msgstr "ssh私钥" -#: users/models/user.py:709 +#: users/models/user.py:711 msgid "Source" msgstr "来源" -#: users/models/user.py:713 +#: users/models/user.py:715 msgid "Date password last updated" msgstr "最后更新密码日期" -#: users/models/user.py:716 +#: users/models/user.py:718 msgid "Need update password" msgstr "需要更新密码" -#: users/models/user.py:886 +#: users/models/user.py:888 msgid "Can invite user" msgstr "可以邀请用户" -#: users/models/user.py:887 +#: users/models/user.py:889 msgid "Can remove user" msgstr "可以移除用户" -#: users/models/user.py:888 +#: users/models/user.py:890 msgid "Can match user" msgstr "可以匹配用户" -#: users/models/user.py:897 +#: users/models/user.py:899 msgid "Administrator" msgstr "管理员" -#: users/models/user.py:900 +#: users/models/user.py:902 msgid "Administrator is the super user of system" msgstr "Administrator是初始的超级管理员" -#: users/models/user.py:925 +#: users/models/user.py:927 msgid "User password history" msgstr "用户密码历史" @@ -5782,97 +5782,101 @@ msgstr "新密码不能是最近 {} 次的密码" msgid "The newly set password is inconsistent" msgstr "两次密码不一致" -#: users/serializers/profile.py:142 users/serializers/user.py:138 +#: users/serializers/profile.py:142 users/serializers/user.py:140 msgid "Is first login" msgstr "首次登录" -#: users/serializers/user.py:24 users/serializers/user.py:31 +#: users/serializers/user.py:25 users/serializers/user.py:32 msgid "System roles" msgstr "系统角色" -#: users/serializers/user.py:29 users/serializers/user.py:32 +#: users/serializers/user.py:30 users/serializers/user.py:33 msgid "Org roles" msgstr "组织角色" -#: users/serializers/user.py:77 +#: users/serializers/user.py:78 #: xpack/plugins/change_auth_plan/models/base.py:35 #: xpack/plugins/change_auth_plan/serializers/base.py:22 msgid "Password strategy" msgstr "密码策略" -#: users/serializers/user.py:79 +#: users/serializers/user.py:80 msgid "MFA enabled" msgstr "MFA" -#: users/serializers/user.py:80 +#: users/serializers/user.py:81 msgid "MFA force enabled" msgstr "强制 MFA" -#: users/serializers/user.py:82 +#: users/serializers/user.py:83 msgid "MFA level display" msgstr "MFA 等级名称" -#: users/serializers/user.py:84 +#: users/serializers/user.py:85 msgid "Login blocked" msgstr "登录被阻塞" -#: users/serializers/user.py:87 +#: users/serializers/user.py:88 msgid "Can public key authentication" msgstr "能否公钥认证" -#: users/serializers/user.py:142 +#: users/serializers/user.py:144 msgid "Avatar url" msgstr "头像路径" -#: users/serializers/user.py:144 +#: users/serializers/user.py:146 msgid "Groups name" msgstr "用户组名" -#: users/serializers/user.py:145 +#: users/serializers/user.py:147 msgid "Source name" msgstr "用户来源名" -#: users/serializers/user.py:146 +#: users/serializers/user.py:148 msgid "Organization role name" msgstr "组织角色名称" -#: users/serializers/user.py:147 +#: users/serializers/user.py:149 msgid "Super role name" msgstr "超级角色名称" -#: users/serializers/user.py:148 +#: users/serializers/user.py:150 msgid "Total role name" msgstr "汇总角色名称" -#: users/serializers/user.py:150 +#: users/serializers/user.py:152 msgid "Is wecom bound" msgstr "是否绑定了企业微信" -#: users/serializers/user.py:151 +#: users/serializers/user.py:153 msgid "Is dingtalk bound" msgstr "是否绑定了钉钉" -#: users/serializers/user.py:152 +#: users/serializers/user.py:154 msgid "Is feishu bound" msgstr "是否绑定了飞书" -#: users/serializers/user.py:153 +#: users/serializers/user.py:155 msgid "Is OTP bound" msgstr "是否绑定了虚拟 MFA" -#: users/serializers/user.py:155 +#: users/serializers/user.py:157 msgid "System role name" msgstr "系统角色名称" -#: users/serializers/user.py:247 +#: users/serializers/user.py:197 +msgid "User cannot self-update fields: {}" +msgstr "用户不能更新自己的字段: {}" + +#: users/serializers/user.py:254 msgid "Select users" msgstr "选择用户" -#: users/serializers/user.py:248 +#: users/serializers/user.py:255 msgid "For security, only list several users" msgstr "为了安全,仅列出几个用户" -#: users/serializers/user.py:281 +#: users/serializers/user.py:290 msgid "name not unique" msgstr "名称重复" diff --git a/apps/users/serializers/user.py b/apps/users/serializers/user.py index 3014aa2d9..5a1043267 100644 --- a/apps/users/serializers/user.py +++ b/apps/users/serializers/user.py @@ -194,7 +194,7 @@ class UserSerializer(RolesSerializerMixin, CommonBulkSerializerMixin, serializer if not disallow_fields: return attrs # 用户自己不能更新自己的一些字段 - error = 'User Cannot self-update fields: {}'.format(disallow_fields) + error = _('User cannot self-update fields: {}').format(disallow_fields) raise serializers.ValidationError(error) def validate(self, attrs): From 3121b4e3ff36f097a1aa9f3f96ba4a12670a9094 Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" Date: Thu, 31 Mar 2022 11:38:49 +0800 Subject: [PATCH 41/59] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E7=BF=BB?= =?UTF-8?q?=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/ja/LC_MESSAGES/django.mo | 4 ++-- apps/locale/zh/LC_MESSAGES/django.mo | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index 22c57dcbe..69226e3a4 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:050a3fd63c1cf9b3dc60c8f138d58f029f2e8a32a71abd99fff6899b68c0f6d9 -size 129742 +oid sha256:bf72c66551e2e7b951960d96054ede0e3e6f3419c4d693f844dc2a61f583390f +size 129861 diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 860a45eaa..511437fb2 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1baa8c35aa2493c03c1fe7383a13ca4cfd9b18b44150770fb51f39433c18c74c -size 107492 +oid sha256:6e803750e498ee3d0f3f66f7b74ee9c4b9fd3a6b2bc9a0ecf4bbd5a9c1582e18 +size 107581 From e602bc03419cbc9747d984cd8632260ea01deab4 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Fri, 1 Apr 2022 16:52:50 +0800 Subject: [PATCH 42/59] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=BD=91?= =?UTF-8?q?=E5=85=B3=E7=BF=BB=E8=AF=91=20(#8016)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng626 <1304903146@qq.com> --- apps/assets/serializers/domain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/assets/serializers/domain.py b/apps/assets/serializers/domain.py index b86938c43..6932572f8 100644 --- a/apps/assets/serializers/domain.py +++ b/apps/assets/serializers/domain.py @@ -43,7 +43,7 @@ class DomainSerializer(BulkOrgResourceModelSerializer): class GatewaySerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): - is_connective = serializers.BooleanField(required=False) + is_connective = serializers.BooleanField(required=False, label=_('Connectivity')) class Meta: model = Gateway From a936092020f42e1bda57aa8f5d905c8b570f53a0 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Sat, 2 Apr 2022 13:26:18 +0800 Subject: [PATCH 43/59] =?UTF-8?q?perf:=20es=E7=9B=B8=E5=85=B3=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=A0=BC=E5=BC=8F=E4=BC=98=E5=8C=96=20(#8020)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng626 <1304903146@qq.com> --- apps/terminal/backends/command/es.py | 37 ++++++++++++++-------------- apps/terminal/serializers/storage.py | 18 +++----------- 2 files changed, 21 insertions(+), 34 deletions(-) diff --git a/apps/terminal/backends/command/es.py b/apps/terminal/backends/command/es.py index d74ad3fa8..2e8a82c88 100644 --- a/apps/terminal/backends/command/es.py +++ b/apps/terminal/backends/command/es.py @@ -18,7 +18,6 @@ from common.utils import get_logger from common.exceptions import JMSException from .models import AbstractSessionCommand - logger = get_logger(__file__) @@ -27,7 +26,7 @@ class InvalidElasticsearch(JMSException): default_detail = _('Invalid elasticsearch config') -class CommandStore(): +class CommandStore(object): def __init__(self, config): hosts = config.get("HOSTS") kwargs = config.get("OTHER", {}) @@ -208,7 +207,7 @@ class CommandStore(): elif org_id in (real_default_org_id, ''): match.pop('org_id') should.append({ - 'bool':{ + 'bool': { 'must_not': [ { 'wildcard': {'org_id': '*'} @@ -226,20 +225,20 @@ class CommandStore(): ], 'should': should, 'filter': [ - { - 'term': {k: v} - } for k, v in exact.items() - ] + [ - { - 'range': { - 'timestamp': timestamp_range - } - } - ] + [ - { - 'ids': {k: v} - } for k, v in index.items() - ] + { + 'term': {k: v} + } for k, v in exact.items() + ] + [ + { + 'range': { + 'timestamp': timestamp_range + } + } + ] + [ + { + 'ids': {k: v} + } for k, v in index.items() + ] } }, } @@ -326,8 +325,8 @@ class QuerySet(DJQuerySet): def __getattribute__(self, item): if any(( - item.startswith('__'), - item in QuerySet.__dict__, + item.startswith('__'), + item in QuerySet.__dict__, )): return object.__getattribute__(self, item) diff --git a/apps/terminal/serializers/storage.py b/apps/terminal/serializers/storage.py index 2b21625bd..81c885862 100644 --- a/apps/terminal/serializers/storage.py +++ b/apps/terminal/serializers/storage.py @@ -13,8 +13,6 @@ from rest_framework.validators import UniqueValidator # Replay storage serializers # -------------------------- - - def replay_storage_endpoint_format_validator(endpoint): h = urlparse(endpoint) if h.path: @@ -116,9 +114,8 @@ class ReplayStorageTypeAzureSerializer(serializers.Serializer): label=_('Endpoint suffix'), allow_null=True, ) + # mapping - - replay_storage_type_serializer_classes_mapping = { const.ReplayStorageTypeChoices.s3.value: ReplayStorageTypeS3Serializer, const.ReplayStorageTypeChoices.ceph.value: ReplayStorageTypeCephSerializer, @@ -129,10 +126,9 @@ replay_storage_type_serializer_classes_mapping = { const.ReplayStorageTypeChoices.cos.value: ReplayStorageTypeCOSSerializer } + # Command storage serializers # --------------------------- - - def command_storage_es_host_format_validator(host): h = urlparse(host) default_error_msg = _('The address format is incorrect') @@ -151,7 +147,6 @@ def command_storage_es_host_format_validator(host): class CommandStorageTypeESSerializer(serializers.Serializer): - hosts_help_text = ''' Tip: If there are multiple hosts, use a comma (,) to separate them.
    (eg: http://www.jumpserver.a.com:9100, http://www.jumpserver.b.com:9100) @@ -169,17 +164,14 @@ class CommandStorageTypeESSerializer(serializers.Serializer): source='OTHER.IGNORE_VERIFY_CERTS', allow_null=True, ) + # mapping - - command_storage_type_serializer_classes_mapping = { const.CommandStorageTypeChoices.es.value: CommandStorageTypeESSerializer } # BaseStorageSerializer - - class BaseStorageSerializer(serializers.ModelSerializer): storage_type_serializer_classes_mapping = {} meta = MethodSerializer() @@ -223,8 +215,6 @@ class BaseStorageSerializer(serializers.ModelSerializer): # CommandStorageSerializer - - class CommandStorageSerializer(BaseStorageSerializer): storage_type_serializer_classes_mapping = command_storage_type_serializer_classes_mapping @@ -236,8 +226,6 @@ class CommandStorageSerializer(BaseStorageSerializer): # ReplayStorageSerializer - - class ReplayStorageSerializer(BaseStorageSerializer): storage_type_serializer_classes_mapping = replay_storage_type_serializer_classes_mapping From 2cb08b4785a1c249290b56905003727cf6461e77 Mon Sep 17 00:00:00 2001 From: feng626 <1304903146@qq.com> Date: Sat, 2 Apr 2022 15:51:23 +0800 Subject: [PATCH 44/59] fix: user is common user --- apps/ops/api/command.py | 2 +- apps/rbac/builtin.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/apps/ops/api/command.py b/apps/ops/api/command.py index 2b7e5fda9..0d513cd9e 100644 --- a/apps/ops/api/command.py +++ b/apps/ops/api/command.py @@ -59,7 +59,7 @@ class CommandExecutionViewSet(RootOrgViewMixin, viewsets.ModelViewSet): raise ValidationError({"hosts": msg}) def check_permissions(self, request): - if not settings.SECURITY_COMMAND_EXECUTION and request.user.is_common_user: + if not settings.SECURITY_COMMAND_EXECUTION: return self.permission_denied(request, "Command execution disabled") return super().check_permissions(request) diff --git a/apps/rbac/builtin.py b/apps/rbac/builtin.py index a47139132..ce735ce8f 100644 --- a/apps/rbac/builtin.py +++ b/apps/rbac/builtin.py @@ -29,7 +29,6 @@ auditor_perms = user_perms + ( ('ops', 'commandexecution', 'view', 'commandexecution') ) - app_exclude_perms = [ ('users', 'user', 'add,delete', 'user'), ('orgs', 'org', 'add,delete,change', 'org'), @@ -59,7 +58,8 @@ class PredefineRole: from rbac.models import Role return Role.objects.get(id=self.id) - def _get_defaults(self): + @property + def default_perms(self): from rbac.models import Permission q = Permission.get_define_permissions_q(self.perms) permissions = Permission.get_permissions(self.scope) @@ -72,6 +72,10 @@ class PredefineRole: permissions = permissions.exclude(q) perms = permissions.values_list('id', flat=True) + return perms + + def _get_defaults(self): + perms = self.default_perms defaults = { 'id': self.id, 'name': self.name, 'scope': self.scope, 'builtin': True, 'permissions': perms From fe8527fd074de1c4300db60c21d2d9107d9c6875 Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Sat, 2 Apr 2022 10:04:18 +0800 Subject: [PATCH 45/59] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=E7=BF=BB?= =?UTF-8?q?=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/ja/LC_MESSAGES/django.mo | 4 +-- apps/locale/ja/LC_MESSAGES/django.po | 49 +++++++++++++++++----------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +-- apps/locale/zh/LC_MESSAGES/django.po | 49 +++++++++++++++++----------- 4 files changed, 64 insertions(+), 42 deletions(-) diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index 69226e3a4..663dad9e1 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bf72c66551e2e7b951960d96054ede0e3e6f3419c4d693f844dc2a61f583390f -size 129861 +oid sha256:17e378f009274c169039e815158ea9072ee89811bb27a5b17a628f2066fcfb86 +size 129989 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index bc5707e14..cc8a3b317 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-03-31 11:21+0800\n" +"POT-Creation-Date: 2022-04-02 10:01+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -343,7 +343,7 @@ msgid "Domain" msgstr "ドメイン" #: applications/models/application.py:228 xpack/plugins/cloud/models.py:33 -#: xpack/plugins/cloud/serializers/account.py:58 +#: xpack/plugins/cloud/serializers/account.py:59 msgid "Attrs" msgstr "ツールバーの" @@ -767,11 +767,11 @@ msgstr "OK" #: assets/models/base.py:32 audits/models.py:116 #: xpack/plugins/change_auth_plan/serializers/app.py:88 #: xpack/plugins/change_auth_plan/serializers/asset.py:198 -#: xpack/plugins/cloud/const.py:30 +#: xpack/plugins/cloud/const.py:31 msgid "Failed" msgstr "失敗しました" -#: assets/models/base.py:38 +#: assets/models/base.py:38 assets/serializers/domain.py:46 msgid "Connectivity" msgstr "接続性" @@ -6520,58 +6520,62 @@ msgid "Baidu Cloud" msgstr "百度雲" #: xpack/plugins/cloud/const.py:15 +msgid "JD Cloud" +msgstr "京東雲" + +#: xpack/plugins/cloud/const.py:16 msgid "Tencent Cloud" msgstr "テンセント雲" -#: xpack/plugins/cloud/const.py:16 +#: xpack/plugins/cloud/const.py:17 msgid "VMware" msgstr "VMware" -#: xpack/plugins/cloud/const.py:17 xpack/plugins/cloud/providers/nutanix.py:13 +#: xpack/plugins/cloud/const.py:18 xpack/plugins/cloud/providers/nutanix.py:13 msgid "Nutanix" msgstr "Nutanix" -#: xpack/plugins/cloud/const.py:18 +#: xpack/plugins/cloud/const.py:19 msgid "Huawei Private Cloud" msgstr "華為私有雲" -#: xpack/plugins/cloud/const.py:19 +#: xpack/plugins/cloud/const.py:20 msgid "Qingyun Private Cloud" msgstr "青雲私有雲" -#: xpack/plugins/cloud/const.py:20 +#: xpack/plugins/cloud/const.py:21 msgid "OpenStack" msgstr "OpenStack" -#: xpack/plugins/cloud/const.py:21 +#: xpack/plugins/cloud/const.py:22 msgid "Google Cloud Platform" msgstr "谷歌雲" -#: xpack/plugins/cloud/const.py:25 +#: xpack/plugins/cloud/const.py:26 msgid "Instance name" msgstr "インスタンス名" -#: xpack/plugins/cloud/const.py:26 +#: xpack/plugins/cloud/const.py:27 msgid "Instance name and Partial IP" msgstr "インスタンス名と部分IP" -#: xpack/plugins/cloud/const.py:31 +#: xpack/plugins/cloud/const.py:32 msgid "Succeed" msgstr "成功" -#: xpack/plugins/cloud/const.py:35 +#: xpack/plugins/cloud/const.py:36 msgid "Unsync" msgstr "同期していません" -#: xpack/plugins/cloud/const.py:36 +#: xpack/plugins/cloud/const.py:37 msgid "New Sync" msgstr "新しい同期" -#: xpack/plugins/cloud/const.py:37 +#: xpack/plugins/cloud/const.py:38 msgid "Synced" msgstr "同期済み" -#: xpack/plugins/cloud/const.py:38 +#: xpack/plugins/cloud/const.py:39 msgid "Released" msgstr "リリース済み" @@ -6744,11 +6748,13 @@ msgid "South America (São Paulo)" msgstr "南米 (サンパウロ)" #: xpack/plugins/cloud/providers/baiducloud.py:54 +#: xpack/plugins/cloud/providers/jdcloud.py:127 msgid "CN North-Beijing" msgstr "華北-北京" #: xpack/plugins/cloud/providers/baiducloud.py:55 #: xpack/plugins/cloud/providers/huaweicloud.py:40 +#: xpack/plugins/cloud/providers/jdcloud.py:130 msgid "CN South-Guangzhou" msgstr "華南-広州" @@ -6770,6 +6776,7 @@ msgid "CN North-Baoding" msgstr "華北-保定" #: xpack/plugins/cloud/providers/baiducloud.py:60 +#: xpack/plugins/cloud/providers/jdcloud.py:129 msgid "CN East-Shanghai" msgstr "華東-上海" @@ -6834,11 +6841,15 @@ msgstr "華北-ウランチャブ一" msgid "CN South-Guangzhou-InvitationOnly" msgstr "華南-広州-友好ユーザー環境" -#: xpack/plugins/cloud/serializers/account.py:59 +#: xpack/plugins/cloud/providers/jdcloud.py:128 +msgid "CN East-Suqian" +msgstr "華東-宿遷" + +#: xpack/plugins/cloud/serializers/account.py:60 msgid "Validity display" msgstr "有効表示" -#: xpack/plugins/cloud/serializers/account.py:60 +#: xpack/plugins/cloud/serializers/account.py:61 msgid "Provider display" msgstr "プロバイダ表示" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 511437fb2..944990cc4 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e803750e498ee3d0f3f66f7b74ee9c4b9fd3a6b2bc9a0ecf4bbd5a9c1582e18 -size 107581 +oid sha256:51c19db490e2e3a7cc3c3fce33b2e4422239d8c64d591208cadaf062c5ccb0c9 +size 107709 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index ffd8d4ba3..68b8a566c 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-03-31 11:19+0800\n" +"POT-Creation-Date: 2022-04-02 10:01+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -338,7 +338,7 @@ msgid "Domain" msgstr "网域" #: applications/models/application.py:228 xpack/plugins/cloud/models.py:33 -#: xpack/plugins/cloud/serializers/account.py:58 +#: xpack/plugins/cloud/serializers/account.py:59 msgid "Attrs" msgstr "属性" @@ -762,11 +762,11 @@ msgstr "成功" #: assets/models/base.py:32 audits/models.py:116 #: xpack/plugins/change_auth_plan/serializers/app.py:88 #: xpack/plugins/change_auth_plan/serializers/asset.py:198 -#: xpack/plugins/cloud/const.py:30 +#: xpack/plugins/cloud/const.py:31 msgid "Failed" msgstr "失败" -#: assets/models/base.py:38 +#: assets/models/base.py:38 assets/serializers/domain.py:46 msgid "Connectivity" msgstr "可连接性" @@ -6430,58 +6430,62 @@ msgid "Baidu Cloud" msgstr "百度云" #: xpack/plugins/cloud/const.py:15 +msgid "JD Cloud" +msgstr "京东云" + +#: xpack/plugins/cloud/const.py:16 msgid "Tencent Cloud" msgstr "腾讯云" -#: xpack/plugins/cloud/const.py:16 +#: xpack/plugins/cloud/const.py:17 msgid "VMware" msgstr "VMware" -#: xpack/plugins/cloud/const.py:17 xpack/plugins/cloud/providers/nutanix.py:13 +#: xpack/plugins/cloud/const.py:18 xpack/plugins/cloud/providers/nutanix.py:13 msgid "Nutanix" msgstr "Nutanix" -#: xpack/plugins/cloud/const.py:18 +#: xpack/plugins/cloud/const.py:19 msgid "Huawei Private Cloud" msgstr "华为私有云" -#: xpack/plugins/cloud/const.py:19 +#: xpack/plugins/cloud/const.py:20 msgid "Qingyun Private Cloud" msgstr "青云私有云" -#: xpack/plugins/cloud/const.py:20 +#: xpack/plugins/cloud/const.py:21 msgid "OpenStack" msgstr "OpenStack" -#: xpack/plugins/cloud/const.py:21 +#: xpack/plugins/cloud/const.py:22 msgid "Google Cloud Platform" msgstr "谷歌云" -#: xpack/plugins/cloud/const.py:25 +#: xpack/plugins/cloud/const.py:26 msgid "Instance name" msgstr "实例名称" -#: xpack/plugins/cloud/const.py:26 +#: xpack/plugins/cloud/const.py:27 msgid "Instance name and Partial IP" msgstr "实例名称和部分IP" -#: xpack/plugins/cloud/const.py:31 +#: xpack/plugins/cloud/const.py:32 msgid "Succeed" msgstr "成功" -#: xpack/plugins/cloud/const.py:35 +#: xpack/plugins/cloud/const.py:36 msgid "Unsync" msgstr "未同步" -#: xpack/plugins/cloud/const.py:36 +#: xpack/plugins/cloud/const.py:37 msgid "New Sync" msgstr "新同步" -#: xpack/plugins/cloud/const.py:37 +#: xpack/plugins/cloud/const.py:38 msgid "Synced" msgstr "已同步" -#: xpack/plugins/cloud/const.py:38 +#: xpack/plugins/cloud/const.py:39 msgid "Released" msgstr "已释放" @@ -6654,11 +6658,13 @@ msgid "South America (São Paulo)" msgstr "南美洲(圣保罗)" #: xpack/plugins/cloud/providers/baiducloud.py:54 +#: xpack/plugins/cloud/providers/jdcloud.py:127 msgid "CN North-Beijing" msgstr "华北-北京" #: xpack/plugins/cloud/providers/baiducloud.py:55 #: xpack/plugins/cloud/providers/huaweicloud.py:40 +#: xpack/plugins/cloud/providers/jdcloud.py:130 msgid "CN South-Guangzhou" msgstr "华南-广州" @@ -6680,6 +6686,7 @@ msgid "CN North-Baoding" msgstr "华北-保定" #: xpack/plugins/cloud/providers/baiducloud.py:60 +#: xpack/plugins/cloud/providers/jdcloud.py:129 msgid "CN East-Shanghai" msgstr "华东-上海" @@ -6744,11 +6751,15 @@ msgstr "华北-乌兰察布一" msgid "CN South-Guangzhou-InvitationOnly" msgstr "华南-广州-友好用户环境" -#: xpack/plugins/cloud/serializers/account.py:59 +#: xpack/plugins/cloud/providers/jdcloud.py:128 +msgid "CN East-Suqian" +msgstr "华东-宿迁" + +#: xpack/plugins/cloud/serializers/account.py:60 msgid "Validity display" msgstr "有效性显示" -#: xpack/plugins/cloud/serializers/account.py:60 +#: xpack/plugins/cloud/serializers/account.py:61 msgid "Provider display" msgstr "服务商显示" From ef36b2e66265de4f196d2a90ac8444c9a7b74063 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 6 Apr 2022 14:58:13 +0800 Subject: [PATCH 46/59] =?UTF-8?q?perf:=20=E5=AE=8C=E5=96=84=20setting=20?= =?UTF-8?q?=E7=9A=84=E5=8A=A8=E6=80=81=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/settings/signal_handlers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/settings/signal_handlers.py b/apps/settings/signal_handlers.py index 818b7ba03..18449a771 100644 --- a/apps/settings/signal_handlers.py +++ b/apps/settings/signal_handlers.py @@ -94,7 +94,7 @@ def monkey_patch_settings(sender, **kwargs): def monkey_patch_getattr(self, name): val = getattr(self._wrapped, name) # 只解析 defaults 中的 callable - if callable(val) and val.__module__ == 'jumpserver.conf': + if callable(val) and val.__module__.endswith('jumpserver.conf'): val = val() return val From c8758f417d5208d35d34c84adf7dcbc3570a01b6 Mon Sep 17 00:00:00 2001 From: feng626 <1304903146@qq.com> Date: Fri, 1 Apr 2022 15:33:14 +0800 Subject: [PATCH 47/59] =?UTF-8?q?feat:=20ldap=E4=B8=80=E9=94=AE=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E5=8F=8A=E8=AE=BE=E7=BD=AE=E7=94=A8=E6=88=B7=E7=BB=84?= =?UTF-8?q?=E7=BB=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/conf.py | 5 +++-- apps/jumpserver/settings/auth.py | 1 + apps/settings/api/ldap.py | 5 +++-- apps/settings/serializers/auth/ldap.py | 9 ++++++--- apps/users/tasks.py | 6 ++++-- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 7aa8dc436..8e34d6f91 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -41,7 +41,7 @@ def import_string(dotted_path): except AttributeError as err: raise ImportError('Module "%s" does not define a "%s" attribute/class' % ( module_path, class_name) - ) from err + ) from err def is_absolute_uri(uri): @@ -176,6 +176,7 @@ class Config(dict): 'AUTH_LDAP_SYNC_IS_PERIODIC': False, 'AUTH_LDAP_SYNC_INTERVAL': None, 'AUTH_LDAP_SYNC_CRONTAB': None, + 'AUTH_LDAP_SYNC_ORG_ID': '00000000-0000-0000-0000-000000000002', 'AUTH_LDAP_USER_LOGIN_ONLY_IN_USERS': False, 'AUTH_LDAP_OPTIONS_OPT_REFERRALS': -1, @@ -272,7 +273,7 @@ class Config(dict): 'FEISHU_APP_ID': '', 'FEISHU_APP_SECRET': '', - 'LOGIN_REDIRECT_TO_BACKEND': '', # 'OPENID / CAS / SAML2 + 'LOGIN_REDIRECT_TO_BACKEND': '', # 'OPENID / CAS / SAML2 'LOGIN_REDIRECT_MSG_ENABLED': True, 'SMS_ENABLED': False, diff --git a/apps/jumpserver/settings/auth.py b/apps/jumpserver/settings/auth.py index c545772e1..f71afec9b 100644 --- a/apps/jumpserver/settings/auth.py +++ b/apps/jumpserver/settings/auth.py @@ -43,6 +43,7 @@ AUTH_LDAP_SEARCH_PAGED_SIZE = CONFIG.AUTH_LDAP_SEARCH_PAGED_SIZE AUTH_LDAP_SYNC_IS_PERIODIC = CONFIG.AUTH_LDAP_SYNC_IS_PERIODIC AUTH_LDAP_SYNC_INTERVAL = CONFIG.AUTH_LDAP_SYNC_INTERVAL AUTH_LDAP_SYNC_CRONTAB = CONFIG.AUTH_LDAP_SYNC_CRONTAB +AUTH_LDAP_SYNC_ORG_ID = CONFIG.AUTH_LDAP_SYNC_ORG_ID AUTH_LDAP_USER_LOGIN_ONLY_IN_USERS = CONFIG.AUTH_LDAP_USER_LOGIN_ONLY_IN_USERS diff --git a/apps/settings/api/ldap.py b/apps/settings/api/ldap.py index a66f0977e..e45414b81 100644 --- a/apps/settings/api/ldap.py +++ b/apps/settings/api/ldap.py @@ -195,7 +195,9 @@ class LDAPUserImportAPI(APIView): def get_ldap_users(self): username_list = self.request.data.get('username_list', []) cache_police = self.request.query_params.get('cache_police', True) - if cache_police in LDAP_USE_CACHE_FLAGS: + if '*' in username_list: + users = LDAPServerUtil().search() + elif cache_police in LDAP_USE_CACHE_FLAGS: users = LDAPCacheUtil().search(search_users=username_list) else: users = LDAPServerUtil().search(search_users=username_list) @@ -234,4 +236,3 @@ class LDAPCacheRefreshAPI(generics.RetrieveAPIView): logger.error(str(e)) return Response(data={'msg': str(e)}, status=400) return Response(data={'msg': 'success'}) - diff --git a/apps/settings/serializers/auth/ldap.py b/apps/settings/serializers/auth/ldap.py index 8508d2ee8..8e65d67b7 100644 --- a/apps/settings/serializers/auth/ldap.py +++ b/apps/settings/serializers/auth/ldap.py @@ -1,4 +1,3 @@ - from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers @@ -40,8 +39,9 @@ class LDAPSettingSerializer(serializers.Serializer): help_text=_('eg: ldap://localhost:389') ) AUTH_LDAP_BIND_DN = serializers.CharField(required=False, max_length=1024, label=_('Bind DN')) - AUTH_LDAP_BIND_PASSWORD = serializers.CharField(max_length=1024, write_only=True, required=False, - label=_('Password')) + AUTH_LDAP_BIND_PASSWORD = serializers.CharField( + max_length=1024, write_only=True, required=False, label=_('Password') + ) AUTH_LDAP_SEARCH_OU = serializers.CharField( max_length=1024, allow_blank=True, required=False, label=_('User OU'), help_text=_('Use | split multi OUs') @@ -55,6 +55,9 @@ class LDAPSettingSerializer(serializers.Serializer): help_text=_('User attr map present how to map LDAP user attr to ' 'jumpserver, username,name,email is jumpserver attr') ) + AUTH_LDAP_SYNC_ORG_ID = serializers.CharField( + required=False, label=_('Organization'), max_length=36 + ) AUTH_LDAP_SYNC_IS_PERIODIC = serializers.BooleanField( required=False, label=_('Periodic perform') ) diff --git a/apps/users/tasks.py b/apps/users/tasks.py index a92fc2fb0..0f93fa6c3 100644 --- a/apps/users/tasks.py +++ b/apps/users/tasks.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- # -import sys from celery import shared_task from django.conf import settings @@ -11,6 +10,7 @@ from ops.celery.utils import ( ) from ops.celery.decorator import after_app_ready_start from common.utils import get_logger +from orgs.models import Organization from .models import User from users.notifications import UserExpirationReminderMsg from settings.utils import LDAPServerUtil, LDAPImportUtil @@ -81,7 +81,9 @@ def import_ldap_user(): util_server = LDAPServerUtil() util_import = LDAPImportUtil() users = util_server.search() - errors = util_import.perform_import(users) + org_id = settings.AUTH_LDAP_SYNC_ORG_ID + org = Organization.get_instance(org_id) + errors = util_import.perform_import(users, org) if errors: logger.error("Imported LDAP users errors: {}".format(errors)) else: From f769d5a9bbc5b2efecf71e349f7f12c4e4d6e24c Mon Sep 17 00:00:00 2001 From: feng626 <1304903146@qq.com> Date: Thu, 7 Apr 2022 10:11:16 +0800 Subject: [PATCH 48/59] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=95=B0=E6=8D=AE=E4=B8=8D=E5=90=8C=E6=AD=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/orgs/signal_handlers/cache.py | 48 +++++++++++++++++++++++------- apps/users/models/user.py | 12 ++++---- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/apps/orgs/signal_handlers/cache.py b/apps/orgs/signal_handlers/cache.py index 1d9ca3891..546d11311 100644 --- a/apps/orgs/signal_handlers/cache.py +++ b/apps/orgs/signal_handlers/cache.py @@ -1,33 +1,61 @@ +from functools import wraps from django.db.models.signals import post_save, pre_delete, pre_save, post_delete from django.dispatch import receiver from orgs.models import Organization from assets.models import Node -from perms.models import (AssetPermission, ApplicationPermission) +from perms.models import AssetPermission, ApplicationPermission from users.models import UserGroup, User +from users.signals import pre_user_leave_org from applications.models import Application from terminal.models import Session +from rbac.models import OrgRoleBinding, SystemRoleBinding from assets.models import Asset, SystemUser, Domain, Gateway from orgs.caches import OrgResourceStatisticsCache +from orgs.utils import current_org +from common.utils import get_logger + +logger = get_logger(__name__) -def refresh_user_amount_on_user_create_or_delete(user_id): - orgs = Organization.objects.filter(m2m_org_members__user_id=user_id).distinct() +def refresh_cache(name, org): + names = None + if isinstance(name, (str,)): + names = [name, ] + if isinstance(names, (list, tuple)): + for name in names: + OrgResourceStatisticsCache(org).expire(name) + OrgResourceStatisticsCache(Organization.root()).expire(name) + else: + logger.warning('refresh cache fail: {}'.format(name)) + + +def refresh_user_amount_cache(user): + orgs = user.orgs.distinct() for org in orgs: - org_cache = OrgResourceStatisticsCache(org) - org_cache.expire('users_amount') - OrgResourceStatisticsCache(Organization.root()).expire('users_amount') + refresh_cache('users_amount', org) -@receiver(post_save, sender=User) -def on_user_create_refresh_cache(sender, instance, created, **kwargs): +@receiver(post_save, sender=OrgRoleBinding) +def on_user_create_or_invite_refresh_cache(sender, instance, created, **kwargs): if created: - refresh_user_amount_on_user_create_or_delete(instance.id) + refresh_cache('users_amount', instance.org) + + +@receiver(post_save, sender=SystemRoleBinding) +def on_user_global_create_refresh_cache(sender, instance, created, **kwargs): + if created and current_org.is_root(): + refresh_cache('users_amount', current_org) + + +@receiver(pre_user_leave_org) +def on_user_remove_refresh_cache(sender, org=None, **kwargs): + refresh_cache('users_amount', org) @receiver(pre_delete, sender=User) def on_user_delete_refresh_cache(sender, instance, **kwargs): - refresh_user_amount_on_user_create_or_delete(instance.id) + refresh_user_amount_cache(instance) # @receiver(m2m_changed, sender=OrganizationMember) diff --git a/apps/users/models/user.py b/apps/users/models/user.py index 1a5ce634c..ede795d13 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -78,7 +78,7 @@ class AuthMixin: def is_history_password(self, password): allow_history_password_count = settings.OLD_PASSWORD_HISTORY_LIMIT_COUNT history_passwords = self.history_passwords.all() \ - .order_by('-date_created')[:int(allow_history_password_count)] + .order_by('-date_created')[:int(allow_history_password_count)] for history_password in history_passwords: if check_password(password, history_password.password): @@ -726,7 +726,7 @@ class User(AuthMixin, TokenMixin, RoleMixin, MFAMixin, AbstractUser): @classmethod def get_group_ids_by_user_id(cls, user_id): - group_ids = cls.groups.through.objects.filter(user_id=user_id)\ + group_ids = cls.groups.through.objects.filter(user_id=user_id) \ .distinct().values_list('usergroup_id', flat=True) group_ids = list(group_ids) return group_ids @@ -866,20 +866,20 @@ class User(AuthMixin, TokenMixin, RoleMixin, MFAMixin, AbstractUser): @property def all_orgs(self): from rbac.builtin import BuiltinRole - has_system_role = self.system_roles.all()\ - .exclude(name=BuiltinRole.system_user.name)\ + has_system_role = self.system_roles.all() \ + .exclude(name=BuiltinRole.system_user.name) \ .exists() if has_system_role: orgs = list(Organization.objects.all()) else: - orgs = list(self.orgs.all().distinct()) + orgs = list(self.orgs.distinct()) if self.has_perm('orgs.view_rootorg'): orgs = [Organization.root()] + orgs return orgs @property def my_orgs(self): - return list(self.orgs.all().distinct()) + return list(self.orgs.distinct()) class Meta: ordering = ['username'] From 7c7d7d52b2f4fbad35cdbd5b71ab0f1e4be3286c Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 12 Apr 2022 14:01:57 +0800 Subject: [PATCH 49/59] =?UTF-8?q?perf:=20asset=20number=20=E6=89=A9?= =?UTF-8?q?=E5=AE=B9=20(#8045)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng626 <1304903146@qq.com> --- .../migrations/0090_auto_20220412_1145.py | 18 ++++++++++++++++++ apps/assets/models/asset.py | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 apps/assets/migrations/0090_auto_20220412_1145.py diff --git a/apps/assets/migrations/0090_auto_20220412_1145.py b/apps/assets/migrations/0090_auto_20220412_1145.py new file mode 100644 index 000000000..c2cb879aa --- /dev/null +++ b/apps/assets/migrations/0090_auto_20220412_1145.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.14 on 2022-04-12 03:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0089_auto_20220310_0616'), + ] + + operations = [ + migrations.AlterField( + model_name='asset', + name='number', + field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Asset number'), + ), + ] diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py index c4ecf9cfe..84ddee404 100644 --- a/apps/assets/models/asset.py +++ b/apps/assets/models/asset.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# +# import uuid import logging @@ -223,7 +223,7 @@ class Asset(AbsConnectivity, AbsHardwareInfo, ProtocolsMixin, NodesRelationMixin # Some information public_ip = models.CharField(max_length=128, blank=True, null=True, verbose_name=_('Public IP')) - number = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Asset number')) + number = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Asset number')) labels = models.ManyToManyField('assets.Label', blank=True, related_name='assets', verbose_name=_("Labels")) created_by = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Created by')) From 1f8ded49fa13846cb75ca303e5206a6647a5d3ae Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 12 Apr 2022 14:25:49 +0800 Subject: [PATCH 50/59] =?UTF-8?q?feat:=20=E5=B7=A5=E4=BD=9C=E5=8F=B0?= =?UTF-8?q?=E5=8C=BA=E5=88=86=E7=BB=84=E7=BB=87=20(#8040)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 工作台受组织角色控制 * perf: workspace => workbench * perf: 修改 workspace codename Co-authored-by: ibuler --- apps/authentication/urls/view_urls.py | 1 - apps/jumpserver/views/index.py | 5 +- apps/locale/ja/LC_MESSAGES/django.mo | 2 +- apps/locale/ja/LC_MESSAGES/django.po | 4 +- apps/locale/zh/LC_MESSAGES/django.mo | 2 +- apps/locale/zh/LC_MESSAGES/django.po | 4 +- .../api/application/user_permission/mixin.py | 4 - apps/perms/api/asset/user_permission/mixin.py | 4 - apps/perms/utils/asset/user_permission.py | 8 +- apps/rbac/builtin.py | 3 +- apps/rbac/migrations/0001_initial.py | 2 +- .../migrations/0005_auto_20220307_1524.py | 2 +- .../migrations/0006_auto_20220310_0616.py | 2 +- .../migrations/0008_auto_20220411_1709.py | 22 + .../migrations/0009_auto_20220411_1724.py | 19 + apps/rbac/models/menu.py | 2 +- apps/rbac/tree.py | 16 +- apps/templates/_base_asset_tree_list.html | 54 -- apps/templates/_base_create_update.html | 43 -- apps/templates/_base_list.html | 70 -- apps/templates/_nav.html | 0 apps/templates/_nav_user.html | 0 apps/templates/_pagination.html | 66 -- apps/templates/delete_confirm.html | 15 - apps/templates/index.html | 618 ------------------ apps/terminal/api/session.py | 7 +- apps/tickets/api/relation.py | 7 +- .../templates/users/_base_user_detail.html | 26 - .../templates/users/_granted_assets.html | 222 ------- .../templates/users/_select_user_modal.html | 23 - .../users/_user_detail_nav_header.html | 97 --- .../users/_user_update_pk_modal.html | 8 - apps/users/templates/users/first_login.html | 10 - .../templates/users/first_login_done.html | 54 -- .../users/user_asset_permission.html | 201 ------ .../users/user_database_app_permission.html | 168 ----- .../templates/users/user_password_update.html | 134 ---- apps/users/utils.py | 2 - apps/users/views/profile/reset.py | 7 +- 39 files changed, 77 insertions(+), 1857 deletions(-) create mode 100644 apps/rbac/migrations/0008_auto_20220411_1709.py create mode 100644 apps/rbac/migrations/0009_auto_20220411_1724.py delete mode 100644 apps/templates/_base_asset_tree_list.html delete mode 100644 apps/templates/_base_create_update.html delete mode 100644 apps/templates/_base_list.html delete mode 100644 apps/templates/_nav.html delete mode 100644 apps/templates/_nav_user.html delete mode 100644 apps/templates/_pagination.html delete mode 100644 apps/templates/delete_confirm.html delete mode 100644 apps/templates/index.html delete mode 100644 apps/users/templates/users/_base_user_detail.html delete mode 100644 apps/users/templates/users/_granted_assets.html delete mode 100644 apps/users/templates/users/_select_user_modal.html delete mode 100644 apps/users/templates/users/_user_detail_nav_header.html delete mode 100644 apps/users/templates/users/_user_update_pk_modal.html delete mode 100644 apps/users/templates/users/first_login.html delete mode 100644 apps/users/templates/users/first_login_done.html delete mode 100644 apps/users/templates/users/user_asset_permission.html delete mode 100644 apps/users/templates/users/user_database_app_permission.html delete mode 100644 apps/users/templates/users/user_password_update.html diff --git a/apps/authentication/urls/view_urls.py b/apps/authentication/urls/view_urls.py index 2d0749470..9abd61e3b 100644 --- a/apps/authentication/urls/view_urls.py +++ b/apps/authentication/urls/view_urls.py @@ -55,7 +55,6 @@ urlpatterns = [ path('profile/otp/enable/bind/', users_view.UserOtpEnableBindView.as_view(), name='user-otp-enable-bind'), path('profile/otp/disable/', users_view.UserOtpDisableView.as_view(), name='user-otp-disable'), - path('first-login/', users_view.UserFirstLoginView.as_view(), name='user-first-login'), # openid path('cas/', include(('authentication.backends.cas.urls', 'authentication'), namespace='cas')), diff --git a/apps/jumpserver/views/index.py b/apps/jumpserver/views/index.py index 8f974a483..639f6d683 100644 --- a/apps/jumpserver/views/index.py +++ b/apps/jumpserver/views/index.py @@ -1,4 +1,4 @@ -from django.views.generic import TemplateView +from django.views.generic import View from django.shortcuts import redirect from common.permissions import IsValidUser from common.mixins.views import PermissionsMixin @@ -6,8 +6,7 @@ from common.mixins.views import PermissionsMixin __all__ = ['IndexView'] -class IndexView(PermissionsMixin, TemplateView): - template_name = 'index.html' +class IndexView(PermissionsMixin, View): permission_classes = [IsValidUser] def get(self, request, *args, **kwargs): diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index 663dad9e1..080e2ab5e 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:17e378f009274c169039e815158ea9072ee89811bb27a5b17a628f2066fcfb86 +oid sha256:097c6d06ed8dcf2e1807560b6eb52d98cba31f25fe8d67ce4315668c150ca6b8 size 129989 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index cc8a3b317..757d1e463 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -3188,7 +3188,7 @@ msgid "Can view audit view" msgstr "監査ビューを表示できます" #: rbac/models/menu.py:17 -msgid "Can view workspace view" +msgid "Can view workbench view" msgstr "ワークスペースビューを表示できます" #: rbac/models/menu.py:18 @@ -3271,7 +3271,7 @@ msgid "Console view" msgstr "コンソールビュー" #: rbac/tree.py:27 -msgid "Workspace view" +msgid "Workbench view" msgstr "ワークスペースビュー" #: rbac/tree.py:28 diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 944990cc4..88f701b6b 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:51c19db490e2e3a7cc3c3fce33b2e4422239d8c64d591208cadaf062c5ccb0c9 +oid sha256:3d6a0d40534209f3ffab0b0ecfab7ec82f137156fc8e7b19ce1711036d14aeca size 107709 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 68b8a566c..fb29c7d9c 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -3151,7 +3151,7 @@ msgid "Can view audit view" msgstr "可以显示审计台" #: rbac/models/menu.py:17 -msgid "Can view workspace view" +msgid "Can view workbench view" msgstr "可以显示工作台" #: rbac/models/menu.py:18 @@ -3233,7 +3233,7 @@ msgid "Console view" msgstr "控制台" #: rbac/tree.py:27 -msgid "Workspace view" +msgid "Workbench view" msgstr "工作台" #: rbac/tree.py:28 diff --git a/apps/perms/api/application/user_permission/mixin.py b/apps/perms/api/application/user_permission/mixin.py index b66788c31..6e8f91090 100644 --- a/apps/perms/api/application/user_permission/mixin.py +++ b/apps/perms/api/application/user_permission/mixin.py @@ -22,7 +22,3 @@ class AppRoleUserMixin(_RoleUserMixin): ('get_tree', 'perms.view_myapps'), ('GET', 'perms.view_myapps'), ) - - def dispatch(self, *args, **kwargs): - with tmp_to_root_org(): - return super().dispatch(*args, **kwargs) \ No newline at end of file diff --git a/apps/perms/api/asset/user_permission/mixin.py b/apps/perms/api/asset/user_permission/mixin.py index e06ec9787..c28da6c2d 100644 --- a/apps/perms/api/asset/user_permission/mixin.py +++ b/apps/perms/api/asset/user_permission/mixin.py @@ -36,7 +36,3 @@ class AssetRoleUserMixin(PermBaseMixin, _RoleUserMixin): ('get_tree', 'perms.view_myassets'), ('GET', 'perms.view_myassets'), ) - - def dispatch(self, *args, **kwargs): - with tmp_to_root_org(): - return super().dispatch(*args, **kwargs) diff --git a/apps/perms/utils/asset/user_permission.py b/apps/perms/utils/asset/user_permission.py index 1ea189230..5baa93d01 100644 --- a/apps/perms/utils/asset/user_permission.py +++ b/apps/perms/utils/asset/user_permission.py @@ -202,7 +202,9 @@ class UserGrantedTreeRefreshController: user = self.user with tmp_to_root_org(): - UserAssetGrantedTreeNodeRelation.objects.filter(user=user).exclude(org_id__in=self.org_ids).delete() + UserAssetGrantedTreeNodeRelation.objects.filter(user=user)\ + .exclude(org_id__in=self.org_ids)\ + .delete() if force or self.have_need_refresh_orgs(): with UserGrantedTreeRebuildLock(user_id=user.id): @@ -219,7 +221,9 @@ class UserGrantedTreeRefreshController: utils = UserGrantedTreeBuildUtils(user) utils.rebuild_user_granted_tree() logger.info( - f'Rebuild user tree ok: cost={time.time() - t_start} user={self.user} org={current_org}') + f'Rebuild user tree ok: cost={time.time() - t_start} ' + f'user={self.user} org={current_org}' + ) class UserGrantedUtilsBase: diff --git a/apps/rbac/builtin.py b/apps/rbac/builtin.py index ce735ce8f..4ce706a46 100644 --- a/apps/rbac/builtin.py +++ b/apps/rbac/builtin.py @@ -5,7 +5,7 @@ from .const import Scope, system_exclude_permissions, org_exclude_permissions # Todo: 获取应该区分 系统用户,和组织用户的权限 # 工作台也区分组织后再考虑 user_perms = ( - ('rbac', 'menupermission', 'view', 'workspace'), + ('rbac', 'menupermission', 'view', 'workbench'), ('rbac', 'menupermission', 'view', 'webterminal'), ('rbac', 'menupermission', 'view', 'filemanager'), ('perms', 'permedasset', 'view,connect', 'myassets'), @@ -17,6 +17,7 @@ user_perms = ( ('ops', 'commandexecution', 'add', 'commandexecution'), ('authentication', 'connectiontoken', 'add', 'connectiontoken'), ('tickets', 'ticket', 'view', 'ticket'), + ('orgs', 'organization', 'view', 'rootorg'), ) auditor_perms = user_perms + ( diff --git a/apps/rbac/migrations/0001_initial.py b/apps/rbac/migrations/0001_initial.py index 5687bf574..d3f94f6f2 100644 --- a/apps/rbac/migrations/0001_initial.py +++ b/apps/rbac/migrations/0001_initial.py @@ -27,7 +27,7 @@ class Migration(migrations.Migration): ], options={ 'verbose_name': 'Menu permission', - 'permissions': [('view_console', 'Can view console view'), ('view_audit', 'Can view audit view'), ('view_workspace', 'Can view workspace view')], + 'permissions': [('view_console', 'Can view console view'), ('view_audit', 'Can view audit view'), ('view_workspace', 'Can view workbench view')], 'default_permissions': [], }, ), diff --git a/apps/rbac/migrations/0005_auto_20220307_1524.py b/apps/rbac/migrations/0005_auto_20220307_1524.py index afc8ea8ba..ba4427709 100644 --- a/apps/rbac/migrations/0005_auto_20220307_1524.py +++ b/apps/rbac/migrations/0005_auto_20220307_1524.py @@ -12,6 +12,6 @@ class Migration(migrations.Migration): operations = [ migrations.AlterModelOptions( name='menupermission', - options={'default_permissions': [], 'permissions': [('view_console', 'Can view console view'), ('view_audit', 'Can view audit view'), ('view_workspace', 'Can view workspace view'), ('view_webterminal', 'Can view web terminal'), ('view_filemanager', 'Can view file manager')], 'verbose_name': 'Menu permission'}, + options={'default_permissions': [], 'permissions': [('view_console', 'Can view console view'), ('view_audit', 'Can view audit view'), ('view_workspace', 'Can view workbench view'), ('view_webterminal', 'Can view web terminal'), ('view_filemanager', 'Can view file manager')], 'verbose_name': 'Menu permission'}, ), ] diff --git a/apps/rbac/migrations/0006_auto_20220310_0616.py b/apps/rbac/migrations/0006_auto_20220310_0616.py index 395b73f03..7e3ba72de 100644 --- a/apps/rbac/migrations/0006_auto_20220310_0616.py +++ b/apps/rbac/migrations/0006_auto_20220310_0616.py @@ -12,6 +12,6 @@ class Migration(migrations.Migration): operations = [ migrations.AlterModelOptions( name='menupermission', - options={'default_permissions': [], 'permissions': [('view_console', 'Can view console view'), ('view_audit', 'Can view audit view'), ('view_workspace', 'Can view workspace view'), ('view_webterminal', 'Can view web terminal'), ('view_filemanager', 'Can view file manager') ], 'verbose_name': 'Menu permission'}, + options={'default_permissions': [], 'permissions': [('view_console', 'Can view console view'), ('view_audit', 'Can view audit view'), ('view_workspace', 'Can view workbench view'), ('view_webterminal', 'Can view web terminal'), ('view_filemanager', 'Can view file manager') ], 'verbose_name': 'Menu permission'}, ), ] diff --git a/apps/rbac/migrations/0008_auto_20220411_1709.py b/apps/rbac/migrations/0008_auto_20220411_1709.py new file mode 100644 index 000000000..319fa5a37 --- /dev/null +++ b/apps/rbac/migrations/0008_auto_20220411_1709.py @@ -0,0 +1,22 @@ +# Generated by Django 3.1.14 on 2022-04-11 09:09 + +from django.db import migrations + + +def migrate_workspace_to_workbench(apps, *args): + model = apps.get_model('auth', 'Permission') + model.objects.filter(codename='view_workspace').delete() + + +class Migration(migrations.Migration): + + dependencies = [ + ('rbac', '0007_auto_20220314_1525'), + ] + + operations = [ + migrations.AlterModelOptions( + name='menupermission', + options={'default_permissions': [], 'permissions': [('view_console', 'Can view console view'), ('view_audit', 'Can view audit view'), ('view_workbench', 'Can view workbench view'), ('view_webterminal', 'Can view web terminal'), ('view_filemanager', 'Can view file manager')], 'verbose_name': 'Menu permission'}, + ), + ] diff --git a/apps/rbac/migrations/0009_auto_20220411_1724.py b/apps/rbac/migrations/0009_auto_20220411_1724.py new file mode 100644 index 000000000..4ffb51068 --- /dev/null +++ b/apps/rbac/migrations/0009_auto_20220411_1724.py @@ -0,0 +1,19 @@ +# Generated by Django 3.1.14 on 2022-04-11 09:24 + +from django.db import migrations + + +def migrate_workspace_to_workbench(apps, *args): + model = apps.get_model('auth', 'Permission') + model.objects.filter(codename='view_workspace').delete() + + +class Migration(migrations.Migration): + + dependencies = [ + ('rbac', '0008_auto_20220411_1709'), + ] + + operations = [ + migrations.RunPython(migrate_workspace_to_workbench) + ] diff --git a/apps/rbac/models/menu.py b/apps/rbac/models/menu.py index 524894664..48538199b 100644 --- a/apps/rbac/models/menu.py +++ b/apps/rbac/models/menu.py @@ -14,7 +14,7 @@ class MenuPermission(models.Model): permissions = [ ('view_console', _('Can view console view')), ('view_audit', _('Can view audit view')), - ('view_workspace', _('Can view workspace view')), + ('view_workbench', _('Can view workbench view')), ('view_webterminal', _('Can view web terminal')), ('view_filemanager', _('Can view file manager')), ] diff --git a/apps/rbac/tree.py b/apps/rbac/tree.py index 5ea43e5ee..dfccafa8f 100644 --- a/apps/rbac/tree.py +++ b/apps/rbac/tree.py @@ -1,7 +1,7 @@ #!/usr/bin/python +import os from collections import defaultdict from typing import Callable -import os from django.utils.translation import gettext_lazy as _, gettext, get_language from django.conf import settings @@ -24,7 +24,7 @@ root_node_data = { # 第二层 view 节点,手动创建的 view_nodes_data = [ {'id': 'view_console', 'name': _('Console view')}, - {'id': 'view_workspace', 'name': _('Workspace view')}, + {'id': 'view_workbench', 'name': _('Workbench view')}, {'id': 'view_audit', 'name': _('Audit view')}, {'id': 'view_setting', 'name': _('System setting')}, {'id': 'view_other', 'name': _('Other')}, @@ -55,8 +55,8 @@ extra_nodes_data = [ {"id": "app_change_plan_node", "name": _("App change auth"), "pId": "accounts"}, {"id": "asset_change_plan_node", "name": _("Asset change auth"), "pId": "accounts"}, {"id": "terminal_node", "name": _("Terminal setting"), "pId": "view_setting"}, - {'id': "my_assets", "name": _("My assets"), "pId": "view_workspace"}, - {'id': "my_apps", "name": _("My apps"), "pId": "view_workspace"}, + {'id': "my_assets", "name": _("My assets"), "pId": "view_workbench"}, + {'id': "my_apps", "name": _("My apps"), "pId": "view_workbench"}, ] # 将 model 放到其它节点下,而不是本来的 app 中 @@ -89,7 +89,7 @@ special_pid_mapper = { 'audits.ftplog': 'terminal', 'perms.view_myassets': 'my_assets', 'perms.view_myapps': 'my_apps', - 'ops.add_commandexecution': 'view_workspace', + 'ops.add_commandexecution': 'view_workbench', 'ops.view_commandexecution': 'audits', "perms.view_mykubernetsapp": "my_apps", "perms.connect_mykubernetsapp": "my_apps", @@ -102,9 +102,9 @@ special_pid_mapper = { "settings.view_setting": "view_setting", "rbac.view_console": "view_console", "rbac.view_audit": "view_audit", - "rbac.view_workspace": "view_workspace", - "rbac.view_webterminal": "view_workspace", - "rbac.view_filemanager": "view_workspace", + "rbac.view_workbench": "view_workbench", + "rbac.view_webterminal": "view_workbench", + "rbac.view_filemanager": "view_workbench", 'tickets.view_ticket': 'tickets' } diff --git a/apps/templates/_base_asset_tree_list.html b/apps/templates/_base_asset_tree_list.html deleted file mode 100644 index a989a4da1..000000000 --- a/apps/templates/_base_asset_tree_list.html +++ /dev/null @@ -1,54 +0,0 @@ -{% extends 'base.html' %} -{% load static %} -{% load i18n %} - -{% block help_message %} -{% endblock %} - -{% block content %} -
    -
    -
    - {% include 'assets/_node_tree.html' %} -
    -
    -
    -
    - -
    -
    -
    - {% block table_container %} - - - - {% block table_head %} {% endblock %} - - - - {% block table_body %} {% endblock %} - -
    - {% endblock %} -
    -
    -
    -
    - -{% endblock %} diff --git a/apps/templates/_base_create_update.html b/apps/templates/_base_create_update.html deleted file mode 100644 index d206d40b2..000000000 --- a/apps/templates/_base_create_update.html +++ /dev/null @@ -1,43 +0,0 @@ -{% extends 'base.html' %} -{% load i18n %} -{% load static %} -{% load bootstrap3 %} -{% block custom_head_css_js %} - - {% block custom_head_css_js_create %} {% endblock %} -{% endblock %} - -{% block content %} -
    -
    -
    -
    -
    -
    {{ action }}
    - -
    -
    - {% if form.errors.all %} -
    - {{ form.errors.all }} -
    - {% endif %} - {% block form %} - {% endblock %} -
    -
    -
    -
    -
    -{% endblock %} - diff --git a/apps/templates/_base_list.html b/apps/templates/_base_list.html deleted file mode 100644 index 9759081bd..000000000 --- a/apps/templates/_base_list.html +++ /dev/null @@ -1,70 +0,0 @@ -{% extends 'base.html' %} -{% load static %} -{% load i18n %} -{% block content %} -
    -
    -
    -
    -
    -
    - {{ action }} -
    - -
    -
    -
    - {% block content_left_head %} {% endblock %} - {% block table_search %} - - {% endblock %} -
    - {% block table_container %} - - - - {% block table_head %} {% endblock %} - - - - {% block table_body %} {% endblock %} - -
    - {% endblock %} -
    -
    - {% block content_bottom_left %} {% endblock %} -
    - {% block table_pagination %} - {% include '_pagination.html' %} - {% endblock %} -
    -
    -
    -
    -
    -
    -{% endblock %} diff --git a/apps/templates/_nav.html b/apps/templates/_nav.html deleted file mode 100644 index e69de29bb..000000000 diff --git a/apps/templates/_nav_user.html b/apps/templates/_nav_user.html deleted file mode 100644 index e69de29bb..000000000 diff --git a/apps/templates/_pagination.html b/apps/templates/_pagination.html deleted file mode 100644 index cf23b04fa..000000000 --- a/apps/templates/_pagination.html +++ /dev/null @@ -1,66 +0,0 @@ -{% load i18n %} -{% load common_tags %} - {% if is_paginated %} -
    -
    -{# 显示第 {{ page_obj.start_index }} 至 {{ page_obj.end_index }} 项结果,共 {{ paginator.count }} 项#} -
    -
    -
    -
    -
      - {% if page_obj.has_previous %} - - {% endif %} - - {% for page in paginator.num_pages|pagination_range:page_obj.number %} - {% if page == page_obj.number %} -
    • - {% else %} -
    • - {% endif %} - {{ page }} -
    • - {% endfor %} - - {% if page_obj.has_next %} - - {% endif %} -
    -
    -
    - {% endif %} - diff --git a/apps/templates/delete_confirm.html b/apps/templates/delete_confirm.html deleted file mode 100644 index 94f017ca2..000000000 --- a/apps/templates/delete_confirm.html +++ /dev/null @@ -1,15 +0,0 @@ -{% load i18n %} - - - - - {% trans 'Confirm delete' %} - - -
    - {% csrf_token %} -

    {% trans 'Are you sure delete' %} {{ object.name }} ?

    - -
    - - \ No newline at end of file diff --git a/apps/templates/index.html b/apps/templates/index.html deleted file mode 100644 index a216ddac8..000000000 --- a/apps/templates/index.html +++ /dev/null @@ -1,618 +0,0 @@ -{% extends 'base.html' %} -{% load i18n %} -{% load static %} -{% block content %} -
    -
    -
    -
    -
    - Users -
    {% trans 'Total users' %}
    -
    -
    -

    - All users -
    -
    -
    -
    -
    -
    - Assets -
    {% trans 'Total assets' %}
    -
    -
    -

    - All assets -
    -
    -
    - -
    -
    -
    - Online -
    {% trans 'Online users' %}
    -
    -
    -

    - Online users -
    -
    -
    - -
    -
    -
    - Connected -
    {% trans 'Online sessions' %}
    - -
    -
    -

    - Online sessions -
    -
    -
    -
    -
    -
    - {% trans 'In the past week, a total of ' %}{% trans ' users have logged in ' %}{% trans ' times asset.' %} -
      -
    -
    -
    -
    -
    -

    - {% trans 'Active user asset ratio' %} -

    -

    - {% trans 'The following graphs describe the percentage of active users per month and assets per user host per month, respectively.' %} -

    -
    -
    -
    -
    -
    {% trans 'User' %}
    -
    -
    -
    -
    {% trans 'Asset' %}
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    {% trans 'Top 10 assets in a week' %}
    - -
    -
    -

    {% trans 'Top 10 assets in a week'%}

    - {% trans 'Login frequency and last login record.' %} -
    -
    -
    -
    -
    -
    -
    -
    -
    {% trans 'Last 10 login' %}
    -
    - 10 Messages -
    -
    -
    -

    {% trans 'Login record' %}

    - {% trans 'Last 10 login records.' %} -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    {% trans 'Top 10 users in a week' %}
    - -
    -
    -

    {% trans 'Top 10 users in a week' %}

    - {% trans 'User login frequency and last login record.' %} -
    -
    -
    -
    -
    -
    -
    - -{% endblock %} - -{% block custom_foot_js %} - - - -{% endblock %} diff --git a/apps/terminal/api/session.py b/apps/terminal/api/session.py index c78d48383..3193956e5 100644 --- a/apps/terminal/api/session.py +++ b/apps/terminal/api/session.py @@ -42,10 +42,9 @@ class MySessionAPIView(generics.ListAPIView): serializer_class = serializers.SessionSerializer def get_queryset(self): - with tmp_to_root_org(): - user = self.request.user - qs = Session.objects.filter(user_id=user.id) - return qs + user = self.request.user + qs = Session.objects.filter(user_id=user.id) + return qs class SessionViewSet(OrgBulkModelViewSet): diff --git a/apps/tickets/api/relation.py b/apps/tickets/api/relation.py index 2dfa33146..5061e6c00 100644 --- a/apps/tickets/api/relation.py +++ b/apps/tickets/api/relation.py @@ -24,10 +24,11 @@ class TicketSessionApi(views.APIView): def get(self, request, *args, **kwargs): with tmp_to_root_org(): - ticketsession = TicketSession.objects.filter(ticket=self.kwargs['ticket_id']).first() - if not ticketsession: + tid = self.kwargs['ticket_id'] + ticket_session = TicketSession.objects.filter(ticket=tid).first() + if not ticket_session: return Response(status=status.HTTP_404_NOT_FOUND) - session = ticketsession.session + session = ticket_session.session serializer = SessionSerializer(session) return Response(serializer.data) diff --git a/apps/users/templates/users/_base_user_detail.html b/apps/users/templates/users/_base_user_detail.html deleted file mode 100644 index 936037ab8..000000000 --- a/apps/users/templates/users/_base_user_detail.html +++ /dev/null @@ -1,26 +0,0 @@ -{% extends 'base.html' %} -{% load static %} -{% load i18n %} - -{% block content %} -
    -
    -
    -
    -
    - -
    -
    - {% block content_table %} - {% endblock %} -
    -
    -
    -
    -
    -{% endblock %} diff --git a/apps/users/templates/users/_granted_assets.html b/apps/users/templates/users/_granted_assets.html deleted file mode 100644 index 9d5006910..000000000 --- a/apps/users/templates/users/_granted_assets.html +++ /dev/null @@ -1,222 +0,0 @@ -{% load i18n %} -
    -
    -
    -
    -
    - {% trans 'Loading' %} ... -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    - - - - - - - - {% if show_actions %} - - {% endif %} - - - - -
    {% trans 'Hostname' %}{% trans 'IP' %}{% trans 'System user' %}{% trans 'Action' %}
    -
    -
    - diff --git a/apps/users/templates/users/_select_user_modal.html b/apps/users/templates/users/_select_user_modal.html deleted file mode 100644 index 5395b0a05..000000000 --- a/apps/users/templates/users/_select_user_modal.html +++ /dev/null @@ -1,23 +0,0 @@ -{% extends '_modal.html' %} -{% load i18n %} -{% block modal_class %}modal-lg{% endblock %} -{% block modal_id %}select_user_modal{% endblock %} -{% block modal_title%}{% trans "Please Select User" %}{% endblock %} -{% block modal_body %} - - - - - - - - - - - - -
    -
    -
    {% trans 'Name' %}{% trans 'Username' %}{% trans 'Role' %}{% trans 'User group' %}{% trans 'Asset num' %}{% trans 'Active' %}
    -{% endblock %} -{% block modal_confirm_id %}btn_select_user{% endblock %} diff --git a/apps/users/templates/users/_user_detail_nav_header.html b/apps/users/templates/users/_user_detail_nav_header.html deleted file mode 100644 index 28079e149..000000000 --- a/apps/users/templates/users/_user_detail_nav_header.html +++ /dev/null @@ -1,97 +0,0 @@ -{% load static %} -{% load i18n %} - - - -
  • - {% trans 'User detail' %} -
  • -
  • - - {% trans "User permissions" %} - - - - -
  • - - \ No newline at end of file diff --git a/apps/users/templates/users/_user_update_pk_modal.html b/apps/users/templates/users/_user_update_pk_modal.html deleted file mode 100644 index a7ed525c4..000000000 --- a/apps/users/templates/users/_user_update_pk_modal.html +++ /dev/null @@ -1,8 +0,0 @@ -{% extends '_modal.html' %} -{% load i18n %} -{% block modal_id %}user_update_pk_modal{% endblock %} -{% block modal_title%}{% trans "Update User SSH Public Key" %}{% endblock %} -{% block modal_body %} - -{% endblock %} -{% block modal_confirm_id %}btn_user_update_pk{% endblock %} diff --git a/apps/users/templates/users/first_login.html b/apps/users/templates/users/first_login.html deleted file mode 100644 index bffa2fc0e..000000000 --- a/apps/users/templates/users/first_login.html +++ /dev/null @@ -1,10 +0,0 @@ -{% extends '_base_only_content.html' %} -{% load static %} -{% load i18n %} -{% load bootstrap3 %} - -{% block title %} {% trans 'First Login' %} {% endblock %} - -{% block content %} - 使用UI重构这个页面 -{% endblock %} diff --git a/apps/users/templates/users/first_login_done.html b/apps/users/templates/users/first_login_done.html deleted file mode 100644 index ae43d032b..000000000 --- a/apps/users/templates/users/first_login_done.html +++ /dev/null @@ -1,54 +0,0 @@ -{% extends 'base.html' %} -{% load static %} -{% load i18n %} -{% load bootstrap3 %} - - -{% block custom_head_css_js %} -{{ wizard.form.media }} - -{% endblock %} -{% block first_login_message %}{% endblock %} - -{% block content %} -
    -
    -
    -
    -
    -
    {% trans 'First Login' %}
    - -
    -
    -
    - {% trans 'Welcome to use jumpserver, visit ' %} - {% trans 'Use guide' %} {% trans ' for more information' %} -
    -
    -
    -
    -
    -
    -{% endblock %} - - -{% block custom_foot_js %} - -{% endblock %} diff --git a/apps/users/templates/users/user_asset_permission.html b/apps/users/templates/users/user_asset_permission.html deleted file mode 100644 index d0975f4b8..000000000 --- a/apps/users/templates/users/user_asset_permission.html +++ /dev/null @@ -1,201 +0,0 @@ -{% extends 'users/_base_user_detail.html' %} -{% load static %} -{% load i18n %} - -{% block custom_head_css_js %} - - -{% endblock %} - - -{% block content_table %} -
    -
    -
    - {{ object.name }} -
    - - - - - - - - - - -
    -
    -
    - - - - - - - - - - - - - - - - -
    {% trans 'Name' %}{% trans 'User' %}{% trans 'User group' %}{% trans 'Asset' %}{% trans 'Node' %}{% trans 'System user' %}{% trans 'Validity' %}{% trans 'Action' %}
    -
    -
    -
    - -{% include '_filter_dropdown.html' %} - -{% endblock %} - -{% block custom_foot_js %} - -{% endblock %} diff --git a/apps/users/templates/users/user_database_app_permission.html b/apps/users/templates/users/user_database_app_permission.html deleted file mode 100644 index 73b3a7972..000000000 --- a/apps/users/templates/users/user_database_app_permission.html +++ /dev/null @@ -1,168 +0,0 @@ -{% extends 'users/_base_user_detail.html' %} -{% load static %} -{% load i18n %} - -{% block custom_head_css_js %} - - -{% endblock %} - -{% block content_table %} -
    -
    -
    - {{ object.name }} -
    - - - - - - - - - - -
    -
    -
    - - - - - - - - - - - - - - - -
    {% trans 'Name' %}{% trans 'User' %}{% trans 'User group' %}{% trans 'DatabaseApp' %}{% trans 'System user' %}{% trans 'Validity' %}{% trans 'Action' %}
    -
    -
    -
    -{% endblock %} - -{% block custom_foot_js %} - -{% endblock %} diff --git a/apps/users/templates/users/user_password_update.html b/apps/users/templates/users/user_password_update.html deleted file mode 100644 index 97bc044d6..000000000 --- a/apps/users/templates/users/user_password_update.html +++ /dev/null @@ -1,134 +0,0 @@ -{% extends 'base.html' %} -{% load static %} -{% load i18n %} -{% load bootstrap3 %} - -{% block custom_head_css_js %} - - - - - - - -{% endblock %} -{% block content %} -
    -
    -
    -
    -
    - -
    -
    -
    -
    - {% csrf_token %} - {% bootstrap_field form.old_password layout="horizontal" %} - {% bootstrap_field form.new_password layout="horizontal" %} - {# 密码popover #} -
    - -
    - {% bootstrap_field form.confirm_password layout="horizontal" %} - -
    -
    -
    - - -
    -
    -
    -
    -
    -
    -
    -
    -
    -{% endblock %} - -{% block custom_foot_js %} - - -{% endblock %} diff --git a/apps/users/utils.py b/apps/users/utils.py index b32b0c0e0..f11d233e4 100644 --- a/apps/users/utils.py +++ b/apps/users/utils.py @@ -46,8 +46,6 @@ def get_user_or_pre_auth_user(request): def redirect_user_first_login_or_index(request, redirect_field_name): - # if request.user.is_first_login: - # return reverse('authentication:user-first-login') url_in_post = request.POST.get(redirect_field_name) if url_in_post: return url_in_post diff --git a/apps/users/views/profile/reset.py b/apps/users/views/profile/reset.py index c3529c73c..cc14f6d53 100644 --- a/apps/users/views/profile/reset.py +++ b/apps/users/views/profile/reset.py @@ -21,7 +21,7 @@ from ... import forms __all__ = [ - 'UserLoginView', 'UserResetPasswordView', 'UserForgotPasswordView', 'UserFirstLoginView', + 'UserLoginView', 'UserResetPasswordView', 'UserForgotPasswordView', ] @@ -130,8 +130,3 @@ class UserResetPasswordView(FormView): 'auto_redirect': True, } return FlashMessageUtil.gen_message_url(message_data) - - -class UserFirstLoginView(PermissionsMixin, TemplateView): - template_name = 'users/first_login.html' - permission_classes = [IsValidUser] From ffd98c6e3f409fd48ac7efc563356c8fc9481426 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 12 Apr 2022 15:11:51 +0800 Subject: [PATCH 51/59] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=20import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/utils.py | 3 +-- apps/terminal/api/terminal.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/authentication/utils.py b/apps/authentication/utils.py index 6dc3866fe..cf4ce8185 100644 --- a/apps/authentication/utils.py +++ b/apps/authentication/utils.py @@ -9,8 +9,7 @@ from django.conf import settings from .notifications import DifferentCityLoginMessage from audits.models import UserLoginLog from audits.const import DEFAULT_CITY -from common.utils import get_request_ip -from common.utils import validate_ip, get_ip_city +from common.utils import validate_ip, get_ip_city, get_request_ip from common.utils import get_logger logger = get_logger(__file__) diff --git a/apps/terminal/api/terminal.py b/apps/terminal/api/terminal.py index f3fa8f5d0..209492baa 100644 --- a/apps/terminal/api/terminal.py +++ b/apps/terminal/api/terminal.py @@ -12,7 +12,7 @@ from django.utils.translation import gettext_lazy as _ from common.exceptions import JMSException from common.drf.api import JMSBulkModelViewSet -from common.utils import get_object_or_none +from common.utils import get_object_or_none, get_request_ip from common.permissions import WithBootstrapToken from ..models import Terminal from .. import serializers From 4cf90df17ca174ef1a107bf9a114cdef0ca0763e Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 12 Apr 2022 15:19:59 +0800 Subject: [PATCH 52/59] =?UTF-8?q?perf:=20=E9=BB=98=E8=AE=A4=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E6=B7=BB=E5=8A=A0=20created=20by?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/rbac/builtin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/rbac/builtin.py b/apps/rbac/builtin.py index 4ce706a46..513ec210a 100644 --- a/apps/rbac/builtin.py +++ b/apps/rbac/builtin.py @@ -79,7 +79,7 @@ class PredefineRole: perms = self.default_perms defaults = { 'id': self.id, 'name': self.name, 'scope': self.scope, - 'builtin': True, 'permissions': perms + 'builtin': True, 'permissions': perms, 'created_by': 'System', } return defaults From f481463c64553490e0f1d43e55f35ef94b7a30f6 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 12 Apr 2022 17:45:10 +0800 Subject: [PATCH 53/59] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0Endpoint=20(#80?= =?UTF-8?q?41)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add Endpoint EndpointRule EndpointProtocol model * feat: add Endpoint EndpointRule EndpointProtocol API * feat: modify protocols field * feat: 修改序列类 * feat: 获取connect-url连接地址 * feat: 获取connect-url连接地址 * feat: 优化后台获取smart-endpoint逻辑 * feat: 优化后台获取smart-endpoint逻辑 * feat: 删除配置KOKO、XRDP、MAGNUS * feat: 删除配置KOKO、XRDP、MAGNUS * feat: 修改翻译 * feat: 修改smart endpoint * feat: 修改翻译 * feat: smart API 添加token解析 * feat: 删除 smart serializer * feat: 修改迁移逻辑 * feat: 解决冲突 * feat: 修改匹配 endpoint Co-authored-by: Jiangjie.Bai --- apps/applications/models/application.py | 20 + apps/assets/models/asset.py | 3 + apps/authentication/api/connection_token.py | 30 +- apps/common/fields/model.py | 14 +- apps/jumpserver/conf.py | 14 +- apps/jumpserver/settings/custom.py | 11 - apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 628 +++++------------ apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 634 +++++------------- apps/settings/api/public.py | 7 - apps/settings/serializers/terminal.py | 30 +- apps/terminal/api/__init__.py | 1 + apps/terminal/api/endpoint.py | 78 +++ .../migrations/0048_endpoint_endpointrule.py | 86 +++ apps/terminal/models/__init__.py | 1 + apps/terminal/models/endpoint.py | 94 +++ apps/terminal/models/session.py | 9 + apps/terminal/serializers/__init__.py | 1 + apps/terminal/serializers/endpoint.py | 51 ++ apps/terminal/urls/api_urls.py | 2 + 21 files changed, 695 insertions(+), 1027 deletions(-) create mode 100644 apps/terminal/api/endpoint.py create mode 100644 apps/terminal/migrations/0048_endpoint_endpointrule.py create mode 100644 apps/terminal/models/endpoint.py create mode 100644 apps/terminal/serializers/endpoint.py diff --git a/apps/applications/models/application.py b/apps/applications/models/application.py index aa2d56f70..15e7dae14 100644 --- a/apps/applications/models/application.py +++ b/apps/applications/models/application.py @@ -247,6 +247,14 @@ class Application(CommonModelMixin, OrgModelMixin, ApplicationTreeNodeMixin): def category_remote_app(self): return self.category == const.AppCategory.remote_app.value + @property + def category_cloud(self): + return self.category == const.AppCategory.cloud.value + + @property + def category_db(self): + return self.category == const.AppCategory.db.value + def get_rdp_remote_app_setting(self): from applications.serializers.attrs import get_serializer_class_by_application_type if not self.category_remote_app: @@ -279,6 +287,18 @@ class Application(CommonModelMixin, OrgModelMixin, ApplicationTreeNodeMixin): if raise_exception: raise ValueError("Remote App not has asset attr") + def get_target_ip(self): + if self.category_remote_app: + asset = self.get_remote_app_asset() + target_ip = asset.ip + elif self.category_cloud: + target_ip = self.attrs.get('cluster') + elif self.category_db: + target_ip = self.attrs.get('host') + else: + target_ip = '' + return target_ip + class ApplicationUser(SystemUser): class Meta: diff --git a/apps/assets/models/asset.py b/apps/assets/models/asset.py index 84ddee404..c80c65ce6 100644 --- a/apps/assets/models/asset.py +++ b/apps/assets/models/asset.py @@ -235,6 +235,9 @@ class Asset(AbsConnectivity, AbsHardwareInfo, ProtocolsMixin, NodesRelationMixin def __str__(self): return '{0.hostname}({0.ip})'.format(self) + def get_target_ip(self): + return self.ip + def set_admin_user_relation(self): from .authbook import AuthBook if not self.admin_user: diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index f8c64e417..3e905076c 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -31,12 +31,13 @@ from perms.models.base import Action from perms.utils.application.permission import get_application_actions from perms.utils.asset.permission import get_asset_actions from common.const.http import PATCH +from terminal.models import EndpointRule from ..serializers import ( ConnectionTokenSerializer, ConnectionTokenSecretSerializer, ) logger = get_logger(__name__) -__all__ = ['UserConnectionTokenViewSet'] +__all__ = ['UserConnectionTokenViewSet', 'TokenCacheMixin'] class ClientProtocolMixin: @@ -51,6 +52,17 @@ class ClientProtocolMixin: request: Request get_serializer: Callable create_token: Callable + get_serializer_context: Callable + + def get_smart_endpoint(self, protocol, asset=None, application=None): + if asset: + target_ip = asset.get_target_ip() + elif application: + target_ip = application.get_target_ip() + else: + target_ip = '' + endpoint = EndpointRule.match_endpoint(target_ip, protocol, self.request) + return endpoint def get_request_resource(self, serializer): asset = serializer.validated_data.get('asset') @@ -122,10 +134,10 @@ class ClientProtocolMixin: options['screen mode id:i'] = '2' if full_screen else '1' # RDP Server 地址 - address = settings.TERMINAL_RDP_ADDR - if not address or address == 'localhost:3389': - address = self.request.get_host().split(':')[0] + ':3389' - options['full address:s'] = address + endpoint = self.get_smart_endpoint( + protocol='rdp', asset=asset, application=application + ) + options['full address:s'] = f'{endpoint.host}:{endpoint.rdp_port}' # 用户名 options['username:s'] = '{}|{}'.format(user.username, token) if system_user.ad_domain: @@ -169,9 +181,12 @@ class ClientProtocolMixin: else: name = '*' + endpoint = self.get_smart_endpoint( + protocol='ssh', asset=asset, application=application + ) content = { - 'ip': settings.TERMINAL_KOKO_HOST, - 'port': str(settings.TERMINAL_KOKO_SSH_PORT), + 'ip': endpoint.host, + 'port': endpoint.ssh_port, 'username': f'JMS-{token}', 'password': secret } @@ -345,6 +360,7 @@ class SecretDetailMixin: class TokenCacheMixin: + """ endpoint smart view 用到此类来解析token中的资产、应用 """ CACHE_KEY_PREFIX = 'CONNECTION_TOKEN_{}' def get_token_cache_key(self, token): diff --git a/apps/common/fields/model.py b/apps/common/fields/model.py index 4a4f3525d..a3ac13e82 100644 --- a/apps/common/fields/model.py +++ b/apps/common/fields/model.py @@ -4,7 +4,7 @@ import json from django.db import models from django.utils.translation import ugettext_lazy as _ from django.utils.encoding import force_text - +from django.core.validators import MinValueValidator, MaxValueValidator from ..utils import signer, crypto @@ -13,7 +13,7 @@ __all__ = [ 'JsonCharField', 'JsonTextField', 'JsonListCharField', 'JsonListTextField', 'JsonDictCharField', 'JsonDictTextField', 'EncryptCharField', 'EncryptTextField', 'EncryptMixin', 'EncryptJsonDictTextField', - 'EncryptJsonDictCharField', + 'EncryptJsonDictCharField', 'PortField' ] @@ -180,3 +180,13 @@ class EncryptJsonDictTextField(EncryptMixin, JsonDictTextField): class EncryptJsonDictCharField(EncryptMixin, JsonDictCharField): pass + +class PortField(models.IntegerField): + def __init__(self, *args, **kwargs): + kwargs.update({ + 'blank': False, + 'null': False, + 'validators': [MinValueValidator(0), MaxValueValidator(65535)] + }) + super().__init__(*args, **kwargs) + diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 8e34d6f91..f72ed899f 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -310,16 +310,12 @@ class Config(dict): 'TERMINAL_HOST_KEY': '', 'TERMINAL_TELNET_REGEX': '', 'TERMINAL_COMMAND_STORAGE': {}, - 'TERMINAL_RDP_ADDR': lambda: urlparse(settings.SITE_URL).hostname + ':3389', - 'XRDP_ENABLED': True, - 'TERMINAL_KOKO_HOST': lambda: urlparse(settings.SITE_URL).hostname, - 'TERMINAL_KOKO_SSH_PORT': 2222, - + # 未来废弃(当下迁移会用) + 'TERMINAL_RDP_ADDR': '', + # 保留(Luna还在用) 'TERMINAL_MAGNUS_ENABLED': True, - 'TERMINAL_MAGNUS_HOST': lambda: urlparse(settings.SITE_URL).hostname, - 'TERMINAL_MAGNUS_MYSQL_PORT': 33060, - 'TERMINAL_MAGNUS_MARIADB_PORT': 33061, - 'TERMINAL_MAGNUS_POSTGRE_PORT': 54320, + # 保留(Luna还在用) + 'XRDP_ENABLED': True, # 安全配置 'SECURITY_MFA_AUTH': 0, # 0 不开启 1 全局开启 2 管理员开启 diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index 2aa05afe5..794180fd2 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -140,9 +140,6 @@ CLOUD_SYNC_TASK_EXECUTION_KEEP_DAYS = CONFIG.CLOUD_SYNC_TASK_EXECUTION_KEEP_DAYS XRDP_ENABLED = CONFIG.XRDP_ENABLED -TERMINAL_KOKO_HOST = CONFIG.TERMINAL_KOKO_HOST -TERMINAL_KOKO_SSH_PORT = CONFIG.TERMINAL_KOKO_SSH_PORT - # SMS enabled SMS_ENABLED = CONFIG.SMS_ENABLED SMS_BACKEND = CONFIG.SMS_BACKEND @@ -170,11 +167,3 @@ ANNOUNCEMENT = CONFIG.ANNOUNCEMENT # help HELP_DOCUMENT_URL = CONFIG.HELP_DOCUMENT_URL HELP_SUPPORT_URL = CONFIG.HELP_SUPPORT_URL - -# Magnus -MAGNUS_ENABLED = CONFIG.MAGNUS_ENABLED -TERMINAL_MAGNUS_HOST = CONFIG.TERMINAL_MAGNUS_HOST -TERMINAL_MAGNUS_ENABLED = CONFIG.TERMINAL_MAGNUS_ENABLED -TERMINAL_MAGNUS_MYSQL_PORT = CONFIG.TERMINAL_MAGNUS_MYSQL_PORT -TERMINAL_MAGNUS_MARIADB_PORT = CONFIG.TERMINAL_MAGNUS_MARIADB_PORT -TERMINAL_MAGNUS_POSTGRE_PORT = CONFIG.TERMINAL_MAGNUS_POSTGRE_PORT diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index 080e2ab5e..73226f058 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:097c6d06ed8dcf2e1807560b6eb52d98cba31f25fe8d67ce4315668c150ca6b8 -size 129989 +oid sha256:70685e92cbf84f4178224a44fd84eb884a0acfb9749200541ea6655a9a397a72 +size 125019 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 757d1e463..c80ef4904 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-04-02 10:01+0800\n" +"POT-Creation-Date: 2022-04-12 17:03+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -29,31 +29,27 @@ msgstr "Acls" #: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24 #: orgs/models.py:65 perms/models/base.py:83 rbac/models/role.py:29 #: settings/models.py:29 settings/serializers/sms.py:6 +#: terminal/models/endpoint.py:10 terminal/models/endpoint.py:53 #: terminal/models/storage.py:23 terminal/models/task.py:16 #: terminal/models/terminal.py:100 users/forms/profile.py:32 #: users/models/group.py:15 users/models/user.py:661 -#: users/templates/users/_select_user_modal.html:13 -#: users/templates/users/user_asset_permission.html:37 -#: users/templates/users/user_asset_permission.html:154 -#: users/templates/users/user_database_app_permission.html:36 #: xpack/plugins/cloud/models.py:28 msgid "Name" msgstr "名前" #: acls/models/base.py:27 assets/models/cmd_filter.py:84 -#: assets/models/user.py:247 +#: assets/models/user.py:247 terminal/models/endpoint.py:56 msgid "Priority" msgstr "優先順位" #: acls/models/base.py:28 assets/models/cmd_filter.py:84 -#: assets/models/user.py:247 +#: assets/models/user.py:247 terminal/models/endpoint.py:57 msgid "1-100, the lower the value will be match first" msgstr "1-100、低い値は最初に一致します" #: acls/models/base.py:31 authentication/models.py:17 #: authentication/templates/authentication/_access_key_modal.html:32 #: perms/models/base.py:88 terminal/models/sharing.py:26 -#: users/templates/users/_select_user_modal.html:18 msgid "Active" msgstr "アクティブ" @@ -65,6 +61,7 @@ msgstr "アクティブ" #: assets/models/domain.py:64 assets/models/group.py:23 #: assets/models/label.py:23 ops/models/adhoc.py:38 orgs/models.py:68 #: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34 +#: terminal/models/endpoint.py:20 terminal/models/endpoint.py:63 #: terminal/models/storage.py:26 terminal/models/terminal.py:114 #: tickets/models/comment.py:24 tickets/models/ticket.py:154 #: users/models/group.py:16 users/models/user.py:698 @@ -91,16 +88,12 @@ msgstr "ログイン確認" #: assets/models/cmd_filter.py:30 assets/models/label.py:15 audits/models.py:37 #: audits/models.py:60 audits/models.py:85 audits/serializers.py:100 #: authentication/models.py:50 orgs/models.py:214 perms/models/base.py:84 -#: rbac/builtin.py:101 rbac/models/rolebinding.py:40 templates/index.html:78 +#: rbac/builtin.py:106 rbac/models/rolebinding.py:40 #: terminal/backends/command/models.py:19 -#: terminal/backends/command/serializers.py:12 terminal/models/session.py:42 +#: terminal/backends/command/serializers.py:12 terminal/models/session.py:44 #: terminal/notifications.py:91 terminal/notifications.py:139 #: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:886 #: users/models/user.py:917 users/serializers/group.py:19 -#: users/templates/users/user_asset_permission.html:38 -#: users/templates/users/user_asset_permission.html:64 -#: users/templates/users/user_database_app_permission.html:37 -#: users/templates/users/user_database_app_permission.html:58 msgid "User" msgstr "ユーザー" @@ -112,10 +105,6 @@ msgstr "ルール" #: acls/serializers/login_acl.py:17 acls/serializers/login_asset_acl.py:75 #: assets/models/cmd_filter.py:89 audits/models.py:61 audits/serializers.py:51 #: authentication/templates/authentication/_access_key_modal.html:34 -#: users/templates/users/_granted_assets.html:29 -#: users/templates/users/user_asset_permission.html:44 -#: users/templates/users/user_asset_permission.html:79 -#: users/templates/users/user_database_app_permission.html:42 msgid "Action" msgstr "アクション" @@ -136,16 +125,13 @@ msgstr "システムユーザー" #: acls/models/login_asset_acl.py:22 #: applications/serializers/attrs/application_category/remote_app.py:36 -#: assets/models/asset.py:383 assets/models/authbook.py:19 +#: assets/models/asset.py:386 assets/models/authbook.py:19 #: assets/models/backup.py:31 assets/models/cmd_filter.py:38 #: assets/models/gathered_user.py:14 assets/serializers/label.py:30 #: assets/serializers/system_user.py:264 audits/models.py:39 -#: perms/models/asset_permission.py:23 templates/index.html:82 -#: terminal/backends/command/models.py:20 -#: terminal/backends/command/serializers.py:13 terminal/models/session.py:44 +#: perms/models/asset_permission.py:23 terminal/backends/command/models.py:20 +#: terminal/backends/command/serializers.py:13 terminal/models/session.py:46 #: terminal/notifications.py:90 -#: users/templates/users/user_asset_permission.html:40 -#: users/templates/users/user_asset_permission.html:70 #: xpack/plugins/change_auth_plan/models/asset.py:199 #: xpack/plugins/change_auth_plan/serializers/asset.py:180 #: xpack/plugins/cloud/models.py:223 @@ -172,7 +158,6 @@ msgstr "コンマ区切り文字列の形式。* はすべて一致すること #: authentication/templates/authentication/_msg_oauth_bind.html:9 #: ops/models/adhoc.py:159 users/forms/profile.py:31 users/models/user.py:659 #: users/templates/users/_msg_user_created.html:12 -#: users/templates/users/_select_user_modal.html:14 #: xpack/plugins/change_auth_plan/models/asset.py:34 #: xpack/plugins/change_auth_plan/models/asset.py:195 #: xpack/plugins/cloud/serializers/account_attrs.py:22 @@ -196,17 +181,13 @@ msgstr "" #: authentication/templates/authentication/_msg_oauth_bind.html:12 #: authentication/templates/authentication/_msg_rest_password_success.html:8 #: authentication/templates/authentication/_msg_rest_public_key_success.html:8 -#: settings/serializers/terminal.py:8 -#: users/templates/users/_granted_assets.html:26 -#: users/templates/users/user_asset_permission.html:156 +#: settings/serializers/terminal.py:8 terminal/serializers/endpoint.py:37 msgid "IP" msgstr "IP" #: acls/serializers/login_asset_acl.py:35 assets/models/asset.py:211 #: assets/serializers/account.py:14 assets/serializers/gathered_user.py:23 #: settings/serializers/terminal.py:7 -#: users/templates/users/_granted_assets.html:25 -#: users/templates/users/user_asset_permission.html:157 msgid "Hostname" msgstr "ホスト名" @@ -220,7 +201,7 @@ msgstr "" #: acls/serializers/login_asset_acl.py:55 assets/models/asset.py:213 #: assets/models/domain.py:62 assets/models/user.py:248 -#: terminal/serializers/session.py:30 terminal/serializers/storage.py:69 +#: terminal/serializers/session.py:30 terminal/serializers/storage.py:67 msgid "Protocol" msgstr "プロトコル" @@ -285,13 +266,7 @@ msgstr "アプリケーション" #: assets/models/cmd_filter.py:42 assets/models/user.py:338 audits/models.py:40 #: perms/models/application_permission.py:33 #: perms/models/asset_permission.py:25 terminal/backends/command/models.py:21 -#: terminal/backends/command/serializers.py:35 terminal/models/session.py:46 -#: users/templates/users/_granted_assets.html:27 -#: users/templates/users/user_asset_permission.html:42 -#: users/templates/users/user_asset_permission.html:76 -#: users/templates/users/user_asset_permission.html:159 -#: users/templates/users/user_database_app_permission.html:40 -#: users/templates/users/user_database_app_permission.html:67 +#: terminal/backends/command/serializers.py:35 terminal/models/session.py:48 #: xpack/plugins/change_auth_plan/models/app.py:36 #: xpack/plugins/change_auth_plan/models/app.py:147 #: xpack/plugins/change_auth_plan/serializers/app.py:65 @@ -343,7 +318,7 @@ msgid "Domain" msgstr "ドメイン" #: applications/models/application.py:228 xpack/plugins/cloud/models.py:33 -#: xpack/plugins/cloud/serializers/account.py:59 +#: xpack/plugins/cloud/serializers/account.py:58 msgid "Attrs" msgstr "ツールバーの" @@ -351,7 +326,7 @@ msgstr "ツールバーの" msgid "Can match application" msgstr "アプリケーションを一致させることができます" -#: applications/models/application.py:286 +#: applications/models/application.py:306 msgid "Application user" msgstr "アプリケーションユーザー" @@ -409,6 +384,7 @@ msgstr "クラスター" #: applications/serializers/attrs/application_category/db.py:11 #: ops/models/adhoc.py:157 settings/serializers/auth/radius.py:14 +#: terminal/models/endpoint.py:11 #: xpack/plugins/cloud/serializers/account_attrs.py:68 msgid "Host" msgstr "ホスト" @@ -639,27 +615,27 @@ msgstr "ラベル" msgid "Created by" msgstr "によって作成された" -#: assets/models/asset.py:386 +#: assets/models/asset.py:389 msgid "Can refresh asset hardware info" msgstr "資産ハードウェア情報を更新できます" -#: assets/models/asset.py:387 +#: assets/models/asset.py:390 msgid "Can test asset connectivity" msgstr "資産接続をテストできます" -#: assets/models/asset.py:388 +#: assets/models/asset.py:391 msgid "Can push system user to asset" msgstr "システムユーザーを資産にプッシュできます" -#: assets/models/asset.py:389 +#: assets/models/asset.py:392 msgid "Can match asset" msgstr "アセットを一致させることができます" -#: assets/models/asset.py:390 +#: assets/models/asset.py:393 msgid "Add asset to node" msgstr "ノードにアセットを追加する" -#: assets/models/asset.py:391 +#: assets/models/asset.py:394 msgid "Move asset to node" msgstr "アセットをノードに移動する" @@ -706,7 +682,7 @@ msgid "Timing trigger" msgstr "タイミングトリガー" #: assets/models/backup.py:105 audits/models.py:44 ops/models/command.py:31 -#: perms/models/base.py:89 terminal/models/session.py:56 +#: perms/models/base.py:89 terminal/models/session.py:58 #: tickets/serializers/ticket/meta/ticket_type/apply_application.py:55 #: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:57 #: xpack/plugins/change_auth_plan/models/base.py:112 @@ -767,7 +743,7 @@ msgstr "OK" #: assets/models/base.py:32 audits/models.py:116 #: xpack/plugins/change_auth_plan/serializers/app.py:88 #: xpack/plugins/change_auth_plan/serializers/asset.py:198 -#: xpack/plugins/cloud/const.py:31 +#: xpack/plugins/cloud/const.py:30 msgid "Failed" msgstr "失敗しました" @@ -782,9 +758,8 @@ msgstr "確認済みの日付" #: assets/models/base.py:177 audits/signal_handlers.py:68 #: authentication/forms.py:22 #: authentication/templates/authentication/login.html:181 -#: settings/serializers/auth/ldap.py:44 users/forms/profile.py:21 +#: settings/serializers/auth/ldap.py:43 users/forms/profile.py:21 #: users/templates/users/_msg_user_created.html:13 -#: users/templates/users/user_password_update.html:43 #: users/templates/users/user_password_verify.html:18 #: xpack/plugins/change_auth_plan/models/base.py:42 #: xpack/plugins/change_auth_plan/models/base.py:121 @@ -849,11 +824,6 @@ msgstr "デフォルトクラスター" #: assets/models/cmd_filter.py:34 perms/models/base.py:86 #: users/models/group.py:31 users/models/user.py:667 -#: users/templates/users/_select_user_modal.html:16 -#: users/templates/users/user_asset_permission.html:39 -#: users/templates/users/user_asset_permission.html:67 -#: users/templates/users/user_database_app_permission.html:38 -#: users/templates/users/user_database_app_permission.html:61 msgid "User group" msgstr "ユーザーグループ" @@ -866,7 +836,7 @@ msgid "Regex" msgstr "正規情報" #: assets/models/cmd_filter.py:68 ops/models/command.py:26 -#: terminal/backends/command/serializers.py:14 terminal/models/session.py:53 +#: terminal/backends/command/serializers.py:14 terminal/models/session.py:55 #: terminal/templates/terminal/_msg_command_alert.html:12 #: terminal/templates/terminal/_msg_command_execute_alert.html:10 msgid "Command" @@ -966,7 +936,7 @@ msgstr "ラベル" msgid "New node" msgstr "新しいノード" -#: assets/models/node.py:474 users/templates/users/_granted_assets.html:130 +#: assets/models/node.py:474 msgid "empty" msgstr "空" @@ -983,9 +953,6 @@ msgid "Parent key" msgstr "親キー" #: assets/models/node.py:559 assets/serializers/system_user.py:263 -#: users/templates/users/user_asset_permission.html:41 -#: users/templates/users/user_asset_permission.html:73 -#: users/templates/users/user_asset_permission.html:158 #: xpack/plugins/cloud/models.py:96 xpack/plugins/cloud/serializers/task.py:69 msgid "Node" msgstr "ノード" @@ -1140,7 +1107,7 @@ msgid "Actions" msgstr "アクション" #: assets/serializers/backup.py:31 ops/mixin.py:106 ops/mixin.py:147 -#: settings/serializers/auth/ldap.py:59 +#: settings/serializers/auth/ldap.py:62 #: xpack/plugins/change_auth_plan/serializers/base.py:42 msgid "Periodic perform" msgstr "定期的なパフォーマンス" @@ -1388,8 +1355,7 @@ msgstr "監査" #: audits/models.py:27 audits/models.py:57 #: authentication/templates/authentication/_access_key_modal.html:65 -#: rbac/tree.py:166 users/templates/users/user_asset_permission.html:128 -#: users/templates/users/user_database_app_permission.html:111 +#: rbac/tree.py:166 msgid "Delete" msgstr "削除" @@ -1418,7 +1384,7 @@ msgid "Symlink" msgstr "Symlink" #: audits/models.py:38 audits/models.py:64 audits/models.py:87 -#: terminal/models/session.py:49 terminal/models/sharing.py:82 +#: terminal/models/session.py:51 terminal/models/sharing.py:82 msgid "Remote addr" msgstr "リモートaddr" @@ -1448,8 +1414,6 @@ msgstr "作成" #: audits/models.py:56 rbac/tree.py:165 templates/_csv_import_export.html:18 #: templates/_csv_update_modal.html:6 -#: users/templates/users/user_asset_permission.html:127 -#: users/templates/users/user_database_app_permission.html:110 msgid "Update" msgstr "更新" @@ -1558,7 +1522,7 @@ msgstr "ホスト表示" msgid "Result" msgstr "結果" -#: audits/serializers.py:98 terminal/serializers/storage.py:161 +#: audits/serializers.py:98 terminal/serializers/storage.py:156 msgid "Hosts" msgstr "ホスト" @@ -1669,7 +1633,6 @@ msgid "{AssetPermission} REMOVE {UserGroup}" msgstr "{AssetPermission} 削除 {UserGroup}" #: audits/signal_handlers.py:131 perms/models/asset_permission.py:29 -#: users/templates/users/_user_detail_nav_header.html:31 msgid "Asset permission" msgstr "資産権限" @@ -1767,7 +1730,7 @@ msgstr "{ApplicationPermission} 追加 {SystemUser}" msgid "{ApplicationPermission} REMOVE {SystemUser}" msgstr "{ApplicationPermission} 削除 {SystemUser}" -#: authentication/api/connection_token.py:313 +#: authentication/api/connection_token.py:328 msgid "Invalid token" msgstr "無効なトークン" @@ -2065,7 +2028,7 @@ msgstr "MFAタイプ ({}) が有効になっていない" msgid "Please change your password" msgstr "パスワードを変更してください" -#: authentication/models.py:33 terminal/serializers/storage.py:30 +#: authentication/models.py:33 terminal/serializers/storage.py:28 msgid "Access key" msgstr "アクセスキー" @@ -2129,7 +2092,6 @@ msgid "Date" msgstr "日付" #: authentication/templates/authentication/_access_key_modal.html:48 -#: users/templates/users/_granted_assets.html:75 msgid "Show" msgstr "表示" @@ -2189,7 +2151,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:295 ops/tasks.py:145 ops/tasks.py:148 +#: jumpserver/conf.py:296 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 #: users/templates/users/_msg_account_expire_reminder.html:4 @@ -2650,11 +2612,11 @@ msgstr "特殊文字を含むべきではない" msgid "The mobile phone number format is incorrect" msgstr "携帯電話番号の形式が正しくありません" -#: jumpserver/conf.py:294 +#: jumpserver/conf.py:295 msgid "Create account successfully" msgstr "アカウントを正常に作成" -#: jumpserver/conf.py:296 +#: jumpserver/conf.py:297 msgid "Your account has been created successfully" msgstr "アカウントが正常に作成されました" @@ -2720,12 +2682,12 @@ msgid "App ops" msgstr "アプリ操作" #: ops/mixin.py:29 ops/mixin.py:92 ops/mixin.py:162 -#: settings/serializers/auth/ldap.py:66 +#: settings/serializers/auth/ldap.py:69 msgid "Cycle perform" msgstr "サイクル実行" #: ops/mixin.py:33 ops/mixin.py:90 ops/mixin.py:109 ops/mixin.py:150 -#: settings/serializers/auth/ldap.py:63 +#: settings/serializers/auth/ldap.py:66 msgid "Regularly perform" msgstr "定期的に実行する" @@ -2912,7 +2874,8 @@ msgstr "アプリ組織" #: orgs/mixins/models.py:46 orgs/mixins/serializers.py:25 orgs/models.py:80 #: orgs/models.py:211 rbac/const.py:7 rbac/models/rolebinding.py:47 -#: rbac/serializers/rolebinding.py:40 tickets/serializers/ticket/ticket.py:77 +#: rbac/serializers/rolebinding.py:40 settings/serializers/auth/ldap.py:59 +#: tickets/serializers/ticket/ticket.py:77 msgid "Organization" msgstr "組織" @@ -2925,7 +2888,7 @@ msgid "Can view root org" msgstr "グローバル組織を表示できます" #: orgs/models.py:216 rbac/models/role.py:46 rbac/models/rolebinding.py:43 -#: users/models/user.py:671 users/templates/users/_select_user_modal.html:15 +#: users/models/user.py:671 msgid "Role" msgstr "ロール" @@ -3151,27 +3114,27 @@ msgstr "{} 少なくとも1つのシステムロール" msgid "RBAC" msgstr "RBAC" -#: rbac/builtin.py:92 +#: rbac/builtin.py:97 msgid "SystemAdmin" msgstr "システム管理者" -#: rbac/builtin.py:95 +#: rbac/builtin.py:100 msgid "SystemAuditor" msgstr "システム監査人" -#: rbac/builtin.py:98 +#: rbac/builtin.py:103 msgid "SystemComponent" msgstr "システムコンポーネント" -#: rbac/builtin.py:104 +#: rbac/builtin.py:109 msgid "OrgAdmin" msgstr "組織管理者" -#: rbac/builtin.py:107 +#: rbac/builtin.py:112 msgid "OrgAuditor" msgstr "監査員を組織する" -#: rbac/builtin.py:110 +#: rbac/builtin.py:115 msgid "OrgUser" msgstr "組織ユーザー" @@ -3376,11 +3339,11 @@ msgstr "同期が実行中です。しばらくお待ちください。" msgid "Synchronization error: {}" msgstr "同期エラー: {}" -#: settings/api/ldap.py:211 +#: settings/api/ldap.py:213 msgid "Get ldap users is None" msgstr "Ldapユーザーを取得するにはNone" -#: settings/api/ldap.py:220 +#: settings/api/ldap.py:222 msgid "Imported {} users successfully (Organization: {})" msgstr "{} 人のユーザーを正常にインポートしました (組織: {})" @@ -3508,15 +3471,15 @@ msgstr "ピン認証の有効化" msgid "Enable FeiShu Auth" msgstr "飛本認証の有効化" -#: settings/serializers/auth/ldap.py:39 +#: settings/serializers/auth/ldap.py:38 msgid "LDAP server" msgstr "LDAPサーバー" -#: settings/serializers/auth/ldap.py:40 +#: settings/serializers/auth/ldap.py:39 msgid "eg: ldap://localhost:389" msgstr "例: ldap://localhost:389" -#: settings/serializers/auth/ldap.py:42 +#: settings/serializers/auth/ldap.py:41 msgid "Bind DN" msgstr "DN のバインド" @@ -3549,15 +3512,15 @@ msgstr "" "ユーザー属性マッピングは、LDAPのユーザー属性をjumpserverユーザーにマッピング" "する方法、username, name,emailはjumpserverのユーザーが必要とする属性です" -#: settings/serializers/auth/ldap.py:70 +#: settings/serializers/auth/ldap.py:73 msgid "Connect timeout" msgstr "接続タイムアウト" -#: settings/serializers/auth/ldap.py:72 +#: settings/serializers/auth/ldap.py:75 msgid "Search paged size" msgstr "ページサイズを検索" -#: settings/serializers/auth/ldap.py:74 +#: settings/serializers/auth/ldap.py:77 msgid "Enable LDAP auth" msgstr "LDAP認証の有効化" @@ -4256,61 +4219,13 @@ msgstr "" "ログイン成功メッセージはデバイスによって異なります。Telnet経由でデバイスにロ" "グインできない場合は、このパラメーターを設定します。" -#: settings/serializers/terminal.py:37 -msgid "RDP address" -msgstr "RDPアドレス" - -#: settings/serializers/terminal.py:38 -msgid "RDP visit address, eg: dev.jumpserver.org:3389" -msgstr "RDP訪問先住所、例: dev.jumpserver.org:3389" - -#: settings/serializers/terminal.py:40 -msgid "Enable XRDP" -msgstr "XRDPの有効化" - -#: settings/serializers/terminal.py:43 -msgid "Koko host" -msgstr "KOKO ホストアドレス" - -#: settings/serializers/terminal.py:46 -msgid "Koko ssh port" -msgstr "Koko ssh ポート" - -#: settings/serializers/terminal.py:49 +#: settings/serializers/terminal.py:36 msgid "Enable database proxy" msgstr "属性マップの有効化" -#: settings/serializers/terminal.py:51 -msgid "Database proxy host" -msgstr "データベースエージェントホスト" - -#: settings/serializers/terminal.py:52 -msgid "Database proxy host, eg: dev.jumpserver.org" -msgstr "RDP訪問先住所、例: dev.jumpserver.org:3389" - -#: settings/serializers/terminal.py:55 -msgid "MySQL port" -msgstr "MySQLポート" - -#: settings/serializers/terminal.py:56 -msgid "MySQL protocol listen port" -msgstr "MySQLプロトコルリッスンポート" - -#: settings/serializers/terminal.py:59 -msgid "MariaDB port" -msgstr "MariaDBポート" - -#: settings/serializers/terminal.py:60 -msgid "MariaDB protocol listen port" -msgstr "MariaDBプロトコルリッスンポート" - -#: settings/serializers/terminal.py:63 -msgid "PostgreSQL port" -msgstr "PostgreSQLポート" - -#: settings/serializers/terminal.py:64 -msgid "PostgreSQL protocol listen port" -msgstr "PostgreSQLプロトコルリッスンポート" +#: settings/serializers/terminal.py:37 +msgid "Enable XRDP" +msgstr "XRDPの有効化" #: settings/utils/ldap.py:417 msgid "ldap:// or ldaps:// protocol is used." @@ -4413,10 +4328,6 @@ msgstr "認証に失敗しました (不明): {}" msgid "Authentication success: {}" msgstr "認証成功: {}" -#: templates/_base_list.html:37 -msgid "Search" -msgstr "検索" - #: templates/_csv_import_export.html:8 msgid "Export" msgstr "エクスポート" @@ -4466,7 +4377,6 @@ msgid "Commercial support" msgstr "商用サポート" #: templates/_header_bar.html:76 users/forms/profile.py:43 -#: users/templates/users/user_password_update.html:39 msgid "Profile" msgstr "プロフィール" @@ -4572,175 +4482,14 @@ msgstr "待つ:" msgid "The verification code has been sent" msgstr "確認コードが送信されました" -#: templates/_pagination.html:59 -msgid "" -"Displays the results of items _START_ to _END_; A total of _TOTAL_ entries" -msgstr "アイテムの結果を表示します _START_ to _END_; 合計 _TOTAL_ エントリ" - #: templates/_without_nav_base.html:26 msgid "Home page" msgstr "ホームページ" -#: templates/delete_confirm.html:6 -msgid "Confirm delete" -msgstr "削除の確認" - -#: templates/delete_confirm.html:11 -msgid "Are you sure delete" -msgstr "削除してもよろしいですか" - #: templates/flash_message_standalone.html:25 msgid "Cancel" msgstr "キャンセル" -#: templates/index.html:11 -msgid "Total users" -msgstr "合計ユーザー数" - -#: templates/index.html:23 -msgid "Total assets" -msgstr "総資産" - -#: templates/index.html:36 -msgid "Online users" -msgstr "オンラインユーザー" - -#: templates/index.html:49 -msgid "Online sessions" -msgstr "オンラインセッション" - -#: templates/index.html:61 -msgid "In the past week, a total of " -msgstr "過去1週間、共有 " - -#: templates/index.html:61 -msgid " users have logged in " -msgstr " ビットユーザーログイン." - -#: templates/index.html:61 -msgid " times asset." -msgstr " 次资产." - -#: templates/index.html:69 -msgid "Active user asset ratio" -msgstr "アクティブなユーザー資産比率" - -#: templates/index.html:72 -msgid "" -"The following graphs describe the percentage of active users per month and " -"assets per user host per month, respectively." -msgstr "" -"次のグラフは、1か月あたりのアクティブユーザーの割合と、1か月あたりのユーザー" -"ホストあたりの資産の割合をそれぞれ示しています。" - -#: templates/index.html:97 templates/index.html:112 -msgid "Top 10 assets in a week" -msgstr "1週間でトップ10の資産" - -#: templates/index.html:113 -msgid "Login frequency and last login record." -msgstr "ログイン頻度と最後のログイン記録。" - -#: templates/index.html:122 -msgid "Last 10 login" -msgstr "最後の10ログイン" - -#: templates/index.html:128 -msgid "Login record" -msgstr "ログイン記録" - -#: templates/index.html:129 -msgid "Last 10 login records." -msgstr "最後の10件のログイン記録。" - -#: templates/index.html:143 templates/index.html:158 -msgid "Top 10 users in a week" -msgstr "1週間でトップ10のユーザー" - -#: templates/index.html:159 -msgid "User login frequency and last login record." -msgstr "ユーザーログイン頻度と最後のログインレコード。" - -#: templates/index.html:184 -msgid "Monthly data overview" -msgstr "毎月のデータ概要" - -#: templates/index.html:185 -msgid "History summary in one month" -msgstr "1ヶ月で履歴概要" - -#: templates/index.html:193 templates/index.html:217 -msgid "Login count" -msgstr "ログイン数" - -#: templates/index.html:193 templates/index.html:224 -msgid "Active users" -msgstr "アクティブユーザー" - -#: templates/index.html:193 templates/index.html:231 -msgid "Active assets" -msgstr "アクティブな資産" - -#: templates/index.html:262 templates/index.html:313 -msgid "Monthly active users" -msgstr "毎月のアクティブユーザー数" - -#: templates/index.html:262 templates/index.html:314 -msgid "Disable user" -msgstr "ユーザーを無効にする" - -#: templates/index.html:262 templates/index.html:315 -msgid "Month not logged in user" -msgstr "ユーザーにログインしていない月" - -#: templates/index.html:288 templates/index.html:368 -msgid "Access to the source" -msgstr "ソースへのアクセス" - -#: templates/index.html:342 -msgid "Month is logged into the asset" -msgstr "月が資産にログインされます" - -#: templates/index.html:342 templates/index.html:393 -msgid "Disable host" -msgstr "ホストの無効化" - -#: templates/index.html:342 templates/index.html:394 -msgid "Month not logged on host" -msgstr "月がホストにログオンしていない" - -#: templates/index.html:392 -msgid "Month is logged into the host" -msgstr "月がホストにログインされます" - -#: templates/index.html:466 -msgid " times/week" -msgstr " 時間/週" - -#: templates/index.html:491 templates/index.html:527 -msgid " times" -msgstr " 回数" - -#: templates/index.html:494 templates/index.html:530 -msgid "The time last logged in" -msgstr "最後にログインした時刻" - -#: templates/index.html:495 templates/index.html:531 -msgid "At" -msgstr "于" - -#: templates/index.html:510 templates/index.html:545 templates/index.html:580 -msgid "(No)" -msgstr "(しばらく)" - -#: templates/index.html:561 -msgid "Before" -msgstr "前" - -#: templates/index.html:562 -msgid "Login in " -msgstr "ログイン" - #: templates/resource_download.html:18 templates/resource_download.html:24 #: templates/resource_download.html:25 templates/resource_download.html:30 msgid "Client" @@ -4786,19 +4535,23 @@ msgstr "" msgid "Filters" msgstr "フィルター" -#: terminal/api/session.py:211 +#: terminal/api/endpoint.py:65 +msgid "Not found protocol query params" +msgstr "" + +#: terminal/api/session.py:210 msgid "Session does not exist: {}" msgstr "セッションが存在しません: {}" -#: terminal/api/session.py:214 +#: terminal/api/session.py:213 msgid "Session is finished or the protocol not supported" msgstr "セッションが終了したか、プロトコルがサポートされていません" -#: terminal/api/session.py:219 +#: terminal/api/session.py:218 msgid "User does not exist: {}" msgstr "ユーザーが存在しない: {}" -#: terminal/api/session.py:227 +#: terminal/api/session.py:226 msgid "User does not have permission" msgstr "ユーザーに権限がありません" @@ -4842,7 +4595,7 @@ msgstr "オンラインセッションを持つ" msgid "Terminals" msgstr "ターミナル管理" -#: terminal/backends/command/es.py:27 +#: terminal/backends/command/es.py:26 msgid "Invalid elasticsearch config" msgstr "無効なElasticsearch構成" @@ -4899,7 +4652,6 @@ msgid "High" msgstr "高い" #: terminal/const.py:35 users/templates/users/reset_password.html:50 -#: users/templates/users/user_password_update.html:104 msgid "Normal" msgstr "正常" @@ -4919,6 +4671,49 @@ msgstr "ストレージが無効です" msgid "Command record" msgstr "コマンドレコード" +#: terminal/models/endpoint.py:13 +msgid "HTTPS Port" +msgstr "HTTPS ポート" + +#: terminal/models/endpoint.py:14 terminal/models/terminal.py:107 +msgid "HTTP Port" +msgstr "HTTP ポート" + +#: terminal/models/endpoint.py:15 terminal/models/terminal.py:106 +msgid "SSH Port" +msgstr "SSH ポート" + +#: terminal/models/endpoint.py:16 +msgid "RDP Port" +msgstr "RDP ポート" + +#: terminal/models/endpoint.py:17 +msgid "MySQL Port" +msgstr "MySQL ポート" + +#: terminal/models/endpoint.py:18 +msgid "MariaDB Port" +msgstr "MariaDB ポート" + +#: terminal/models/endpoint.py:19 +msgid "PostgreSQL Port" +msgstr "PostgreSQL ポート" + +#: terminal/models/endpoint.py:25 terminal/models/endpoint.py:61 +#: terminal/serializers/endpoint.py:40 terminal/serializers/storage.py:37 +#: terminal/serializers/storage.py:49 terminal/serializers/storage.py:79 +#: terminal/serializers/storage.py:89 terminal/serializers/storage.py:97 +msgid "Endpoint" +msgstr "エンドポイント" + +#: terminal/models/endpoint.py:54 +msgid "IP group" +msgstr "IP グループ" + +#: terminal/models/endpoint.py:66 +msgid "Endpoint rule" +msgstr "エンドポイントルール" + #: terminal/models/replay.py:12 msgid "Session replay" msgstr "セッション再生" @@ -4931,35 +4726,35 @@ msgstr "セッションのリプレイをアップロードできます" msgid "Can download session replay" msgstr "セッション再生をダウンロードできます" -#: terminal/models/session.py:48 terminal/models/sharing.py:87 +#: terminal/models/session.py:50 terminal/models/sharing.py:87 msgid "Login from" msgstr "ログイン元" -#: terminal/models/session.py:52 +#: terminal/models/session.py:54 msgid "Replay" msgstr "リプレイ" -#: terminal/models/session.py:57 +#: terminal/models/session.py:59 msgid "Date end" msgstr "終了日" -#: terminal/models/session.py:242 +#: terminal/models/session.py:251 msgid "Session record" msgstr "セッション記録" -#: terminal/models/session.py:244 +#: terminal/models/session.py:253 msgid "Can monitor session" msgstr "セッションを監視できます" -#: terminal/models/session.py:245 +#: terminal/models/session.py:254 msgid "Can share session" msgstr "セッションを共有できます" -#: terminal/models/session.py:246 +#: terminal/models/session.py:255 msgid "Can terminate session" msgstr "セッションを終了できます" -#: terminal/models/session.py:247 +#: terminal/models/session.py:256 msgid "Can validate session action perm" msgstr "セッションアクションのパーマを検証できます" @@ -5068,14 +4863,6 @@ msgstr "クワーグ" msgid "type" msgstr "タイプ" -#: terminal/models/terminal.py:106 -msgid "SSH Port" -msgstr "SSHポート" - -#: terminal/models/terminal.py:107 -msgid "HTTP Port" -msgstr "HTTPポート" - #: terminal/models/terminal.py:183 terminal/serializers/session.py:38 msgid "Terminal" msgstr "ターミナル" @@ -5132,65 +4919,59 @@ msgstr "終了できます" msgid "Command amount" msgstr "コマンド量" -#: terminal/serializers/storage.py:21 +#: terminal/serializers/storage.py:19 msgid "Endpoint invalid: remove path `{}`" msgstr "エンドポイントが無効: パス '{}' を削除" -#: terminal/serializers/storage.py:27 +#: terminal/serializers/storage.py:25 msgid "Bucket" msgstr "バケット" -#: terminal/serializers/storage.py:34 users/models/user.py:695 +#: terminal/serializers/storage.py:32 users/models/user.py:695 msgid "Secret key" msgstr "秘密キー" -#: terminal/serializers/storage.py:39 terminal/serializers/storage.py:51 -#: terminal/serializers/storage.py:81 terminal/serializers/storage.py:91 -#: terminal/serializers/storage.py:99 -msgid "Endpoint" -msgstr "エンドポイント" - -#: terminal/serializers/storage.py:66 xpack/plugins/cloud/models.py:220 +#: terminal/serializers/storage.py:64 xpack/plugins/cloud/models.py:220 msgid "Region" msgstr "リージョン" -#: terminal/serializers/storage.py:110 +#: terminal/serializers/storage.py:108 msgid "Container name" msgstr "コンテナー名" -#: terminal/serializers/storage.py:112 +#: terminal/serializers/storage.py:110 msgid "Account name" msgstr "アカウント名" -#: terminal/serializers/storage.py:113 +#: terminal/serializers/storage.py:111 msgid "Account key" msgstr "アカウントキー" -#: terminal/serializers/storage.py:116 +#: terminal/serializers/storage.py:114 msgid "Endpoint suffix" msgstr "エンドポイントサフィックス" -#: terminal/serializers/storage.py:138 +#: terminal/serializers/storage.py:134 msgid "The address format is incorrect" msgstr "アドレス形式が正しくありません" -#: terminal/serializers/storage.py:145 +#: terminal/serializers/storage.py:141 msgid "Host invalid" msgstr "ホスト無効" -#: terminal/serializers/storage.py:148 +#: terminal/serializers/storage.py:144 msgid "Port invalid" msgstr "ポートが無効" -#: terminal/serializers/storage.py:164 +#: terminal/serializers/storage.py:159 msgid "Index" msgstr "インデックス" -#: terminal/serializers/storage.py:166 +#: terminal/serializers/storage.py:161 msgid "Doc type" msgstr "Docタイプ" -#: terminal/serializers/storage.py:168 +#: terminal/serializers/storage.py:163 msgid "Ignore Certificate Verification" msgstr "証明書の検証を無視する" @@ -5748,7 +5529,6 @@ msgid "Not a valid ssh public key" msgstr "有効なssh公開鍵ではありません" #: users/forms/profile.py:160 users/models/user.py:692 -#: users/templates/users/user_password_update.html:48 msgid "Public key" msgstr "公開キー" @@ -5957,10 +5737,6 @@ msgstr "セキュリティのために、複数のユーザーのみをリスト msgid "name not unique" msgstr "名前が一意ではない" -#: users/templates/users/_granted_assets.html:7 -msgid "Loading" -msgstr "読み込み中" - #: users/templates/users/_msg_account_expire_reminder.html:7 msgid "Your account will expire in" msgstr "アカウントの有効期限は" @@ -6015,69 +5791,11 @@ msgstr "あなたのssh公開鍵はサイト管理者によってリセットさ msgid "click here to set your password" msgstr "ここをクリックしてパスワードを設定してください" -#: users/templates/users/_select_user_modal.html:5 -msgid "Please Select User" -msgstr "ユーザーを選択してください" - -#: users/templates/users/_select_user_modal.html:17 -msgid "Asset num" -msgstr "資産num" - -#: users/templates/users/_user_detail_nav_header.html:11 -msgid "User detail" -msgstr "ユーザーの詳細" - -#: users/templates/users/_user_detail_nav_header.html:15 -msgid "User permissions" -msgstr "ユーザー権限" - -#: users/templates/users/_user_detail_nav_header.html:23 -msgid "Asset granted" -msgstr "付与された資産" - -#: users/templates/users/_user_detail_nav_header.html:40 -msgid "RemoteApp granted" -msgstr "承認されたリモートアプリケーション" - -#: users/templates/users/_user_detail_nav_header.html:47 -msgid "RemoteApp permission" -msgstr "リモートアプリケーションのライセンス" - -#: users/templates/users/_user_detail_nav_header.html:54 -msgid "DatabaseApp granted" -msgstr "認可されたデータベース・アプリケーション" - -#: users/templates/users/_user_detail_nav_header.html:61 -msgid "DatabaseApp permission" -msgstr "数据库应用授权" - -#: users/templates/users/_user_update_pk_modal.html:4 -msgid "Update User SSH Public Key" -msgstr "SSHキーの更新" - -#: users/templates/users/first_login.html:6 -#: users/templates/users/first_login_done.html:19 -msgid "First Login" -msgstr "最初のログイン" - -#: users/templates/users/first_login_done.html:31 -msgid "Welcome to use jumpserver, visit " -msgstr "JumpServer砦機へようこそ" - -#: users/templates/users/first_login_done.html:32 -msgid "Use guide" -msgstr "ガイド人" - -#: users/templates/users/first_login_done.html:32 -msgid " for more information" -msgstr "より多くの情報のため" - #: users/templates/users/forgot_password.html:23 msgid "Input your email, that will send a mail to your" msgstr "あなたのメールを入力し、それはあなたにメールを送信します" #: users/templates/users/forgot_password.html:32 -#: users/templates/users/user_password_update.html:75 msgid "Submit" msgstr "送信" @@ -6094,12 +5812,10 @@ msgid "MFA setting" msgstr "MFAの設定" #: users/templates/users/reset_password.html:23 -#: users/templates/users/user_password_update.html:64 msgid "Your password must satisfy" msgstr "パスワードを満たす必要があります" #: users/templates/users/reset_password.html:24 -#: users/templates/users/user_password_update.html:65 msgid "Password strength" msgstr "パスワードの強さ" @@ -6108,54 +5824,25 @@ msgid "Setting" msgstr "設定" #: users/templates/users/reset_password.html:48 -#: users/templates/users/user_password_update.html:102 msgid "Very weak" msgstr "非常に弱い" #: users/templates/users/reset_password.html:49 -#: users/templates/users/user_password_update.html:103 msgid "Weak" msgstr "弱い" #: users/templates/users/reset_password.html:51 -#: users/templates/users/user_password_update.html:105 msgid "Medium" msgstr "中" #: users/templates/users/reset_password.html:52 -#: users/templates/users/user_password_update.html:106 msgid "Strong" msgstr "強い" #: users/templates/users/reset_password.html:53 -#: users/templates/users/user_password_update.html:107 msgid "Very strong" msgstr "非常に強い" -#: users/templates/users/user_asset_permission.html:43 -#: users/templates/users/user_asset_permission.html:155 -#: users/templates/users/user_database_app_permission.html:41 -#: xpack/plugins/cloud/models.py:34 -msgid "Validity" -msgstr "有効性" - -#: users/templates/users/user_asset_permission.html:160 -msgid "Inherit" -msgstr "継承" - -#: users/templates/users/user_asset_permission.html:161 -msgid "Include" -msgstr "含める" - -#: users/templates/users/user_asset_permission.html:162 -msgid "Exclude" -msgstr "除外" - -#: users/templates/users/user_database_app_permission.html:39 -#: users/templates/users/user_database_app_permission.html:64 -msgid "DatabaseApp" -msgstr "データベースの適用" - #: users/templates/users/user_otp_check_password.html:6 msgid "Enable OTP" msgstr "OTPの有効化" @@ -6205,10 +5892,6 @@ msgstr "" "インストール後、次のステップをクリックしてバインディングページに入ります (イ" "ンストールされている場合は、次のステップに直接進みます)。" -#: users/templates/users/user_password_update.html:74 -msgid "Reset" -msgstr "リセット" - #: users/templates/users/user_password_verify.html:8 #: users/templates/users/user_password_verify.html:9 msgid "Verify password" @@ -6520,62 +6203,58 @@ msgid "Baidu Cloud" msgstr "百度雲" #: xpack/plugins/cloud/const.py:15 -msgid "JD Cloud" -msgstr "京東雲" - -#: xpack/plugins/cloud/const.py:16 msgid "Tencent Cloud" msgstr "テンセント雲" -#: xpack/plugins/cloud/const.py:17 +#: xpack/plugins/cloud/const.py:16 msgid "VMware" msgstr "VMware" -#: xpack/plugins/cloud/const.py:18 xpack/plugins/cloud/providers/nutanix.py:13 +#: xpack/plugins/cloud/const.py:17 xpack/plugins/cloud/providers/nutanix.py:13 msgid "Nutanix" msgstr "Nutanix" -#: xpack/plugins/cloud/const.py:19 +#: xpack/plugins/cloud/const.py:18 msgid "Huawei Private Cloud" msgstr "華為私有雲" -#: xpack/plugins/cloud/const.py:20 +#: xpack/plugins/cloud/const.py:19 msgid "Qingyun Private Cloud" msgstr "青雲私有雲" -#: xpack/plugins/cloud/const.py:21 +#: xpack/plugins/cloud/const.py:20 msgid "OpenStack" msgstr "OpenStack" -#: xpack/plugins/cloud/const.py:22 +#: xpack/plugins/cloud/const.py:21 msgid "Google Cloud Platform" msgstr "谷歌雲" -#: xpack/plugins/cloud/const.py:26 +#: xpack/plugins/cloud/const.py:25 msgid "Instance name" msgstr "インスタンス名" -#: xpack/plugins/cloud/const.py:27 +#: xpack/plugins/cloud/const.py:26 msgid "Instance name and Partial IP" msgstr "インスタンス名と部分IP" -#: xpack/plugins/cloud/const.py:32 +#: xpack/plugins/cloud/const.py:31 msgid "Succeed" msgstr "成功" -#: xpack/plugins/cloud/const.py:36 +#: xpack/plugins/cloud/const.py:35 msgid "Unsync" msgstr "同期していません" -#: xpack/plugins/cloud/const.py:37 +#: xpack/plugins/cloud/const.py:36 msgid "New Sync" msgstr "新しい同期" -#: xpack/plugins/cloud/const.py:38 +#: xpack/plugins/cloud/const.py:37 msgid "Synced" msgstr "同期済み" -#: xpack/plugins/cloud/const.py:39 +#: xpack/plugins/cloud/const.py:38 msgid "Released" msgstr "リリース済み" @@ -6587,6 +6266,10 @@ msgstr "クラウドセンター" msgid "Provider" msgstr "プロバイダー" +#: xpack/plugins/cloud/models.py:34 +msgid "Validity" +msgstr "有効性" + #: xpack/plugins/cloud/models.py:39 msgid "Cloud account" msgstr "クラウドアカウント" @@ -6748,13 +6431,11 @@ msgid "South America (São Paulo)" msgstr "南米 (サンパウロ)" #: xpack/plugins/cloud/providers/baiducloud.py:54 -#: xpack/plugins/cloud/providers/jdcloud.py:127 msgid "CN North-Beijing" msgstr "華北-北京" #: xpack/plugins/cloud/providers/baiducloud.py:55 #: xpack/plugins/cloud/providers/huaweicloud.py:40 -#: xpack/plugins/cloud/providers/jdcloud.py:130 msgid "CN South-Guangzhou" msgstr "華南-広州" @@ -6776,7 +6457,6 @@ msgid "CN North-Baoding" msgstr "華北-保定" #: xpack/plugins/cloud/providers/baiducloud.py:60 -#: xpack/plugins/cloud/providers/jdcloud.py:129 msgid "CN East-Shanghai" msgstr "華東-上海" @@ -6841,15 +6521,11 @@ msgstr "華北-ウランチャブ一" msgid "CN South-Guangzhou-InvitationOnly" msgstr "華南-広州-友好ユーザー環境" -#: xpack/plugins/cloud/providers/jdcloud.py:128 -msgid "CN East-Suqian" -msgstr "華東-宿遷" - -#: xpack/plugins/cloud/serializers/account.py:60 +#: xpack/plugins/cloud/serializers/account.py:59 msgid "Validity display" msgstr "有効表示" -#: xpack/plugins/cloud/serializers/account.py:61 +#: xpack/plugins/cloud/serializers/account.py:60 msgid "Provider display" msgstr "プロバイダ表示" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 88f701b6b..5b9f31b64 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d6a0d40534209f3ffab0b0ecfab7ec82f137156fc8e7b19ce1711036d14aeca -size 107709 +oid sha256:9c13775875a335e3c8dbc7f666af622c5aa12050100b15e616c210e8e3043e38 +size 103490 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index fb29c7d9c..b15b2c545 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-04-02 10:01+0800\n" +"POT-Creation-Date: 2022-04-12 17:03+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -28,31 +28,27 @@ msgstr "访问控制" #: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24 #: orgs/models.py:65 perms/models/base.py:83 rbac/models/role.py:29 #: settings/models.py:29 settings/serializers/sms.py:6 +#: terminal/models/endpoint.py:10 terminal/models/endpoint.py:53 #: terminal/models/storage.py:23 terminal/models/task.py:16 #: terminal/models/terminal.py:100 users/forms/profile.py:32 #: users/models/group.py:15 users/models/user.py:661 -#: users/templates/users/_select_user_modal.html:13 -#: users/templates/users/user_asset_permission.html:37 -#: users/templates/users/user_asset_permission.html:154 -#: users/templates/users/user_database_app_permission.html:36 #: xpack/plugins/cloud/models.py:28 msgid "Name" msgstr "名称" #: acls/models/base.py:27 assets/models/cmd_filter.py:84 -#: assets/models/user.py:247 +#: assets/models/user.py:247 terminal/models/endpoint.py:56 msgid "Priority" msgstr "优先级" #: acls/models/base.py:28 assets/models/cmd_filter.py:84 -#: assets/models/user.py:247 +#: assets/models/user.py:247 terminal/models/endpoint.py:57 msgid "1-100, the lower the value will be match first" msgstr "优先级可选范围为 1-100 (数值越小越优先)" #: acls/models/base.py:31 authentication/models.py:17 #: authentication/templates/authentication/_access_key_modal.html:32 #: perms/models/base.py:88 terminal/models/sharing.py:26 -#: users/templates/users/_select_user_modal.html:18 msgid "Active" msgstr "激活中" @@ -64,6 +60,7 @@ msgstr "激活中" #: assets/models/domain.py:64 assets/models/group.py:23 #: assets/models/label.py:23 ops/models/adhoc.py:38 orgs/models.py:68 #: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34 +#: terminal/models/endpoint.py:20 terminal/models/endpoint.py:63 #: terminal/models/storage.py:26 terminal/models/terminal.py:114 #: tickets/models/comment.py:24 tickets/models/ticket.py:154 #: users/models/group.py:16 users/models/user.py:698 @@ -90,16 +87,12 @@ msgstr "登录复核" #: assets/models/cmd_filter.py:30 assets/models/label.py:15 audits/models.py:37 #: audits/models.py:60 audits/models.py:85 audits/serializers.py:100 #: authentication/models.py:50 orgs/models.py:214 perms/models/base.py:84 -#: rbac/builtin.py:101 rbac/models/rolebinding.py:40 templates/index.html:78 +#: rbac/builtin.py:106 rbac/models/rolebinding.py:40 #: terminal/backends/command/models.py:19 -#: terminal/backends/command/serializers.py:12 terminal/models/session.py:42 +#: terminal/backends/command/serializers.py:12 terminal/models/session.py:44 #: terminal/notifications.py:91 terminal/notifications.py:139 #: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:886 #: users/models/user.py:917 users/serializers/group.py:19 -#: users/templates/users/user_asset_permission.html:38 -#: users/templates/users/user_asset_permission.html:64 -#: users/templates/users/user_database_app_permission.html:37 -#: users/templates/users/user_database_app_permission.html:58 msgid "User" msgstr "用户" @@ -111,10 +104,6 @@ msgstr "规则" #: acls/serializers/login_acl.py:17 acls/serializers/login_asset_acl.py:75 #: assets/models/cmd_filter.py:89 audits/models.py:61 audits/serializers.py:51 #: authentication/templates/authentication/_access_key_modal.html:34 -#: users/templates/users/_granted_assets.html:29 -#: users/templates/users/user_asset_permission.html:44 -#: users/templates/users/user_asset_permission.html:79 -#: users/templates/users/user_database_app_permission.html:42 msgid "Action" msgstr "动作" @@ -135,16 +124,13 @@ msgstr "系统用户" #: acls/models/login_asset_acl.py:22 #: applications/serializers/attrs/application_category/remote_app.py:36 -#: assets/models/asset.py:383 assets/models/authbook.py:19 +#: assets/models/asset.py:386 assets/models/authbook.py:19 #: assets/models/backup.py:31 assets/models/cmd_filter.py:38 #: assets/models/gathered_user.py:14 assets/serializers/label.py:30 #: assets/serializers/system_user.py:264 audits/models.py:39 -#: perms/models/asset_permission.py:23 templates/index.html:82 -#: terminal/backends/command/models.py:20 -#: terminal/backends/command/serializers.py:13 terminal/models/session.py:44 +#: perms/models/asset_permission.py:23 terminal/backends/command/models.py:20 +#: terminal/backends/command/serializers.py:13 terminal/models/session.py:46 #: terminal/notifications.py:90 -#: users/templates/users/user_asset_permission.html:40 -#: users/templates/users/user_asset_permission.html:70 #: xpack/plugins/change_auth_plan/models/asset.py:199 #: xpack/plugins/change_auth_plan/serializers/asset.py:180 #: xpack/plugins/cloud/models.py:223 @@ -171,7 +157,6 @@ msgstr "格式为逗号分隔的字符串, * 表示匹配所有. " #: authentication/templates/authentication/_msg_oauth_bind.html:9 #: ops/models/adhoc.py:159 users/forms/profile.py:31 users/models/user.py:659 #: users/templates/users/_msg_user_created.html:12 -#: users/templates/users/_select_user_modal.html:14 #: xpack/plugins/change_auth_plan/models/asset.py:34 #: xpack/plugins/change_auth_plan/models/asset.py:195 #: xpack/plugins/cloud/serializers/account_attrs.py:22 @@ -194,17 +179,13 @@ msgstr "" #: authentication/templates/authentication/_msg_oauth_bind.html:12 #: authentication/templates/authentication/_msg_rest_password_success.html:8 #: authentication/templates/authentication/_msg_rest_public_key_success.html:8 -#: settings/serializers/terminal.py:8 -#: users/templates/users/_granted_assets.html:26 -#: users/templates/users/user_asset_permission.html:156 +#: settings/serializers/terminal.py:8 terminal/serializers/endpoint.py:37 msgid "IP" msgstr "IP" #: acls/serializers/login_asset_acl.py:35 assets/models/asset.py:211 #: assets/serializers/account.py:14 assets/serializers/gathered_user.py:23 #: settings/serializers/terminal.py:7 -#: users/templates/users/_granted_assets.html:25 -#: users/templates/users/user_asset_permission.html:157 msgid "Hostname" msgstr "主机名" @@ -216,7 +197,7 @@ msgstr "格式为逗号分隔的字符串, * 表示匹配所有. 可选的协议 #: acls/serializers/login_asset_acl.py:55 assets/models/asset.py:213 #: assets/models/domain.py:62 assets/models/user.py:248 -#: terminal/serializers/session.py:30 terminal/serializers/storage.py:69 +#: terminal/serializers/session.py:30 terminal/serializers/storage.py:67 msgid "Protocol" msgstr "协议" @@ -280,13 +261,7 @@ msgstr "应用程序" #: assets/models/cmd_filter.py:42 assets/models/user.py:338 audits/models.py:40 #: perms/models/application_permission.py:33 #: perms/models/asset_permission.py:25 terminal/backends/command/models.py:21 -#: terminal/backends/command/serializers.py:35 terminal/models/session.py:46 -#: users/templates/users/_granted_assets.html:27 -#: users/templates/users/user_asset_permission.html:42 -#: users/templates/users/user_asset_permission.html:76 -#: users/templates/users/user_asset_permission.html:159 -#: users/templates/users/user_database_app_permission.html:40 -#: users/templates/users/user_database_app_permission.html:67 +#: terminal/backends/command/serializers.py:35 terminal/models/session.py:48 #: xpack/plugins/change_auth_plan/models/app.py:36 #: xpack/plugins/change_auth_plan/models/app.py:147 #: xpack/plugins/change_auth_plan/serializers/app.py:65 @@ -338,7 +313,7 @@ msgid "Domain" msgstr "网域" #: applications/models/application.py:228 xpack/plugins/cloud/models.py:33 -#: xpack/plugins/cloud/serializers/account.py:59 +#: xpack/plugins/cloud/serializers/account.py:58 msgid "Attrs" msgstr "属性" @@ -346,7 +321,7 @@ msgstr "属性" msgid "Can match application" msgstr "匹配应用" -#: applications/models/application.py:286 +#: applications/models/application.py:306 msgid "Application user" msgstr "应用用户" @@ -404,6 +379,7 @@ msgstr "集群" #: applications/serializers/attrs/application_category/db.py:11 #: ops/models/adhoc.py:157 settings/serializers/auth/radius.py:14 +#: terminal/models/endpoint.py:11 #: xpack/plugins/cloud/serializers/account_attrs.py:68 msgid "Host" msgstr "主机" @@ -634,27 +610,27 @@ msgstr "标签管理" msgid "Created by" msgstr "创建者" -#: assets/models/asset.py:386 +#: assets/models/asset.py:389 msgid "Can refresh asset hardware info" msgstr "可以更新资产硬件信息" -#: assets/models/asset.py:387 +#: assets/models/asset.py:390 msgid "Can test asset connectivity" msgstr "可以测试资产连接性" -#: assets/models/asset.py:388 +#: assets/models/asset.py:391 msgid "Can push system user to asset" msgstr "可以推送系统用户到资产" -#: assets/models/asset.py:389 +#: assets/models/asset.py:392 msgid "Can match asset" msgstr "可以匹配资产" -#: assets/models/asset.py:390 +#: assets/models/asset.py:393 msgid "Add asset to node" msgstr "添加资产到节点" -#: assets/models/asset.py:391 +#: assets/models/asset.py:394 msgid "Move asset to node" msgstr "移动资产到节点" @@ -701,7 +677,7 @@ msgid "Timing trigger" msgstr "定时触发" #: assets/models/backup.py:105 audits/models.py:44 ops/models/command.py:31 -#: perms/models/base.py:89 terminal/models/session.py:56 +#: perms/models/base.py:89 terminal/models/session.py:58 #: tickets/serializers/ticket/meta/ticket_type/apply_application.py:55 #: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:57 #: xpack/plugins/change_auth_plan/models/base.py:112 @@ -762,7 +738,7 @@ msgstr "成功" #: assets/models/base.py:32 audits/models.py:116 #: xpack/plugins/change_auth_plan/serializers/app.py:88 #: xpack/plugins/change_auth_plan/serializers/asset.py:198 -#: xpack/plugins/cloud/const.py:31 +#: xpack/plugins/cloud/const.py:30 msgid "Failed" msgstr "失败" @@ -777,9 +753,8 @@ msgstr "校验日期" #: assets/models/base.py:177 audits/signal_handlers.py:68 #: authentication/forms.py:22 #: authentication/templates/authentication/login.html:181 -#: settings/serializers/auth/ldap.py:44 users/forms/profile.py:21 +#: settings/serializers/auth/ldap.py:43 users/forms/profile.py:21 #: users/templates/users/_msg_user_created.html:13 -#: users/templates/users/user_password_update.html:43 #: users/templates/users/user_password_verify.html:18 #: xpack/plugins/change_auth_plan/models/base.py:42 #: xpack/plugins/change_auth_plan/models/base.py:121 @@ -844,11 +819,6 @@ msgstr "默认Cluster" #: assets/models/cmd_filter.py:34 perms/models/base.py:86 #: users/models/group.py:31 users/models/user.py:667 -#: users/templates/users/_select_user_modal.html:16 -#: users/templates/users/user_asset_permission.html:39 -#: users/templates/users/user_asset_permission.html:67 -#: users/templates/users/user_database_app_permission.html:38 -#: users/templates/users/user_database_app_permission.html:61 msgid "User group" msgstr "用户组" @@ -861,7 +831,7 @@ msgid "Regex" msgstr "正则表达式" #: assets/models/cmd_filter.py:68 ops/models/command.py:26 -#: terminal/backends/command/serializers.py:14 terminal/models/session.py:53 +#: terminal/backends/command/serializers.py:14 terminal/models/session.py:55 #: terminal/templates/terminal/_msg_command_alert.html:12 #: terminal/templates/terminal/_msg_command_execute_alert.html:10 msgid "Command" @@ -961,7 +931,7 @@ msgstr "标签" msgid "New node" msgstr "新节点" -#: assets/models/node.py:474 users/templates/users/_granted_assets.html:130 +#: assets/models/node.py:474 msgid "empty" msgstr "空" @@ -978,9 +948,6 @@ msgid "Parent key" msgstr "ssh私钥" #: assets/models/node.py:559 assets/serializers/system_user.py:263 -#: users/templates/users/user_asset_permission.html:41 -#: users/templates/users/user_asset_permission.html:73 -#: users/templates/users/user_asset_permission.html:158 #: xpack/plugins/cloud/models.py:96 xpack/plugins/cloud/serializers/task.py:69 msgid "Node" msgstr "节点" @@ -1132,7 +1099,7 @@ msgid "Actions" msgstr "动作" #: assets/serializers/backup.py:31 ops/mixin.py:106 ops/mixin.py:147 -#: settings/serializers/auth/ldap.py:59 +#: settings/serializers/auth/ldap.py:62 #: xpack/plugins/change_auth_plan/serializers/base.py:42 msgid "Periodic perform" msgstr "定时执行" @@ -1376,8 +1343,7 @@ msgstr "日志审计" #: audits/models.py:27 audits/models.py:57 #: authentication/templates/authentication/_access_key_modal.html:65 -#: rbac/tree.py:166 users/templates/users/user_asset_permission.html:128 -#: users/templates/users/user_database_app_permission.html:111 +#: rbac/tree.py:166 msgid "Delete" msgstr "删除" @@ -1406,7 +1372,7 @@ msgid "Symlink" msgstr "建立软链接" #: audits/models.py:38 audits/models.py:64 audits/models.py:87 -#: terminal/models/session.py:49 terminal/models/sharing.py:82 +#: terminal/models/session.py:51 terminal/models/sharing.py:82 msgid "Remote addr" msgstr "远端地址" @@ -1436,8 +1402,6 @@ msgstr "创建" #: audits/models.py:56 rbac/tree.py:165 templates/_csv_import_export.html:18 #: templates/_csv_update_modal.html:6 -#: users/templates/users/user_asset_permission.html:127 -#: users/templates/users/user_database_app_permission.html:110 msgid "Update" msgstr "更新" @@ -1546,7 +1510,7 @@ msgstr "主机名称" msgid "Result" msgstr "结果" -#: audits/serializers.py:98 terminal/serializers/storage.py:161 +#: audits/serializers.py:98 terminal/serializers/storage.py:156 msgid "Hosts" msgstr "主机" @@ -1657,7 +1621,6 @@ msgid "{AssetPermission} REMOVE {UserGroup}" msgstr "{AssetPermission} 移除 {UserGroup}" #: audits/signal_handlers.py:131 perms/models/asset_permission.py:29 -#: users/templates/users/_user_detail_nav_header.html:31 msgid "Asset permission" msgstr "资产授权" @@ -1755,7 +1718,7 @@ msgstr "{ApplicationPermission} 添加 {SystemUser}" msgid "{ApplicationPermission} REMOVE {SystemUser}" msgstr "{ApplicationPermission} 移除 {SystemUser}" -#: authentication/api/connection_token.py:313 +#: authentication/api/connection_token.py:328 msgid "Invalid token" msgstr "无效的令牌" @@ -2044,7 +2007,7 @@ msgstr "该 MFA ({}) 方式没有启用" msgid "Please change your password" msgstr "请修改密码" -#: authentication/models.py:33 terminal/serializers/storage.py:30 +#: authentication/models.py:33 terminal/serializers/storage.py:28 msgid "Access key" msgstr "API key" @@ -2108,7 +2071,6 @@ msgid "Date" msgstr "日期" #: authentication/templates/authentication/_access_key_modal.html:48 -#: users/templates/users/_granted_assets.html:75 msgid "Show" msgstr "显示" @@ -2168,7 +2130,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:295 ops/tasks.py:145 ops/tasks.py:148 +#: jumpserver/conf.py:296 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 #: users/templates/users/_msg_account_expire_reminder.html:4 @@ -2620,11 +2582,11 @@ msgstr "不能包含特殊字符" msgid "The mobile phone number format is incorrect" msgstr "手机号格式不正确" -#: jumpserver/conf.py:294 +#: jumpserver/conf.py:295 msgid "Create account successfully" msgstr "创建账号成功" -#: jumpserver/conf.py:296 +#: jumpserver/conf.py:297 msgid "Your account has been created successfully" msgstr "你的账号已创建成功" @@ -2685,12 +2647,12 @@ msgid "App ops" msgstr "作业中心" #: ops/mixin.py:29 ops/mixin.py:92 ops/mixin.py:162 -#: settings/serializers/auth/ldap.py:66 +#: settings/serializers/auth/ldap.py:69 msgid "Cycle perform" msgstr "周期执行" #: ops/mixin.py:33 ops/mixin.py:90 ops/mixin.py:109 ops/mixin.py:150 -#: settings/serializers/auth/ldap.py:63 +#: settings/serializers/auth/ldap.py:66 msgid "Regularly perform" msgstr "定期执行" @@ -2877,7 +2839,8 @@ msgstr "组织管理" #: orgs/mixins/models.py:46 orgs/mixins/serializers.py:25 orgs/models.py:80 #: orgs/models.py:211 rbac/const.py:7 rbac/models/rolebinding.py:47 -#: rbac/serializers/rolebinding.py:40 tickets/serializers/ticket/ticket.py:77 +#: rbac/serializers/rolebinding.py:40 settings/serializers/auth/ldap.py:59 +#: tickets/serializers/ticket/ticket.py:77 msgid "Organization" msgstr "组织" @@ -2890,7 +2853,7 @@ msgid "Can view root org" msgstr "可以查看全局组织" #: orgs/models.py:216 rbac/models/role.py:46 rbac/models/rolebinding.py:43 -#: users/models/user.py:671 users/templates/users/_select_user_modal.html:15 +#: users/models/user.py:671 msgid "Role" msgstr "角色" @@ -3114,27 +3077,27 @@ msgstr "{} 至少有一个系统角色" msgid "RBAC" msgstr "RBAC" -#: rbac/builtin.py:92 +#: rbac/builtin.py:97 msgid "SystemAdmin" msgstr "系统管理员" -#: rbac/builtin.py:95 +#: rbac/builtin.py:100 msgid "SystemAuditor" msgstr "系统审计员" -#: rbac/builtin.py:98 +#: rbac/builtin.py:103 msgid "SystemComponent" msgstr "系统组件" -#: rbac/builtin.py:104 +#: rbac/builtin.py:109 msgid "OrgAdmin" msgstr "组织管理员" -#: rbac/builtin.py:107 +#: rbac/builtin.py:112 msgid "OrgAuditor" msgstr "组织审计员" -#: rbac/builtin.py:110 +#: rbac/builtin.py:115 msgid "OrgUser" msgstr "组织用户" @@ -3338,11 +3301,11 @@ msgstr "同步正在运行,请稍等" msgid "Synchronization error: {}" msgstr "同步错误: {}" -#: settings/api/ldap.py:211 +#: settings/api/ldap.py:213 msgid "Get ldap users is None" msgstr "获取 LDAP 用户为 None" -#: settings/api/ldap.py:220 +#: settings/api/ldap.py:222 msgid "Imported {} users successfully (Organization: {})" msgstr "成功导入 {} 个用户 ( 组织: {} )" @@ -3470,15 +3433,15 @@ msgstr "启用钉钉认证" msgid "Enable FeiShu Auth" msgstr "启用飞书认证" -#: settings/serializers/auth/ldap.py:39 +#: settings/serializers/auth/ldap.py:38 msgid "LDAP server" msgstr "LDAP 地址" -#: settings/serializers/auth/ldap.py:40 +#: settings/serializers/auth/ldap.py:39 msgid "eg: ldap://localhost:389" msgstr "如: ldap://localhost:389" -#: settings/serializers/auth/ldap.py:42 +#: settings/serializers/auth/ldap.py:41 msgid "Bind DN" msgstr "绑定 DN" @@ -3511,15 +3474,15 @@ msgstr "" "用户属性映射代表怎样将LDAP中用户属性映射到jumpserver用户上,username, name," "email 是jumpserver的用户需要属性" -#: settings/serializers/auth/ldap.py:70 +#: settings/serializers/auth/ldap.py:73 msgid "Connect timeout" msgstr "连接超时时间" -#: settings/serializers/auth/ldap.py:72 +#: settings/serializers/auth/ldap.py:75 msgid "Search paged size" msgstr "搜索分页数量" -#: settings/serializers/auth/ldap.py:74 +#: settings/serializers/auth/ldap.py:77 msgid "Enable LDAP auth" msgstr "启用 LDAP 认证" @@ -4194,61 +4157,13 @@ msgid "" "device through Telnet, set this parameter" msgstr "不同设备登录成功提示不一样,所以如果 telnet 不能正常登录,可以这里设置" -#: settings/serializers/terminal.py:37 -msgid "RDP address" -msgstr "RDP 地址" - -#: settings/serializers/terminal.py:38 -msgid "RDP visit address, eg: dev.jumpserver.org:3389" -msgstr "RDP 访问地址, 如: dev.jumpserver.org:3389" - -#: settings/serializers/terminal.py:40 -msgid "Enable XRDP" -msgstr "启用 XRDP 服务" - -#: settings/serializers/terminal.py:43 -msgid "Koko host" -msgstr "KOKO 主机地址" - -#: settings/serializers/terminal.py:46 -msgid "Koko ssh port" -msgstr "KOKO ssh 端口" - -#: settings/serializers/terminal.py:49 +#: settings/serializers/terminal.py:36 msgid "Enable database proxy" msgstr "启用数据库组件" -#: settings/serializers/terminal.py:51 -msgid "Database proxy host" -msgstr "数据库主机地址" - -#: settings/serializers/terminal.py:52 -msgid "Database proxy host, eg: dev.jumpserver.org" -msgstr "数据库组件地址, 如: dev.jumpserver.org (没有端口, 不同协议端口不同)" - -#: settings/serializers/terminal.py:55 -msgid "MySQL port" -msgstr "MySQL 协议端口" - -#: settings/serializers/terminal.py:56 -msgid "MySQL protocol listen port" -msgstr "MySQL 协议监听端口" - -#: settings/serializers/terminal.py:59 -msgid "MariaDB port" -msgstr "MariaDB 端口" - -#: settings/serializers/terminal.py:60 -msgid "MariaDB protocol listen port" -msgstr "MariaDB 协议监听的端口" - -#: settings/serializers/terminal.py:63 -msgid "PostgreSQL port" -msgstr "PostgreSQL 端口" - -#: settings/serializers/terminal.py:64 -msgid "PostgreSQL protocol listen port" -msgstr "PostgreSQL 协议监听端口" +#: settings/serializers/terminal.py:37 +msgid "Enable XRDP" +msgstr "启用 XRDP 服务" #: settings/utils/ldap.py:417 msgid "ldap:// or ldaps:// protocol is used." @@ -4351,10 +4266,6 @@ msgstr "认证失败: (未知): {}" msgid "Authentication success: {}" msgstr "认证成功: {}" -#: templates/_base_list.html:37 -msgid "Search" -msgstr "搜索" - #: templates/_csv_import_export.html:8 msgid "Export" msgstr "导出" @@ -4400,7 +4311,6 @@ msgid "Commercial support" msgstr "商业支持" #: templates/_header_bar.html:76 users/forms/profile.py:43 -#: users/templates/users/user_password_update.html:39 msgid "Profile" msgstr "个人信息" @@ -4505,173 +4415,14 @@ msgstr "等待:" msgid "The verification code has been sent" msgstr "验证码已发送" -#: templates/_pagination.html:59 -msgid "" -"Displays the results of items _START_ to _END_; A total of _TOTAL_ entries" -msgstr "显示第 _START_ 至 _END_ 项结果; 总共 _TOTAL_ 项" - #: templates/_without_nav_base.html:26 msgid "Home page" msgstr "首页" -#: templates/delete_confirm.html:6 -msgid "Confirm delete" -msgstr "确认删除" - -#: templates/delete_confirm.html:11 -msgid "Are you sure delete" -msgstr "您确定删除吗?" - #: templates/flash_message_standalone.html:25 msgid "Cancel" msgstr "取消" -#: templates/index.html:11 -msgid "Total users" -msgstr "用户总数" - -#: templates/index.html:23 -msgid "Total assets" -msgstr "资产总数" - -#: templates/index.html:36 -msgid "Online users" -msgstr "在线用户" - -#: templates/index.html:49 -msgid "Online sessions" -msgstr "在线会话" - -#: templates/index.html:61 -msgid "In the past week, a total of " -msgstr "过去一周, 共有 " - -#: templates/index.html:61 -msgid " users have logged in " -msgstr " 位用户登录 " - -#: templates/index.html:61 -msgid " times asset." -msgstr " 次资产." - -#: templates/index.html:69 -msgid "Active user asset ratio" -msgstr "活跃用户资产占比" - -#: templates/index.html:72 -msgid "" -"The following graphs describe the percentage of active users per month and " -"assets per user host per month, respectively." -msgstr "以下图形分别描述一个月活跃用户和资产占所有用户主机的百分比" - -#: templates/index.html:97 templates/index.html:112 -msgid "Top 10 assets in a week" -msgstr "一周Top10资产" - -#: templates/index.html:113 -msgid "Login frequency and last login record." -msgstr "登录次数及最近一次登录记录." - -#: templates/index.html:122 -msgid "Last 10 login" -msgstr "最近十次登录" - -#: templates/index.html:128 -msgid "Login record" -msgstr "登录记录" - -#: templates/index.html:129 -msgid "Last 10 login records." -msgstr "最近十次登录记录." - -#: templates/index.html:143 templates/index.html:158 -msgid "Top 10 users in a week" -msgstr "一周Top10用户" - -#: templates/index.html:159 -msgid "User login frequency and last login record." -msgstr "用户登录次数及最近一次登录记录" - -#: templates/index.html:184 -msgid "Monthly data overview" -msgstr "月数据总览" - -#: templates/index.html:185 -msgid "History summary in one month" -msgstr "一个月内历史汇总" - -#: templates/index.html:193 templates/index.html:217 -msgid "Login count" -msgstr "登录次数" - -#: templates/index.html:193 templates/index.html:224 -msgid "Active users" -msgstr "活跃用户" - -#: templates/index.html:193 templates/index.html:231 -msgid "Active assets" -msgstr "活跃资产" - -#: templates/index.html:262 templates/index.html:313 -msgid "Monthly active users" -msgstr "月活跃用户" - -#: templates/index.html:262 templates/index.html:314 -msgid "Disable user" -msgstr "禁用用户" - -#: templates/index.html:262 templates/index.html:315 -msgid "Month not logged in user" -msgstr "月未登录用户" - -#: templates/index.html:288 templates/index.html:368 -msgid "Access to the source" -msgstr "访问来源" - -#: templates/index.html:342 -msgid "Month is logged into the asset" -msgstr "月被登录资产" - -#: templates/index.html:342 templates/index.html:393 -msgid "Disable host" -msgstr "禁用主机" - -#: templates/index.html:342 templates/index.html:394 -msgid "Month not logged on host" -msgstr "月未登录主机" - -#: templates/index.html:392 -msgid "Month is logged into the host" -msgstr "月被登录主机" - -#: templates/index.html:466 -msgid " times/week" -msgstr " 次/周" - -#: templates/index.html:491 templates/index.html:527 -msgid " times" -msgstr " 次" - -#: templates/index.html:494 templates/index.html:530 -msgid "The time last logged in" -msgstr "最近一次登录日期" - -#: templates/index.html:495 templates/index.html:531 -msgid "At" -msgstr "于" - -#: templates/index.html:510 templates/index.html:545 templates/index.html:580 -msgid "(No)" -msgstr "(暂无)" - -#: templates/index.html:561 -msgid "Before" -msgstr "前" - -#: templates/index.html:562 -msgid "Login in " -msgstr "登录了" - #: templates/resource_download.html:18 templates/resource_download.html:24 #: templates/resource_download.html:25 templates/resource_download.html:30 msgid "Client" @@ -4713,19 +4464,23 @@ msgstr "Jmservisor 是在 windows 远程应用发布服务器中用来拉起远 msgid "Filters" msgstr "过滤" -#: terminal/api/session.py:211 +#: terminal/api/endpoint.py:65 +msgid "Not found protocol query params" +msgstr "" + +#: terminal/api/session.py:210 msgid "Session does not exist: {}" msgstr "会话不存在: {}" -#: terminal/api/session.py:214 +#: terminal/api/session.py:213 msgid "Session is finished or the protocol not supported" msgstr "会话已经完成或协议不支持" -#: terminal/api/session.py:219 +#: terminal/api/session.py:218 msgid "User does not exist: {}" msgstr "用户不存在: {}" -#: terminal/api/session.py:227 +#: terminal/api/session.py:226 msgid "User does not have permission" msgstr "用户没有权限" @@ -4769,7 +4524,7 @@ msgstr "有在线会话" msgid "Terminals" msgstr "终端管理" -#: terminal/backends/command/es.py:27 +#: terminal/backends/command/es.py:26 msgid "Invalid elasticsearch config" msgstr "无效的 Elasticsearch 配置" @@ -4826,7 +4581,6 @@ msgid "High" msgstr "较高" #: terminal/const.py:35 users/templates/users/reset_password.html:50 -#: users/templates/users/user_password_update.html:104 msgid "Normal" msgstr "正常" @@ -4846,6 +4600,49 @@ msgstr "存储无效" msgid "Command record" msgstr "命令记录" +#: terminal/models/endpoint.py:13 +msgid "HTTPS Port" +msgstr "HTTPS 端口" + +#: terminal/models/endpoint.py:14 terminal/models/terminal.py:107 +msgid "HTTP Port" +msgstr "HTTP 端口" + +#: terminal/models/endpoint.py:15 terminal/models/terminal.py:106 +msgid "SSH Port" +msgstr "SSH 端口" + +#: terminal/models/endpoint.py:16 +msgid "RDP Port" +msgstr "RDP 端口" + +#: terminal/models/endpoint.py:17 +msgid "MySQL Port" +msgstr "MySQL 端口" + +#: terminal/models/endpoint.py:18 +msgid "MariaDB Port" +msgstr "MariaDB 端口" + +#: terminal/models/endpoint.py:19 +msgid "PostgreSQL Port" +msgstr "PostgreSQL 端口" + +#: terminal/models/endpoint.py:25 terminal/models/endpoint.py:61 +#: terminal/serializers/endpoint.py:40 terminal/serializers/storage.py:37 +#: terminal/serializers/storage.py:49 terminal/serializers/storage.py:79 +#: terminal/serializers/storage.py:89 terminal/serializers/storage.py:97 +msgid "Endpoint" +msgstr "端点" + +#: terminal/models/endpoint.py:54 +msgid "IP group" +msgstr "IP 组" + +#: terminal/models/endpoint.py:66 +msgid "Endpoint rule" +msgstr "端点规则" + #: terminal/models/replay.py:12 msgid "Session replay" msgstr "会话录像" @@ -4858,35 +4655,35 @@ msgstr "可以上传会话录像" msgid "Can download session replay" msgstr "可以下载会话录像" -#: terminal/models/session.py:48 terminal/models/sharing.py:87 +#: terminal/models/session.py:50 terminal/models/sharing.py:87 msgid "Login from" msgstr "登录来源" -#: terminal/models/session.py:52 +#: terminal/models/session.py:54 msgid "Replay" msgstr "回放" -#: terminal/models/session.py:57 +#: terminal/models/session.py:59 msgid "Date end" msgstr "结束日期" -#: terminal/models/session.py:242 +#: terminal/models/session.py:251 msgid "Session record" msgstr "会话记录" -#: terminal/models/session.py:244 +#: terminal/models/session.py:253 msgid "Can monitor session" msgstr "可以监控会话" -#: terminal/models/session.py:245 +#: terminal/models/session.py:254 msgid "Can share session" msgstr "可以分享会话" -#: terminal/models/session.py:246 +#: terminal/models/session.py:255 msgid "Can terminate session" msgstr "可以终断会话" -#: terminal/models/session.py:247 +#: terminal/models/session.py:256 msgid "Can validate session action perm" msgstr "可以验证会话动作权限" @@ -4995,14 +4792,6 @@ msgstr "其它参数" msgid "type" msgstr "类型" -#: terminal/models/terminal.py:106 -msgid "SSH Port" -msgstr "SSH端口" - -#: terminal/models/terminal.py:107 -msgid "HTTP Port" -msgstr "HTTP端口" - #: terminal/models/terminal.py:183 terminal/serializers/session.py:38 msgid "Terminal" msgstr "终端" @@ -5059,65 +4848,59 @@ msgstr "是否可中断" msgid "Command amount" msgstr "命令数量" -#: terminal/serializers/storage.py:21 +#: terminal/serializers/storage.py:19 msgid "Endpoint invalid: remove path `{}`" msgstr "端点无效: 移除路径 `{}`" -#: terminal/serializers/storage.py:27 +#: terminal/serializers/storage.py:25 msgid "Bucket" msgstr "桶名称" -#: terminal/serializers/storage.py:34 users/models/user.py:695 +#: terminal/serializers/storage.py:32 users/models/user.py:695 msgid "Secret key" msgstr "密钥" -#: terminal/serializers/storage.py:39 terminal/serializers/storage.py:51 -#: terminal/serializers/storage.py:81 terminal/serializers/storage.py:91 -#: terminal/serializers/storage.py:99 -msgid "Endpoint" -msgstr "端点" - -#: terminal/serializers/storage.py:66 xpack/plugins/cloud/models.py:220 +#: terminal/serializers/storage.py:64 xpack/plugins/cloud/models.py:220 msgid "Region" msgstr "地域" -#: terminal/serializers/storage.py:110 +#: terminal/serializers/storage.py:108 msgid "Container name" msgstr "容器名称" -#: terminal/serializers/storage.py:112 +#: terminal/serializers/storage.py:110 msgid "Account name" msgstr "账号名称" -#: terminal/serializers/storage.py:113 +#: terminal/serializers/storage.py:111 msgid "Account key" msgstr "账号密钥" -#: terminal/serializers/storage.py:116 +#: terminal/serializers/storage.py:114 msgid "Endpoint suffix" msgstr "端点后缀" -#: terminal/serializers/storage.py:138 +#: terminal/serializers/storage.py:134 msgid "The address format is incorrect" msgstr "地址格式不正确" -#: terminal/serializers/storage.py:145 +#: terminal/serializers/storage.py:141 msgid "Host invalid" msgstr "主机无效" -#: terminal/serializers/storage.py:148 +#: terminal/serializers/storage.py:144 msgid "Port invalid" msgstr "端口无效" -#: terminal/serializers/storage.py:164 +#: terminal/serializers/storage.py:159 msgid "Index" msgstr "索引" -#: terminal/serializers/storage.py:166 +#: terminal/serializers/storage.py:161 msgid "Doc type" msgstr "文档类型" -#: terminal/serializers/storage.py:168 +#: terminal/serializers/storage.py:163 msgid "Ignore Certificate Verification" msgstr "忽略证书认证" @@ -5671,7 +5454,6 @@ msgid "Not a valid ssh public key" msgstr "SSH密钥不合法" #: users/forms/profile.py:160 users/models/user.py:692 -#: users/templates/users/user_password_update.html:48 msgid "Public key" msgstr "SSH公钥" @@ -5880,10 +5662,6 @@ msgstr "为了安全,仅列出几个用户" msgid "name not unique" msgstr "名称重复" -#: users/templates/users/_granted_assets.html:7 -msgid "Loading" -msgstr "加载中" - #: users/templates/users/_msg_account_expire_reminder.html:7 msgid "Your account will expire in" msgstr "您的账号即将过期" @@ -5936,69 +5714,11 @@ msgstr "你的 SSH 密钥已经被管理员重置" msgid "click here to set your password" msgstr "点击这里设置密码" -#: users/templates/users/_select_user_modal.html:5 -msgid "Please Select User" -msgstr "选择用户" - -#: users/templates/users/_select_user_modal.html:17 -msgid "Asset num" -msgstr "资产数量" - -#: users/templates/users/_user_detail_nav_header.html:11 -msgid "User detail" -msgstr "用户详情" - -#: users/templates/users/_user_detail_nav_header.html:15 -msgid "User permissions" -msgstr "用户授权" - -#: users/templates/users/_user_detail_nav_header.html:23 -msgid "Asset granted" -msgstr "授权的资产" - -#: users/templates/users/_user_detail_nav_header.html:40 -msgid "RemoteApp granted" -msgstr "授权的远程应用" - -#: users/templates/users/_user_detail_nav_header.html:47 -msgid "RemoteApp permission" -msgstr "远程应用授权" - -#: users/templates/users/_user_detail_nav_header.html:54 -msgid "DatabaseApp granted" -msgstr "授权的数据库应用" - -#: users/templates/users/_user_detail_nav_header.html:61 -msgid "DatabaseApp permission" -msgstr "数据库应用授权" - -#: users/templates/users/_user_update_pk_modal.html:4 -msgid "Update User SSH Public Key" -msgstr "更新SSH密钥" - -#: users/templates/users/first_login.html:6 -#: users/templates/users/first_login_done.html:19 -msgid "First Login" -msgstr "首次登录" - -#: users/templates/users/first_login_done.html:31 -msgid "Welcome to use jumpserver, visit " -msgstr "欢迎使用 JumpServer 堡垒机" - -#: users/templates/users/first_login_done.html:32 -msgid "Use guide" -msgstr "向导" - -#: users/templates/users/first_login_done.html:32 -msgid " for more information" -msgstr "获取更多信息" - #: users/templates/users/forgot_password.html:23 msgid "Input your email, that will send a mail to your" msgstr "输入您的邮箱, 将会发一封重置邮件到您的邮箱中" #: users/templates/users/forgot_password.html:32 -#: users/templates/users/user_password_update.html:75 msgid "Submit" msgstr "提交" @@ -6015,12 +5735,10 @@ msgid "MFA setting" msgstr "设置 MFA 多因子认证" #: users/templates/users/reset_password.html:23 -#: users/templates/users/user_password_update.html:64 msgid "Your password must satisfy" msgstr "您的密码必须满足:" #: users/templates/users/reset_password.html:24 -#: users/templates/users/user_password_update.html:65 msgid "Password strength" msgstr "密码强度:" @@ -6029,54 +5747,25 @@ msgid "Setting" msgstr "设置" #: users/templates/users/reset_password.html:48 -#: users/templates/users/user_password_update.html:102 msgid "Very weak" msgstr "很弱" #: users/templates/users/reset_password.html:49 -#: users/templates/users/user_password_update.html:103 msgid "Weak" msgstr "弱" #: users/templates/users/reset_password.html:51 -#: users/templates/users/user_password_update.html:105 msgid "Medium" msgstr "一般" #: users/templates/users/reset_password.html:52 -#: users/templates/users/user_password_update.html:106 msgid "Strong" msgstr "强" #: users/templates/users/reset_password.html:53 -#: users/templates/users/user_password_update.html:107 msgid "Very strong" msgstr "很强" -#: users/templates/users/user_asset_permission.html:43 -#: users/templates/users/user_asset_permission.html:155 -#: users/templates/users/user_database_app_permission.html:41 -#: xpack/plugins/cloud/models.py:34 -msgid "Validity" -msgstr "有效" - -#: users/templates/users/user_asset_permission.html:160 -msgid "Inherit" -msgstr "继承" - -#: users/templates/users/user_asset_permission.html:161 -msgid "Include" -msgstr "包含" - -#: users/templates/users/user_asset_permission.html:162 -msgid "Exclude" -msgstr "不包含" - -#: users/templates/users/user_database_app_permission.html:39 -#: users/templates/users/user_database_app_permission.html:64 -msgid "DatabaseApp" -msgstr "数据库应用" - #: users/templates/users/user_otp_check_password.html:6 msgid "Enable OTP" msgstr "启用 MFA(OTP)" @@ -6120,10 +5809,6 @@ msgid "" "installed, go to the next step directly)." msgstr "安装完成后点击下一步进入绑定页面(如已安装,直接进入下一步)" -#: users/templates/users/user_password_update.html:74 -msgid "Reset" -msgstr "重置" - #: users/templates/users/user_password_verify.html:8 #: users/templates/users/user_password_verify.html:9 msgid "Verify password" @@ -6430,62 +6115,58 @@ msgid "Baidu Cloud" msgstr "百度云" #: xpack/plugins/cloud/const.py:15 -msgid "JD Cloud" -msgstr "京东云" - -#: xpack/plugins/cloud/const.py:16 msgid "Tencent Cloud" msgstr "腾讯云" -#: xpack/plugins/cloud/const.py:17 +#: xpack/plugins/cloud/const.py:16 msgid "VMware" msgstr "VMware" -#: xpack/plugins/cloud/const.py:18 xpack/plugins/cloud/providers/nutanix.py:13 +#: xpack/plugins/cloud/const.py:17 xpack/plugins/cloud/providers/nutanix.py:13 msgid "Nutanix" msgstr "Nutanix" -#: xpack/plugins/cloud/const.py:19 +#: xpack/plugins/cloud/const.py:18 msgid "Huawei Private Cloud" msgstr "华为私有云" -#: xpack/plugins/cloud/const.py:20 +#: xpack/plugins/cloud/const.py:19 msgid "Qingyun Private Cloud" msgstr "青云私有云" -#: xpack/plugins/cloud/const.py:21 +#: xpack/plugins/cloud/const.py:20 msgid "OpenStack" msgstr "OpenStack" -#: xpack/plugins/cloud/const.py:22 +#: xpack/plugins/cloud/const.py:21 msgid "Google Cloud Platform" msgstr "谷歌云" -#: xpack/plugins/cloud/const.py:26 +#: xpack/plugins/cloud/const.py:25 msgid "Instance name" msgstr "实例名称" -#: xpack/plugins/cloud/const.py:27 +#: xpack/plugins/cloud/const.py:26 msgid "Instance name and Partial IP" msgstr "实例名称和部分IP" -#: xpack/plugins/cloud/const.py:32 +#: xpack/plugins/cloud/const.py:31 msgid "Succeed" msgstr "成功" -#: xpack/plugins/cloud/const.py:36 +#: xpack/plugins/cloud/const.py:35 msgid "Unsync" msgstr "未同步" -#: xpack/plugins/cloud/const.py:37 +#: xpack/plugins/cloud/const.py:36 msgid "New Sync" msgstr "新同步" -#: xpack/plugins/cloud/const.py:38 +#: xpack/plugins/cloud/const.py:37 msgid "Synced" msgstr "已同步" -#: xpack/plugins/cloud/const.py:39 +#: xpack/plugins/cloud/const.py:38 msgid "Released" msgstr "已释放" @@ -6497,6 +6178,10 @@ msgstr "云管中心" msgid "Provider" msgstr "云服务商" +#: xpack/plugins/cloud/models.py:34 +msgid "Validity" +msgstr "有效" + #: xpack/plugins/cloud/models.py:39 msgid "Cloud account" msgstr "云账号" @@ -6658,13 +6343,11 @@ msgid "South America (São Paulo)" msgstr "南美洲(圣保罗)" #: xpack/plugins/cloud/providers/baiducloud.py:54 -#: xpack/plugins/cloud/providers/jdcloud.py:127 msgid "CN North-Beijing" msgstr "华北-北京" #: xpack/plugins/cloud/providers/baiducloud.py:55 #: xpack/plugins/cloud/providers/huaweicloud.py:40 -#: xpack/plugins/cloud/providers/jdcloud.py:130 msgid "CN South-Guangzhou" msgstr "华南-广州" @@ -6686,7 +6369,6 @@ msgid "CN North-Baoding" msgstr "华北-保定" #: xpack/plugins/cloud/providers/baiducloud.py:60 -#: xpack/plugins/cloud/providers/jdcloud.py:129 msgid "CN East-Shanghai" msgstr "华东-上海" @@ -6751,15 +6433,11 @@ msgstr "华北-乌兰察布一" msgid "CN South-Guangzhou-InvitationOnly" msgstr "华南-广州-友好用户环境" -#: xpack/plugins/cloud/providers/jdcloud.py:128 -msgid "CN East-Suqian" -msgstr "华东-宿迁" - -#: xpack/plugins/cloud/serializers/account.py:60 +#: xpack/plugins/cloud/serializers/account.py:59 msgid "Validity display" msgstr "有效性显示" -#: xpack/plugins/cloud/serializers/account.py:61 +#: xpack/plugins/cloud/serializers/account.py:60 msgid "Provider display" msgstr "服务商显示" @@ -6921,11 +6599,3 @@ msgstr "旗舰版" #: xpack/plugins/license/models.py:77 msgid "Community edition" msgstr "社区版" - -#~ msgid "Database proxy MySQL protocol listen port" -#~ msgstr "MySQL 协议监听的端口" - -#, fuzzy -#~| msgid "Database proxy PostgreSQL port" -#~ msgid "Database proxy PostgreSQL listen port" -#~ msgstr "数据库组件 PostgreSQL 协议监听的端口" diff --git a/apps/settings/api/public.py b/apps/settings/api/public.py index 43acffaf0..a6dc3b43c 100644 --- a/apps/settings/api/public.py +++ b/apps/settings/api/public.py @@ -64,13 +64,6 @@ class PublicSettingApi(generics.RetrieveAPIView): "AUTH_FEISHU": settings.AUTH_FEISHU, # Terminal "XRDP_ENABLED": settings.XRDP_ENABLED, - "TERMINAL_KOKO_HOST": settings.TERMINAL_KOKO_HOST, - "TERMINAL_KOKO_SSH_PORT": settings.TERMINAL_KOKO_SSH_PORT, - "TERMINAL_MAGNUS_ENABLED": settings.TERMINAL_MAGNUS_ENABLED, - "TERMINAL_MAGNUS_HOST": settings.TERMINAL_MAGNUS_HOST, - "TERMINAL_MAGNUS_MYSQL_PORT": settings.TERMINAL_MAGNUS_MYSQL_PORT, - "TERMINAL_MAGNUS_MARIADB_PORT": settings.TERMINAL_MAGNUS_MARIADB_PORT, - "TERMINAL_MAGNUS_POSTGRE_PORT": settings.TERMINAL_MAGNUS_POSTGRE_PORT, # Announcement "ANNOUNCEMENT_ENABLED": settings.ANNOUNCEMENT_ENABLED, "ANNOUNCEMENT": settings.ANNOUNCEMENT, diff --git a/apps/settings/serializers/terminal.py b/apps/settings/serializers/terminal.py index c6073aa28..bf4b8d7a0 100644 --- a/apps/settings/serializers/terminal.py +++ b/apps/settings/serializers/terminal.py @@ -33,33 +33,5 @@ class TerminalSettingSerializer(serializers.Serializer): help_text=_("The login success message varies with devices. " "if you cannot log in to the device through Telnet, set this parameter") ) - TERMINAL_RDP_ADDR = serializers.CharField( - required=False, label=_("RDP address"), max_length=1024, allow_blank=True, - help_text=_('RDP visit address, eg: dev.jumpserver.org:3389') - ) - XRDP_ENABLED = serializers.BooleanField(label=_("Enable XRDP")) - - TERMINAL_KOKO_HOST = serializers.CharField( - required=False, label=_("Koko host"), max_length=1024 - ) - TERMINAL_KOKO_SSH_PORT = serializers.CharField( - required=False, label=_("Koko ssh port"), max_length=1024 - ) - TERMINAL_MAGNUS_ENABLED = serializers.BooleanField(label=_("Enable database proxy")) - TERMINAL_MAGNUS_HOST = serializers.CharField( - required=False, label=_("Database proxy host"), max_length=1024, allow_blank=True, - help_text=_('Database proxy host, eg: dev.jumpserver.org') - ) - TERMINAL_MAGNUS_MYSQL_PORT = serializers.IntegerField( - required=False, label=_("MySQL port"), default=33060, - help_text=_('MySQL protocol listen port') - ) - TERMINAL_MAGNUS_MARIADB_PORT = serializers.IntegerField( - required=False, label=_("MariaDB port"), default=33061, - help_text=_('MariaDB protocol listen port') - ) - TERMINAL_MAGNUS_POSTGRE_PORT = serializers.IntegerField( - required=False, label=_("PostgreSQL port"), default=54320, - help_text=_('PostgreSQL protocol listen port') - ) + XRDP_ENABLED = serializers.BooleanField(label=_("Enable XRDP")) diff --git a/apps/terminal/api/__init__.py b/apps/terminal/api/__init__.py index fec6da11e..16021a5ed 100644 --- a/apps/terminal/api/__init__.py +++ b/apps/terminal/api/__init__.py @@ -7,3 +7,4 @@ from .task import * from .storage import * from .status import * from .sharing import * +from .endpoint import * diff --git a/apps/terminal/api/endpoint.py b/apps/terminal/api/endpoint.py new file mode 100644 index 000000000..14efb738f --- /dev/null +++ b/apps/terminal/api/endpoint.py @@ -0,0 +1,78 @@ +from rest_framework.decorators import action +from rest_framework.response import Response +from rest_framework import status +from common.drf.api import JMSBulkModelViewSet +from common.utils import get_object_or_none +from django.shortcuts import get_object_or_404 +from assets.models import Asset +from orgs.utils import tmp_to_root_org +from applications.models import Application +from terminal.models import Session +from ..models import Endpoint, EndpointRule +from .. import serializers + + +__all__ = ['EndpointViewSet', 'EndpointRuleViewSet'] + + +class EndpointViewSet(JMSBulkModelViewSet): + filterset_fields = ('name', 'host') + search_fields = filterset_fields + serializer_class = serializers.EndpointSerializer + queryset = Endpoint.objects.all() + rbac_perms = { + 'smart': 'terminal.view_endpoint' + } + + @staticmethod + def get_target_ip(request): + # 用来方便测试 + target_ip = request.GET.get('target_ip') + if target_ip: + return target_ip + + asset_id = request.GET.get('asset_id') + app_id = request.GET.get('app_id') + session_id = request.GET.get('session_id') + token = request.GET.get('token') + if token: + from authentication.api.connection_token import TokenCacheMixin as TokenUtil + value = TokenUtil().get_token_from_cache(token) + if value: + if value.get('type') == 'asset': + asset_id = value.get('asset') + else: + app_id = value.get('application') + if asset_id: + pk, model = asset_id, Asset + elif app_id: + pk, model = app_id, Application + elif session_id: + pk, model = session_id, Session + else: + return '' + + with tmp_to_root_org(): + instance = get_object_or_404(model, pk=pk) + target_ip = instance.get_target_ip() + return target_ip + + @action(methods=['get'], detail=False, url_path='smart') + def smart(self, request, *args, **kwargs): + protocol = request.GET.get('protocol') + if not protocol: + return Response( + data={'error': _('Not found protocol query params')}, + status=status.HTTP_404_NOT_FOUND + ) + target_ip = self.get_target_ip(request) + endpoint = EndpointRule.match_endpoint(target_ip, protocol, request) + serializer = self.get_serializer(endpoint) + return Response(serializer.data) + + +class EndpointRuleViewSet(JMSBulkModelViewSet): + filterset_fields = ('name',) + search_fields = filterset_fields + serializer_class = serializers.EndpointRuleSerializer + queryset = EndpointRule.objects.all() diff --git a/apps/terminal/migrations/0048_endpoint_endpointrule.py b/apps/terminal/migrations/0048_endpoint_endpointrule.py new file mode 100644 index 000000000..9e75823e2 --- /dev/null +++ b/apps/terminal/migrations/0048_endpoint_endpointrule.py @@ -0,0 +1,86 @@ +# Generated by Django 3.1.14 on 2022-04-12 07:39 + +import common.fields.model +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import uuid +from django.conf import settings + + +def migrate_endpoints(apps, schema_editor): + endpoint_data = { + 'id': '00000000-0000-0000-0000-000000000001', + 'name': 'Default', + 'host': '', + 'https_port': 0, + 'http_port': 0, + 'created_by': 'System' + } + + if settings.XRDP_ENABLED: + xrdp_addr = settings.TERMINAL_RDP_ADDR + if ':' in xrdp_addr: + hostname, port = xrdp_addr.strip().split(':') + else: + hostname, port = xrdp_addr, 3389 + endpoint_data.update({ + 'host': '' if hostname.strip() in ['localhost', '127.0.0.1'] else hostname.strip(), + 'rdp_port': int(port) + }) + Endpoint = apps.get_model("terminal", "Endpoint") + Endpoint.objects.create(**endpoint_data) + + +class Migration(migrations.Migration): + + dependencies = [ + ('terminal', '0047_auto_20220302_1951'), + ] + + operations = [ + migrations.CreateModel( + name='Endpoint', + fields=[ + ('created_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by')), + ('updated_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Updated by')), + ('date_created', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created')), + ('date_updated', models.DateTimeField(auto_now=True, verbose_name='Date updated')), + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('name', models.CharField(max_length=128, unique=True, blank=True, verbose_name='Name')), + ('host', models.CharField(max_length=256, verbose_name='Host')), + ('https_port', common.fields.model.PortField(default=443, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(65535)], verbose_name='HTTPS Port')), + ('http_port', common.fields.model.PortField(default=80, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(65535)], verbose_name='HTTP Port')), + ('ssh_port', common.fields.model.PortField(default=2222, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(65535)], verbose_name='SSH Port')), + ('rdp_port', common.fields.model.PortField(default=3389, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(65535)], verbose_name='RDP Port')), + ('mysql_port', common.fields.model.PortField(default=33060, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(65535)], verbose_name='MySQL Port')), + ('mariadb_port', common.fields.model.PortField(default=33061, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(65535)], verbose_name='MariaDB Port')), + ('postgresql_port', common.fields.model.PortField(default=54320, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(65535)], verbose_name='PostgreSQL Port')), + ('comment', models.TextField(blank=True, default='', verbose_name='Comment')), + ], + options={ + 'verbose_name': 'Endpoint', + 'ordering': ('name',), + }, + ), + migrations.CreateModel( + name='EndpointRule', + fields=[ + ('created_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by')), + ('updated_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Updated by')), + ('date_created', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created')), + ('date_updated', models.DateTimeField(auto_now=True, verbose_name='Date updated')), + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('name', models.CharField(max_length=128, unique=True, verbose_name='Name')), + ('ip_group', models.JSONField(default=list, verbose_name='IP group')), + ('priority', models.IntegerField(help_text='1-100, the lower the value will be match first', unique=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)], verbose_name='Priority')), + ('comment', models.TextField(blank=True, default='', verbose_name='Comment')), + ('endpoint', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='rules', to='terminal.endpoint', verbose_name='Endpoint')), + ], + options={ + 'verbose_name': 'Endpoint rule', + 'ordering': ('priority', 'name'), + }, + ), + migrations.RunPython(migrate_endpoints), + ] diff --git a/apps/terminal/models/__init__.py b/apps/terminal/models/__init__.py index e69928b3a..be079721d 100644 --- a/apps/terminal/models/__init__.py +++ b/apps/terminal/models/__init__.py @@ -6,3 +6,4 @@ from .task import * from .terminal import * from .sharing import * from .replay import * +from .endpoint import * diff --git a/apps/terminal/models/endpoint.py b/apps/terminal/models/endpoint.py new file mode 100644 index 000000000..39f275f9a --- /dev/null +++ b/apps/terminal/models/endpoint.py @@ -0,0 +1,94 @@ +from django.db import models +from django.utils.translation import ugettext_lazy as _ +from django.core.validators import MinValueValidator, MaxValueValidator +from common.db.models import JMSModel +from common.fields.model import PortField +from common.utils.ip import contains_ip + + +class Endpoint(JMSModel): + name = models.CharField(max_length=128, verbose_name=_('Name'), unique=True) + host = models.CharField(max_length=256, blank=True, verbose_name=_('Host')) + # disabled value=0 + https_port = PortField(default=443, verbose_name=_('HTTPS Port')) + http_port = PortField(default=80, verbose_name=_('HTTP Port')) + ssh_port = PortField(default=2222, verbose_name=_('SSH Port')) + rdp_port = PortField(default=3389, verbose_name=_('RDP Port')) + mysql_port = PortField(default=33060, verbose_name=_('MySQL Port')) + mariadb_port = PortField(default=33061, verbose_name=_('MariaDB Port')) + postgresql_port = PortField(default=54320, verbose_name=_('PostgreSQL Port')) + comment = models.TextField(default='', blank=True, verbose_name=_('Comment')) + + default_id = '00000000-0000-0000-0000-000000000001' + + class Meta: + verbose_name = _('Endpoint') + ordering = ('name',) + + def __str__(self): + return self.name + + def get_port(self, protocol): + return getattr(self, f'{protocol}_port', 0) + + def delete(self, using=None, keep_parents=False): + if self.id == self.default_id: + return + return super().delete(using, keep_parents) + + @classmethod + def get_or_create_default(cls, request=None): + data = { + 'id': cls.default_id, + 'name': 'Default', + 'host': '', + 'https_port': 0, + 'http_port': 0, + } + endpoint, created = cls.objects.get_or_create(id=cls.default_id, defaults=data) + if not endpoint.host and request: + endpoint.host = request.get_host().split(':')[0] + return endpoint + + +class EndpointRule(JMSModel): + name = models.CharField(max_length=128, verbose_name=_('Name'), unique=True) + ip_group = models.JSONField(default=list, verbose_name=_('IP group')) + priority = models.IntegerField( + verbose_name=_("Priority"), validators=[MinValueValidator(1), MaxValueValidator(100)], + unique=True, help_text=_("1-100, the lower the value will be match first"), + ) + endpoint = models.ForeignKey( + 'terminal.Endpoint', null=True, blank=True, related_name='rules', + on_delete=models.SET_NULL, verbose_name=_("Endpoint"), + ) + comment = models.TextField(default='', blank=True, verbose_name=_('Comment')) + + class Meta: + verbose_name = _('Endpoint rule') + ordering = ('priority', 'name') + + def __str__(self): + return f'{self.name}({self.priority})' + + @classmethod + def match(cls, target_ip, protocol): + for endpoint_rule in cls.objects.all().prefetch_related('endpoint'): + if not contains_ip(target_ip, endpoint_rule.ip_group): + continue + if not endpoint_rule.endpoint: + continue + if not endpoint_rule.endpoint.host: + continue + if endpoint_rule.endpoint.get_port(protocol) == 0: + continue + return endpoint_rule + + @classmethod + def match_endpoint(cls, target_ip, protocol, request=None): + endpoint_rule = cls.match(target_ip, protocol) + if endpoint_rule: + endpoint = endpoint_rule.endpoint + else: + endpoint = Endpoint.get_or_create_default(request) + return endpoint diff --git a/apps/terminal/models/session.py b/apps/terminal/models/session.py index 09f1c9e91..565c54335 100644 --- a/apps/terminal/models/session.py +++ b/apps/terminal/models/session.py @@ -11,9 +11,11 @@ from django.core.files.storage import default_storage from django.core.cache import cache from assets.models import Asset +from applications.models import Application from users.models import User from orgs.mixins.models import OrgModelMixin from django.db.models import TextChoices +from common.utils import get_object_or_none from ..backends import get_multi_command_storage @@ -194,6 +196,13 @@ class Session(OrgModelMixin): def login_from_display(self): return self.get_login_from_display() + def get_target_ip(self): + instance = get_object_or_none(Asset, pk=self.asset_id) + if not instance: + instance = get_object_or_none(Application, pk=self.asset_id) + target_ip = instance.get_target_ip() if instance else '' + return target_ip + @classmethod def generate_fake(cls, count=100, is_finished=True): import random diff --git a/apps/terminal/serializers/__init__.py b/apps/terminal/serializers/__init__.py index 4e868cabc..e1312ebae 100644 --- a/apps/terminal/serializers/__init__.py +++ b/apps/terminal/serializers/__init__.py @@ -4,3 +4,4 @@ from .terminal import * from .session import * from .storage import * from .sharing import * +from .endpoint import * diff --git a/apps/terminal/serializers/endpoint.py b/apps/terminal/serializers/endpoint.py new file mode 100644 index 000000000..822c6b5c2 --- /dev/null +++ b/apps/terminal/serializers/endpoint.py @@ -0,0 +1,51 @@ +from rest_framework import serializers +from django.utils.translation import ugettext_lazy as _ +from common.drf.serializers import BulkModelSerializer +from acls.serializers.rules import ip_group_help_text, ip_group_child_validator +from ..models import Endpoint, EndpointRule + +__all__ = ['EndpointSerializer', 'EndpointRuleSerializer'] + + +class EndpointSerializer(BulkModelSerializer): + + class Meta: + model = Endpoint + fields_mini = ['id', 'name'] + fields_small = [ + 'host', + 'https_port', 'http_port', 'ssh_port', + 'rdp_port', 'mysql_port', 'mariadb_port', + 'postgresql_port', + ] + fields = fields_mini + fields_small + [ + 'comment', 'date_created', 'date_updated', 'created_by' + ] + extra_kwargs = { + 'https_port': {'default': 443}, + 'http_port': {'default': 80}, + 'ssh_port': {'default': 2222}, + 'rdp_port': {'default': 3389}, + 'mysql_port': {'default': 33060}, + 'mariadb_port': {'default': 33061}, + 'postgresql_port': {'default': 54320}, + } + + +class EndpointRuleSerializer(BulkModelSerializer): + ip_group = serializers.ListField( + default=['*'], label=_('IP'), help_text=ip_group_help_text, + child=serializers.CharField(max_length=1024, validators=[ip_group_child_validator]) + ) + endpoint_display = serializers.ReadOnlyField(source='endpoint.name', label=_('Endpoint')) + + class Meta: + model = EndpointRule + fields_mini = ['id', 'name'] + fields_small = fields_mini + ['ip_group', 'priority'] + fields_fk = ['endpoint', 'endpoint_display'] + fields = fields_mini + fields_small + fields_fk + [ + 'comment', 'date_created', 'date_updated', 'created_by' + ] + extra_kwargs = { + } diff --git a/apps/terminal/urls/api_urls.py b/apps/terminal/urls/api_urls.py index 9366332e2..c392f9c07 100644 --- a/apps/terminal/urls/api_urls.py +++ b/apps/terminal/urls/api_urls.py @@ -22,6 +22,8 @@ router.register(r'replay-storages', api.ReplayStorageViewSet, 'replay-storage') router.register(r'command-storages', api.CommandStorageViewSet, 'command-storage') router.register(r'session-sharings', api.SessionSharingViewSet, 'session-sharing') router.register(r'session-join-records', api.SessionJoinRecordsViewSet, 'session-sharing-record') +router.register(r'endpoints', api.EndpointViewSet, 'endpoint') +router.register(r'endpoint-rules', api.EndpointRuleViewSet, 'endpoint-rule') urlpatterns = [ path('my-sessions/', api.MySessionAPIView.as_view(), name='my-session'), From 3213fe098408e6908e176944ae055cb6ee9608c0 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 12 Apr 2022 17:59:28 +0800 Subject: [PATCH 54/59] =?UTF-8?q?chore:=20=E6=B7=BB=E5=8A=A0action=20lgtm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/lgtm.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/lgtm.yml diff --git a/.github/workflows/lgtm.yml b/.github/workflows/lgtm.yml new file mode 100644 index 000000000..022d89a71 --- /dev/null +++ b/.github/workflows/lgtm.yml @@ -0,0 +1,15 @@ +name: Send LGTM reaction +on: + issue_comment: + types: [created] + pull_request_review: + types: [submitted] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@1.0.0 + - uses: micnncim/action-lgtm-reaction@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 72608146cc76f9ecd9e6c2e07e64d5c2cc21d002 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 12 Apr 2022 18:25:28 +0800 Subject: [PATCH 55/59] chore: lgtm (#8048) * chore: lgtm * perf: add lgtm Co-authored-by: ibuler --- .github/workflows/lgtm.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/lgtm.yml b/.github/workflows/lgtm.yml index 022d89a71..379ca5135 100644 --- a/.github/workflows/lgtm.yml +++ b/.github/workflows/lgtm.yml @@ -1,4 +1,5 @@ name: Send LGTM reaction + on: issue_comment: types: [created] @@ -13,3 +14,5 @@ jobs: - uses: micnncim/action-lgtm-reaction@master env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + trigger: '["^.?lgtm$"]' From b0f7c114fc0ff0c394d2b8b70199709ee0ec883e Mon Sep 17 00:00:00 2001 From: ibuler Date: Wed, 13 Apr 2022 14:41:33 +0800 Subject: [PATCH 56/59] =?UTF-8?q?perf:=20=E4=BF=AE=E6=94=B9=20csrf=20token?= =?UTF-8?q?=20domain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/jumpserver/settings/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/jumpserver/settings/base.py b/apps/jumpserver/settings/base.py index e5b382517..a4441711a 100644 --- a/apps/jumpserver/settings/base.py +++ b/apps/jumpserver/settings/base.py @@ -127,7 +127,7 @@ LOGIN_REDIRECT_URL = reverse_lazy('index') LOGIN_URL = reverse_lazy('authentication:login') SESSION_COOKIE_DOMAIN = CONFIG.SESSION_COOKIE_DOMAIN -CSRF_COOKIE_DOMAIN = CONFIG.CSRF_COOKIE_DOMAIN +CSRF_COOKIE_DOMAIN = CONFIG.SESSION_COOKIE_DOMAIN SESSION_COOKIE_AGE = CONFIG.SESSION_COOKIE_AGE SESSION_EXPIRE_AT_BROWSER_CLOSE = True # 自定义的配置,SESSION_EXPIRE_AT_BROWSER_CLOSE 始终为 True, 下面这个来控制是否强制关闭后过期 cookie From c630b11bd57e763d5c8ee86ae17382a654e596aa Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 13 Apr 2022 19:48:31 +0800 Subject: [PATCH 57/59] fix: port str (#8055) Co-authored-by: feng626 <1304903146@qq.com> --- apps/authentication/api/connection_token.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index 3e905076c..4afa7a306 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -186,7 +186,7 @@ class ClientProtocolMixin: ) content = { 'ip': endpoint.host, - 'port': endpoint.ssh_port, + 'port': str(endpoint.ssh_port), 'username': f'JMS-{token}', 'password': secret } From 10b033010e8b238a7d8af1dc5910ce192ffe1c0d Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" Date: Wed, 13 Apr 2022 18:20:29 +0800 Subject: [PATCH 58/59] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E5=AF=BC=E5=87=BA=E6=97=B6=E9=97=B4=E6=88=B3=E5=8F=AF?= =?UTF-8?q?=E8=AF=BB=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/terminal/api/command.py | 28 +------------------ apps/terminal/backends/command/models.py | 5 ++++ apps/terminal/backends/command/serializers.py | 1 + apps/terminal/urls/api_urls.py | 1 - 4 files changed, 7 insertions(+), 28 deletions(-) diff --git a/apps/terminal/api/command.py b/apps/terminal/api/command.py index 22a2bb5c3..5b60a114a 100644 --- a/apps/terminal/api/command.py +++ b/apps/terminal/api/command.py @@ -1,13 +1,10 @@ # -*- coding: utf-8 -*- # -import time from django.conf import settings from django.utils import timezone -from django.shortcuts import HttpResponse from rest_framework import generics from rest_framework.fields import DateTimeField from rest_framework.response import Response -from django.template import loader from terminal.models import CommandStorage, Session, Command from terminal.filters import CommandFilter @@ -23,7 +20,7 @@ from ..backends import ( from ..notifications import CommandAlertMessage logger = get_logger(__name__) -__all__ = ['CommandViewSet', 'CommandExportApi', 'InsecureCommandAlertAPI'] +__all__ = ['CommandViewSet', 'InsecureCommandAlertAPI'] class CommandQueryMixin: @@ -191,29 +188,6 @@ class CommandViewSet(JMSBulkModelViewSet): return Response({"msg": msg}, status=401) -class CommandExportApi(CommandQueryMixin, generics.ListAPIView): - serializer_class = SessionCommandSerializer - rbac_perms = { - 'list': 'terminal.view_command' - } - - def list(self, request, *args, **kwargs): - queryset = self.filter_queryset(self.get_queryset()) - - template = 'terminal/command_report.html' - context = { - 'queryset': queryset, - 'total_count': len(queryset), - 'now': time.time(), - } - content = loader.render_to_string(template, context, request) - content_type = 'application/octet-stream' - response = HttpResponse(content, content_type) - filename = 'command-report-{}.html'.format(int(time.time())) - response['Content-Disposition'] = 'attachment; filename="%s"' % filename - return response - - class InsecureCommandAlertAPI(generics.CreateAPIView): serializer_class = InsecureCommandAlertSerializer rbac_perms = { diff --git a/apps/terminal/backends/command/models.py b/apps/terminal/backends/command/models.py index 02a16d353..0a795b905 100644 --- a/apps/terminal/backends/command/models.py +++ b/apps/terminal/backends/command/models.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- # +from datetime import datetime import uuid from django.db import models from django.utils.translation import ugettext_lazy as _ @@ -28,6 +29,10 @@ class AbstractSessionCommand(OrgModelMixin): class Meta: abstract = True + @lazyproperty + def timestamp_display(self): + return datetime.fromtimestamp(self.timestamp) + @lazyproperty def remote_addr(self): from terminal.models import Session diff --git a/apps/terminal/backends/command/serializers.py b/apps/terminal/backends/command/serializers.py index 625c4282e..2eb9e434c 100644 --- a/apps/terminal/backends/command/serializers.py +++ b/apps/terminal/backends/command/serializers.py @@ -36,6 +36,7 @@ class SessionCommandSerializer(SimpleSessionCommandSerializer): output = serializers.CharField(max_length=2048, allow_blank=True, label=_("Output")) risk_level_display = serializers.SerializerMethodField(label=_('Risk level display')) timestamp = serializers.IntegerField(label=_('Timestamp')) + timestamp_display = serializers.DateTimeField(label=_('Datetime')) remote_addr = serializers.CharField(read_only=True, label=_('Remote Address')) @staticmethod diff --git a/apps/terminal/urls/api_urls.py b/apps/terminal/urls/api_urls.py index c392f9c07..3f0445350 100644 --- a/apps/terminal/urls/api_urls.py +++ b/apps/terminal/urls/api_urls.py @@ -36,7 +36,6 @@ urlpatterns = [ path('tasks/kill-session/', api.KillSessionAPI.as_view(), name='kill-session'), path('tasks/kill-session-for-ticket/', api.KillSessionForTicketAPI.as_view(), name='kill-session-for-ticket'), path('terminals/config/', api.TerminalConfig.as_view(), name='terminal-config'), - path('commands/export/', api.CommandExportApi.as_view(), name="command-export"), path('commands/insecure-command/', api.InsecureCommandAlertAPI.as_view(), name="command-alert"), path('replay-storages//test-connective/', api.ReplayStorageTestConnectiveApi.as_view(), name='replay-storage-test-connective'), path('command-storages//test-connective/', api.CommandStorageTestConnectiveApi.as_view(), name='command-storage-test-connective'), From b610d71e115a0deb2b042801df18d60eb722f94e Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Wed, 13 Apr 2022 20:24:56 +0800 Subject: [PATCH 59/59] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20=E4=B8=B4?= =?UTF-8?q?=E6=97=B6=20password=20(#8035)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 添加 template password * perf: 修改id * perf: 修改 翻译 * perf: 修改 tmp token * perf: 修改 token Co-authored-by: ibuler --- apps/audits/signal_handlers.py | 1 + apps/authentication/api/__init__.py | 1 + apps/authentication/api/temp_token.py | 27 ++ apps/authentication/api/token.py | 1 - apps/authentication/backends/base.py | 3 +- apps/authentication/backends/ldap.py | 5 +- apps/authentication/backends/radius.py | 27 +- .../authentication/backends/saml2/backends.py | 2 +- apps/authentication/backends/token.py | 26 ++ .../migrations/0010_temptoken.py | 32 ++ apps/authentication/models.py | 24 +- apps/authentication/serializers/__init__.py | 3 + .../connect_token.py} | 97 +----- .../serializers/password_mfa.py | 33 ++ apps/authentication/serializers/token.py | 103 +++++++ apps/authentication/urls/api_urls.py | 1 + apps/common/utils/common.py | 2 + apps/common/utils/random.py | 24 -- apps/jumpserver/conf.py | 2 + apps/jumpserver/settings/auth.py | 10 +- apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 285 ++++++++++-------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 282 +++++++++-------- apps/rbac/builtin.py | 1 + apps/settings/api/public.py | 1 + 26 files changed, 611 insertions(+), 390 deletions(-) create mode 100644 apps/authentication/api/temp_token.py create mode 100644 apps/authentication/backends/token.py create mode 100644 apps/authentication/migrations/0010_temptoken.py create mode 100644 apps/authentication/serializers/__init__.py rename apps/authentication/{serializers.py => serializers/connect_token.py} (59%) create mode 100644 apps/authentication/serializers/password_mfa.py create mode 100644 apps/authentication/serializers/token.py diff --git a/apps/audits/signal_handlers.py b/apps/audits/signal_handlers.py index daa3fa4bf..031b1e25c 100644 --- a/apps/audits/signal_handlers.py +++ b/apps/audits/signal_handlers.py @@ -70,6 +70,7 @@ class AuthBackendLabelMapping(LazyObject): backend_label_mapping[settings.AUTH_BACKEND_AUTH_TOKEN] = _('Auth Token') backend_label_mapping[settings.AUTH_BACKEND_WECOM] = _('WeCom') backend_label_mapping[settings.AUTH_BACKEND_DINGTALK] = _('DingTalk') + backend_label_mapping[settings.AUTH_BACKEND_TEMP_TOKEN] = _('Temporary token') return backend_label_mapping def _setup(self): diff --git a/apps/authentication/api/__init__.py b/apps/authentication/api/__init__.py index c0064f9bd..01a4c52e9 100644 --- a/apps/authentication/api/__init__.py +++ b/apps/authentication/api/__init__.py @@ -11,3 +11,4 @@ from .wecom import * from .dingtalk import * from .feishu import * from .password import * +from .temp_token import * diff --git a/apps/authentication/api/temp_token.py b/apps/authentication/api/temp_token.py new file mode 100644 index 000000000..98c1d74d6 --- /dev/null +++ b/apps/authentication/api/temp_token.py @@ -0,0 +1,27 @@ +from django.utils import timezone +from rest_framework.response import Response +from rest_framework.decorators import action + +from common.drf.api import JMSModelViewSet +from common.permissions import IsValidUser +from ..models import TempToken +from ..serializers import TempTokenSerializer + + +class TempTokenViewSet(JMSModelViewSet): + serializer_class = TempTokenSerializer + permission_classes = [IsValidUser] + http_method_names = ['post', 'get', 'options', 'patch'] + + def get_queryset(self): + username = self.request.user.username + return TempToken.objects.filter(username=username) + + @action(methods=['PATCH'], detail=True, url_path='expire') + def expire(self, *args, **kwargs): + instance = self.get_object() + instance.date_expired = timezone.now() + instance.save() + serializer = self.get_serializer(instance) + return Response(serializer.data) + diff --git a/apps/authentication/api/token.py b/apps/authentication/api/token.py index df8c6eb3f..e5fe8bf2c 100644 --- a/apps/authentication/api/token.py +++ b/apps/authentication/api/token.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- # -from django.shortcuts import redirect from rest_framework.permissions import AllowAny from rest_framework.response import Response from rest_framework.generics import CreateAPIView diff --git a/apps/authentication/backends/base.py b/apps/authentication/backends/base.py index 64faf3334..84cdeab27 100644 --- a/apps/authentication/backends/base.py +++ b/apps/authentication/backends/base.py @@ -1,10 +1,11 @@ -from django.contrib.auth.backends import BaseBackend from django.contrib.auth.backends import ModelBackend +from django.contrib.auth import get_user_model from users.models import User from common.utils import get_logger +UserModel = get_user_model() logger = get_logger(__file__) diff --git a/apps/authentication/backends/ldap.py b/apps/authentication/backends/ldap.py index 1c8a80cb1..895226e58 100644 --- a/apps/authentication/backends/ldap.py +++ b/apps/authentication/backends/ldap.py @@ -53,7 +53,7 @@ class LDAPAuthorizationBackend(JMSBaseAuthBackend, LDAPBackend): else: built = False - return (user, built) + return user, built def pre_check(self, username, password): if not settings.AUTH_LDAP: @@ -75,6 +75,9 @@ class LDAPAuthorizationBackend(JMSBaseAuthBackend, LDAPBackend): def authenticate(self, request=None, username=None, password=None, **kwargs): logger.info('Authentication LDAP backend') + if username is None or password is None: + logger.info('No username or password') + return None match, msg = self.pre_check(username, password) if not match: logger.info('Authenticate failed: {}'.format(msg)) diff --git a/apps/authentication/backends/radius.py b/apps/authentication/backends/radius.py index 170534370..84f88165a 100644 --- a/apps/authentication/backends/radius.py +++ b/apps/authentication/backends/radius.py @@ -13,20 +13,23 @@ User = get_user_model() class CreateUserMixin: - def get_django_user(self, username, password=None, *args, **kwargs): + @staticmethod + def get_django_user(username, password=None, *args, **kwargs): if isinstance(username, bytes): username = username.decode() - try: - user = User.objects.get(username=username) - except User.DoesNotExist: - if '@' in username: - email = username - else: - email_suffix = settings.EMAIL_SUFFIX - email = '{}@{}'.format(username, email_suffix) - user = User(username=username, name=username, email=email) - user.source = user.Source.radius.value - user.save() + user = User.objects.filter(username=username).first() + if user: + return user + + if '@' in username: + email = username + else: + email_suffix = settings.EMAIL_SUFFIX + email = '{}@{}'.format(username, email_suffix) + + user = User(username=username, name=username, email=email) + user.source = user.Source.radius.value + user.save() return user def _perform_radius_auth(self, client, packet): diff --git a/apps/authentication/backends/saml2/backends.py b/apps/authentication/backends/saml2/backends.py index e1b1fb1eb..0ac0efe1c 100644 --- a/apps/authentication/backends/saml2/backends.py +++ b/apps/authentication/backends/saml2/backends.py @@ -14,7 +14,7 @@ from ..base import JMSModelBackend __all__ = ['SAML2Backend'] -logger = get_logger(__file__) +logger = get_logger(__name__) class SAML2Backend(JMSModelBackend): diff --git a/apps/authentication/backends/token.py b/apps/authentication/backends/token.py new file mode 100644 index 000000000..be9cb9032 --- /dev/null +++ b/apps/authentication/backends/token.py @@ -0,0 +1,26 @@ +from django.utils import timezone +from django.conf import settings +from django.core.exceptions import PermissionDenied + +from authentication.models import TempToken +from .base import JMSModelBackend + + +class TempTokenAuthBackend(JMSModelBackend): + model = TempToken + + def authenticate(self, request, username='', password='', *args, **kwargs): + token = self.model.objects.filter(username=username, secret=password).first() + if not token: + return None + if not token.is_valid: + raise PermissionDenied('Token is invalid, expired at {}'.format(token.date_expired)) + + token.verified = True + token.date_verified = timezone.now() + token.save() + return token.user + + @staticmethod + def is_enabled(): + return settings.AUTH_TEMP_TOKEN diff --git a/apps/authentication/migrations/0010_temptoken.py b/apps/authentication/migrations/0010_temptoken.py new file mode 100644 index 000000000..914188d3f --- /dev/null +++ b/apps/authentication/migrations/0010_temptoken.py @@ -0,0 +1,32 @@ +# Generated by Django 3.1.14 on 2022-04-08 07:04 + +from django.db import migrations, models +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('authentication', '0009_auto_20220310_0616'), + ] + + operations = [ + migrations.CreateModel( + name='TempToken', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('created_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Created by')), + ('updated_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='Updated by')), + ('date_created', models.DateTimeField(auto_now_add=True, null=True, verbose_name='Date created')), + ('date_updated', models.DateTimeField(auto_now=True, verbose_name='Date updated')), + ('username', models.CharField(max_length=128, verbose_name='Username')), + ('secret', models.CharField(max_length=64, verbose_name='Secret')), + ('verified', models.BooleanField(default=False, verbose_name='Verified')), + ('date_verified', models.DateTimeField(null=True, verbose_name='Date verified')), + ('date_expired', models.DateTimeField(verbose_name='Date verified')), + ], + options={ + 'verbose_name': 'Temporary token', + }, + ), + ] diff --git a/apps/authentication/models.py b/apps/authentication/models.py index 1b353f737..54cab4fbd 100644 --- a/apps/authentication/models.py +++ b/apps/authentication/models.py @@ -1,8 +1,9 @@ import uuid +from django.utils import timezone from django.utils.translation import ugettext_lazy as _ -from rest_framework.authtoken.models import Token from django.conf import settings +from rest_framework.authtoken.models import Token from common.db import models @@ -64,6 +65,27 @@ class ConnectionToken(models.JMSBaseModel): ] +class TempToken(models.JMSModel): + username = models.CharField(max_length=128, verbose_name=_("Username")) + secret = models.CharField(max_length=64, verbose_name=_("Secret")) + verified = models.BooleanField(default=False, verbose_name=_("Verified")) + date_verified = models.DateTimeField(null=True, verbose_name=_("Date verified")) + date_expired = models.DateTimeField(verbose_name=_("Date expired")) + + class Meta: + verbose_name = _("Temporary token") + + @property + def user(self): + from users.models import User + return User.objects.filter(username=self.username).first() + + @property + def is_valid(self): + not_expired = self.date_expired and self.date_expired > timezone.now() + return not self.verified and not_expired + + class SuperConnectionToken(ConnectionToken): class Meta: proxy = True diff --git a/apps/authentication/serializers/__init__.py b/apps/authentication/serializers/__init__.py new file mode 100644 index 000000000..7697c46db --- /dev/null +++ b/apps/authentication/serializers/__init__.py @@ -0,0 +1,3 @@ +from .token import * +from .connect_token import * +from .password_mfa import * diff --git a/apps/authentication/serializers.py b/apps/authentication/serializers/connect_token.py similarity index 59% rename from apps/authentication/serializers.py rename to apps/authentication/serializers/connect_token.py index f6661ba38..c8f94909d 100644 --- a/apps/authentication/serializers.py +++ b/apps/authentication/serializers/connect_token.py @@ -1,109 +1,22 @@ # -*- coding: utf-8 -*- # -from django.utils import timezone from rest_framework import serializers -from common.utils import get_object_or_none from users.models import User from assets.models import Asset, SystemUser, Gateway, Domain, CommandFilterRule from applications.models import Application -from users.serializers import UserProfileSerializer from assets.serializers import ProtocolsField from perms.serializers.base import ActionsField -from .models import AccessKey __all__ = [ - 'AccessKeySerializer', 'OtpVerifySerializer', 'BearerTokenSerializer', - 'MFAChallengeSerializer', 'SSOTokenSerializer', - 'ConnectionTokenSerializer', 'ConnectionTokenSecretSerializer', - 'PasswordVerifySerializer', 'MFASelectTypeSerializer', + 'ConnectionTokenSerializer', 'ConnectionTokenApplicationSerializer', + 'ConnectionTokenUserSerializer', 'ConnectionTokenFilterRuleSerializer', + 'ConnectionTokenAssetSerializer', 'ConnectionTokenSystemUserSerializer', + 'ConnectionTokenDomainSerializer', 'ConnectionTokenRemoteAppSerializer', + 'ConnectionTokenGatewaySerializer', 'ConnectionTokenSecretSerializer' ] -class AccessKeySerializer(serializers.ModelSerializer): - class Meta: - model = AccessKey - fields = ['id', 'secret', 'is_active', 'date_created'] - read_only_fields = ['id', 'secret', 'date_created'] - - -class OtpVerifySerializer(serializers.Serializer): - code = serializers.CharField(max_length=6, min_length=6) - - -class PasswordVerifySerializer(serializers.Serializer): - password = serializers.CharField() - - -class BearerTokenSerializer(serializers.Serializer): - username = serializers.CharField(allow_null=True, required=False, write_only=True) - password = serializers.CharField(write_only=True, allow_null=True, - required=False, allow_blank=True) - public_key = serializers.CharField(write_only=True, allow_null=True, - allow_blank=True, required=False) - token = serializers.CharField(read_only=True) - keyword = serializers.SerializerMethodField() - date_expired = serializers.DateTimeField(read_only=True) - user = UserProfileSerializer(read_only=True) - - @staticmethod - def get_keyword(obj): - return 'Bearer' - - def update_last_login(self, user): - user.last_login = timezone.now() - user.save(update_fields=['last_login']) - - def get_request_user(self): - request = self.context.get('request') - if request.user and request.user.is_authenticated: - user = request.user - else: - user_id = request.session.get('user_id') - user = get_object_or_none(User, pk=user_id) - if not user: - raise serializers.ValidationError( - "user id {} not exist".format(user_id) - ) - return user - - def create(self, validated_data): - request = self.context.get('request') - user = self.get_request_user() - - token, date_expired = user.create_bearer_token(request) - self.update_last_login(user) - - instance = { - "token": token, - "date_expired": date_expired, - "user": user - } - return instance - - -class MFASelectTypeSerializer(serializers.Serializer): - type = serializers.CharField() - username = serializers.CharField(required=False, allow_blank=True, allow_null=True) - - -class MFAChallengeSerializer(serializers.Serializer): - type = serializers.CharField(write_only=True, required=False, allow_blank=True) - code = serializers.CharField(write_only=True) - - def create(self, validated_data): - pass - - def update(self, instance, validated_data): - pass - - -class SSOTokenSerializer(serializers.Serializer): - username = serializers.CharField(write_only=True) - login_url = serializers.CharField(read_only=True) - next = serializers.CharField(write_only=True, allow_blank=True, required=False, allow_null=True) - - class ConnectionTokenSerializer(serializers.Serializer): user = serializers.CharField(max_length=128, required=False, allow_blank=True) system_user = serializers.CharField(max_length=128, required=True) diff --git a/apps/authentication/serializers/password_mfa.py b/apps/authentication/serializers/password_mfa.py new file mode 100644 index 000000000..c4c0679c6 --- /dev/null +++ b/apps/authentication/serializers/password_mfa.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# +from rest_framework import serializers + + +__all__ = [ + 'OtpVerifySerializer', 'MFAChallengeSerializer', 'MFASelectTypeSerializer', + 'PasswordVerifySerializer', +] + + +class PasswordVerifySerializer(serializers.Serializer): + password = serializers.CharField() + + +class MFASelectTypeSerializer(serializers.Serializer): + type = serializers.CharField() + username = serializers.CharField(required=False, allow_blank=True, allow_null=True) + + +class MFAChallengeSerializer(serializers.Serializer): + type = serializers.CharField(write_only=True, required=False, allow_blank=True) + code = serializers.CharField(write_only=True) + + def create(self, validated_data): + pass + + def update(self, instance, validated_data): + pass + + +class OtpVerifySerializer(serializers.Serializer): + code = serializers.CharField(max_length=6, min_length=6) diff --git a/apps/authentication/serializers/token.py b/apps/authentication/serializers/token.py new file mode 100644 index 000000000..d1e87c0c0 --- /dev/null +++ b/apps/authentication/serializers/token.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +# +from django.utils import timezone +from django.utils.translation import gettext_lazy as _ +from rest_framework import serializers + +from common.utils import get_object_or_none, random_string +from users.models import User +from users.serializers import UserProfileSerializer +from ..models import AccessKey, TempToken + +__all__ = [ + 'AccessKeySerializer', 'BearerTokenSerializer', + 'SSOTokenSerializer', 'TempTokenSerializer', +] + + +class AccessKeySerializer(serializers.ModelSerializer): + class Meta: + model = AccessKey + fields = ['id', 'secret', 'is_active', 'date_created'] + read_only_fields = ['id', 'secret', 'date_created'] + + +class BearerTokenSerializer(serializers.Serializer): + username = serializers.CharField(allow_null=True, required=False, write_only=True) + password = serializers.CharField(write_only=True, allow_null=True, + required=False, allow_blank=True) + public_key = serializers.CharField(write_only=True, allow_null=True, + allow_blank=True, required=False) + token = serializers.CharField(read_only=True) + keyword = serializers.SerializerMethodField() + date_expired = serializers.DateTimeField(read_only=True) + user = UserProfileSerializer(read_only=True) + + @staticmethod + def get_keyword(obj): + return 'Bearer' + + def update_last_login(self, user): + user.last_login = timezone.now() + user.save(update_fields=['last_login']) + + def get_request_user(self): + request = self.context.get('request') + if request.user and request.user.is_authenticated: + user = request.user + else: + user_id = request.session.get('user_id') + user = get_object_or_none(User, pk=user_id) + if not user: + raise serializers.ValidationError( + "user id {} not exist".format(user_id) + ) + return user + + def create(self, validated_data): + request = self.context.get('request') + user = self.get_request_user() + + token, date_expired = user.create_bearer_token(request) + self.update_last_login(user) + + instance = { + "token": token, + "date_expired": date_expired, + "user": user + } + return instance + + +class SSOTokenSerializer(serializers.Serializer): + username = serializers.CharField(write_only=True) + login_url = serializers.CharField(read_only=True) + next = serializers.CharField(write_only=True, allow_blank=True, required=False, allow_null=True) + + +class TempTokenSerializer(serializers.ModelSerializer): + is_valid = serializers.BooleanField(label=_("Is valid"), read_only=True) + + class Meta: + model = TempToken + fields = [ + 'id', 'username', 'secret', 'verified', 'is_valid', + 'date_created', 'date_updated', 'date_verified', + 'date_expired', + ] + read_only_fields = fields + + def create(self, validated_data): + request = self.context.get('request') + if not request or not request.user: + raise PermissionError() + + secret = random_string(36) + username = request.user.username + kwargs = { + 'username': username, 'secret': secret, + 'date_expired': timezone.now() + timezone.timedelta(seconds=5*60), + } + token = TempToken(**kwargs) + token.save() + return token diff --git a/apps/authentication/urls/api_urls.py b/apps/authentication/urls/api_urls.py index 1a6c43dd7..920988ee4 100644 --- a/apps/authentication/urls/api_urls.py +++ b/apps/authentication/urls/api_urls.py @@ -9,6 +9,7 @@ app_name = 'authentication' router = DefaultRouter() router.register('access-keys', api.AccessKeyViewSet, 'access-key') router.register('sso', api.SSOViewSet, 'sso') +router.register('temp-tokens', api.TempTokenViewSet, 'temp-token') router.register('connection-token', api.UserConnectionTokenViewSet, 'connection-token') diff --git a/apps/common/utils/common.py b/apps/common/utils/common.py index d579eacfb..3982b1349 100644 --- a/apps/common/utils/common.py +++ b/apps/common/utils/common.py @@ -31,6 +31,8 @@ def combine_seq(s1, s2, callback=None): def get_logger(name=''): + if '/' in name: + name = os.path.basename(name).replace('.py', '') return logging.getLogger('jumpserver.%s' % name) diff --git a/apps/common/utils/random.py b/apps/common/utils/random.py index 1a7449ef0..db3b39c05 100644 --- a/apps/common/utils/random.py +++ b/apps/common/utils/random.py @@ -40,27 +40,3 @@ def random_string(length, lower=True, upper=True, digit=True, special_char=False password = ''.join(password) return password - - -# def strTimeProp(start, end, prop, fmt): -# time_start = time.mktime(time.strptime(start, fmt)) -# time_end = time.mktime(time.strptime(end, fmt)) -# ptime = time_start + prop * (time_end - time_start) -# return int(ptime) -# -# -# def randomTimestamp(start, end, fmt='%Y-%m-%d %H:%M:%S'): -# return strTimeProp(start, end, random.random(), fmt) -# -# -# def randomDate(start, end, frmt='%Y-%m-%d %H:%M:%S'): -# return time.strftime(frmt, time.localtime(strTimeProp(start, end, random.random(), frmt))) -# -# -# def randomTimestampList(start, end, n, frmt='%Y-%m-%d %H:%M:%S'): -# return [randomTimestamp(start, end, frmt) for _ in range(n)] -# -# -# def randomDateList(start, end, n, frmt='%Y-%m-%d %H:%M:%S'): -# return [randomDate(start, end, frmt) for _ in range(n)] - diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index f72ed899f..3cc8a067d 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -256,6 +256,8 @@ class Config(dict): 'AUTH_SAML2_PROVIDER_AUTHORIZATION_ENDPOINT': '/', 'AUTH_SAML2_AUTHENTICATION_FAILURE_REDIRECT_URI': '/', + 'AUTH_TEMP_TOKEN': False, + # 企业微信 'AUTH_WECOM': False, 'WECOM_CORPID': '', diff --git a/apps/jumpserver/settings/auth.py b/apps/jumpserver/settings/auth.py index f71afec9b..e07883d55 100644 --- a/apps/jumpserver/settings/auth.py +++ b/apps/jumpserver/settings/auth.py @@ -109,11 +109,11 @@ CAS_APPLY_ATTRIBUTES_TO_USER = CONFIG.CAS_APPLY_ATTRIBUTES_TO_USER CAS_RENAME_ATTRIBUTES = CONFIG.CAS_RENAME_ATTRIBUTES CAS_CREATE_USER = CONFIG.CAS_CREATE_USER -# SSO Auth +# SSO auth AUTH_SSO = CONFIG.AUTH_SSO AUTH_SSO_AUTHKEY_TTL = CONFIG.AUTH_SSO_AUTHKEY_TTL -# WECOM Auth +# WECOM auth AUTH_WECOM = CONFIG.AUTH_WECOM WECOM_CORPID = CONFIG.WECOM_CORPID WECOM_AGENTID = CONFIG.WECOM_AGENTID @@ -141,6 +141,9 @@ SAML2_SP_ADVANCED_SETTINGS = CONFIG.SAML2_SP_ADVANCED_SETTINGS SAML2_LOGIN_URL_NAME = "authentication:saml2:saml2-login" SAML2_LOGOUT_URL_NAME = "authentication:saml2:saml2-logout" +# 临时 token +AUTH_TEMP_TOKEN = CONFIG.AUTH_TEMP_TOKEN + # Other setting TOKEN_EXPIRATION = CONFIG.TOKEN_EXPIRATION OTP_IN_RADIUS = CONFIG.OTP_IN_RADIUS @@ -160,6 +163,7 @@ AUTH_BACKEND_DINGTALK = 'authentication.backends.sso.DingTalkAuthentication' AUTH_BACKEND_FEISHU = 'authentication.backends.sso.FeiShuAuthentication' AUTH_BACKEND_AUTH_TOKEN = 'authentication.backends.sso.AuthorizationTokenAuthentication' AUTH_BACKEND_SAML2 = 'authentication.backends.saml2.SAML2Backend' +AUTH_BACKEND_TEMP_TOKEN = 'authentication.backends.token.TempTokenAuthBackend' AUTHENTICATION_BACKENDS = [ @@ -172,7 +176,7 @@ AUTHENTICATION_BACKENDS = [ # 扫码模式 AUTH_BACKEND_WECOM, AUTH_BACKEND_DINGTALK, AUTH_BACKEND_FEISHU, # Token模式 - AUTH_BACKEND_AUTH_TOKEN, AUTH_BACKEND_SSO, + AUTH_BACKEND_AUTH_TOKEN, AUTH_BACKEND_SSO, AUTH_BACKEND_TEMP_TOKEN ] ONLY_ALLOW_EXIST_USER_AUTH = CONFIG.ONLY_ALLOW_EXIST_USER_AUTH diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index 73226f058..7044727ed 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:70685e92cbf84f4178224a44fd84eb884a0acfb9749200541ea6655a9a397a72 -size 125019 +oid sha256:89878c511a62211520b347ccf37676cb11e9a0b3257ff968fb6d5dd81726a1e5 +size 125117 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index c80ef4904..643d66c0c 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-04-12 17:03+0800\n" +"POT-Creation-Date: 2022-04-13 20:21+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -29,25 +29,25 @@ msgstr "Acls" #: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24 #: orgs/models.py:65 perms/models/base.py:83 rbac/models/role.py:29 #: settings/models.py:29 settings/serializers/sms.py:6 -#: terminal/models/endpoint.py:10 terminal/models/endpoint.py:53 +#: terminal/models/endpoint.py:10 terminal/models/endpoint.py:55 #: terminal/models/storage.py:23 terminal/models/task.py:16 #: terminal/models/terminal.py:100 users/forms/profile.py:32 #: users/models/group.py:15 users/models/user.py:661 -#: xpack/plugins/cloud/models.py:28 +#: xpack/plugins/cloud/models.py:27 msgid "Name" msgstr "名前" #: acls/models/base.py:27 assets/models/cmd_filter.py:84 -#: assets/models/user.py:247 terminal/models/endpoint.py:56 +#: assets/models/user.py:247 terminal/models/endpoint.py:58 msgid "Priority" msgstr "優先順位" #: acls/models/base.py:28 assets/models/cmd_filter.py:84 -#: assets/models/user.py:247 terminal/models/endpoint.py:57 +#: assets/models/user.py:247 terminal/models/endpoint.py:59 msgid "1-100, the lower the value will be match first" msgstr "1-100、低い値は最初に一致します" -#: acls/models/base.py:31 authentication/models.py:17 +#: acls/models/base.py:31 authentication/models.py:18 #: authentication/templates/authentication/_access_key_modal.html:32 #: perms/models/base.py:88 terminal/models/sharing.py:26 msgid "Active" @@ -61,12 +61,12 @@ msgstr "アクティブ" #: assets/models/domain.py:64 assets/models/group.py:23 #: assets/models/label.py:23 ops/models/adhoc.py:38 orgs/models.py:68 #: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34 -#: terminal/models/endpoint.py:20 terminal/models/endpoint.py:63 +#: terminal/models/endpoint.py:20 terminal/models/endpoint.py:65 #: terminal/models/storage.py:26 terminal/models/terminal.py:114 #: tickets/models/comment.py:24 tickets/models/ticket.py:154 #: users/models/group.py:16 users/models/user.py:698 #: xpack/plugins/change_auth_plan/models/base.py:44 -#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:116 +#: xpack/plugins/cloud/models.py:34 xpack/plugins/cloud/models.py:115 #: xpack/plugins/gathered_user/models.py:26 msgid "Comment" msgstr "コメント" @@ -87,9 +87,9 @@ msgstr "ログイン確認" #: acls/models/login_acl.py:24 acls/models/login_asset_acl.py:20 #: assets/models/cmd_filter.py:30 assets/models/label.py:15 audits/models.py:37 #: audits/models.py:60 audits/models.py:85 audits/serializers.py:100 -#: authentication/models.py:50 orgs/models.py:214 perms/models/base.py:84 -#: rbac/builtin.py:106 rbac/models/rolebinding.py:40 -#: terminal/backends/command/models.py:19 +#: authentication/models.py:51 orgs/models.py:214 perms/models/base.py:84 +#: rbac/builtin.py:107 rbac/models/rolebinding.py:40 +#: terminal/backends/command/models.py:20 #: terminal/backends/command/serializers.py:12 terminal/models/session.py:44 #: terminal/notifications.py:91 terminal/notifications.py:139 #: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:886 @@ -129,12 +129,12 @@ msgstr "システムユーザー" #: assets/models/backup.py:31 assets/models/cmd_filter.py:38 #: assets/models/gathered_user.py:14 assets/serializers/label.py:30 #: assets/serializers/system_user.py:264 audits/models.py:39 -#: perms/models/asset_permission.py:23 terminal/backends/command/models.py:20 +#: perms/models/asset_permission.py:23 terminal/backends/command/models.py:21 #: terminal/backends/command/serializers.py:13 terminal/models/session.py:46 #: terminal/notifications.py:90 #: xpack/plugins/change_auth_plan/models/asset.py:199 #: xpack/plugins/change_auth_plan/serializers/asset.py:180 -#: xpack/plugins/cloud/models.py:223 +#: xpack/plugins/cloud/models.py:222 msgid "Asset" msgstr "資産" @@ -154,6 +154,7 @@ msgstr "コンマ区切り文字列の形式。* はすべて一致すること #: acls/serializers/login_asset_acl.py:51 assets/models/base.py:176 #: assets/models/gathered_user.py:15 audits/models.py:119 #: authentication/forms.py:15 authentication/forms.py:17 +#: authentication/models.py:69 #: 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:31 users/models/user.py:659 @@ -265,7 +266,7 @@ msgstr "アプリケーション" #: applications/models/account.py:15 assets/models/authbook.py:20 #: assets/models/cmd_filter.py:42 assets/models/user.py:338 audits/models.py:40 #: perms/models/application_permission.py:33 -#: perms/models/asset_permission.py:25 terminal/backends/command/models.py:21 +#: perms/models/asset_permission.py:25 terminal/backends/command/models.py:22 #: terminal/backends/command/serializers.py:35 terminal/models/session.py:48 #: xpack/plugins/change_auth_plan/models/app.py:36 #: xpack/plugins/change_auth_plan/models/app.py:147 @@ -317,7 +318,7 @@ msgstr "タイプ" msgid "Domain" msgstr "ドメイン" -#: applications/models/application.py:228 xpack/plugins/cloud/models.py:33 +#: applications/models/application.py:228 xpack/plugins/cloud/models.py:32 #: xpack/plugins/cloud/serializers/account.py:58 msgid "Attrs" msgstr "ツールバーの" @@ -356,7 +357,7 @@ msgstr "タイプ表示" #: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30 #: orgs/models.py:67 orgs/models.py:217 perms/models/base.py:92 #: users/models/group.py:18 users/models/user.py:918 -#: xpack/plugins/cloud/models.py:125 +#: xpack/plugins/cloud/models.py:124 msgid "Date created" msgstr "作成された日付" @@ -571,7 +572,7 @@ msgstr "ホスト名生" #: assets/models/asset.py:215 assets/serializers/account.py:16 #: assets/serializers/asset.py:65 perms/serializers/asset/user_permission.py:41 -#: xpack/plugins/cloud/models.py:107 xpack/plugins/cloud/serializers/task.py:42 +#: xpack/plugins/cloud/models.py:106 xpack/plugins/cloud/serializers/task.py:42 msgid "Protocols" msgstr "プロトコル" @@ -611,7 +612,7 @@ msgstr "ラベル" #: orgs/models.py:219 perms/models/base.py:91 users/models/user.py:706 #: users/serializers/group.py:33 #: xpack/plugins/change_auth_plan/models/base.py:48 -#: xpack/plugins/cloud/models.py:122 xpack/plugins/gathered_user/models.py:30 +#: xpack/plugins/cloud/models.py:121 xpack/plugins/gathered_user/models.py:30 msgid "Created by" msgstr "によって作成された" @@ -715,7 +716,7 @@ msgstr "トリガーモード" #: xpack/plugins/change_auth_plan/models/base.py:201 #: xpack/plugins/change_auth_plan/serializers/app.py:66 #: xpack/plugins/change_auth_plan/serializers/asset.py:179 -#: xpack/plugins/cloud/models.py:179 +#: xpack/plugins/cloud/models.py:178 msgid "Reason" msgstr "理由" @@ -751,7 +752,7 @@ msgstr "失敗しました" msgid "Connectivity" msgstr "接続性" -#: assets/models/base.py:40 +#: assets/models/base.py:40 authentication/models.py:72 msgid "Date verified" msgstr "確認済みの日付" @@ -953,7 +954,7 @@ msgid "Parent key" msgstr "親キー" #: assets/models/node.py:559 assets/serializers/system_user.py:263 -#: xpack/plugins/cloud/models.py:96 xpack/plugins/cloud/serializers/task.py:69 +#: xpack/plugins/cloud/models.py:95 xpack/plugins/cloud/serializers/task.py:69 msgid "Node" msgstr "ノード" @@ -1011,7 +1012,7 @@ msgstr "ログインモード" msgid "SFTP Root" msgstr "SFTPルート" -#: assets/models/user.py:254 authentication/models.py:48 +#: assets/models/user.py:254 authentication/models.py:49 msgid "Token" msgstr "トークン" @@ -1426,6 +1427,7 @@ msgid "Resource" msgstr "リソース" #: audits/models.py:65 audits/models.py:88 +#: terminal/backends/command/serializers.py:39 msgid "Datetime" msgstr "時間" @@ -1480,8 +1482,8 @@ msgid "MFA" msgstr "MFA" #: audits/models.py:126 terminal/models/status.py:33 -#: tickets/models/ticket.py:140 xpack/plugins/cloud/models.py:175 -#: xpack/plugins/cloud/models.py:227 +#: tickets/models/ticket.py:140 xpack/plugins/cloud/models.py:174 +#: xpack/plugins/cloud/models.py:226 msgid "Status" msgstr "ステータス" @@ -1518,7 +1520,7 @@ msgid "Hosts display" msgstr "ホスト表示" #: audits/serializers.py:96 ops/models/command.py:27 -#: xpack/plugins/cloud/models.py:173 +#: xpack/plugins/cloud/models.py:172 msgid "Result" msgstr "結果" @@ -1562,170 +1564,174 @@ msgstr "企業微信" msgid "DingTalk" msgstr "DingTalk" -#: audits/signal_handlers.py:106 +#: audits/signal_handlers.py:73 authentication/models.py:76 +msgid "Temporary token" +msgstr "一時的なトークン" + +#: audits/signal_handlers.py:107 msgid "User and Group" msgstr "ユーザーとグループ" -#: audits/signal_handlers.py:107 +#: audits/signal_handlers.py:108 #, python-brace-format msgid "{User} JOINED {UserGroup}" msgstr "{User} に参加 {UserGroup}" -#: audits/signal_handlers.py:108 +#: audits/signal_handlers.py:109 #, python-brace-format msgid "{User} LEFT {UserGroup}" msgstr "{User} のそばを通る {UserGroup}" -#: audits/signal_handlers.py:111 +#: audits/signal_handlers.py:112 msgid "Asset and SystemUser" msgstr "資産およびシステム・ユーザー" -#: audits/signal_handlers.py:112 +#: audits/signal_handlers.py:113 #, python-brace-format msgid "{Asset} ADD {SystemUser}" msgstr "{Asset} 追加 {SystemUser}" -#: audits/signal_handlers.py:113 +#: audits/signal_handlers.py:114 #, python-brace-format msgid "{Asset} REMOVE {SystemUser}" msgstr "{Asset} 削除 {SystemUser}" -#: audits/signal_handlers.py:116 +#: audits/signal_handlers.py:117 msgid "Node and Asset" msgstr "ノードと資産" -#: audits/signal_handlers.py:117 +#: audits/signal_handlers.py:118 #, python-brace-format msgid "{Node} ADD {Asset}" msgstr "{Node} 追加 {Asset}" -#: audits/signal_handlers.py:118 +#: audits/signal_handlers.py:119 #, python-brace-format msgid "{Node} REMOVE {Asset}" msgstr "{Node} 削除 {Asset}" -#: audits/signal_handlers.py:121 +#: audits/signal_handlers.py:122 msgid "User asset permissions" msgstr "ユーザー資産の権限" -#: audits/signal_handlers.py:122 +#: audits/signal_handlers.py:123 #, python-brace-format msgid "{AssetPermission} ADD {User}" msgstr "{AssetPermission} 追加 {User}" -#: audits/signal_handlers.py:123 +#: audits/signal_handlers.py:124 #, python-brace-format msgid "{AssetPermission} REMOVE {User}" msgstr "{AssetPermission} 削除 {User}" -#: audits/signal_handlers.py:126 +#: audits/signal_handlers.py:127 msgid "User group asset permissions" msgstr "ユーザーグループの資産権限" -#: audits/signal_handlers.py:127 +#: audits/signal_handlers.py:128 #, python-brace-format msgid "{AssetPermission} ADD {UserGroup}" msgstr "{AssetPermission} 追加 {UserGroup}" -#: audits/signal_handlers.py:128 +#: audits/signal_handlers.py:129 #, python-brace-format msgid "{AssetPermission} REMOVE {UserGroup}" msgstr "{AssetPermission} 削除 {UserGroup}" -#: audits/signal_handlers.py:131 perms/models/asset_permission.py:29 +#: audits/signal_handlers.py:132 perms/models/asset_permission.py:29 msgid "Asset permission" msgstr "資産権限" -#: audits/signal_handlers.py:132 +#: audits/signal_handlers.py:133 #, python-brace-format msgid "{AssetPermission} ADD {Asset}" msgstr "{AssetPermission} 追加 {Asset}" -#: audits/signal_handlers.py:133 +#: audits/signal_handlers.py:134 #, python-brace-format msgid "{AssetPermission} REMOVE {Asset}" msgstr "{AssetPermission} 削除 {Asset}" -#: audits/signal_handlers.py:136 +#: audits/signal_handlers.py:137 msgid "Node permission" msgstr "ノード権限" -#: audits/signal_handlers.py:137 +#: audits/signal_handlers.py:138 #, python-brace-format msgid "{AssetPermission} ADD {Node}" msgstr "{AssetPermission} 追加 {Node}" -#: audits/signal_handlers.py:138 +#: audits/signal_handlers.py:139 #, python-brace-format msgid "{AssetPermission} REMOVE {Node}" msgstr "{AssetPermission} 削除 {Node}" -#: audits/signal_handlers.py:141 +#: audits/signal_handlers.py:142 msgid "Asset permission and SystemUser" msgstr "資産権限とSystemUser" -#: audits/signal_handlers.py:142 +#: audits/signal_handlers.py:143 #, python-brace-format msgid "{AssetPermission} ADD {SystemUser}" msgstr "{AssetPermission} 追加 {SystemUser}" -#: audits/signal_handlers.py:143 +#: audits/signal_handlers.py:144 #, python-brace-format msgid "{AssetPermission} REMOVE {SystemUser}" msgstr "{AssetPermission} 削除 {SystemUser}" -#: audits/signal_handlers.py:146 +#: audits/signal_handlers.py:147 msgid "User application permissions" msgstr "ユーザーアプリケーションの権限" -#: audits/signal_handlers.py:147 +#: audits/signal_handlers.py:148 #, python-brace-format msgid "{ApplicationPermission} ADD {User}" msgstr "{ApplicationPermission} 追加 {User}" -#: audits/signal_handlers.py:148 +#: audits/signal_handlers.py:149 #, python-brace-format msgid "{ApplicationPermission} REMOVE {User}" msgstr "{ApplicationPermission} 削除 {User}" -#: audits/signal_handlers.py:151 +#: audits/signal_handlers.py:152 msgid "User group application permissions" msgstr "ユーザーグループアプリケーションの権限" -#: audits/signal_handlers.py:152 +#: audits/signal_handlers.py:153 #, python-brace-format msgid "{ApplicationPermission} ADD {UserGroup}" msgstr "{ApplicationPermission} 追加 {UserGroup}" -#: audits/signal_handlers.py:153 +#: audits/signal_handlers.py:154 #, python-brace-format msgid "{ApplicationPermission} REMOVE {UserGroup}" msgstr "{ApplicationPermission} 削除 {UserGroup}" -#: audits/signal_handlers.py:156 perms/models/application_permission.py:38 +#: audits/signal_handlers.py:157 perms/models/application_permission.py:38 msgid "Application permission" msgstr "申請許可" -#: audits/signal_handlers.py:157 +#: audits/signal_handlers.py:158 #, python-brace-format msgid "{ApplicationPermission} ADD {Application}" msgstr "{ApplicationPermission} 追加 {Application}" -#: audits/signal_handlers.py:158 +#: audits/signal_handlers.py:159 #, python-brace-format msgid "{ApplicationPermission} REMOVE {Application}" msgstr "{ApplicationPermission} 削除 {Application}" -#: audits/signal_handlers.py:161 +#: audits/signal_handlers.py:162 msgid "Application permission and SystemUser" msgstr "アプリケーション権限とSystemUser" -#: audits/signal_handlers.py:162 +#: audits/signal_handlers.py:163 #, python-brace-format msgid "{ApplicationPermission} ADD {SystemUser}" msgstr "{ApplicationPermission} 追加 {SystemUser}" -#: audits/signal_handlers.py:163 +#: audits/signal_handlers.py:164 #, python-brace-format msgid "{ApplicationPermission} REMOVE {SystemUser}" msgstr "{ApplicationPermission} 削除 {SystemUser}" @@ -2028,31 +2034,48 @@ msgstr "MFAタイプ ({}) が有効になっていない" msgid "Please change your password" msgstr "パスワードを変更してください" -#: authentication/models.py:33 terminal/serializers/storage.py:28 +#: authentication/models.py:34 terminal/serializers/storage.py:28 msgid "Access key" msgstr "アクセスキー" -#: authentication/models.py:40 +#: authentication/models.py:41 msgid "Private Token" msgstr "プライベートトークン" -#: authentication/models.py:49 +#: authentication/models.py:50 msgid "Expired" msgstr "期限切れ" -#: authentication/models.py:53 +#: authentication/models.py:54 msgid "SSO token" msgstr "SSO token" -#: authentication/models.py:61 +#: authentication/models.py:62 msgid "Connection token" msgstr "接続トークン" -#: authentication/models.py:63 +#: authentication/models.py:64 msgid "Can view connection token secret" msgstr "接続トークンの秘密を表示できます" #: authentication/models.py:70 +#: authentication/templates/authentication/_access_key_modal.html:31 +#: settings/serializers/auth/radius.py:17 +msgid "Secret" +msgstr "ひみつ" + +#: authentication/models.py:71 +msgid "Verified" +msgstr "確認済み" + +#: authentication/models.py:73 perms/models/base.py:90 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:58 +#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:60 +#: users/models/user.py:703 +msgid "Date expired" +msgstr "期限切れの日付" + +#: authentication/models.py:92 msgid "Super connection token" msgstr "スーパー接続トークン" @@ -2064,6 +2087,14 @@ msgstr "異なる都市ログインのリマインダー" msgid "binding reminder" msgstr "バインディングリマインダー" +#: authentication/serializers/token.py:79 +#: perms/serializers/application/permission.py:20 +#: perms/serializers/application/permission.py:41 +#: perms/serializers/asset/permission.py:19 +#: perms/serializers/asset/permission.py:45 users/serializers/user.py:141 +msgid "Is valid" +msgstr "有効です" + #: authentication/templates/authentication/_access_key_modal.html:6 msgid "API key list" msgstr "APIキーリスト" @@ -2081,11 +2112,6 @@ msgstr "ドキュメント" msgid "ID" msgstr "ID" -#: authentication/templates/authentication/_access_key_modal.html:31 -#: settings/serializers/auth/radius.py:17 -msgid "Secret" -msgstr "秘密" - #: authentication/templates/authentication/_access_key_modal.html:33 #: terminal/notifications.py:93 terminal/notifications.py:141 msgid "Date" @@ -2151,7 +2177,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:296 ops/tasks.py:145 ops/tasks.py:148 +#: jumpserver/conf.py:298 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 #: users/templates/users/_msg_account_expire_reminder.html:4 @@ -2612,11 +2638,11 @@ msgstr "特殊文字を含むべきではない" msgid "The mobile phone number format is incorrect" msgstr "携帯電話番号の形式が正しくありません" -#: jumpserver/conf.py:295 +#: jumpserver/conf.py:297 msgid "Create account successfully" msgstr "アカウントを正常に作成" -#: jumpserver/conf.py:297 +#: jumpserver/conf.py:299 msgid "Your account has been created successfully" msgstr "アカウントが正常に作成されました" @@ -2972,13 +2998,6 @@ msgstr "クリップボードペースト" msgid "Clipboard copy paste" msgstr "クリップボードコピーペースト" -#: perms/models/base.py:90 -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:58 -#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:60 -#: users/models/user.py:703 -msgid "Date expired" -msgstr "期限切れの日付" - #: perms/models/base.py:94 msgid "From ticket" msgstr "チケットから" @@ -3015,13 +3034,6 @@ msgstr "アプリケーション権限の有効期限が近づいています" msgid "application permissions of organization {}" msgstr "Organization {} のアプリケーション権限" -#: perms/serializers/application/permission.py:20 -#: perms/serializers/application/permission.py:41 -#: perms/serializers/asset/permission.py:19 -#: perms/serializers/asset/permission.py:45 users/serializers/user.py:141 -msgid "Is valid" -msgstr "有効です" - #: perms/serializers/application/permission.py:21 #: perms/serializers/application/permission.py:40 #: perms/serializers/asset/permission.py:20 @@ -3114,27 +3126,27 @@ msgstr "{} 少なくとも1つのシステムロール" msgid "RBAC" msgstr "RBAC" -#: rbac/builtin.py:97 +#: rbac/builtin.py:98 msgid "SystemAdmin" msgstr "システム管理者" -#: rbac/builtin.py:100 +#: rbac/builtin.py:101 msgid "SystemAuditor" msgstr "システム監査人" -#: rbac/builtin.py:103 +#: rbac/builtin.py:104 msgid "SystemComponent" msgstr "システムコンポーネント" -#: rbac/builtin.py:109 +#: rbac/builtin.py:110 msgid "OrgAdmin" msgstr "組織管理者" -#: rbac/builtin.py:112 +#: rbac/builtin.py:113 msgid "OrgAuditor" msgstr "監査員を組織する" -#: rbac/builtin.py:115 +#: rbac/builtin.py:116 msgid "OrgUser" msgstr "組織ユーザー" @@ -4599,30 +4611,30 @@ msgstr "ターミナル管理" msgid "Invalid elasticsearch config" msgstr "無効なElasticsearch構成" -#: terminal/backends/command/models.py:15 +#: terminal/backends/command/models.py:16 msgid "Ordinary" msgstr "普通" -#: terminal/backends/command/models.py:16 +#: terminal/backends/command/models.py:17 msgid "Dangerous" msgstr "危険" -#: terminal/backends/command/models.py:22 +#: terminal/backends/command/models.py:23 msgid "Input" msgstr "入力" -#: terminal/backends/command/models.py:23 +#: terminal/backends/command/models.py:24 #: terminal/backends/command/serializers.py:36 msgid "Output" msgstr "出力" -#: terminal/backends/command/models.py:24 terminal/models/replay.py:9 +#: terminal/backends/command/models.py:25 terminal/models/replay.py:9 #: terminal/models/sharing.py:17 terminal/models/sharing.py:64 #: terminal/templates/terminal/_msg_command_alert.html:10 msgid "Session" msgstr "セッション" -#: terminal/backends/command/models.py:25 +#: terminal/backends/command/models.py:26 #: terminal/backends/command/serializers.py:17 msgid "Risk level" msgstr "リスクレベル" @@ -4639,7 +4651,7 @@ msgstr "リスクレベル表示" msgid "Timestamp" msgstr "タイムスタンプ" -#: terminal/backends/command/serializers.py:39 terminal/models/terminal.py:105 +#: terminal/backends/command/serializers.py:40 terminal/models/terminal.py:105 msgid "Remote Address" msgstr "リモートアドレス" @@ -4699,18 +4711,18 @@ msgstr "MariaDB ポート" msgid "PostgreSQL Port" msgstr "PostgreSQL ポート" -#: terminal/models/endpoint.py:25 terminal/models/endpoint.py:61 +#: terminal/models/endpoint.py:25 terminal/models/endpoint.py:63 #: terminal/serializers/endpoint.py:40 terminal/serializers/storage.py:37 #: terminal/serializers/storage.py:49 terminal/serializers/storage.py:79 #: terminal/serializers/storage.py:89 terminal/serializers/storage.py:97 msgid "Endpoint" msgstr "エンドポイント" -#: terminal/models/endpoint.py:54 +#: terminal/models/endpoint.py:56 msgid "IP group" msgstr "IP グループ" -#: terminal/models/endpoint.py:66 +#: terminal/models/endpoint.py:68 msgid "Endpoint rule" msgstr "エンドポイントルール" @@ -4931,7 +4943,7 @@ msgstr "バケット" msgid "Secret key" msgstr "秘密キー" -#: terminal/serializers/storage.py:64 xpack/plugins/cloud/models.py:220 +#: terminal/serializers/storage.py:64 xpack/plugins/cloud/models.py:219 msgid "Region" msgstr "リージョン" @@ -6262,79 +6274,79 @@ msgstr "リリース済み" msgid "Cloud center" msgstr "クラウドセンター" -#: xpack/plugins/cloud/models.py:30 +#: xpack/plugins/cloud/models.py:29 msgid "Provider" msgstr "プロバイダー" -#: xpack/plugins/cloud/models.py:34 +#: xpack/plugins/cloud/models.py:33 msgid "Validity" msgstr "有効性" -#: xpack/plugins/cloud/models.py:39 +#: xpack/plugins/cloud/models.py:38 msgid "Cloud account" msgstr "クラウドアカウント" -#: xpack/plugins/cloud/models.py:41 +#: xpack/plugins/cloud/models.py:40 msgid "Test cloud account" msgstr "クラウドアカウントのテスト" -#: xpack/plugins/cloud/models.py:85 xpack/plugins/cloud/serializers/task.py:66 +#: xpack/plugins/cloud/models.py:84 xpack/plugins/cloud/serializers/task.py:66 msgid "Account" msgstr "アカウント" -#: xpack/plugins/cloud/models.py:88 xpack/plugins/cloud/serializers/task.py:37 +#: xpack/plugins/cloud/models.py:87 xpack/plugins/cloud/serializers/task.py:37 msgid "Regions" msgstr "リージョン" -#: xpack/plugins/cloud/models.py:91 +#: xpack/plugins/cloud/models.py:90 msgid "Hostname strategy" msgstr "ホスト名戦略" -#: xpack/plugins/cloud/models.py:100 xpack/plugins/cloud/serializers/task.py:67 +#: xpack/plugins/cloud/models.py:99 xpack/plugins/cloud/serializers/task.py:67 msgid "Unix admin user" msgstr "Unix adminユーザー" -#: xpack/plugins/cloud/models.py:104 xpack/plugins/cloud/serializers/task.py:68 +#: xpack/plugins/cloud/models.py:103 xpack/plugins/cloud/serializers/task.py:68 msgid "Windows admin user" msgstr "Windows管理者" -#: xpack/plugins/cloud/models.py:110 xpack/plugins/cloud/serializers/task.py:45 +#: xpack/plugins/cloud/models.py:109 xpack/plugins/cloud/serializers/task.py:45 msgid "IP network segment group" msgstr "IPネットワークセグメントグループ" -#: xpack/plugins/cloud/models.py:113 xpack/plugins/cloud/serializers/task.py:71 +#: xpack/plugins/cloud/models.py:112 xpack/plugins/cloud/serializers/task.py:71 msgid "Always update" msgstr "常に更新" -#: xpack/plugins/cloud/models.py:119 +#: xpack/plugins/cloud/models.py:118 msgid "Date last sync" msgstr "最終同期日" -#: xpack/plugins/cloud/models.py:130 xpack/plugins/cloud/models.py:171 +#: xpack/plugins/cloud/models.py:129 xpack/plugins/cloud/models.py:170 msgid "Sync instance task" msgstr "インスタンスの同期タスク" -#: xpack/plugins/cloud/models.py:182 xpack/plugins/cloud/models.py:230 +#: xpack/plugins/cloud/models.py:181 xpack/plugins/cloud/models.py:229 msgid "Date sync" msgstr "日付の同期" -#: xpack/plugins/cloud/models.py:186 +#: xpack/plugins/cloud/models.py:185 msgid "Sync instance task execution" msgstr "インスタンスタスクの同期実行" -#: xpack/plugins/cloud/models.py:210 +#: xpack/plugins/cloud/models.py:209 msgid "Sync task" msgstr "同期タスク" -#: xpack/plugins/cloud/models.py:214 +#: xpack/plugins/cloud/models.py:213 msgid "Sync instance task history" msgstr "インスタンスタスク履歴の同期" -#: xpack/plugins/cloud/models.py:217 +#: xpack/plugins/cloud/models.py:216 msgid "Instance" msgstr "インスタンス" -#: xpack/plugins/cloud/models.py:234 +#: xpack/plugins/cloud/models.py:233 msgid "Sync instance detail" msgstr "同期インスタンスの詳細" @@ -6688,3 +6700,26 @@ msgstr "究極のエディション" #: xpack/plugins/license/models.py:77 msgid "Community edition" msgstr "コミュニティ版" + +#~ msgid "Inherit" +#~ msgstr "継承" + +#~ msgid "Include" +#~ msgstr "含める" + +#~ msgid "Exclude" +#~ msgstr "除外" + +#~ msgid "DatabaseApp" +#~ msgstr "データベースの適用" + +#, fuzzy +#~| msgid "Connection token" +#~ msgid "One time token" +#~ msgstr "接続トークン" + +#~ msgid "JD Cloud" +#~ msgstr "京東雲" + +#~ msgid "CN East-Suqian" +#~ msgstr "華東-宿遷" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 5b9f31b64..ad6a09539 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9c13775875a335e3c8dbc7f666af622c5aa12050100b15e616c210e8e3043e38 -size 103490 +oid sha256:c5e41035cf1525f01fb773511041f0f8a3a25cdfb1fa4f1e681c6d7eec85f6b9 +size 103570 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index b15b2c545..365f797eb 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-04-12 17:03+0800\n" +"POT-Creation-Date: 2022-04-13 20:21+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -28,25 +28,25 @@ msgstr "访问控制" #: assets/models/group.py:20 assets/models/label.py:18 ops/mixin.py:24 #: orgs/models.py:65 perms/models/base.py:83 rbac/models/role.py:29 #: settings/models.py:29 settings/serializers/sms.py:6 -#: terminal/models/endpoint.py:10 terminal/models/endpoint.py:53 +#: terminal/models/endpoint.py:10 terminal/models/endpoint.py:55 #: terminal/models/storage.py:23 terminal/models/task.py:16 #: terminal/models/terminal.py:100 users/forms/profile.py:32 #: users/models/group.py:15 users/models/user.py:661 -#: xpack/plugins/cloud/models.py:28 +#: xpack/plugins/cloud/models.py:27 msgid "Name" msgstr "名称" #: acls/models/base.py:27 assets/models/cmd_filter.py:84 -#: assets/models/user.py:247 terminal/models/endpoint.py:56 +#: assets/models/user.py:247 terminal/models/endpoint.py:58 msgid "Priority" msgstr "优先级" #: acls/models/base.py:28 assets/models/cmd_filter.py:84 -#: assets/models/user.py:247 terminal/models/endpoint.py:57 +#: assets/models/user.py:247 terminal/models/endpoint.py:59 msgid "1-100, the lower the value will be match first" msgstr "优先级可选范围为 1-100 (数值越小越优先)" -#: acls/models/base.py:31 authentication/models.py:17 +#: acls/models/base.py:31 authentication/models.py:18 #: authentication/templates/authentication/_access_key_modal.html:32 #: perms/models/base.py:88 terminal/models/sharing.py:26 msgid "Active" @@ -60,12 +60,12 @@ msgstr "激活中" #: assets/models/domain.py:64 assets/models/group.py:23 #: assets/models/label.py:23 ops/models/adhoc.py:38 orgs/models.py:68 #: perms/models/base.py:93 rbac/models/role.py:37 settings/models.py:34 -#: terminal/models/endpoint.py:20 terminal/models/endpoint.py:63 +#: terminal/models/endpoint.py:20 terminal/models/endpoint.py:65 #: terminal/models/storage.py:26 terminal/models/terminal.py:114 #: tickets/models/comment.py:24 tickets/models/ticket.py:154 #: users/models/group.py:16 users/models/user.py:698 #: xpack/plugins/change_auth_plan/models/base.py:44 -#: xpack/plugins/cloud/models.py:35 xpack/plugins/cloud/models.py:116 +#: xpack/plugins/cloud/models.py:34 xpack/plugins/cloud/models.py:115 #: xpack/plugins/gathered_user/models.py:26 msgid "Comment" msgstr "备注" @@ -86,9 +86,9 @@ msgstr "登录复核" #: acls/models/login_acl.py:24 acls/models/login_asset_acl.py:20 #: assets/models/cmd_filter.py:30 assets/models/label.py:15 audits/models.py:37 #: audits/models.py:60 audits/models.py:85 audits/serializers.py:100 -#: authentication/models.py:50 orgs/models.py:214 perms/models/base.py:84 -#: rbac/builtin.py:106 rbac/models/rolebinding.py:40 -#: terminal/backends/command/models.py:19 +#: authentication/models.py:51 orgs/models.py:214 perms/models/base.py:84 +#: rbac/builtin.py:107 rbac/models/rolebinding.py:40 +#: terminal/backends/command/models.py:20 #: terminal/backends/command/serializers.py:12 terminal/models/session.py:44 #: terminal/notifications.py:91 terminal/notifications.py:139 #: tickets/models/comment.py:17 users/const.py:14 users/models/user.py:886 @@ -128,12 +128,12 @@ msgstr "系统用户" #: assets/models/backup.py:31 assets/models/cmd_filter.py:38 #: assets/models/gathered_user.py:14 assets/serializers/label.py:30 #: assets/serializers/system_user.py:264 audits/models.py:39 -#: perms/models/asset_permission.py:23 terminal/backends/command/models.py:20 +#: perms/models/asset_permission.py:23 terminal/backends/command/models.py:21 #: terminal/backends/command/serializers.py:13 terminal/models/session.py:46 #: terminal/notifications.py:90 #: xpack/plugins/change_auth_plan/models/asset.py:199 #: xpack/plugins/change_auth_plan/serializers/asset.py:180 -#: xpack/plugins/cloud/models.py:223 +#: xpack/plugins/cloud/models.py:222 msgid "Asset" msgstr "资产" @@ -153,6 +153,7 @@ msgstr "格式为逗号分隔的字符串, * 表示匹配所有. " #: acls/serializers/login_asset_acl.py:51 assets/models/base.py:176 #: assets/models/gathered_user.py:15 audits/models.py:119 #: authentication/forms.py:15 authentication/forms.py:17 +#: authentication/models.py:69 #: 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:31 users/models/user.py:659 @@ -260,7 +261,7 @@ msgstr "应用程序" #: applications/models/account.py:15 assets/models/authbook.py:20 #: assets/models/cmd_filter.py:42 assets/models/user.py:338 audits/models.py:40 #: perms/models/application_permission.py:33 -#: perms/models/asset_permission.py:25 terminal/backends/command/models.py:21 +#: perms/models/asset_permission.py:25 terminal/backends/command/models.py:22 #: terminal/backends/command/serializers.py:35 terminal/models/session.py:48 #: xpack/plugins/change_auth_plan/models/app.py:36 #: xpack/plugins/change_auth_plan/models/app.py:147 @@ -312,7 +313,7 @@ msgstr "类型" msgid "Domain" msgstr "网域" -#: applications/models/application.py:228 xpack/plugins/cloud/models.py:33 +#: applications/models/application.py:228 xpack/plugins/cloud/models.py:32 #: xpack/plugins/cloud/serializers/account.py:58 msgid "Attrs" msgstr "属性" @@ -351,7 +352,7 @@ msgstr "类型名称" #: common/mixins/models.py:50 ops/models/adhoc.py:39 ops/models/command.py:30 #: orgs/models.py:67 orgs/models.py:217 perms/models/base.py:92 #: users/models/group.py:18 users/models/user.py:918 -#: xpack/plugins/cloud/models.py:125 +#: xpack/plugins/cloud/models.py:124 msgid "Date created" msgstr "创建日期" @@ -566,7 +567,7 @@ msgstr "主机名原始" #: assets/models/asset.py:215 assets/serializers/account.py:16 #: assets/serializers/asset.py:65 perms/serializers/asset/user_permission.py:41 -#: xpack/plugins/cloud/models.py:107 xpack/plugins/cloud/serializers/task.py:42 +#: xpack/plugins/cloud/models.py:106 xpack/plugins/cloud/serializers/task.py:42 msgid "Protocols" msgstr "协议组" @@ -606,7 +607,7 @@ msgstr "标签管理" #: orgs/models.py:219 perms/models/base.py:91 users/models/user.py:706 #: users/serializers/group.py:33 #: xpack/plugins/change_auth_plan/models/base.py:48 -#: xpack/plugins/cloud/models.py:122 xpack/plugins/gathered_user/models.py:30 +#: xpack/plugins/cloud/models.py:121 xpack/plugins/gathered_user/models.py:30 msgid "Created by" msgstr "创建者" @@ -710,7 +711,7 @@ msgstr "触发模式" #: xpack/plugins/change_auth_plan/models/base.py:201 #: xpack/plugins/change_auth_plan/serializers/app.py:66 #: xpack/plugins/change_auth_plan/serializers/asset.py:179 -#: xpack/plugins/cloud/models.py:179 +#: xpack/plugins/cloud/models.py:178 msgid "Reason" msgstr "原因" @@ -746,7 +747,7 @@ msgstr "失败" msgid "Connectivity" msgstr "可连接性" -#: assets/models/base.py:40 +#: assets/models/base.py:40 authentication/models.py:72 msgid "Date verified" msgstr "校验日期" @@ -948,7 +949,7 @@ msgid "Parent key" msgstr "ssh私钥" #: assets/models/node.py:559 assets/serializers/system_user.py:263 -#: xpack/plugins/cloud/models.py:96 xpack/plugins/cloud/serializers/task.py:69 +#: xpack/plugins/cloud/models.py:95 xpack/plugins/cloud/serializers/task.py:69 msgid "Node" msgstr "节点" @@ -1006,7 +1007,7 @@ msgstr "认证方式" msgid "SFTP Root" msgstr "SFTP根路径" -#: assets/models/user.py:254 authentication/models.py:48 +#: assets/models/user.py:254 authentication/models.py:49 msgid "Token" msgstr "Token" @@ -1414,6 +1415,7 @@ msgid "Resource" msgstr "资源" #: audits/models.py:65 audits/models.py:88 +#: terminal/backends/command/serializers.py:39 msgid "Datetime" msgstr "日期" @@ -1468,8 +1470,8 @@ msgid "MFA" msgstr "MFA" #: audits/models.py:126 terminal/models/status.py:33 -#: tickets/models/ticket.py:140 xpack/plugins/cloud/models.py:175 -#: xpack/plugins/cloud/models.py:227 +#: tickets/models/ticket.py:140 xpack/plugins/cloud/models.py:174 +#: xpack/plugins/cloud/models.py:226 msgid "Status" msgstr "状态" @@ -1506,7 +1508,7 @@ msgid "Hosts display" msgstr "主机名称" #: audits/serializers.py:96 ops/models/command.py:27 -#: xpack/plugins/cloud/models.py:173 +#: xpack/plugins/cloud/models.py:172 msgid "Result" msgstr "结果" @@ -1550,170 +1552,174 @@ msgstr "企业微信" msgid "DingTalk" msgstr "钉钉" -#: audits/signal_handlers.py:106 +#: audits/signal_handlers.py:73 authentication/models.py:76 +msgid "Temporary token" +msgstr "临时 Token" + +#: audits/signal_handlers.py:107 msgid "User and Group" msgstr "用户与用户组" -#: audits/signal_handlers.py:107 +#: audits/signal_handlers.py:108 #, python-brace-format msgid "{User} JOINED {UserGroup}" msgstr "{User} 加入 {UserGroup}" -#: audits/signal_handlers.py:108 +#: audits/signal_handlers.py:109 #, python-brace-format msgid "{User} LEFT {UserGroup}" msgstr "{User} 离开 {UserGroup}" -#: audits/signal_handlers.py:111 +#: audits/signal_handlers.py:112 msgid "Asset and SystemUser" msgstr "资产与系统用户" -#: audits/signal_handlers.py:112 +#: audits/signal_handlers.py:113 #, python-brace-format msgid "{Asset} ADD {SystemUser}" msgstr "{Asset} 添加 {SystemUser}" -#: audits/signal_handlers.py:113 +#: audits/signal_handlers.py:114 #, python-brace-format msgid "{Asset} REMOVE {SystemUser}" msgstr "{Asset} 移除 {SystemUser}" -#: audits/signal_handlers.py:116 +#: audits/signal_handlers.py:117 msgid "Node and Asset" msgstr "节点与资产" -#: audits/signal_handlers.py:117 +#: audits/signal_handlers.py:118 #, python-brace-format msgid "{Node} ADD {Asset}" msgstr "{Node} 添加 {Asset}" -#: audits/signal_handlers.py:118 +#: audits/signal_handlers.py:119 #, python-brace-format msgid "{Node} REMOVE {Asset}" msgstr "{Node} 移除 {Asset}" -#: audits/signal_handlers.py:121 +#: audits/signal_handlers.py:122 msgid "User asset permissions" msgstr "用户资产授权" -#: audits/signal_handlers.py:122 +#: audits/signal_handlers.py:123 #, python-brace-format msgid "{AssetPermission} ADD {User}" msgstr "{AssetPermission} 添加 {User}" -#: audits/signal_handlers.py:123 +#: audits/signal_handlers.py:124 #, python-brace-format msgid "{AssetPermission} REMOVE {User}" msgstr "{AssetPermission} 移除 {User}" -#: audits/signal_handlers.py:126 +#: audits/signal_handlers.py:127 msgid "User group asset permissions" msgstr "用户组资产授权" -#: audits/signal_handlers.py:127 +#: audits/signal_handlers.py:128 #, python-brace-format msgid "{AssetPermission} ADD {UserGroup}" msgstr "{AssetPermission} 添加 {UserGroup}" -#: audits/signal_handlers.py:128 +#: audits/signal_handlers.py:129 #, python-brace-format msgid "{AssetPermission} REMOVE {UserGroup}" msgstr "{AssetPermission} 移除 {UserGroup}" -#: audits/signal_handlers.py:131 perms/models/asset_permission.py:29 +#: audits/signal_handlers.py:132 perms/models/asset_permission.py:29 msgid "Asset permission" msgstr "资产授权" -#: audits/signal_handlers.py:132 +#: audits/signal_handlers.py:133 #, python-brace-format msgid "{AssetPermission} ADD {Asset}" msgstr "{AssetPermission} 添加 {Asset}" -#: audits/signal_handlers.py:133 +#: audits/signal_handlers.py:134 #, python-brace-format msgid "{AssetPermission} REMOVE {Asset}" msgstr "{AssetPermission} 移除 {Asset}" -#: audits/signal_handlers.py:136 +#: audits/signal_handlers.py:137 msgid "Node permission" msgstr "节点授权" -#: audits/signal_handlers.py:137 +#: audits/signal_handlers.py:138 #, python-brace-format msgid "{AssetPermission} ADD {Node}" msgstr "{AssetPermission} 添加 {Node}" -#: audits/signal_handlers.py:138 +#: audits/signal_handlers.py:139 #, python-brace-format msgid "{AssetPermission} REMOVE {Node}" msgstr "{AssetPermission} 移除 {Node}" -#: audits/signal_handlers.py:141 +#: audits/signal_handlers.py:142 msgid "Asset permission and SystemUser" msgstr "资产授权与系统用户" -#: audits/signal_handlers.py:142 +#: audits/signal_handlers.py:143 #, python-brace-format msgid "{AssetPermission} ADD {SystemUser}" msgstr "{AssetPermission} 添加 {SystemUser}" -#: audits/signal_handlers.py:143 +#: audits/signal_handlers.py:144 #, python-brace-format msgid "{AssetPermission} REMOVE {SystemUser}" msgstr "{AssetPermission} 移除 {SystemUser}" -#: audits/signal_handlers.py:146 +#: audits/signal_handlers.py:147 msgid "User application permissions" msgstr "用户应用授权" -#: audits/signal_handlers.py:147 +#: audits/signal_handlers.py:148 #, python-brace-format msgid "{ApplicationPermission} ADD {User}" msgstr "{ApplicationPermission} 添加 {User}" -#: audits/signal_handlers.py:148 +#: audits/signal_handlers.py:149 #, python-brace-format msgid "{ApplicationPermission} REMOVE {User}" msgstr "{ApplicationPermission} 移除 {User}" -#: audits/signal_handlers.py:151 +#: audits/signal_handlers.py:152 msgid "User group application permissions" msgstr "用户组应用授权" -#: audits/signal_handlers.py:152 +#: audits/signal_handlers.py:153 #, python-brace-format msgid "{ApplicationPermission} ADD {UserGroup}" msgstr "{ApplicationPermission} 添加 {UserGroup}" -#: audits/signal_handlers.py:153 +#: audits/signal_handlers.py:154 #, python-brace-format msgid "{ApplicationPermission} REMOVE {UserGroup}" msgstr "{ApplicationPermission} 移除 {UserGroup}" -#: audits/signal_handlers.py:156 perms/models/application_permission.py:38 +#: audits/signal_handlers.py:157 perms/models/application_permission.py:38 msgid "Application permission" msgstr "应用授权" -#: audits/signal_handlers.py:157 +#: audits/signal_handlers.py:158 #, python-brace-format msgid "{ApplicationPermission} ADD {Application}" msgstr "{ApplicationPermission} 添加 {Application}" -#: audits/signal_handlers.py:158 +#: audits/signal_handlers.py:159 #, python-brace-format msgid "{ApplicationPermission} REMOVE {Application}" msgstr "{ApplicationPermission} 移除 {Application}" -#: audits/signal_handlers.py:161 +#: audits/signal_handlers.py:162 msgid "Application permission and SystemUser" msgstr "应用授权与系统用户" -#: audits/signal_handlers.py:162 +#: audits/signal_handlers.py:163 #, python-brace-format msgid "{ApplicationPermission} ADD {SystemUser}" msgstr "{ApplicationPermission} 添加 {SystemUser}" -#: audits/signal_handlers.py:163 +#: audits/signal_handlers.py:164 #, python-brace-format msgid "{ApplicationPermission} REMOVE {SystemUser}" msgstr "{ApplicationPermission} 移除 {SystemUser}" @@ -2007,31 +2013,48 @@ msgstr "该 MFA ({}) 方式没有启用" msgid "Please change your password" msgstr "请修改密码" -#: authentication/models.py:33 terminal/serializers/storage.py:28 +#: authentication/models.py:34 terminal/serializers/storage.py:28 msgid "Access key" msgstr "API key" -#: authentication/models.py:40 +#: authentication/models.py:41 msgid "Private Token" msgstr "SSH密钥" -#: authentication/models.py:49 +#: authentication/models.py:50 msgid "Expired" msgstr "过期时间" -#: authentication/models.py:53 +#: authentication/models.py:54 msgid "SSO token" msgstr "SSO token" -#: authentication/models.py:61 +#: authentication/models.py:62 msgid "Connection token" msgstr "连接令牌" -#: authentication/models.py:63 +#: authentication/models.py:64 msgid "Can view connection token secret" msgstr "可以查看连接令牌密文" #: authentication/models.py:70 +#: authentication/templates/authentication/_access_key_modal.html:31 +#: settings/serializers/auth/radius.py:17 +msgid "Secret" +msgstr "密钥" + +#: authentication/models.py:71 +msgid "Verified" +msgstr "已校验" + +#: authentication/models.py:73 perms/models/base.py:90 +#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:58 +#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:60 +#: users/models/user.py:703 +msgid "Date expired" +msgstr "失效日期" + +#: authentication/models.py:92 msgid "Super connection token" msgstr "超级连接令牌" @@ -2043,6 +2066,14 @@ msgstr "异地登录提醒" msgid "binding reminder" msgstr "绑定提醒" +#: authentication/serializers/token.py:79 +#: perms/serializers/application/permission.py:20 +#: perms/serializers/application/permission.py:41 +#: perms/serializers/asset/permission.py:19 +#: perms/serializers/asset/permission.py:45 users/serializers/user.py:141 +msgid "Is valid" +msgstr "账号是否有效" + #: authentication/templates/authentication/_access_key_modal.html:6 msgid "API key list" msgstr "API Key列表" @@ -2060,11 +2091,6 @@ msgstr "文档" msgid "ID" msgstr "ID" -#: authentication/templates/authentication/_access_key_modal.html:31 -#: settings/serializers/auth/radius.py:17 -msgid "Secret" -msgstr "密钥" - #: authentication/templates/authentication/_access_key_modal.html:33 #: terminal/notifications.py:93 terminal/notifications.py:141 msgid "Date" @@ -2130,7 +2156,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:296 ops/tasks.py:145 ops/tasks.py:148 +#: jumpserver/conf.py:298 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 #: users/templates/users/_msg_account_expire_reminder.html:4 @@ -2582,11 +2608,11 @@ msgstr "不能包含特殊字符" msgid "The mobile phone number format is incorrect" msgstr "手机号格式不正确" -#: jumpserver/conf.py:295 +#: jumpserver/conf.py:297 msgid "Create account successfully" msgstr "创建账号成功" -#: jumpserver/conf.py:297 +#: jumpserver/conf.py:299 msgid "Your account has been created successfully" msgstr "你的账号已创建成功" @@ -2937,13 +2963,6 @@ msgstr "剪贴板粘贴" msgid "Clipboard copy paste" msgstr "剪贴板复制粘贴" -#: perms/models/base.py:90 -#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:58 -#: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:60 -#: users/models/user.py:703 -msgid "Date expired" -msgstr "失效日期" - #: perms/models/base.py:94 msgid "From ticket" msgstr "来自工单" @@ -2980,13 +2999,6 @@ msgstr "应用授权规则即将过期" msgid "application permissions of organization {}" msgstr "组织 ({}) 的应用授权" -#: perms/serializers/application/permission.py:20 -#: perms/serializers/application/permission.py:41 -#: perms/serializers/asset/permission.py:19 -#: perms/serializers/asset/permission.py:45 users/serializers/user.py:141 -msgid "Is valid" -msgstr "账号是否有效" - #: perms/serializers/application/permission.py:21 #: perms/serializers/application/permission.py:40 #: perms/serializers/asset/permission.py:20 @@ -3077,27 +3089,27 @@ msgstr "{} 至少有一个系统角色" msgid "RBAC" msgstr "RBAC" -#: rbac/builtin.py:97 +#: rbac/builtin.py:98 msgid "SystemAdmin" msgstr "系统管理员" -#: rbac/builtin.py:100 +#: rbac/builtin.py:101 msgid "SystemAuditor" msgstr "系统审计员" -#: rbac/builtin.py:103 +#: rbac/builtin.py:104 msgid "SystemComponent" msgstr "系统组件" -#: rbac/builtin.py:109 +#: rbac/builtin.py:110 msgid "OrgAdmin" msgstr "组织管理员" -#: rbac/builtin.py:112 +#: rbac/builtin.py:113 msgid "OrgAuditor" msgstr "组织审计员" -#: rbac/builtin.py:115 +#: rbac/builtin.py:116 msgid "OrgUser" msgstr "组织用户" @@ -4528,30 +4540,30 @@ msgstr "终端管理" msgid "Invalid elasticsearch config" msgstr "无效的 Elasticsearch 配置" -#: terminal/backends/command/models.py:15 +#: terminal/backends/command/models.py:16 msgid "Ordinary" msgstr "普通" -#: terminal/backends/command/models.py:16 +#: terminal/backends/command/models.py:17 msgid "Dangerous" msgstr "危险" -#: terminal/backends/command/models.py:22 +#: terminal/backends/command/models.py:23 msgid "Input" msgstr "输入" -#: terminal/backends/command/models.py:23 +#: terminal/backends/command/models.py:24 #: terminal/backends/command/serializers.py:36 msgid "Output" msgstr "输出" -#: terminal/backends/command/models.py:24 terminal/models/replay.py:9 +#: terminal/backends/command/models.py:25 terminal/models/replay.py:9 #: terminal/models/sharing.py:17 terminal/models/sharing.py:64 #: terminal/templates/terminal/_msg_command_alert.html:10 msgid "Session" msgstr "会话" -#: terminal/backends/command/models.py:25 +#: terminal/backends/command/models.py:26 #: terminal/backends/command/serializers.py:17 msgid "Risk level" msgstr "风险等级" @@ -4568,7 +4580,7 @@ msgstr "风险等级名称" msgid "Timestamp" msgstr "时间戳" -#: terminal/backends/command/serializers.py:39 terminal/models/terminal.py:105 +#: terminal/backends/command/serializers.py:40 terminal/models/terminal.py:105 msgid "Remote Address" msgstr "远端地址" @@ -4628,18 +4640,18 @@ msgstr "MariaDB 端口" msgid "PostgreSQL Port" msgstr "PostgreSQL 端口" -#: terminal/models/endpoint.py:25 terminal/models/endpoint.py:61 +#: terminal/models/endpoint.py:25 terminal/models/endpoint.py:63 #: terminal/serializers/endpoint.py:40 terminal/serializers/storage.py:37 #: terminal/serializers/storage.py:49 terminal/serializers/storage.py:79 #: terminal/serializers/storage.py:89 terminal/serializers/storage.py:97 msgid "Endpoint" msgstr "端点" -#: terminal/models/endpoint.py:54 +#: terminal/models/endpoint.py:56 msgid "IP group" msgstr "IP 组" -#: terminal/models/endpoint.py:66 +#: terminal/models/endpoint.py:68 msgid "Endpoint rule" msgstr "端点规则" @@ -4860,7 +4872,7 @@ msgstr "桶名称" msgid "Secret key" msgstr "密钥" -#: terminal/serializers/storage.py:64 xpack/plugins/cloud/models.py:220 +#: terminal/serializers/storage.py:64 xpack/plugins/cloud/models.py:219 msgid "Region" msgstr "地域" @@ -6174,79 +6186,79 @@ msgstr "已释放" msgid "Cloud center" msgstr "云管中心" -#: xpack/plugins/cloud/models.py:30 +#: xpack/plugins/cloud/models.py:29 msgid "Provider" msgstr "云服务商" -#: xpack/plugins/cloud/models.py:34 +#: xpack/plugins/cloud/models.py:33 msgid "Validity" msgstr "有效" -#: xpack/plugins/cloud/models.py:39 +#: xpack/plugins/cloud/models.py:38 msgid "Cloud account" msgstr "云账号" -#: xpack/plugins/cloud/models.py:41 +#: xpack/plugins/cloud/models.py:40 msgid "Test cloud account" msgstr "测试云账号" -#: xpack/plugins/cloud/models.py:85 xpack/plugins/cloud/serializers/task.py:66 +#: xpack/plugins/cloud/models.py:84 xpack/plugins/cloud/serializers/task.py:66 msgid "Account" msgstr "账号" -#: xpack/plugins/cloud/models.py:88 xpack/plugins/cloud/serializers/task.py:37 +#: xpack/plugins/cloud/models.py:87 xpack/plugins/cloud/serializers/task.py:37 msgid "Regions" msgstr "地域" -#: xpack/plugins/cloud/models.py:91 +#: xpack/plugins/cloud/models.py:90 msgid "Hostname strategy" msgstr "主机名策略" -#: xpack/plugins/cloud/models.py:100 xpack/plugins/cloud/serializers/task.py:67 +#: xpack/plugins/cloud/models.py:99 xpack/plugins/cloud/serializers/task.py:67 msgid "Unix admin user" msgstr "Unix 管理员" -#: xpack/plugins/cloud/models.py:104 xpack/plugins/cloud/serializers/task.py:68 +#: xpack/plugins/cloud/models.py:103 xpack/plugins/cloud/serializers/task.py:68 msgid "Windows admin user" msgstr "Windows 管理员" -#: xpack/plugins/cloud/models.py:110 xpack/plugins/cloud/serializers/task.py:45 +#: xpack/plugins/cloud/models.py:109 xpack/plugins/cloud/serializers/task.py:45 msgid "IP network segment group" msgstr "IP网段组" -#: xpack/plugins/cloud/models.py:113 xpack/plugins/cloud/serializers/task.py:71 +#: xpack/plugins/cloud/models.py:112 xpack/plugins/cloud/serializers/task.py:71 msgid "Always update" msgstr "总是更新" -#: xpack/plugins/cloud/models.py:119 +#: xpack/plugins/cloud/models.py:118 msgid "Date last sync" msgstr "最后同步日期" -#: xpack/plugins/cloud/models.py:130 xpack/plugins/cloud/models.py:171 +#: xpack/plugins/cloud/models.py:129 xpack/plugins/cloud/models.py:170 msgid "Sync instance task" msgstr "同步实例任务" -#: xpack/plugins/cloud/models.py:182 xpack/plugins/cloud/models.py:230 +#: xpack/plugins/cloud/models.py:181 xpack/plugins/cloud/models.py:229 msgid "Date sync" msgstr "同步日期" -#: xpack/plugins/cloud/models.py:186 +#: xpack/plugins/cloud/models.py:185 msgid "Sync instance task execution" msgstr "同步实例任务执行" -#: xpack/plugins/cloud/models.py:210 +#: xpack/plugins/cloud/models.py:209 msgid "Sync task" msgstr "同步任务" -#: xpack/plugins/cloud/models.py:214 +#: xpack/plugins/cloud/models.py:213 msgid "Sync instance task history" msgstr "同步实例任务历史" -#: xpack/plugins/cloud/models.py:217 +#: xpack/plugins/cloud/models.py:216 msgid "Instance" msgstr "实例" -#: xpack/plugins/cloud/models.py:234 +#: xpack/plugins/cloud/models.py:233 msgid "Sync instance detail" msgstr "同步实例详情" @@ -6599,3 +6611,23 @@ msgstr "旗舰版" #: xpack/plugins/license/models.py:77 msgid "Community edition" msgstr "社区版" + +#~ msgid "Inherit" +#~ msgstr "继承" + +#~ msgid "Include" +#~ msgstr "包含" + +#~ msgid "Exclude" +#~ msgstr "不包含" + +#~ msgid "DatabaseApp" +#~ msgstr "数据库应用" + +#~ msgid "Database proxy MySQL protocol listen port" +#~ msgstr "MySQL 协议监听的端口" + +#, fuzzy +#~| msgid "Database proxy PostgreSQL port" +#~ msgid "Database proxy PostgreSQL listen port" +#~ msgstr "数据库组件 PostgreSQL 协议监听的端口" diff --git a/apps/rbac/builtin.py b/apps/rbac/builtin.py index 513ec210a..d8e84a554 100644 --- a/apps/rbac/builtin.py +++ b/apps/rbac/builtin.py @@ -16,6 +16,7 @@ user_perms = ( ('applications', 'application', 'match', 'application'), ('ops', 'commandexecution', 'add', 'commandexecution'), ('authentication', 'connectiontoken', 'add', 'connectiontoken'), + ('authentication', 'temptoken', 'add', 'temptoken'), ('tickets', 'ticket', 'view', 'ticket'), ('orgs', 'organization', 'view', 'rootorg'), ) diff --git a/apps/settings/api/public.py b/apps/settings/api/public.py index a6dc3b43c..ca221f2de 100644 --- a/apps/settings/api/public.py +++ b/apps/settings/api/public.py @@ -67,6 +67,7 @@ class PublicSettingApi(generics.RetrieveAPIView): # Announcement "ANNOUNCEMENT_ENABLED": settings.ANNOUNCEMENT_ENABLED, "ANNOUNCEMENT": settings.ANNOUNCEMENT, + "AUTH_TEMP_TOKEN": settings.AUTH_TEMP_TOKEN, } } return instance