Compare commits

...

9 Commits

Author SHA1 Message Date
ibuler
4bceac8e83 fix: 修复系统用户解密 2022-07-21 17:58:50 +08:00
Jiangjie.Bai
8aa21db52b fix: 修改用户自更新失败的问题 2022-07-12 14:24:22 +08:00
Jiangjie.Bai
9cfbbe9157 fix: 修复 ES 存储 config 被修改的问题 2022-07-08 11:00:00 +08:00
Jiangjie.Bai
ade78ef94e fix: 修复创建共享会话链接时 created_by 字段长度问题 2022-07-07 15:43:41 +08:00
Jiangjie.Bai
52fdac3853 feat: 添加 OmniDB Enabled 控制
feat: 添加 OmniDB Enabled 控制
2022-07-05 11:13:02 +08:00
fit2bot
70418ef8c8 perf: 修复命令表系统用户字段长度问题,截取成64字符 (#8520)
* perf: 修复命令表系统用户字段长度问题,截取成64字符

* perf: 优化截取方法

* perf: 优化截取方法

Co-authored-by: halo <wuyihuangw@gmail.com>
2022-07-04 11:01:14 +08:00
Jiangjie.Bai
58798094e5 perf: 优化 BASE_SITE_URL OIDC 可以为空,实现多个不同端点访问时回调为当前访问的地址 2022-06-29 18:46:28 +08:00
jiangweidong
a6367af7d3 fix: 修复部署在无证书的Redis上,定时任务不执行的问题-v2.23 2022-06-28 12:33:58 +08:00
ibuler
dd2c736b8e perf: 修改 jumpserver 版本号,避免缓存 2022-06-28 10:48:25 +08:00
15 changed files with 34 additions and 28 deletions

View File

@@ -14,7 +14,7 @@
<!-- Stylesheets --> <!-- Stylesheets -->
<link href="{% static 'css/login-style.css' %}" rel="stylesheet"> <link href="{% static 'css/login-style.css' %}" rel="stylesheet">
<link href="{% static 'css/jumpserver.css' %}" rel="stylesheet"> <link href="{% static 'css/jumpserver.css' %}" rel="stylesheet">
<script src="{% static "js/jumpserver.js" %}"></script> <script src="{% static "js/jumpserver.js" %}?_=9"></script>
<style> <style>
.login-content { .login-content {

View File

@@ -10,7 +10,7 @@
<title>{{ title }}</title> <title>{{ title }}</title>
{% include '_head_css_js.html' %} {% include '_head_css_js.html' %}
<link href="{% static "css/jumpserver.css" %}" rel="stylesheet"> <link href="{% static "css/jumpserver.css" %}" rel="stylesheet">
<script src="{% static "js/jumpserver.js" %}"></script> <script src="{% static "js/jumpserver.js" %}?_=9"></script>
</head> </head>

View File

@@ -259,7 +259,7 @@ def decrypt_password(value):
aes = get_aes_crypto(aes_key, 'ECB') aes = get_aes_crypto(aes_key, 'ECB')
try: try:
password = aes.decrypt(password_cipher) password = aes.decrypt(password_cipher)
except UnicodeDecodeError as e: except Exception as e:
logging.error("Decript password error: {}, {}".format(password_cipher, e)) logging.error("Decript password error: {}, {}".format(password_cipher, e))
return value return value
return password return password

View File

@@ -325,6 +325,7 @@ class Config(dict):
'TERMINAL_MAGNUS_ENABLED': True, 'TERMINAL_MAGNUS_ENABLED': True,
'TERMINAL_KOKO_SSH_ENABLED': True, 'TERMINAL_KOKO_SSH_ENABLED': True,
'TERMINAL_RAZOR_ENABLED': True, 'TERMINAL_RAZOR_ENABLED': True,
'TERMINAL_OMNIDB_ENABLED': True,
# 安全配置 # 安全配置
'SECURITY_MFA_AUTH': 0, # 0 不开启 1 全局开启 2 管理员开启 'SECURITY_MFA_AUTH': 0, # 0 不开启 1 全局开启 2 管理员开启

View File

@@ -140,6 +140,7 @@ LOGIN_REDIRECT_MSG_ENABLED = CONFIG.LOGIN_REDIRECT_MSG_ENABLED
CLOUD_SYNC_TASK_EXECUTION_KEEP_DAYS = CONFIG.CLOUD_SYNC_TASK_EXECUTION_KEEP_DAYS CLOUD_SYNC_TASK_EXECUTION_KEEP_DAYS = CONFIG.CLOUD_SYNC_TASK_EXECUTION_KEEP_DAYS
TERMINAL_RAZOR_ENABLED = CONFIG.TERMINAL_RAZOR_ENABLED TERMINAL_RAZOR_ENABLED = CONFIG.TERMINAL_RAZOR_ENABLED
TERMINAL_OMNIDB_ENABLED = CONFIG.TERMINAL_OMNIDB_ENABLED
TERMINAL_MAGNUS_ENABLED = CONFIG.TERMINAL_MAGNUS_ENABLED TERMINAL_MAGNUS_ENABLED = CONFIG.TERMINAL_MAGNUS_ENABLED
TERMINAL_KOKO_SSH_ENABLED = CONFIG.TERMINAL_KOKO_SSH_ENABLED TERMINAL_KOKO_SSH_ENABLED = CONFIG.TERMINAL_KOKO_SSH_ENABLED

View File

@@ -11,7 +11,8 @@ __all__ = [
class CommonSettingSerializer(serializers.Serializer): class CommonSettingSerializer(serializers.Serializer):
# OpenID 公有配置参数 (version <= 1.5.8 或 version >= 1.5.8) # OpenID 公有配置参数 (version <= 1.5.8 或 version >= 1.5.8)
BASE_SITE_URL = serializers.CharField( BASE_SITE_URL = serializers.CharField(
required=False, allow_null=True, max_length=1024, label=_('Base site url') required=False, allow_null=True, allow_blank=True,
max_length=1024, label=_('Base site url')
) )
AUTH_OPENID_CLIENT_ID = serializers.CharField( AUTH_OPENID_CLIENT_ID = serializers.CharField(
required=False, max_length=1024, label=_('Client Id') required=False, max_length=1024, label=_('Client Id')

View File

@@ -38,6 +38,7 @@ class PrivateSettingSerializer(PublicSettingSerializer):
TERMINAL_RAZOR_ENABLED = serializers.BooleanField() TERMINAL_RAZOR_ENABLED = serializers.BooleanField()
TERMINAL_MAGNUS_ENABLED = serializers.BooleanField() TERMINAL_MAGNUS_ENABLED = serializers.BooleanField()
TERMINAL_KOKO_SSH_ENABLED = serializers.BooleanField() TERMINAL_KOKO_SSH_ENABLED = serializers.BooleanField()
TERMINAL_OMNIDB_ENABLED = serializers.BooleanField()
ANNOUNCEMENT_ENABLED = serializers.BooleanField() ANNOUNCEMENT_ENABLED = serializers.BooleanField()
ANNOUNCEMENT = serializers.DictField() ANNOUNCEMENT = serializers.DictField()

View File

@@ -11,7 +11,7 @@
{% include '_head_css_js.html' %} {% include '_head_css_js.html' %}
<link href="{% static "css/jumpserver.css" %}" rel="stylesheet"> <link href="{% static "css/jumpserver.css" %}" rel="stylesheet">
<script src="{% static "js/jumpserver.js" %}"></script> <script src="{% static "js/jumpserver.js" %}?_=9"></script>
<style> <style>
.outerBox { .outerBox {
margin: 0 auto; margin: 0 auto;

View File

@@ -11,7 +11,7 @@
{% include '_head_css_js.html' %} {% include '_head_css_js.html' %}
<link href="{% static "css/jumpserver.css" %}" rel="stylesheet"> <link href="{% static "css/jumpserver.css" %}" rel="stylesheet">
<script src="{% static "js/jumpserver.js" %}"></script> <script src="{% static "js/jumpserver.js" %}?_=9"></script>
<style> <style>
.passwordBox { .passwordBox {
max-width: 560px; max-width: 560px;

View File

@@ -6,7 +6,7 @@
<!-- Custom and plugin javascript --> <!-- Custom and plugin javascript -->
<script src="{% static "js/plugins/toastr/toastr.min.js" %}"></script> <script src="{% static "js/plugins/toastr/toastr.min.js" %}"></script>
<script src="{% static "js/inspinia.js" %}"></script> <script src="{% static "js/inspinia.js" %}"></script>
<script src="{% static "js/jumpserver.js" %}?v=8"></script> <script src="{% static "js/jumpserver.js" %}?v=9"></script>
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script> <script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
<script src="{% static 'js/plugins/select2/i18n/zh-CN.js' %}"></script> <script src="{% static 'js/plugins/select2/i18n/zh-CN.js' %}"></script>
<script> <script>

View File

@@ -2,6 +2,7 @@
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers from rest_framework import serializers
from common.utils import pretty_string
from .models import AbstractSessionCommand from .models import AbstractSessionCommand
__all__ = ['SessionCommandSerializer', 'InsecureCommandAlertSerializer'] __all__ = ['SessionCommandSerializer', 'InsecureCommandAlertSerializer']
@@ -32,7 +33,7 @@ class SessionCommandSerializer(SimpleSessionCommandSerializer):
"""使用这个类作为基础Command Log Serializer类, 用来序列化""" """使用这个类作为基础Command Log Serializer类, 用来序列化"""
id = serializers.UUIDField(read_only=True) id = serializers.UUIDField(read_only=True)
system_user = serializers.CharField(max_length=64, label=_("System user")) system_user = serializers.CharField(label=_("System user")) # 限制 64 字符,不能直接迁移成 128 字符,命令表数据量会比较大
output = serializers.CharField(max_length=2048, allow_blank=True, label=_("Output")) output = serializers.CharField(max_length=2048, allow_blank=True, label=_("Output"))
risk_level_display = serializers.SerializerMethodField(label=_('Risk level display')) risk_level_display = serializers.SerializerMethodField(label=_('Risk level display'))
timestamp = serializers.IntegerField(label=_('Timestamp')) timestamp = serializers.IntegerField(label=_('Timestamp'))
@@ -43,3 +44,8 @@ class SessionCommandSerializer(SimpleSessionCommandSerializer):
def get_risk_level_display(obj): def get_risk_level_display(obj):
risk_mapper = dict(AbstractSessionCommand.RISK_LEVEL_CHOICES) risk_mapper = dict(AbstractSessionCommand.RISK_LEVEL_CHOICES)
return risk_mapper.get(obj.risk_level) return risk_mapper.get(obj.risk_level)
def validate_system_user(self, value):
if len(value) > 64:
value = pretty_string(value, 64)
return value

View File

@@ -85,7 +85,8 @@ class CommandStorage(CommonStorageModelMixin, CommonModelMixin):
config = self.config config = self.config
if self.type_es and config.get('INDEX_BY_DATE'): if self.type_es and config.get('INDEX_BY_DATE'):
engine_mod = import_module(TYPE_ENGINE_MAPPING[self.type]) engine_mod = import_module(TYPE_ENGINE_MAPPING[self.type])
store = engine_mod.CommandStore(config) # 这里使用一个全新的 config, 防止修改当前的 config
store = engine_mod.CommandStore(self.config)
store._ensure_index_exists() store._ensure_index_exists()
index_prefix = config.get('INDEX') or 'jumpserver' index_prefix = config.get('INDEX') or 'jumpserver'
date = local_now_date_display() date = local_now_date_display()

View File

@@ -2,6 +2,7 @@ from rest_framework import serializers
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from orgs.mixins.serializers import OrgResourceModelSerializerMixin from orgs.mixins.serializers import OrgResourceModelSerializerMixin
from common.utils.random import random_string from common.utils.random import random_string
from common.utils.common import pretty_string
from ..models import SessionSharing, SessionJoinRecord from ..models import SessionSharing, SessionJoinRecord
__all__ = ['SessionSharingSerializer', 'SessionJoinRecordSerializer'] __all__ = ['SessionSharingSerializer', 'SessionJoinRecordSerializer']
@@ -24,7 +25,7 @@ class SessionSharingSerializer(OrgResourceModelSerializerMixin):
session = validated_data.get('session') session = validated_data.get('session')
if session: if session:
validated_data['creator_id'] = session.user_id validated_data['creator_id'] = session.user_id
validated_data['created_by'] = str(session.user) validated_data['created_by'] = pretty_string(str(session.user), max_length=32)
validated_data['org_id'] = session.org_id validated_data['org_id'] = session.org_id
return super().create(validated_data) return super().create(validated_data)

View File

@@ -6,7 +6,7 @@ from rest_framework import serializers
from common.mixins import CommonBulkSerializerMixin from common.mixins import CommonBulkSerializerMixin
from common.validators import PhoneValidator from common.validators import PhoneValidator
from common.utils import pretty_string from common.utils import pretty_string, get_logger
from common.drf.fields import EncryptedField from common.drf.fields import EncryptedField
from rbac.builtin import BuiltinRole from rbac.builtin import BuiltinRole
from rbac.permissions import RBACPermission from rbac.permissions import RBACPermission
@@ -19,6 +19,8 @@ __all__ = [
'InviteSerializer', 'ServiceAccountSerializer', 'InviteSerializer', 'ServiceAccountSerializer',
] ]
logger = get_logger(__file__)
class RolesSerializerMixin(serializers.Serializer): class RolesSerializerMixin(serializers.Serializer):
system_roles = serializers.ManyRelatedField( system_roles = serializers.ManyRelatedField(
@@ -198,8 +200,10 @@ class UserSerializer(RolesSerializerMixin, CommonBulkSerializerMixin, serializer
if not disallow_fields: if not disallow_fields:
return attrs return attrs
# 用户自己不能更新自己的一些字段 # 用户自己不能更新自己的一些字段
error = _('User cannot self-update fields: {}').format(disallow_fields) logger.debug('Disallow update self fields: %s', disallow_fields)
raise serializers.ValidationError(error) for field in disallow_fields:
attrs.pop(field, None)
return attrs
def validate(self, attrs): def validate(self, attrs):
attrs = self.check_disallow_self_update_fields(attrs) attrs = self.check_disallow_self_update_fields(attrs)

View File

@@ -12,33 +12,23 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
APPS_DIR = os.path.join(BASE_DIR, 'apps') APPS_DIR = os.path.join(BASE_DIR, 'apps')
sys.path.insert(0, BASE_DIR) sys.path.insert(0, BASE_DIR)
sys.path.insert(0, APPS_DIR)
from apps.jumpserver.const import CONFIG from apps.jumpserver.const import CONFIG
from apps.jumpserver.settings import base as jms_settings
os.environ.setdefault('PYTHONOPTIMIZE', '1') os.environ.setdefault('PYTHONOPTIMIZE', '1')
if os.getuid() == 0: if os.getuid() == 0:
os.environ.setdefault('C_FORCE_ROOT', '1') 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 = { params = {
'host': CONFIG.REDIS_HOST, 'host': CONFIG.REDIS_HOST,
'port': CONFIG.REDIS_PORT, 'port': CONFIG.REDIS_PORT,
'password': CONFIG.REDIS_PASSWORD, 'password': CONFIG.REDIS_PASSWORD,
"ssl": CONFIG.REDIS_USE_SSL, "ssl": CONFIG.REDIS_USE_SSL,
'ssl_cert_reqs': CONFIG.REDIS_SSL_REQUIRED, 'ssl_cert_reqs': CONFIG.REDIS_SSL_REQUIRED,
"ssl_keyfile": REDIS_SSL_KEYFILE, "ssl_keyfile": jms_settings.REDIS_SSL_KEYFILE,
"ssl_certfile": REDIS_SSL_CERTFILE, "ssl_certfile": jms_settings.REDIS_SSL_CERTFILE,
"ssl_ca_certs": REDIS_SSL_CA_CERTS "ssl_ca_certs": jms_settings.REDIS_SSL_CA_CERTS
} }
redis = Redis(**params) redis = Redis(**params)
scheduler = "django_celery_beat.schedulers:DatabaseScheduler" scheduler = "django_celery_beat.schedulers:DatabaseScheduler"