Compare commits

...

17 Commits
v4.4 ... v2.26

Author SHA1 Message Date
Eric
1bbb5eaf6f fix: 修复存储故障造成的录像获取失败问题 2023-03-09 11:52:56 +08:00
feng
b5b7cd7693 fix: ticket xss inject 2022-12-12 17:04:38 +08:00
“huailei000”
5b35e99866 perf: update jquery 2022-10-13 14:44:59 +08:00
Jiangjie.Bai
680c174dcf fix: 修复 OAuth2 用户本地被禁用后,页面一直跳转的问题. 2022-10-11 18:46:24 +08:00
feng626
68a1388afd fix: 修复创建工单无备注信息bug 2022-10-10 16:55:37 +08:00
Jiangjie.Bai
da47706dda fix: 修复es存储失效时,会话命令列表页面报错的问题 2022-09-28 17:04:01 +08:00
Jiangjie.Bai
922f777fbb fix: 修复命令存储es失效时, 会话、命令记录列表创建和查看失败的问题 2022-09-28 17:04:01 +08:00
Jiangjie.Bai
ca3c56320e fix: 锁定依赖包版本 pyOpenSSL==22.0.0 2022-09-27 15:47:47 +08:00
Aaron3S
2ed2c16ff5 fix: 修改解密异常抛出范围 2022-09-27 15:47:03 +08:00
Aaron3S
3069bb5b0c fix: 修复空字符串加密报错的问题 2022-09-27 11:28:31 +08:00
Aaron3S
b0650b0047 perf: 优化去除结尾空字节的写法 2022-09-26 15:29:28 +08:00
Aaron3S
7e133bb0c4 feat: 增加PIICO设备配置项 2022-09-26 14:39:53 +08:00
Aaron3S
bd854cfd0f feat: 增加国密配置项 2022-09-26 14:39:53 +08:00
Aaron3S
f458eff527 fix: 修复密码后空格的问题 2022-09-26 14:38:45 +08:00
feng626
97b37bfb5d fix: reset ssh url problem 2022-09-21 18:34:47 +08:00
吴小白
4d7ff0828b fix: 修复 redis 异常后 celery 旧任务不执行的问题 2022-09-21 18:34:00 +08:00
ibuler
7db3d63e64 fix: 修复 celery 丢失心跳不会重连的问题 2022-09-21 18:34:00 +08:00
17 changed files with 63 additions and 27 deletions

View File

@@ -55,7 +55,9 @@ class OAuth2AuthCallbackView(View):
)
logger.debug(log_prompt.format('Redirect'))
return HttpResponseRedirect(settings.AUTH_OAUTH2_AUTHENTICATION_FAILURE_REDIRECT_URI)
# OAuth2 服务端认证成功, 但是用户被禁用了, 这时候需要调用服务端的logout
redirect_url = settings.AUTH_OAUTH2_PROVIDER_END_SESSION_ENDPOINT
return HttpResponseRedirect(redirect_url)
class OAuth2EndSessionView(View):

View File

@@ -30,7 +30,9 @@ class CeleryBaseService(BaseService):
'-l', 'INFO',
'-c', str(self.num),
'-Q', self.queue,
'-n', f'{self.queue}@{server_hostname}'
'--heartbeat-interval', '10',
'-n', f'{self.queue}@{server_hostname}',
'--without-mingle',
]
return cmd

View File

@@ -33,7 +33,7 @@ class EBCCipher:
def __padding(val):
# padding
val = bytes(val)
while len(val) % 16 != 0:
while len(val) == 0 or len(val) % 16 != 0:
val += b'\0'
return val

View File

@@ -82,7 +82,8 @@ class PiicoSM4EcbCrypto(BaseCrypto):
return self.cipher.encrypt(self.to_16(data))
def _decrypt(self, data: bytes) -> bytes:
return self.cipher.decrypt(data)
bs = self.cipher.decrypt(data)
return bs.rstrip(b'\0')
class AESCrypto:
@@ -232,6 +233,8 @@ class Crypto:
return self.cryptos[0]
def encrypt(self, text):
if text is None:
return text
return self.encryptor.encrypt(text)
def decrypt(self, text):
@@ -241,7 +244,7 @@ class Crypto:
if origin_text:
# 有时不同算法解密不报错,但是返回空字符串
return origin_text
except (TypeError, ValueError, UnicodeDecodeError, IndexError):
except Exception:
continue

View File

