mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-12-15 08:32:48 +00:00
Compare commits
17 Commits
pr@dev@per
...
v2.26
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1bbb5eaf6f | ||
|
|
b5b7cd7693 | ||
|
|
5b35e99866 | ||
|
|
680c174dcf | ||
|
|
68a1388afd | ||
|
|
da47706dda | ||
|
|
922f777fbb | ||
|
|
ca3c56320e | ||
|
|
2ed2c16ff5 | ||
|
|
3069bb5b0c | ||
|
|
b0650b0047 | ||
|
|
7e133bb0c4 | ||
|
|
bd854cfd0f | ||
|
|
f458eff527 | ||
|
|
97b37bfb5d | ||
|
|
4d7ff0828b | ||
|
|
7db3d63e64 |
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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 = '/'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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' %}" />
|
||||
|
||||
4
apps/static/js/jquery-3.1.1.min.js
vendored
4
apps/static/js/jquery-3.1.1.min.js
vendored
File diff suppressed because one or more lines are too long
2
apps/static/js/jquery-3.6.1.min.js
vendored
Executable file
2
apps/static/js/jquery-3.6.1.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
]
|
||||
|
||||
@@ -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 + \
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user