mirror of https://github.com/jumpserver/jumpserver
Merge pull request #9362 from jumpserver/pr@dev@perf_applet_upload
perf: 优化 applet 上传报错pull/9365/head
commit
e5ca8c5b2c
|
@ -126,7 +126,9 @@ function csrfSafeMethod(method) {
|
|||
|
||||
function setAjaxCSRFToken() {
|
||||
let prefix = getCookie('SESSION_COOKIE_NAME_PREFIX');
|
||||
if (!prefix || [`""`, `''`].indexOf(prefix) > -1) { prefix = ''; }
|
||||
if (!prefix || [`""`, `''`].indexOf(prefix) > -1) {
|
||||
prefix = '';
|
||||
}
|
||||
var csrftoken = getCookie(`${prefix}csrftoken`);
|
||||
var sessionid = getCookie(`${prefix}sessionid`);
|
||||
|
||||
|
@ -267,7 +269,7 @@ function requestApi(props) {
|
|||
flash_message = false;
|
||||
}
|
||||
var dataBody = props.body || props.data;
|
||||
if (typeof(dataBody) === "object") {
|
||||
if (typeof (dataBody) === "object") {
|
||||
dataBody = JSON.stringify(dataBody)
|
||||
}
|
||||
var headers = props.headers || {}
|
||||
|
@ -431,13 +433,13 @@ function parseTableFilter(value) {
|
|||
return {}
|
||||
}
|
||||
var valuesArray = value.split(':');
|
||||
for (var i=0; i<valuesArray.length; i++) {
|
||||
for (var i = 0; i < valuesArray.length; i++) {
|
||||
var v = valuesArray[i].trim();
|
||||
if (!v) {
|
||||
continue
|
||||
}
|
||||
// 如果是最后一个元素,直接push,不需要再处理了, 因为最后一个肯定不是key
|
||||
if (i === valuesArray.length -1) {
|
||||
if (i === valuesArray.length - 1) {
|
||||
cleanValues.push(v);
|
||||
continue
|
||||
}
|
||||
|
@ -454,8 +456,8 @@ function parseTableFilter(value) {
|
|||
}
|
||||
var filter = {};
|
||||
var key = '';
|
||||
for (i=0; i<cleanValues.length; i++) {
|
||||
if (i%2 === 0) {
|
||||
for (i = 0; i < cleanValues.length; i++) {
|
||||
if (i % 2 === 0) {
|
||||
key = cleanValues[i]
|
||||
} else {
|
||||
value = cleanValues[i];
|
||||
|
@ -469,28 +471,7 @@ function parseTableFilter(value) {
|
|||
var jumpserver = {};
|
||||
jumpserver.checked = false;
|
||||
jumpserver.selected = {};
|
||||
jumpserver.language = {
|
||||
processing: gettext('Loading') + '...',
|
||||
search: gettext('Search'),
|
||||
select: {
|
||||
rows: {
|
||||
_: gettext("Selected item %d"),
|
||||
0: ""
|
||||
}
|
||||
},
|
||||
lengthMenu: gettext("Per page _MENU_"),
|
||||
info: gettext('Displays the results of items _START_ to _END_; A total of _TOTAL_ entries'),
|
||||
infoFiltered: "",
|
||||
infoEmpty: "",
|
||||
zeroRecords: gettext("No match"),
|
||||
emptyTable: gettext('No record'),
|
||||
paginate: {
|
||||
first: "«",
|
||||
previous: "‹",
|
||||
next: "›",
|
||||
last: "»"
|
||||
}
|
||||
};
|
||||
jumpserver.language = {};
|
||||
|
||||
function setDataTablePagerLength(num) {
|
||||
$.fn.DataTable.ext.pager.numbers_length = num;
|
||||
|
@ -612,7 +593,7 @@ jumpserver.initServerSideDataTable = function (options) {
|
|||
// hideDefaultDefs: false;
|
||||
// }
|
||||
var pagingNumbersLength = 5;
|
||||
if (options.paging_numbers_length){
|
||||
if (options.paging_numbers_length) {
|
||||
pagingNumbersLength = options.paging_numbers_length;
|
||||
}
|
||||
setDataTablePagerLength(pagingNumbersLength);
|
||||
|
@ -660,7 +641,7 @@ jumpserver.initServerSideDataTable = function (options) {
|
|||
ajax: {
|
||||
url: options.ajax_url,
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
if (jqXHR.responseText && jqXHR.responseText.indexOf("%(value)s") !== -1 ) {
|
||||
if (jqXHR.responseText && jqXHR.responseText.indexOf("%(value)s") !== -1) {
|
||||
return
|
||||
}
|
||||
var msg = gettext("Unknown error occur");
|
||||
|
@ -727,11 +708,10 @@ jumpserver.initServerSideDataTable = function (options) {
|
|||
var rows = table.rows(indexes).data();
|
||||
$.each(rows, function (id, row) {
|
||||
if (row.id && $.inArray(row.id, table.selected) === -1) {
|
||||
if (select.style === 'multi'){
|
||||
if (select.style === 'multi') {
|
||||
table.selected.push(row.id);
|
||||
table.selected_rows.push(row);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
table.selected = [row.id];
|
||||
table.selected_rows = [row];
|
||||
}
|
||||
|
@ -915,14 +895,6 @@ var rules_short_map_id = {
|
|||
'special': 'id_security_password_special_char'
|
||||
};
|
||||
|
||||
var rules_id_map_label = {
|
||||
'id_security_password_min_length': gettext('Password minimum length {N} bits'),
|
||||
'id_security_password_upper_case': gettext('Must contain capital letters'),
|
||||
'id_security_password_lower_case': gettext('Must contain lowercase letters'),
|
||||
'id_security_password_number': gettext('Must contain numeric characters'),
|
||||
'id_security_password_special_char': gettext('Must contain special characters')
|
||||
};
|
||||
|
||||
function getRuleLabel(rule) {
|
||||
var label = '';
|
||||
if (rule.key === rules_short_map_id['min']) {
|
||||
|
@ -1030,7 +1002,6 @@ function initPopover($container, $progress, $idPassword, $el, password_check_rul
|
|||
}
|
||||
|
||||
|
||||
|
||||
function rootNodeAddDom(ztree, callback) {
|
||||
var refreshIcon = "<a id='tree-refresh'><i class='fa fa-refresh'></i></a>";
|
||||
var rootNode = ztree.getNodes()[0];
|
||||
|
@ -1048,146 +1019,6 @@ function rootNodeAddDom(ztree, callback) {
|
|||
})
|
||||
}
|
||||
|
||||
function APIExportCSV(props) {
|
||||
/*
|
||||
{
|
||||
listUrl:
|
||||
objectsId:
|
||||
template:
|
||||
table:
|
||||
params:
|
||||
}
|
||||
*/
|
||||
var _listUrl = props.listUrl;
|
||||
var _objectsId = props.objectsId;
|
||||
var _template = props.template;
|
||||
var _table = props.table;
|
||||
var _params = props.params || {};
|
||||
|
||||
var tableParams = _table.ajax.params();
|
||||
var exportUrl = setUrlParam(_listUrl, 'format', 'csv');
|
||||
if (_template) {
|
||||
exportUrl = setUrlParam(exportUrl, 'template', _template)
|
||||
}
|
||||
for (var k in tableParams) {
|
||||
if (datatableInternalParams.includes(k)) {
|
||||
continue
|
||||
}
|
||||
if (!tableParams[k]) {
|
||||
continue
|
||||
}
|
||||
exportUrl = setUrlParam(exportUrl, k, tableParams[k])
|
||||
}
|
||||
for (var k in _params) {
|
||||
exportUrl = setUrlParam(exportUrl, k, tableParams[k])
|
||||
}
|
||||
|
||||
if (!_objectsId) {
|
||||
console.log(exportUrl);
|
||||
window.open(exportUrl);
|
||||
return
|
||||
}
|
||||
|
||||
requestApi({
|
||||
url: '/api/v1/common/resources/cache/',
|
||||
data: JSON.stringify({resources: _objectsId}),
|
||||
method: "POST",
|
||||
flash_message: false,
|
||||
success: function (data) {
|
||||
exportUrl = setUrlParam(exportUrl, 'spm', data.spm);
|
||||
console.log(exportUrl);
|
||||
window.open(exportUrl);
|
||||
},
|
||||
failed: function () {
|
||||
toastr.error(gettext('Export failed'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function APIExportData(props) {
|
||||
props = props || {};
|
||||
$.ajax({
|
||||
url: '/api/common/v1/resources/cache/',
|
||||
type: props.method || "POST",
|
||||
data: props.body,
|
||||
contentType: props.content_type || "application/json; charset=utf-8",
|
||||
dataType: props.data_type || "json",
|
||||
success: function (data) {
|
||||
var export_url = props.success_url;
|
||||
var params = props.params || {};
|
||||
params['format'] = props.format;
|
||||
params['spm'] = data.spm;
|
||||
for (var k in params) {
|
||||
export_url = setUrlParam(export_url, k, params[k])
|
||||
}
|
||||
window.open(export_url);
|
||||
},
|
||||
error: function () {
|
||||
toastr.error(gettext('Export failed'));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function APIImportData(props) {
|
||||
props = props || {};
|
||||
$.ajax({
|
||||
url: props.url,
|
||||
type: props.method || "POST",
|
||||
processData: false,
|
||||
data: props.body,
|
||||
contentType: props.content_type || 'text/csv',
|
||||
success: function (data) {
|
||||
if (props.method === 'POST') {
|
||||
$('#created_failed').html('');
|
||||
$('#created_failed_detail').html('');
|
||||
$('#success_created').html(gettext("Import Success"));
|
||||
$('#success_created_detail').html("Count" + ": " + data.length);
|
||||
} else {
|
||||
$('#updated_failed').html('');
|
||||
$('#updated_failed_detail').html('');
|
||||
$('#success_updated').html(gettext("Update Success"));
|
||||
$('#success_updated_detail').html(gettext("Count") + ": " + data.length);
|
||||
}
|
||||
|
||||
props.data_table.ajax.reload()
|
||||
},
|
||||
error: function (error) {
|
||||
var data = error.responseJSON;
|
||||
console.log(data);
|
||||
if (data instanceof Array) {
|
||||
var html = '';
|
||||
var li = '';
|
||||
var err = '';
|
||||
$.each(data, function (index, item) {
|
||||
err = '';
|
||||
for (var prop in item) {
|
||||
err += prop + ": " + item[prop][0] + " "
|
||||
}
|
||||
if (err) {
|
||||
li = "<li>" + "Line " + (++index) + ". " + err + "</li>";
|
||||
html += li
|
||||
}
|
||||
});
|
||||
html = "<ul>" + html + "</ul>"
|
||||
} else {
|
||||
html = error.responseText
|
||||
}
|
||||
if (props.method === 'POST') {
|
||||
$('#success_created').html('');
|
||||
$('#success_created_detail').html('');
|
||||
$('#created_failed').html(gettext("Import failed"));
|
||||
$('#created_failed_detail').html(html);
|
||||
} else {
|
||||
$('#success_updated').html('');
|
||||
$('#success_updated_detail').html('');
|
||||
$('#updated_failed').html(gettext("Update failed"));
|
||||
$('#updated_failed_detail').html(html);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function htmlEscape(d) {
|
||||
return typeof d === 'string' ?
|
||||
d.replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"') :
|
||||
|
@ -1329,7 +1160,6 @@ function readFile(ref) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
function select2AjaxInit(option) {
|
||||
/*
|
||||
{
|
||||
|
@ -1385,9 +1215,11 @@ function usersSelect2Init(selector, url, disabledData) {
|
|||
if (!url) {
|
||||
url = '/api/v1/users/users/'
|
||||
}
|
||||
|
||||
function displayFormat(v) {
|
||||
return v.name + '(' + v.username +')';
|
||||
return v.name + '(' + v.username + ')';
|
||||
}
|
||||
|
||||
var option = {
|
||||
url: url,
|
||||
selector: selector,
|
||||
|
@ -1402,9 +1234,11 @@ function nodesSelect2Init(selector, url, disabledData) {
|
|||
if (!url) {
|
||||
url = '/api/v1/assets/nodes/'
|
||||
}
|
||||
|
||||
function displayFormat(v) {
|
||||
return v.full_value;
|
||||
}
|
||||
|
||||
var option = {
|
||||
url: url,
|
||||
selector: selector,
|
||||
|
@ -1419,12 +1253,11 @@ function showCeleryTaskLog(taskId) {
|
|||
window.open(url, '', 'width=900,height=600')
|
||||
}
|
||||
|
||||
function getUserLang(){
|
||||
function getUserLang() {
|
||||
let userLangEN = document.cookie.indexOf('django_language=en');
|
||||
if (userLangEN === -1){
|
||||
if (userLangEN === -1) {
|
||||
return 'zh-CN'
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
return 'en-US'
|
||||
}
|
||||
}
|
||||
|
@ -1460,8 +1293,7 @@ function initDateRangePicker(selector, options) {
|
|||
};
|
||||
if (getUserLang() === 'zh-CN') {
|
||||
defaultOption.locale = zhLocale;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
// en-US
|
||||
defaultOption.locale = enLocale;
|
||||
}
|
||||
|
@ -1470,7 +1302,9 @@ function initDateRangePicker(selector, options) {
|
|||
}
|
||||
|
||||
function reloadPage() {
|
||||
setTimeout( function () {window.location.reload();}, 300);
|
||||
setTimeout(function () {
|
||||
window.location.reload();
|
||||
}, 300);
|
||||
}
|
||||
|
||||
function isEmptyObject(obj) {
|
||||
|
@ -1494,7 +1328,7 @@ function getStatusIcon(status, mapping, title) {
|
|||
default: 'navy'
|
||||
};
|
||||
if (!mapping) {
|
||||
mapping = defaultMapping;
|
||||
mapping = defaultMapping;
|
||||
}
|
||||
var name = mapping[status] || mapping['default'];
|
||||
var icon = icons[name];
|
||||
|
@ -1564,10 +1398,10 @@ function encryptPassword(password) {
|
|||
|
||||
|
||||
function randomString(length) {
|
||||
const characters ='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let result = '';
|
||||
const charactersLength = characters.length;
|
||||
for ( let i = 0; i < length; i++ ) {
|
||||
for (let i = 0; i < length; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
|
||||
|
@ -1577,11 +1411,11 @@ function randomString(length) {
|
|||
function testEncrypt() {
|
||||
const radio = []
|
||||
const len2 = []
|
||||
for (let i=1;i<4096;i++) {
|
||||
for (let i = 1; i < 4096; i++) {
|
||||
const password = randomString(i)
|
||||
const cipher = encryptPassword(password)
|
||||
len2.push([password.length, cipher.length])
|
||||
radio.push(cipher.length/password.length)
|
||||
radio.push(cipher.length / password.length)
|
||||
}
|
||||
return radio
|
||||
}
|
||||
|
|
|
@ -7,14 +7,13 @@
|
|||
<link href="{% static 'css/plugins/sweetalert/sweetalert.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'css/style.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'css/plugins/vaildator/jquery.validator.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'css/plugins/datatables/datatables.min.css' %}" rel="stylesheet">
|
||||
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
|
||||
|
||||
<!-- scripts -->
|
||||
<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>
|
||||
<script src="{% url 'javascript-catalog' %}"></script>
|
||||
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
|
||||
<script src="{% static 'js/bootstrap.min.js' %}"></script>
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #1ab394;
|
||||
|
@ -24,6 +23,6 @@
|
|||
<script>
|
||||
const themeInfo = {{ INTERFACE.theme_info | safe }};
|
||||
if (themeInfo && themeInfo.colors && themeInfo.colors['--color-primary']) {
|
||||
document.documentElement.style.setProperty('--primary-color', themeInfo.colors['--color-primary']);
|
||||
document.documentElement.style.setProperty('--primary-color', themeInfo.colors['--color-primary']);
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -7,6 +7,7 @@ from django.conf import settings
|
|||
from django.core.files.storage import default_storage
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils.translation import gettext as _
|
||||
from rest_framework import viewsets
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.request import Request
|
||||
|
@ -41,10 +42,13 @@ class DownloadUploadMixin:
|
|||
if os.path.exists(extract_to):
|
||||
shutil.rmtree(extract_to)
|
||||
|
||||
with zipfile.ZipFile(path) as zp:
|
||||
if zp.testzip() is not None:
|
||||
return Response({'msg': 'Invalid Zip file'}, status=400)
|
||||
zp.extractall(extract_to)
|
||||
try:
|
||||
with zipfile.ZipFile(path) as zp:
|
||||
if zp.testzip() is not None:
|
||||
raise ValidationError({'error': _('Invalid zip file')})
|
||||
zp.extractall(extract_to)
|
||||
except RuntimeError as e:
|
||||
raise ValidationError({'error': _('Invalid zip file') + ': {}'.format(e)})
|
||||
|
||||
tmp_dir = os.path.join(extract_to, file.name.replace('.zip', ''))
|
||||
manifest = Applet.validate_pkg(tmp_dir)
|
||||
|
|
|
@ -78,7 +78,7 @@ class Applet(JMSBaseModel):
|
|||
for name in files:
|
||||
path = os.path.join(d, name)
|
||||
if not os.path.exists(path):
|
||||
raise ValidationError({'error': 'Missing file {}'.format(path)})
|
||||
raise ValidationError({'error': _('Applet pkg not valid, Missing file {}').format(name)})
|
||||
|
||||
with open(os.path.join(d, 'manifest.yml')) as f:
|
||||
manifest = yaml.safe_load(f)
|
||||
|
|
Loading…
Reference in New Issue