@@ -161,6 +161,8 @@ AUTH_OAUTH2_CLIENT_SECRET = CONFIG.AUTH_OAUTH2_CLIENT_SECRET
AUTH_OAUTH2_CLIENT_ID = CONFIG.AUTH_OAUTH2_CLIENT_ID
AUTH_OAUTH2_SCOPE = CONFIG.AUTH_OAUTH2_SCOPE
AUTH_OAUTH2_USER_ATTR_MAP = CONFIG.AUTH_OAUTH2_USER_ATTR_MAP
AUTH_OAUTH2_LOGOUT_COMPLETELY = CONFIG.AUTH_OAUTH2_LOGOUT_COMPLETELY
AUTH_OAUTH2_PROVIDER_END_SESSION_ENDPOINT = CONFIG.AUTH_OAUTH2_PROVIDER_END_SESSION_ENDPOINT
AUTH_OAUTH2_AUTH_LOGIN_CALLBACK_URL_NAME = 'authentication:oauth2:login-callback'
AUTH_OAUTH2_AUTHENTICATION_REDIRECT_URI = '/'
AUTH_OAUTH2_AUTHENTICATION_FAILURE_REDIRECT_URI = '/'

View File

@@ -9,7 +9,6 @@ from .base import (
)
from ..const import CONFIG, PROJECT_DIR
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
@@ -64,7 +63,6 @@ SWAGGER_SETTINGS = {
'DEFAULT_INFO': 'jumpserver.views.swagger.api_info',
}
# Captcha settings, more see https://django-simple-captcha.readthedocs.io/en/latest/advanced.html
CAPTCHA_IMAGE_SIZE = (180, 38)
CAPTCHA_FOREGROUND_COLOR = '#001100'
@@ -81,7 +79,6 @@ BOOTSTRAP3 = {
'required_css_class': 'required',
}
# Django channels support websocket
if not REDIS_USE_SSL:
redis_ssl = None
@@ -101,14 +98,13 @@ CHANNEL_LAYERS = {
'address': (CONFIG.REDIS_HOST, CONFIG.REDIS_PORT),
'db': CONFIG.REDIS_DB_WS,
'password': CONFIG.REDIS_PASSWORD or None,
'ssl': redis_ssl
'ssl': redis_ssl
}],
},
},
}
ASGI_APPLICATION = 'jumpserver.routing.application'
# Dump all celery log to here
CELERY_LOG_DIR = os.path.join(PROJECT_DIR, 'data', 'celery')
@@ -131,6 +127,7 @@ CELERY_TASK_EAGER_PROPAGATES = True
CELERY_WORKER_REDIRECT_STDOUTS = True
CELERY_WORKER_REDIRECT_STDOUTS_LEVEL = "INFO"
CELERY_TASK_SOFT_TIME_LIMIT = 3600
CELERY_WORKER_CANCEL_LONG_RUNNING_TASKS_ON_CONNECTION_LOSS = True
if REDIS_USE_SSL:
CELERY_BROKER_USE_SSL = CELERY_REDIS_BACKEND_USE_SSL = {
@@ -148,3 +145,7 @@ REDIS_PORT = CONFIG.REDIS_PORT
REDIS_PASSWORD = CONFIG.REDIS_PASSWORD
DJANGO_REDIS_SCAN_ITERSIZE = 1000
# GM DEVICE
PIICO_DEVICE_ENABLE = CONFIG.PIICO_DEVICE_ENABLE
PIICO_DRIVER_PATH = CONFIG.PIICO_DRIVER_PATH

View File

@@ -2,7 +2,7 @@
{% load i18n %}
<head>
<title>{% trans 'Task log' %}</title>
<script src="{% static 'js/jquery-3.1.1.min.js' %}"></script>
<script src="{% static 'js/jquery-3.6.1.min.js' %}"></script>
<script src="{% static 'js/plugins/xterm/xterm.js' %}"></script>
<script src="{% static 'js/plugins/xterm/addons/fit/fit.js' %}"></script>
<link rel="stylesheet" href="{% static 'js/plugins/xterm/xterm.css' %}" />

File diff suppressed because one or more lines are too long

2
apps/static/js/jquery-3.6.1.min.js vendored Executable file

File diff suppressed because one or more lines are too long

View File

@@ -9,7 +9,7 @@
<link href="{% static 'css/plugins/vaildator/jquery.validator.css' %}" rel="stylesheet">
<link href="{% static 'css/plugins/datatables/datatables.min.css' %}" rel="stylesheet">
<!-- scripts -->
<script src="{% static 'js/jquery-3.1.1.min.js' %}"></script>
<script src="{% static 'js/jquery-3.6.1.min.js' %}"></script>
<script src="{% static 'js/plugins/sweetalert/sweetalert.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<script src="{% static 'js/plugins/datatables/datatables.min.js' %}"></script>

View File

@@ -169,6 +169,14 @@ class CommandStore(object):
return self.es.index(index=self.index, doc_type=self.doc_type, body=data)
def filter(self, query: dict, from_=None, size=None, sort=None):
try:
data = self._filter(query, from_, size, sort)
except Exception as e:
logger.error('ES filter error: {}'.format(e))
data = []
return data
def _filter(self, query: dict, from_=None, size=None, sort=None):
body = self.get_query_body(**query)
data = self.es.search(
@@ -184,9 +192,14 @@ class CommandStore(object):
return Command.from_multi_dict(source_data)
def count(self, **query):
body = self.get_query_body(**query)
data = self.es.count(index=self.query_index, doc_type=self.doc_type, body=body)
return data["count"]
try:
body = self.get_query_body(**query)
data = self.es.count(index=self.query_index, doc_type=self.doc_type, body=body)
count = data["count"]
except Exception as e:
logger.error('ES count error: {}'.format(e))
count = 0
return count
def __getattr__(self, item):
return getattr(self.es, item)

View File

@@ -117,9 +117,13 @@ class Session(OrgModelMixin):
def find_ok_relative_path_in_storage(self, storage):
session_paths = self.get_all_possible_relative_path()
for rel_path in session_paths:
if storage.exists(rel_path):
return rel_path
# storage 为多个外部存储时, 可能会因部分不可用,
# 抛出异常, 影响录像的获取
try:
if storage.exists(rel_path):
return rel_path
except:
pass
@property
def asset_obj(self):
return Asset.objects.get(id=self.asset_id)

View File

@@ -1,3 +1,5 @@
from html import escape
from django.utils.translation import ugettext as _
from django.template.loader import render_to_string
@@ -42,7 +44,7 @@ class BaseHandler:
def _on_step_rejected(self, step):
self._send_processed_mail_to_applicant(step)
def _on_step_closed(self, step):
def _on_step_closed(self):
self._send_processed_mail_to_applicant()
def _send_applied_mail_to_assignees(self, step=None):
@@ -96,11 +98,19 @@ class BaseHandler:
approve_info = _('{} {} the ticket').format(user_display, state_display)
context = self._diff_prev_approve_context(state)
context.update({'approve_info': approve_info})
body = self.reject_html_script(
render_to_string('tickets/ticket_approve_diff.html', context)
)
data = {
'body': render_to_string('tickets/ticket_approve_diff.html', context),
'body': body,
'user': user,
'user_display': str(user),
'type': 'state',
'state': state
}
return self.ticket.comments.create(**data)
@staticmethod
def reject_html_script(unsafe_html):
safe_html = escape(unsafe_html)
return safe_html

View File

@@ -19,7 +19,7 @@ class ApplyApplicationSerializer(BaseApplyAssetApplicationSerializer, TicketAppl
class Meta:
model = ApplyApplicationTicket
writeable_fields = [
'id', 'title', 'type', 'apply_category',
'id', 'title', 'type', 'apply_category', 'comment',
'apply_type', 'apply_applications', 'apply_system_users',
'apply_actions', 'apply_date_start', 'apply_date_expired', 'org_id'
]

View File

@@ -23,7 +23,7 @@ class ApplyAssetSerializer(BaseApplyAssetApplicationSerializer, TicketApplySeria
model = ApplyAssetTicket
writeable_fields = [
'id', 'title', 'type', 'apply_nodes', 'apply_assets',
'apply_system_users', 'apply_actions',
'apply_system_users', 'apply_actions', 'comment',
'apply_date_start', 'apply_date_expired', 'org_id'
]
fields = TicketApplySerializer.Meta.fields + \

View File

@@ -191,7 +191,7 @@ class UserExpirationReminderMsg(UserMessage):
class ResetSSHKeyMsg(UserMessage):
def get_html_msg(self) -> dict:
subject = _('Reset SSH Key')
update_url = urljoin(settings.SITE_URL, '/ui/#/users/profile/?activeTab=SSHUpdate')
update_url = urljoin(settings.SITE_URL, '/ui/#/profile/setting/?activeTab=SSHUpdate')
context = {
'name': self.user.name,
'url': update_url,

View File

@@ -133,6 +133,7 @@ pymssql==2.1.5
django-mysql==3.9.0
django-redis==5.2.0
python-redis-lock==3.7.0
pyOpenSSL==22.0.0
redis==4.3.3
pymongo==4.2.0
# Debug