mirror of https://github.com/jumpserver/jumpserver
commit
7183f0d274
|
@ -6,4 +6,5 @@ tmp/*
|
||||||
django.db
|
django.db
|
||||||
celerybeat.pid
|
celerybeat.pid
|
||||||
### Vagrant ###
|
### Vagrant ###
|
||||||
.vagrant/
|
.vagrant/
|
||||||
|
apps/xpack/.git
|
|
@ -1,3 +1,4 @@
|
||||||
|
# 编译代码
|
||||||
FROM python:3.8.6-slim as stage-build
|
FROM python:3.8.6-slim as stage-build
|
||||||
MAINTAINER JumpServer Team <ibuler@qq.com>
|
MAINTAINER JumpServer Team <ibuler@qq.com>
|
||||||
ARG VERSION
|
ARG VERSION
|
||||||
|
@ -7,9 +8,12 @@ WORKDIR /opt/jumpserver
|
||||||
ADD . .
|
ADD . .
|
||||||
RUN cd utils && bash -ixeu build.sh
|
RUN cd utils && bash -ixeu build.sh
|
||||||
|
|
||||||
|
# 构建运行时环境
|
||||||
FROM python:3.8.6-slim
|
FROM python:3.8.6-slim
|
||||||
ARG PIP_MIRROR=https://pypi.douban.com/simple
|
ARG PIP_MIRROR=https://pypi.douban.com/simple
|
||||||
ENV PIP_MIRROR=$PIP_MIRROR
|
ENV PIP_MIRROR=$PIP_MIRROR
|
||||||
|
ARG PIP_JMS_MIRROR=https://pypi.douban.com/simple
|
||||||
|
ENV PIP_JMS_MIRROR=$PIP_JMS_MIRROR
|
||||||
|
|
||||||
WORKDIR /opt/jumpserver
|
WORKDIR /opt/jumpserver
|
||||||
|
|
||||||
|
@ -27,6 +31,7 @@ RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list \
|
||||||
|
|
||||||
COPY ./requirements/requirements.txt ./requirements/requirements.txt
|
COPY ./requirements/requirements.txt ./requirements/requirements.txt
|
||||||
RUN pip install --upgrade pip==20.2.4 setuptools==49.6.0 wheel==0.34.2 -i ${PIP_MIRROR} \
|
RUN pip install --upgrade pip==20.2.4 setuptools==49.6.0 wheel==0.34.2 -i ${PIP_MIRROR} \
|
||||||
|
&& pip install --no-cache-dir $(grep -E 'jms|jumpserver' requirements/requirements.txt) -i ${PIP_JMS_MIRROR} \
|
||||||
&& pip install --no-cache-dir -r requirements/requirements.txt -i ${PIP_MIRROR} \
|
&& pip install --no-cache-dir -r requirements/requirements.txt -i ${PIP_MIRROR} \
|
||||||
&& rm -rf ~/.cache/pip
|
&& rm -rf ~/.cache/pip
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ class Migration(migrations.Migration):
|
||||||
dependencies = [
|
dependencies = [
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
('acls', '0001_initial'),
|
('acls', '0001_initial'),
|
||||||
|
('authentication', '0004_ssotoken'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
@ -86,4 +87,12 @@ class Migration(migrations.Migration):
|
||||||
model_name='loginacl',
|
model_name='loginacl',
|
||||||
name='ip_group',
|
name='ip_group',
|
||||||
),
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='loginacl',
|
||||||
|
options={'ordering': ('priority', '-date_updated', 'name'), 'verbose_name': 'Login acl'},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='loginassetacl',
|
||||||
|
options={'ordering': ('priority', '-date_updated', 'name'), 'verbose_name': 'Login asset acl'},
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -40,6 +40,7 @@ class LoginACL(BaseACL):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('priority', '-date_updated', 'name')
|
ordering = ('priority', '-date_updated', 'name')
|
||||||
|
verbose_name = _('Login acl')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
|
@ -37,6 +37,7 @@ class LoginAssetACL(BaseACL, OrgModelMixin):
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ('name', 'org_id')
|
unique_together = ('name', 'org_id')
|
||||||
ordering = ('priority', '-date_updated', 'name')
|
ordering = ('priority', '-date_updated', 'name')
|
||||||
|
verbose_name = _('Login asset acl')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Generated by Django 3.1.13 on 2021-10-26 09:11
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('applications', '0012_auto_20211014_2209'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='application',
|
||||||
|
options={'ordering': ('name',), 'verbose_name': 'Application'},
|
||||||
|
),
|
||||||
|
]
|
|
@ -180,6 +180,7 @@ class Application(CommonModelMixin, OrgModelMixin, ApplicationTreeNodeMixin):
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
verbose_name = _('Application')
|
||||||
unique_together = [('org_id', 'name')]
|
unique_together = [('org_id', 'name')]
|
||||||
ordering = ('name',)
|
ordering = ('name',)
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,8 @@ class AppAccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
'username': {'default': '', 'required': False},
|
'username': {'default': '', 'required': False},
|
||||||
'password': {'write_only': True},
|
'password': {'write_only': True},
|
||||||
'app_display': {'label': _('Application display')}
|
'app_display': {'label': _('Application display')},
|
||||||
|
'systemuser_display': {'label': _('System User')}
|
||||||
}
|
}
|
||||||
use_model_bulk_create = True
|
use_model_bulk_create = True
|
||||||
model_bulk_create_kwargs = {
|
model_bulk_create_kwargs = {
|
||||||
|
@ -134,4 +135,6 @@ class AppAccountSecretSerializer(AppAccountSerializer):
|
||||||
'password': {'write_only': False},
|
'password': {'write_only': False},
|
||||||
'private_key': {'write_only': False},
|
'private_key': {'write_only': False},
|
||||||
'public_key': {'write_only': False},
|
'public_key': {'write_only': False},
|
||||||
|
'app_display': {'label': _('Application display')},
|
||||||
|
'systemuser_display': {'label': _('System User')}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ class SystemUserViewSet(SuggestionMixin, OrgBulkModelViewSet):
|
||||||
'default': serializers.SystemUserSerializer,
|
'default': serializers.SystemUserSerializer,
|
||||||
'suggestion': serializers.MiniSystemUserSerializer
|
'suggestion': serializers.MiniSystemUserSerializer
|
||||||
}
|
}
|
||||||
ordering_fields = ('name', 'protocol')
|
ordering_fields = ('name', 'protocol', 'login_mode')
|
||||||
ordering = ('name', )
|
ordering = ('name', )
|
||||||
permission_classes = (IsOrgAdminOrAppUser,)
|
permission_classes = (IsOrgAdminOrAppUser,)
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,9 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
||||||
auto_generate_key = serializers.BooleanField(initial=True, required=False, write_only=True)
|
auto_generate_key = serializers.BooleanField(initial=True, required=False, write_only=True)
|
||||||
type_display = serializers.ReadOnlyField(source='get_type_display', label=_('Type display'))
|
type_display = serializers.ReadOnlyField(source='get_type_display', label=_('Type display'))
|
||||||
ssh_key_fingerprint = serializers.ReadOnlyField(label=_('SSH key fingerprint'))
|
ssh_key_fingerprint = serializers.ReadOnlyField(label=_('SSH key fingerprint'))
|
||||||
applications_amount = serializers.IntegerField(source='apps_amount', label=_('Apps amount'))
|
applications_amount = serializers.IntegerField(
|
||||||
|
source='apps_amount', read_only=True, label=_('Apps amount')
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SystemUser
|
model = SystemUser
|
||||||
|
|
|
@ -372,9 +372,19 @@ class NotEnableMFAError(JMSException):
|
||||||
default_detail = mfa_unset_msg
|
default_detail = mfa_unset_msg
|
||||||
|
|
||||||
|
|
||||||
class OTPRequiredError(JMSException):
|
class OTPBindRequiredError(JMSException):
|
||||||
default_detail = otp_unset_msg
|
default_detail = otp_unset_msg
|
||||||
|
|
||||||
def __init__(self, url, *args, **kwargs):
|
def __init__(self, url, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.url = url
|
self.url = url
|
||||||
|
|
||||||
|
|
||||||
|
class OTPCodeRequiredError(AuthFailedError):
|
||||||
|
msg = _("Please enter MFA code")
|
||||||
|
|
||||||
|
class SMSCodeRequiredError(AuthFailedError):
|
||||||
|
msg = _("Please enter SMS code")
|
||||||
|
|
||||||
|
class UserPhoneNotSet(AuthFailedError):
|
||||||
|
msg = _('Phone not set')
|
||||||
|
|
|
@ -242,7 +242,12 @@ class AuthMixin(PasswordEncryptionViewMixin):
|
||||||
data = request.POST
|
data = request.POST
|
||||||
code = data.get('code')
|
code = data.get('code')
|
||||||
mfa_type = data.get('mfa_type')
|
mfa_type = data.get('mfa_type')
|
||||||
if settings.SECURITY_MFA_IN_LOGIN_PAGE and code and mfa_type:
|
if settings.SECURITY_MFA_IN_LOGIN_PAGE and mfa_type:
|
||||||
|
if not code:
|
||||||
|
if mfa_type == MFAType.OTP and bool(user.otp_secret_key):
|
||||||
|
raise errors.OTPCodeRequiredError
|
||||||
|
elif mfa_type == MFAType.SMS_CODE:
|
||||||
|
raise errors.SMSCodeRequiredError
|
||||||
self.check_user_mfa(code, mfa_type, user=user)
|
self.check_user_mfa(code, mfa_type, user=user)
|
||||||
|
|
||||||
def _check_login_acl(self, user, ip):
|
def _check_login_acl(self, user, ip):
|
||||||
|
@ -405,9 +410,12 @@ class AuthMixin(PasswordEncryptionViewMixin):
|
||||||
if not user.mfa_enabled:
|
if not user.mfa_enabled:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if not bool(user.phone) and mfa_type == MFAType.SMS_CODE:
|
||||||
|
raise errors.UserPhoneNotSet
|
||||||
|
|
||||||
if not bool(user.otp_secret_key) and mfa_type == MFAType.OTP:
|
if not bool(user.otp_secret_key) and mfa_type == MFAType.OTP:
|
||||||
self.set_passwd_verify_on_session(user)
|
self.set_passwd_verify_on_session(user)
|
||||||
raise errors.OTPRequiredError(reverse_lazy('authentication:user-otp-enable-bind'))
|
raise errors.OTPBindRequiredError(reverse_lazy('authentication:user-otp-enable-bind'))
|
||||||
|
|
||||||
ip = self.get_request_ip()
|
ip = self.get_request_ip()
|
||||||
self.check_mfa_is_block(user.username, ip)
|
self.check_mfa_is_block(user.username, ip)
|
||||||
|
|
|
@ -124,18 +124,19 @@ class UserLoginView(mixins.AuthMixin, FormView):
|
||||||
except (
|
except (
|
||||||
errors.PasswdTooSimple,
|
errors.PasswdTooSimple,
|
||||||
errors.PasswordRequireResetError,
|
errors.PasswordRequireResetError,
|
||||||
errors.PasswdNeedUpdate
|
errors.PasswdNeedUpdate,
|
||||||
|
errors.OTPBindRequiredError
|
||||||
) as e:
|
) as e:
|
||||||
return redirect(e.url)
|
return redirect(e.url)
|
||||||
except (
|
except (
|
||||||
errors.MFAUnsetError,
|
|
||||||
errors.MFAFailedError,
|
errors.MFAFailedError,
|
||||||
errors.BlockMFAError
|
errors.BlockMFAError,
|
||||||
|
errors.OTPCodeRequiredError,
|
||||||
|
errors.SMSCodeRequiredError,
|
||||||
|
errors.UserPhoneNotSet
|
||||||
) as e:
|
) as e:
|
||||||
form.add_error('code', e.msg)
|
form.add_error('code', e.msg)
|
||||||
return super().form_invalid(form)
|
return super().form_invalid(form)
|
||||||
except errors.OTPRequiredError as e:
|
|
||||||
return redirect(e.url)
|
|
||||||
self.clear_rsa_key()
|
self.clear_rsa_key()
|
||||||
return self.redirect_to_guard_view()
|
return self.redirect_to_guard_view()
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ def utc_now():
|
||||||
|
|
||||||
|
|
||||||
def local_now():
|
def local_now():
|
||||||
return as_current_tz(utc_now())
|
return dj_timezone.localtime(dj_timezone.now())
|
||||||
|
|
||||||
|
|
||||||
def local_now_display(fmt='%Y-%m-%d %H:%M:%S'):
|
def local_now_display(fmt='%Y-%m-%d %H:%M:%S'):
|
||||||
|
|
|
@ -18,6 +18,7 @@ import copy
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from urllib.parse import urljoin, urlparse
|
from urllib.parse import urljoin, urlparse
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
PROJECT_DIR = os.path.dirname(BASE_DIR)
|
PROJECT_DIR = os.path.dirname(BASE_DIR)
|
||||||
|
@ -263,6 +264,11 @@ class Config(dict):
|
||||||
'TENCENT_VERIFY_SIGN_NAME': '',
|
'TENCENT_VERIFY_SIGN_NAME': '',
|
||||||
'TENCENT_VERIFY_TEMPLATE_CODE': '',
|
'TENCENT_VERIFY_TEMPLATE_CODE': '',
|
||||||
|
|
||||||
|
# Email
|
||||||
|
'EMAIL_CUSTOM_USER_CREATED_SUBJECT': _('Create account successfully'),
|
||||||
|
'EMAIL_CUSTOM_USER_CREATED_HONORIFIC': _('Hello'),
|
||||||
|
'EMAIL_CUSTOM_USER_CREATED_BODY': _('Your account has been created successfully'),
|
||||||
|
|
||||||
'OTP_VALID_WINDOW': 2,
|
'OTP_VALID_WINDOW': 2,
|
||||||
'OTP_ISSUER_NAME': 'JumpServer',
|
'OTP_ISSUER_NAME': 'JumpServer',
|
||||||
'EMAIL_SUFFIX': 'example.com',
|
'EMAIL_SUFFIX': 'example.com',
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:55a2062981ea7eef4ca28142f325f52e15cb7679ad0a2600234a5bdb6d005c87
|
oid sha256:cc8a022ddc7438e50aa0cdb4ce24eec327638143731dbe0ed0ad783df06ecbaf
|
||||||
size 89996
|
size 89882
|
||||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: JumpServer 0.3.3\n"
|
"Project-Id-Version: JumpServer 0.3.3\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-10-25 14:56+0800\n"
|
"POT-Creation-Date: 2021-10-26 17:16+0800\n"
|
||||||
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
|
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
|
||||||
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
||||||
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
||||||
|
@ -74,7 +74,7 @@ msgstr "拒绝"
|
||||||
msgid "Allow"
|
msgid "Allow"
|
||||||
msgstr "允许"
|
msgstr "允许"
|
||||||
|
|
||||||
#: acls/models/login_acl.py:21 acls/models/login_acl.py:113
|
#: acls/models/login_acl.py:21 acls/models/login_acl.py:114
|
||||||
#: acls/models/login_asset_acl.py:17 tickets/const.py:9
|
#: acls/models/login_asset_acl.py:17 tickets/const.py:9
|
||||||
msgid "Login confirm"
|
msgid "Login confirm"
|
||||||
msgstr "登录复核"
|
msgstr "登录复核"
|
||||||
|
@ -116,14 +116,20 @@ msgstr "动作"
|
||||||
msgid "Reviewers"
|
msgid "Reviewers"
|
||||||
msgstr "审批人"
|
msgstr "审批人"
|
||||||
|
|
||||||
|
#: acls/models/login_acl.py:43
|
||||||
|
msgid "Login acl"
|
||||||
|
msgstr "登录访问控制"
|
||||||
|
|
||||||
#: acls/models/login_asset_acl.py:21
|
#: acls/models/login_asset_acl.py:21
|
||||||
|
#: applications/serializers/application.py:108
|
||||||
|
#: applications/serializers/application.py:139
|
||||||
msgid "System User"
|
msgid "System User"
|
||||||
msgstr "系统用户"
|
msgstr "系统用户"
|
||||||
|
|
||||||
#: acls/models/login_asset_acl.py:22
|
#: acls/models/login_asset_acl.py:22
|
||||||
#: applications/serializers/attrs/application_category/remote_app.py:37
|
#: applications/serializers/attrs/application_category/remote_app.py:37
|
||||||
#: assets/models/asset.py:357 assets/models/authbook.py:18
|
#: assets/models/asset.py:357 assets/models/authbook.py:18
|
||||||
#: assets/models/gathered_user.py:14 assets/serializers/system_user.py:231
|
#: assets/models/gathered_user.py:14 assets/serializers/system_user.py:233
|
||||||
#: audits/models.py:38 perms/models/asset_permission.py:99
|
#: audits/models.py:38 perms/models/asset_permission.py:99
|
||||||
#: templates/index.html:82 terminal/backends/command/models.py:19
|
#: templates/index.html:82 terminal/backends/command/models.py:19
|
||||||
#: terminal/backends/command/serializers.py:13 terminal/models/session.py:40
|
#: terminal/backends/command/serializers.py:13 terminal/models/session.py:40
|
||||||
|
@ -135,7 +141,11 @@ msgstr "系统用户"
|
||||||
msgid "Asset"
|
msgid "Asset"
|
||||||
msgstr "资产"
|
msgstr "资产"
|
||||||
|
|
||||||
#: acls/models/login_asset_acl.py:89 tickets/const.py:12
|
#: acls/models/login_asset_acl.py:40
|
||||||
|
msgid "Login asset acl"
|
||||||
|
msgstr "登录资产访问控制"
|
||||||
|
|
||||||
|
#: acls/models/login_asset_acl.py:90 tickets/const.py:12
|
||||||
msgid "Login asset confirm"
|
msgid "Login asset confirm"
|
||||||
msgstr "登录资产复核"
|
msgstr "登录资产复核"
|
||||||
|
|
||||||
|
@ -153,7 +163,7 @@ msgstr "格式为逗号分隔的字符串, * 表示匹配所有. "
|
||||||
#: audits/models.py:105 authentication/forms.py:15 authentication/forms.py:17
|
#: audits/models.py:105 authentication/forms.py:15 authentication/forms.py:17
|
||||||
#: authentication/templates/authentication/_msg_different_city.html:9
|
#: authentication/templates/authentication/_msg_different_city.html:9
|
||||||
#: ops/models/adhoc.py:148 users/forms/profile.py:31 users/models/user.py:595
|
#: ops/models/adhoc.py:148 users/forms/profile.py:31 users/models/user.py:595
|
||||||
#: users/templates/users/_msg_user_created.html:10
|
#: users/templates/users/_msg_user_created.html:12
|
||||||
#: users/templates/users/_select_user_modal.html:14
|
#: users/templates/users/_select_user_modal.html:14
|
||||||
#: xpack/plugins/change_auth_plan/models/asset.py:35
|
#: xpack/plugins/change_auth_plan/models/asset.py:35
|
||||||
#: xpack/plugins/change_auth_plan/models/asset.py:191
|
#: xpack/plugins/change_auth_plan/models/asset.py:191
|
||||||
|
@ -312,6 +322,11 @@ msgstr "网域"
|
||||||
msgid "Attrs"
|
msgid "Attrs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: applications/models/application.py:183
|
||||||
|
#: perms/models/application_permission.py:27 users/models/user.py:174
|
||||||
|
msgid "Application"
|
||||||
|
msgstr "应用程序"
|
||||||
|
|
||||||
#: applications/serializers/application.py:59
|
#: applications/serializers/application.py:59
|
||||||
#: applications/serializers/application.py:89 assets/serializers/label.py:13
|
#: applications/serializers/application.py:89 assets/serializers/label.py:13
|
||||||
#: perms/serializers/application/permission.py:16
|
#: perms/serializers/application/permission.py:16
|
||||||
|
@ -330,6 +345,7 @@ msgid "Type display"
|
||||||
msgstr "类型名称"
|
msgstr "类型名称"
|
||||||
|
|
||||||
#: applications/serializers/application.py:107
|
#: applications/serializers/application.py:107
|
||||||
|
#: applications/serializers/application.py:138
|
||||||
msgid "Application display"
|
msgid "Application display"
|
||||||
msgstr "应用名称"
|
msgstr "应用名称"
|
||||||
|
|
||||||
|
@ -384,7 +400,7 @@ msgstr "目标URL"
|
||||||
#: authentication/forms.py:22
|
#: authentication/forms.py:22
|
||||||
#: authentication/templates/authentication/login.html:151
|
#: authentication/templates/authentication/login.html:151
|
||||||
#: settings/serializers/auth/ldap.py:44 users/forms/profile.py:21
|
#: settings/serializers/auth/ldap.py:44 users/forms/profile.py:21
|
||||||
#: users/templates/users/_msg_user_created.html:11
|
#: users/templates/users/_msg_user_created.html:13
|
||||||
#: users/templates/users/user_otp_check_password.html:13
|
#: users/templates/users/user_otp_check_password.html:13
|
||||||
#: users/templates/users/user_password_update.html:43
|
#: users/templates/users/user_password_update.html:43
|
||||||
#: users/templates/users/user_password_verify.html:18
|
#: users/templates/users/user_password_verify.html:18
|
||||||
|
@ -747,7 +763,7 @@ msgstr "全称"
|
||||||
msgid "Parent key"
|
msgid "Parent key"
|
||||||
msgstr "ssh私钥"
|
msgstr "ssh私钥"
|
||||||
|
|
||||||
#: assets/models/node.py:559 assets/serializers/system_user.py:230
|
#: assets/models/node.py:559 assets/serializers/system_user.py:232
|
||||||
#: users/templates/users/user_asset_permission.html:41
|
#: users/templates/users/user_asset_permission.html:41
|
||||||
#: users/templates/users/user_asset_permission.html:73
|
#: users/templates/users/user_asset_permission.html:73
|
||||||
#: users/templates/users/user_asset_permission.html:158
|
#: users/templates/users/user_asset_permission.html:158
|
||||||
|
@ -848,7 +864,7 @@ msgstr "节点名称"
|
||||||
msgid "Hardware info"
|
msgid "Hardware info"
|
||||||
msgstr "硬件信息"
|
msgstr "硬件信息"
|
||||||
|
|
||||||
#: assets/serializers/asset.py:104 assets/serializers/system_user.py:249
|
#: assets/serializers/asset.py:104 assets/serializers/system_user.py:251
|
||||||
#: orgs/mixins/serializers.py:26
|
#: orgs/mixins/serializers.py:26
|
||||||
msgid "Org name"
|
msgid "Org name"
|
||||||
msgstr "组织名称"
|
msgstr "组织名称"
|
||||||
|
@ -862,7 +878,7 @@ msgid "private key invalid"
|
||||||
msgstr "密钥不合法"
|
msgstr "密钥不合法"
|
||||||
|
|
||||||
#: assets/serializers/domain.py:13 assets/serializers/label.py:12
|
#: assets/serializers/domain.py:13 assets/serializers/label.py:12
|
||||||
#: assets/serializers/system_user.py:54
|
#: assets/serializers/system_user.py:56
|
||||||
#: perms/serializers/asset/permission.py:72
|
#: perms/serializers/asset/permission.py:72
|
||||||
msgid "Assets amount"
|
msgid "Assets amount"
|
||||||
msgstr "资产数量"
|
msgstr "资产数量"
|
||||||
|
@ -892,52 +908,52 @@ msgstr "同级别节点名字不能重复"
|
||||||
msgid "SSH key fingerprint"
|
msgid "SSH key fingerprint"
|
||||||
msgstr "密钥指纹"
|
msgstr "密钥指纹"
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:29
|
#: assets/serializers/system_user.py:30
|
||||||
msgid "Apps amount"
|
msgid "Apps amount"
|
||||||
msgstr "应用数量"
|
msgstr "应用数量"
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:53
|
#: assets/serializers/system_user.py:55
|
||||||
#: perms/serializers/asset/permission.py:73
|
#: perms/serializers/asset/permission.py:73
|
||||||
msgid "Nodes amount"
|
msgid "Nodes amount"
|
||||||
msgstr "节点数量"
|
msgstr "节点数量"
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:55 assets/serializers/system_user.py:232
|
#: assets/serializers/system_user.py:57 assets/serializers/system_user.py:234
|
||||||
msgid "Login mode display"
|
msgid "Login mode display"
|
||||||
msgstr "认证方式名称"
|
msgstr "认证方式名称"
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:57
|
#: assets/serializers/system_user.py:59
|
||||||
msgid "Ad domain"
|
msgid "Ad domain"
|
||||||
msgstr "Ad 网域"
|
msgstr "Ad 网域"
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:58
|
#: assets/serializers/system_user.py:60
|
||||||
msgid "Is asset protocol"
|
msgid "Is asset protocol"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:98
|
#: assets/serializers/system_user.py:100
|
||||||
msgid "Username same with user with protocol {} only allow 1"
|
msgid "Username same with user with protocol {} only allow 1"
|
||||||
msgstr "用户名和用户相同的一种协议只允许存在一个"
|
msgstr "用户名和用户相同的一种协议只允许存在一个"
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:108 common/validators.py:14
|
#: assets/serializers/system_user.py:110 common/validators.py:14
|
||||||
msgid "Special char not allowed"
|
msgid "Special char not allowed"
|
||||||
msgstr "不能包含特殊字符"
|
msgstr "不能包含特殊字符"
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:117
|
#: assets/serializers/system_user.py:119
|
||||||
msgid "* Automatic login mode must fill in the username."
|
msgid "* Automatic login mode must fill in the username."
|
||||||
msgstr "自动登录模式,必须填写用户名"
|
msgstr "自动登录模式,必须填写用户名"
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:132
|
#: assets/serializers/system_user.py:134
|
||||||
msgid "Path should starts with /"
|
msgid "Path should starts with /"
|
||||||
msgstr "路径应该以 / 开头"
|
msgstr "路径应该以 / 开头"
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:144
|
#: assets/serializers/system_user.py:146
|
||||||
msgid "Password or private key required"
|
msgid "Password or private key required"
|
||||||
msgstr "密码或密钥密码需要一个"
|
msgstr "密码或密钥密码需要一个"
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:248
|
#: assets/serializers/system_user.py:250
|
||||||
msgid "System user name"
|
msgid "System user name"
|
||||||
msgstr "系统用户名称"
|
msgstr "系统用户名称"
|
||||||
|
|
||||||
#: assets/serializers/system_user.py:258
|
#: assets/serializers/system_user.py:260
|
||||||
msgid "Asset hostname"
|
msgid "Asset hostname"
|
||||||
msgstr "资产主机名"
|
msgstr "资产主机名"
|
||||||
|
|
||||||
|
@ -1257,12 +1273,12 @@ msgstr ""
|
||||||
msgid "Auth Token"
|
msgid "Auth Token"
|
||||||
msgstr "认证令牌"
|
msgstr "认证令牌"
|
||||||
|
|
||||||
#: audits/signals_handler.py:68 authentication/views/login.py:168
|
#: audits/signals_handler.py:68 authentication/views/login.py:169
|
||||||
#: notifications/backends/__init__.py:11 users/models/user.py:652
|
#: notifications/backends/__init__.py:11 users/models/user.py:652
|
||||||
msgid "WeCom"
|
msgid "WeCom"
|
||||||
msgstr "企业微信"
|
msgstr "企业微信"
|
||||||
|
|
||||||
#: audits/signals_handler.py:69 authentication/views/login.py:174
|
#: audits/signals_handler.py:69 authentication/views/login.py:175
|
||||||
#: notifications/backends/__init__.py:12 users/models/user.py:653
|
#: notifications/backends/__init__.py:12 users/models/user.py:653
|
||||||
msgid "DingTalk"
|
msgid "DingTalk"
|
||||||
msgstr "钉钉"
|
msgstr "钉钉"
|
||||||
|
@ -1424,7 +1440,7 @@ msgstr "{ApplicationPermission} 移除 {UserGroup}"
|
||||||
|
|
||||||
#: audits/signals_handler.py:157 perms/models/application_permission.py:37
|
#: audits/signals_handler.py:157 perms/models/application_permission.py:37
|
||||||
msgid "Application permission"
|
msgid "Application permission"
|
||||||
msgstr "应用管理"
|
msgstr "应用授权"
|
||||||
|
|
||||||
#: audits/signals_handler.py:158
|
#: audits/signals_handler.py:158
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
|
@ -1641,15 +1657,15 @@ msgstr "该 时间段 不被允许登录"
|
||||||
msgid "SSO auth closed"
|
msgid "SSO auth closed"
|
||||||
msgstr "SSO 认证关闭了"
|
msgstr "SSO 认证关闭了"
|
||||||
|
|
||||||
#: authentication/errors.py:310 authentication/mixins.py:340
|
#: authentication/errors.py:310 authentication/mixins.py:345
|
||||||
msgid "Your password is too simple, please change it for security"
|
msgid "Your password is too simple, please change it for security"
|
||||||
msgstr "你的密码过于简单,为了安全,请修改"
|
msgstr "你的密码过于简单,为了安全,请修改"
|
||||||
|
|
||||||
#: authentication/errors.py:319 authentication/mixins.py:347
|
#: authentication/errors.py:319 authentication/mixins.py:352
|
||||||
msgid "You should to change your password before login"
|
msgid "You should to change your password before login"
|
||||||
msgstr "登录完成前,请先修改密码"
|
msgstr "登录完成前,请先修改密码"
|
||||||
|
|
||||||
#: authentication/errors.py:328 authentication/mixins.py:354
|
#: authentication/errors.py:328 authentication/mixins.py:359
|
||||||
msgid "Your password has expired, please reset before logging in"
|
msgid "Your password has expired, please reset before logging in"
|
||||||
msgstr "您的密码已过期,先修改再登录"
|
msgstr "您的密码已过期,先修改再登录"
|
||||||
|
|
||||||
|
@ -1661,6 +1677,18 @@ msgstr "您的密码无效"
|
||||||
msgid "No upload or download permission"
|
msgid "No upload or download permission"
|
||||||
msgstr "没有上传下载权限"
|
msgstr "没有上传下载权限"
|
||||||
|
|
||||||
|
#: authentication/errors.py:384 templates/_mfa_otp_login.html:37
|
||||||
|
msgid "Please enter MFA code"
|
||||||
|
msgstr "请输入6位动态安全码"
|
||||||
|
|
||||||
|
#: authentication/errors.py:387 templates/_mfa_otp_login.html:38
|
||||||
|
msgid "Please enter SMS code"
|
||||||
|
msgstr "请输入短信验证码"
|
||||||
|
|
||||||
|
#: authentication/errors.py:390 users/exceptions.py:15
|
||||||
|
msgid "Phone not set"
|
||||||
|
msgstr "手机号没有设置"
|
||||||
|
|
||||||
#: authentication/forms.py:35
|
#: authentication/forms.py:35
|
||||||
msgid "{} days auto login"
|
msgid "{} days auto login"
|
||||||
msgstr "{} 天内自动登录"
|
msgstr "{} 天内自动登录"
|
||||||
|
@ -1681,11 +1709,11 @@ msgstr "多因子认证验证码"
|
||||||
msgid "Dynamic code"
|
msgid "Dynamic code"
|
||||||
msgstr "动态码"
|
msgstr "动态码"
|
||||||
|
|
||||||
#: authentication/mixins.py:330
|
#: authentication/mixins.py:335
|
||||||
msgid "Please change your password"
|
msgid "Please change your password"
|
||||||
msgstr "请修改密码"
|
msgstr "请修改密码"
|
||||||
|
|
||||||
#: authentication/mixins.py:515
|
#: authentication/mixins.py:523
|
||||||
msgid "SMS"
|
msgid "SMS"
|
||||||
msgstr "短信"
|
msgstr "短信"
|
||||||
|
|
||||||
|
@ -1796,6 +1824,7 @@ msgstr "代码错误"
|
||||||
#: authentication/templates/authentication/_msg_different_city.html:3
|
#: authentication/templates/authentication/_msg_different_city.html:3
|
||||||
#: authentication/templates/authentication/_msg_reset_password.html:3
|
#: authentication/templates/authentication/_msg_reset_password.html:3
|
||||||
#: authentication/templates/authentication/_msg_rest_password_success.html:2
|
#: authentication/templates/authentication/_msg_rest_password_success.html:2
|
||||||
|
#: jumpserver/conf.py:269
|
||||||
#: perms/templates/perms/_msg_item_permissions_expire.html:3
|
#: perms/templates/perms/_msg_item_permissions_expire.html:3
|
||||||
#: perms/templates/perms/_msg_permed_items_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_account_expire_reminder.html:4
|
||||||
|
@ -1830,12 +1859,12 @@ msgid "Click here reset password"
|
||||||
msgstr "点击这里重置密码"
|
msgstr "点击这里重置密码"
|
||||||
|
|
||||||
#: authentication/templates/authentication/_msg_reset_password.html:15
|
#: authentication/templates/authentication/_msg_reset_password.html:15
|
||||||
#: users/templates/users/_msg_user_created.html:17
|
#: users/templates/users/_msg_user_created.html:19
|
||||||
msgid "This link is valid for 1 hour. After it expires"
|
msgid "This link is valid for 1 hour. After it expires"
|
||||||
msgstr "这个链接有效期1小时, 超过时间您可以"
|
msgstr "这个链接有效期1小时, 超过时间您可以"
|
||||||
|
|
||||||
#: authentication/templates/authentication/_msg_reset_password.html:17
|
#: authentication/templates/authentication/_msg_reset_password.html:17
|
||||||
#: users/templates/users/_msg_user_created.html:18
|
#: users/templates/users/_msg_user_created.html:20
|
||||||
msgid "request new one"
|
msgid "request new one"
|
||||||
msgstr "重新申请"
|
msgstr "重新申请"
|
||||||
|
|
||||||
|
@ -1999,12 +2028,12 @@ msgstr "正在跳转到 {} 认证"
|
||||||
msgid "Please enable cookies and try again."
|
msgid "Please enable cookies and try again."
|
||||||
msgstr "设置你的浏览器支持cookie"
|
msgstr "设置你的浏览器支持cookie"
|
||||||
|
|
||||||
#: authentication/views/login.py:180 notifications/backends/__init__.py:14
|
#: authentication/views/login.py:181 notifications/backends/__init__.py:14
|
||||||
#: users/models/user.py:654
|
#: users/models/user.py:654
|
||||||
msgid "FeiShu"
|
msgid "FeiShu"
|
||||||
msgstr "飞书"
|
msgstr "飞书"
|
||||||
|
|
||||||
#: authentication/views/login.py:268
|
#: authentication/views/login.py:269
|
||||||
msgid ""
|
msgid ""
|
||||||
"Wait for <b>{}</b> confirm, You also can copy link to her/him <br/>\n"
|
"Wait for <b>{}</b> confirm, You also can copy link to her/him <br/>\n"
|
||||||
" Don't close this page"
|
" Don't close this page"
|
||||||
|
@ -2012,15 +2041,15 @@ msgstr ""
|
||||||
"等待 <b>{}</b> 确认, 你也可以复制链接发给他/她 <br/>\n"
|
"等待 <b>{}</b> 确认, 你也可以复制链接发给他/她 <br/>\n"
|
||||||
" 不要关闭本页面"
|
" 不要关闭本页面"
|
||||||
|
|
||||||
#: authentication/views/login.py:273
|
#: authentication/views/login.py:274
|
||||||
msgid "No ticket found"
|
msgid "No ticket found"
|
||||||
msgstr "没有发现工单"
|
msgstr "没有发现工单"
|
||||||
|
|
||||||
#: authentication/views/login.py:305
|
#: authentication/views/login.py:306
|
||||||
msgid "Logout success"
|
msgid "Logout success"
|
||||||
msgstr "退出登录成功"
|
msgstr "退出登录成功"
|
||||||
|
|
||||||
#: authentication/views/login.py:306
|
#: authentication/views/login.py:307
|
||||||
msgid "Logout success, return login page"
|
msgid "Logout success, return login page"
|
||||||
msgstr "退出登录成功,返回到登录页面"
|
msgstr "退出登录成功,返回到登录页面"
|
||||||
|
|
||||||
|
@ -2207,6 +2236,14 @@ msgstr "不能包含特殊字符"
|
||||||
msgid "The mobile phone number format is incorrect"
|
msgid "The mobile phone number format is incorrect"
|
||||||
msgstr "手机号格式不正确"
|
msgstr "手机号格式不正确"
|
||||||
|
|
||||||
|
#: jumpserver/conf.py:268
|
||||||
|
msgid "Create account successfully"
|
||||||
|
msgstr "创建账户成功"
|
||||||
|
|
||||||
|
#: jumpserver/conf.py:270
|
||||||
|
msgid "Your account has been created successfully"
|
||||||
|
msgstr "你的账户已创建成功"
|
||||||
|
|
||||||
#: jumpserver/context_processor.py:17
|
#: jumpserver/context_processor.py:17
|
||||||
msgid "JumpServer Open Source Bastion Host"
|
msgid "JumpServer Open Source Bastion Host"
|
||||||
msgstr "JumpServer 开源堡垒机"
|
msgstr "JumpServer 开源堡垒机"
|
||||||
|
@ -2467,10 +2504,6 @@ msgstr "管理员正在修改授权,请稍等"
|
||||||
msgid "The authorization cannot be revoked for the time being"
|
msgid "The authorization cannot be revoked for the time being"
|
||||||
msgstr "该授权暂时不能撤销"
|
msgstr "该授权暂时不能撤销"
|
||||||
|
|
||||||
#: perms/models/application_permission.py:27 users/models/user.py:174
|
|
||||||
msgid "Application"
|
|
||||||
msgstr "应用程序"
|
|
||||||
|
|
||||||
#: perms/models/asset_permission.py:37 settings/serializers/terminal.py:12
|
#: perms/models/asset_permission.py:37 settings/serializers/terminal.py:12
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "全部"
|
msgstr "全部"
|
||||||
|
@ -3100,7 +3133,7 @@ msgstr "提示: 创建用户时,发送设置密码邮件的主题 (例如: 创
|
||||||
|
|
||||||
#: settings/serializers/email.py:54
|
#: settings/serializers/email.py:54
|
||||||
msgid "Create user honorific"
|
msgid "Create user honorific"
|
||||||
msgstr "邮件的敬语"
|
msgstr "邮件问候语"
|
||||||
|
|
||||||
#: settings/serializers/email.py:55
|
#: settings/serializers/email.py:55
|
||||||
msgid "Tips: When creating a user, send the honorific of the email (eg:Hello)"
|
msgid "Tips: When creating a user, send the honorific of the email (eg:Hello)"
|
||||||
|
@ -3671,14 +3704,6 @@ msgstr "请输入验证码"
|
||||||
msgid "Send verification code"
|
msgid "Send verification code"
|
||||||
msgstr "发送验证码"
|
msgstr "发送验证码"
|
||||||
|
|
||||||
#: templates/_mfa_otp_login.html:37
|
|
||||||
msgid "Please enter MFA code"
|
|
||||||
msgstr "请输入6位动态安全码"
|
|
||||||
|
|
||||||
#: templates/_mfa_otp_login.html:38
|
|
||||||
msgid "Please enter SMS code"
|
|
||||||
msgstr "请输入短信验证码"
|
|
||||||
|
|
||||||
#: templates/_mfa_otp_login.html:60 templates/_mfa_otp_login.html:65
|
#: templates/_mfa_otp_login.html:60 templates/_mfa_otp_login.html:65
|
||||||
msgid "Wait: "
|
msgid "Wait: "
|
||||||
msgstr "等待:"
|
msgstr "等待:"
|
||||||
|
@ -3989,6 +4014,27 @@ msgstr "前"
|
||||||
msgid "Login in "
|
msgid "Login in "
|
||||||
msgstr "登录了"
|
msgstr "登录了"
|
||||||
|
|
||||||
|
#: templates/resource_download.html:15 templates/resource_download.html:21
|
||||||
|
#: templates/resource_download.html:22 templates/resource_download.html:27
|
||||||
|
msgid "Client"
|
||||||
|
msgstr "客户端"
|
||||||
|
|
||||||
|
#: templates/resource_download.html:17
|
||||||
|
msgid ""
|
||||||
|
"JumpServer Client, currently used to launch the client, now only support "
|
||||||
|
"launch RDP client, The SSH client will next"
|
||||||
|
msgstr "JumpServer 客户端,目前用来唤起 特定客户端程序 连接资产, 目前仅支持 RDP 客户端,SSH、Telnet 会在未来支持"
|
||||||
|
|
||||||
|
#: templates/resource_download.html:27
|
||||||
|
msgid "Official"
|
||||||
|
msgstr "官方"
|
||||||
|
|
||||||
|
#: templates/resource_download.html:29
|
||||||
|
msgid ""
|
||||||
|
"macOS needs to download the client to connect RDP asset, which comes with "
|
||||||
|
"Windows"
|
||||||
|
msgstr "macOS 需要下载客户端来连接 RDP 资产,Windows 系统默认安装了该程序"
|
||||||
|
|
||||||
#: templates/rest_framework/base.html:128
|
#: templates/rest_framework/base.html:128
|
||||||
msgid "Filters"
|
msgid "Filters"
|
||||||
msgstr "过滤"
|
msgstr "过滤"
|
||||||
|
@ -4776,10 +4822,6 @@ msgstr "设置密码"
|
||||||
msgid "MFA not enabled"
|
msgid "MFA not enabled"
|
||||||
msgstr "MFA没有开启"
|
msgstr "MFA没有开启"
|
||||||
|
|
||||||
#: users/exceptions.py:15
|
|
||||||
msgid "Phone not set"
|
|
||||||
msgstr "手机号没有设置"
|
|
||||||
|
|
||||||
#: users/exceptions.py:20
|
#: users/exceptions.py:20
|
||||||
msgid "MFA method not support"
|
msgid "MFA method not support"
|
||||||
msgstr "MFA 方法不支持"
|
msgstr "MFA 方法不支持"
|
||||||
|
@ -4908,38 +4950,30 @@ msgstr "管理员"
|
||||||
msgid "Administrator is the super user of system"
|
msgid "Administrator is the super user of system"
|
||||||
msgstr "Administrator是初始的超级管理员"
|
msgstr "Administrator是初始的超级管理员"
|
||||||
|
|
||||||
#: users/notifications.py:15
|
#: users/notifications.py:48
|
||||||
msgid "Create account successfully"
|
|
||||||
msgstr "创建账户成功"
|
|
||||||
|
|
||||||
#: users/notifications.py:19
|
|
||||||
msgid "Hello {}"
|
|
||||||
msgstr "你好"
|
|
||||||
|
|
||||||
#: users/notifications.py:51
|
|
||||||
#: users/templates/users/_msg_password_expire_reminder.html:17
|
#: users/templates/users/_msg_password_expire_reminder.html:17
|
||||||
#: users/templates/users/reset_password.html:5
|
#: users/templates/users/reset_password.html:5
|
||||||
#: users/templates/users/reset_password.html:6
|
#: users/templates/users/reset_password.html:6
|
||||||
msgid "Reset password"
|
msgid "Reset password"
|
||||||
msgstr "重置密码"
|
msgstr "重置密码"
|
||||||
|
|
||||||
#: users/notifications.py:81 users/views/profile/reset.py:127
|
#: users/notifications.py:78 users/views/profile/reset.py:127
|
||||||
msgid "Reset password success"
|
msgid "Reset password success"
|
||||||
msgstr "重置密码成功"
|
msgstr "重置密码成功"
|
||||||
|
|
||||||
#: users/notifications.py:107
|
#: users/notifications.py:104
|
||||||
msgid "Password is about expire"
|
msgid "Password is about expire"
|
||||||
msgstr "密码即将过期"
|
msgstr "密码即将过期"
|
||||||
|
|
||||||
#: users/notifications.py:135
|
#: users/notifications.py:132
|
||||||
msgid "Account is about expire"
|
msgid "Account is about expire"
|
||||||
msgstr "账号即将过期"
|
msgstr "账号即将过期"
|
||||||
|
|
||||||
#: users/notifications.py:157
|
#: users/notifications.py:154
|
||||||
msgid "Reset SSH Key"
|
msgid "Reset SSH Key"
|
||||||
msgstr "重置 SSH 密钥"
|
msgstr "重置 SSH 密钥"
|
||||||
|
|
||||||
#: users/notifications.py:178
|
#: users/notifications.py:175
|
||||||
msgid "Reset MFA"
|
msgid "Reset MFA"
|
||||||
msgstr "重置 MFA"
|
msgstr "重置 MFA"
|
||||||
|
|
||||||
|
@ -5109,11 +5143,7 @@ msgstr "点击这里设置"
|
||||||
msgid "Your ssh public key has been reset by site administrator"
|
msgid "Your ssh public key has been reset by site administrator"
|
||||||
msgstr "你的 SSH 密钥已经被管理员重置"
|
msgstr "你的 SSH 密钥已经被管理员重置"
|
||||||
|
|
||||||
#: users/templates/users/_msg_user_created.html:8
|
#: users/templates/users/_msg_user_created.html:15
|
||||||
msgid "Your account has been created successfully"
|
|
||||||
msgstr "您的账户已创建成功"
|
|
||||||
|
|
||||||
#: users/templates/users/_msg_user_created.html:13
|
|
||||||
msgid "click here to set your password"
|
msgid "click here to set your password"
|
||||||
msgstr "点击这里设置密码"
|
msgstr "点击这里设置密码"
|
||||||
|
|
||||||
|
@ -5500,15 +5530,15 @@ msgstr "* 请输入正确的密码长度"
|
||||||
msgid "* Password length range 6-30 bits"
|
msgid "* Password length range 6-30 bits"
|
||||||
msgstr "* 密码长度范围 6-30 位"
|
msgstr "* 密码长度范围 6-30 位"
|
||||||
|
|
||||||
#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:248
|
#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:249
|
||||||
msgid "Invalid/incorrect password"
|
msgid "Invalid/incorrect password"
|
||||||
msgstr "无效/错误 密码"
|
msgstr "无效/错误 密码"
|
||||||
|
|
||||||
#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:250
|
#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:251
|
||||||
msgid "Failed to connect to the host"
|
msgid "Failed to connect to the host"
|
||||||
msgstr "连接主机失败"
|
msgstr "连接主机失败"
|
||||||
|
|
||||||
#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:252
|
#: xpack/plugins/change_auth_plan/task_handlers/base/handler.py:253
|
||||||
msgid "Data could not be sent to remote"
|
msgid "Data could not be sent to remote"
|
||||||
msgstr "无法将数据发送到远程"
|
msgstr "无法将数据发送到远程"
|
||||||
|
|
||||||
|
@ -5866,7 +5896,7 @@ msgstr "执行次数"
|
||||||
msgid "Instance count"
|
msgid "Instance count"
|
||||||
msgstr "实例个数"
|
msgstr "实例个数"
|
||||||
|
|
||||||
#: xpack/plugins/cloud/utils.py:65
|
#: xpack/plugins/cloud/utils.py:68
|
||||||
msgid "Account unavailable"
|
msgid "Account unavailable"
|
||||||
msgstr "账户无效"
|
msgstr "账户无效"
|
||||||
|
|
||||||
|
@ -5954,6 +5984,10 @@ msgstr "旗舰版"
|
||||||
msgid "Community edition"
|
msgid "Community edition"
|
||||||
msgstr "社区版"
|
msgstr "社区版"
|
||||||
|
|
||||||
|
#, python-brace-format
|
||||||
|
#~ msgid "Hello {name}"
|
||||||
|
#~ msgstr "你好 {name}"
|
||||||
|
|
||||||
#~ msgid "Login direct"
|
#~ msgid "Login direct"
|
||||||
#~ msgstr "直接登录"
|
#~ msgstr "直接登录"
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,36 @@
|
||||||
{% extends '_without_nav_base.html' %}
|
{% extends '_without_nav_base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
<style>
|
||||||
|
li {
|
||||||
|
list-style: disc;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
padding-left: 30px;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<div style="margin: 0 200px">
|
<div style="margin: 0 200px">
|
||||||
<div class="group">
|
<div class="group">
|
||||||
<h2>JumpServer Clients</h2>
|
<h2>JumpServer {% trans 'Client' %}</h2>
|
||||||
|
<p>
|
||||||
|
{% trans 'JumpServer Client, currently used to launch the client, now only support launch RDP client, The SSH client will next' %}
|
||||||
|
{# //JumpServer 客户端,支持 RDP 的本地拉起,后续会支持拉起 ssh。#}
|
||||||
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/download/JumpServer-Client-Installer.msi">jumpserver-client-windows.msi</a></li>
|
<li> <a href="/download/JumpServer-Client-Installer.msi">Windows {% trans 'Client' %}</a></li>
|
||||||
<li><a href="/download/JumpServer-Client-Installer.dmg">jumpserver-client-macos.dmg</a></li>
|
<li> <a href="/download/JumpServer-Client-Installer.dmg">macOS {% trans 'Client' %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="group">
|
<div class="group">
|
||||||
<h2>RDP Clients</h2>
|
<h2>{% trans 'Microsoft' %} RDP {% trans 'Official' %}{% trans 'Client' %}</h2>
|
||||||
|
<p>
|
||||||
|
{% trans 'macOS needs to download the client to connect RDP asset, which comes with Windows' %}
|
||||||
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/download/Microsoft_Remote_Desktop_10.6.7_installer.pkg">Microsoft_Remote_Desktop_10.6.7_installer.pkg</a></li>
|
<li><a href="/download/Microsoft_Remote_Desktop_10.6.7_installer.pkg">Microsoft_Remote_Desktop_10.6.7_installer.pkg</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -131,10 +131,13 @@ class CommandStore():
|
||||||
index=self.index, doc_type=self.doc_type, body=body, from_=from_, size=size,
|
index=self.index, doc_type=self.doc_type, body=body, from_=from_, size=size,
|
||||||
sort=sort
|
sort=sort
|
||||||
)
|
)
|
||||||
|
source_data = []
|
||||||
|
for item in data['hits']['hits']:
|
||||||
|
if item:
|
||||||
|
item['_source'].update({'id': item['_id']})
|
||||||
|
source_data.append(item['_source'])
|
||||||
|
|
||||||
return AbstractSessionCommand.from_multi_dict(
|
return AbstractSessionCommand.from_multi_dict(source_data)
|
||||||
[item['_source'] for item in data['hits']['hits'] if item]
|
|
||||||
)
|
|
||||||
|
|
||||||
def count(self, **query):
|
def count(self, **query):
|
||||||
body = self.get_query_body(**query)
|
body = self.get_query_body(**query)
|
||||||
|
@ -160,11 +163,16 @@ class CommandStore():
|
||||||
new_kwargs[k] = str(v) if isinstance(v, UUID) else v
|
new_kwargs[k] = str(v) if isinstance(v, UUID) else v
|
||||||
kwargs = new_kwargs
|
kwargs = new_kwargs
|
||||||
|
|
||||||
|
index_in_field = 'id__in'
|
||||||
exact_fields = self.exact_fields
|
exact_fields = self.exact_fields
|
||||||
match_fields = self.match_fields
|
match_fields = self.match_fields
|
||||||
|
|
||||||
match = {}
|
match = {}
|
||||||
exact = {}
|
exact = {}
|
||||||
|
index = {}
|
||||||
|
|
||||||
|
if index_in_field in kwargs:
|
||||||
|
index['values'] = kwargs[index_in_field]
|
||||||
|
|
||||||
for k, v in kwargs.items():
|
for k, v in kwargs.items():
|
||||||
if k in exact_fields:
|
if k in exact_fields:
|
||||||
|
@ -221,6 +229,10 @@ class CommandStore():
|
||||||
'timestamp': timestamp_range
|
'timestamp': timestamp_range
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
] + [
|
||||||
|
{
|
||||||
|
'ids': {k: v}
|
||||||
|
} for k, v in index.items()
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,3 +8,4 @@ class InsecureCommandAlertSerializer(serializers.Serializer):
|
||||||
user = serializers.CharField()
|
user = serializers.CharField()
|
||||||
risk_level = serializers.IntegerField()
|
risk_level = serializers.IntegerField()
|
||||||
session = serializers.UUIDField()
|
session = serializers.UUIDField()
|
||||||
|
org_id = serializers.CharField()
|
||||||
|
|
|
@ -29,7 +29,7 @@ class TicketViewSet(CommonApiMixin, viewsets.ModelViewSet):
|
||||||
search_fields = [
|
search_fields = [
|
||||||
'title', 'action', 'type', 'status', 'applicant_display'
|
'title', 'action', 'type', 'status', 'applicant_display'
|
||||||
]
|
]
|
||||||
ordering_fields = ('title',)
|
ordering_fields = ('title', 'applicant_display', 'status', 'state', 'action_display', 'date_created')
|
||||||
ordering = ('title', )
|
ordering = ('title', )
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
|
|
|
@ -12,21 +12,18 @@ from notifications.notifications import UserMessage
|
||||||
class UserCreatedMsg(UserMessage):
|
class UserCreatedMsg(UserMessage):
|
||||||
def get_html_msg(self) -> dict:
|
def get_html_msg(self) -> dict:
|
||||||
user = self.user
|
user = self.user
|
||||||
subject = _('Create account successfully')
|
|
||||||
if settings.EMAIL_CUSTOM_USER_CREATED_SUBJECT:
|
|
||||||
subject = settings.EMAIL_CUSTOM_USER_CREATED_SUBJECT
|
|
||||||
|
|
||||||
honorific = settings.EMAIL_CUSTOM_USER_CREATED_HONORIFIC or _('Hello {}').format(user.name)
|
subject = str(settings.EMAIL_CUSTOM_USER_CREATED_SUBJECT)
|
||||||
signature = settings.EMAIL_CUSTOM_USER_CREATED_SIGNATURE or 'JumpServer'
|
honorific = str(settings.EMAIL_CUSTOM_USER_CREATED_HONORIFIC)
|
||||||
|
content = str(settings.EMAIL_CUSTOM_USER_CREATED_BODY)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'honorific': honorific,
|
'honorific': honorific,
|
||||||
'signature': signature,
|
'content': content,
|
||||||
'username': user.username,
|
'user': user,
|
||||||
'rest_password_url': reverse('authentication:reset-password', external=True),
|
'rest_password_url': reverse('authentication:reset-password', external=True),
|
||||||
'rest_password_token': user.generate_reset_token(),
|
'rest_password_token': user.generate_reset_token(),
|
||||||
'forget_password_url': reverse('authentication:forgot-password', external=True),
|
'forget_password_url': reverse('authentication:forgot-password', external=True),
|
||||||
'email': user.email,
|
|
||||||
'login_url': reverse('authentication:login', external=True),
|
'login_url': reverse('authentication:login', external=True),
|
||||||
}
|
}
|
||||||
message = render_to_string('users/_msg_user_created.html', context)
|
message = render_to_string('users/_msg_user_created.html', context)
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
{{ honorific }}:
|
{{ honorific }} {{ user }},
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p>{% trans 'Your account has been created successfully' %}</p>
|
|
||||||
<p>
|
<p>
|
||||||
{% trans 'Username' %}: {{ username }} <br />
|
{{ content }}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{% trans 'Username' %}: {{ user.username }} <br />
|
||||||
{% trans 'Password' %}:
|
{% trans 'Password' %}:
|
||||||
<a href="{{ rest_password_url}}?token={{ rest_password_token }}">
|
<a href="{{ rest_password_url}}?token={{ rest_password_token }}">
|
||||||
{% trans 'click here to set your password' %}
|
{% trans 'click here to set your password' %}
|
||||||
|
@ -15,6 +17,6 @@
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{% trans 'This link is valid for 1 hour. After it expires' %}
|
{% trans 'This link is valid for 1 hour. After it expires' %}
|
||||||
<a href="{{ forget_password_url }}?email={{ email }}">{% trans 'request new one' %}</a>
|
<a href="{{ forget_password_url }}?email={{ user.email }}">{% trans 'request new one' %}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,7 +22,7 @@ def send_user_created_mail(user):
|
||||||
from .notifications import UserCreatedMsg
|
from .notifications import UserCreatedMsg
|
||||||
|
|
||||||
recipient_list = [user.email]
|
recipient_list = [user.email]
|
||||||
msg = UserCreatedMsg.html_msg
|
msg = UserCreatedMsg(user).html_msg
|
||||||
subject = msg['subject']
|
subject = msg['subject']
|
||||||
message = msg['message']
|
message = msg['message']
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ ipython
|
||||||
huaweicloud-sdk-python==1.0.21
|
huaweicloud-sdk-python==1.0.21
|
||||||
django-redis==4.11.0
|
django-redis==4.11.0
|
||||||
python-redis-lock==3.5.0
|
python-redis-lock==3.5.0
|
||||||
jumpserver-django-oidc-rp==0.3.7.7
|
jumpserver-django-oidc-rp==0.3.7.8
|
||||||
django-mysql==3.9.0
|
django-mysql==3.9.0
|
||||||
gmssl==3.2.1
|
gmssl==3.2.1
|
||||||
azure-mgmt-compute==4.6.2
|
azure-mgmt-compute==4.6.2
|
||||||
|
@ -119,4 +119,4 @@ cx-Oracle==8.2.1
|
||||||
psycopg2-binary==2.9.1
|
psycopg2-binary==2.9.1
|
||||||
alibabacloud_dysmsapi20170525==2.0.2
|
alibabacloud_dysmsapi20170525==2.0.2
|
||||||
geoip2==4.4.0
|
geoip2==4.4.0
|
||||||
html2text==2020.1.16
|
html2text==2020.1.16
|
||||||
|
|
Loading…
Reference in New Issue