multiple working on simple mode

* security level overriding default multiple settings
* start updating tests
This commit is contained in:
Jordan Blasenhauer 2024-04-24 16:44:02 +02:00
parent e865de71a2
commit 34804ebfb9
4 changed files with 186 additions and 29 deletions

View file

@ -257,7 +257,7 @@ class ServiceModal {
this.openModal();
}
} catch (err) {}
// security lrbrl
// security
try {
if (
e.target
@ -648,7 +648,7 @@ class ServiceModal {
this.SetSelectTabsVisible(action === "delete" ? false : true);
this.setHeaderActionsVisible(action === "delete" ? false : true);
this.changeSubmitBtn(action);
this.setMode(action);
if (action === "edit" || action === "new" || action === "clone") {
this.formNewEdit.classList.remove("hidden");
this.simpleForm.classList.remove("hidden");
@ -819,6 +819,16 @@ class ServiceModal {
}
}
setMode(action) {
if (action === "new") {
this.switchModeBtn.classList.remove("hidden");
this.setSettingMode("simple");
} else {
this.switchModeBtn.classList.add("hidden");
this.setSettingMode("advanced");
}
}
setCardViewportHeight(setAsViewport) {
if (setAsViewport) {
this.modalCard.classList.add("h-[90vh]");
@ -949,10 +959,18 @@ class ServiceModal {
}
class Multiple {
constructor(prefix, formContainerSelector) {
constructor(prefix, formContainerSelector, handleSecurityLevel = false) {
this.multSettingsName = JSON.parse(
document
.querySelector("input[data-plugins-multiple]")
.getAttribute("data-plugins-multiple")
.replaceAll(`'`, `"`),
);
this.currServName = "";
this.prefix = prefix;
this.container = document.querySelector("main");
this.formContainer = document.querySelector(formContainerSelector);
this.handleSecurityLevel = handleSecurityLevel;
this.init();
}
@ -962,6 +980,46 @@ class Multiple {
});
this.container.addEventListener("click", (e) => {
// Update security level
try {
if (
e.target
.closest("button")
.getAttribute("data-setting-select-dropdown-btn") ==
"security-level"
) {
// Need to wait atm for the attributes value to be updated
setTimeout(() => {
//remove all multiples
this.removePrevMultiples();
// set settings
const service = document.querySelector(
`[data-services-card][data-services-service='${this.currServName}']`,
);
const serviceSettings = service
? service
.querySelector("[data-services-settings]")
.getAttribute("data-value")
: "{}";
//get multiple service values and parse as obj
const settings = this.getSettingsMultiple(serviceSettings);
//keep only multiple settings value
const multipleSettings = this.getMultiplesOnly(settings);
const sortMultiples =
this.sortMultipleByContainerAndSuffixe(multipleSettings);
// Need to set method as ui if clone
const isClone =
e.target
.closest("button")
.getAttribute(`data-${this.prefix}-action`) === "clone"
? true
: false;
this.setMultipleToDOM(sortMultiples, isClone);
}, 30);
}
} catch (err) {}
// Edit service button
try {
if (
@ -974,8 +1032,13 @@ class Multiple {
) {
//remove all multiples
this.removePrevMultiples();
//get multiple service values and parse as obj
const settings = this.getSettingsMultiple(e.target);
// set settings
const service = e.target.closest("[data-services-service]");
this.serviceName = service.getAttribute("data-services-service");
const serviceSettings = service
.querySelector("[data-services-settings]")
.getAttribute("data-value");
const settings = this.getSettingsMultiple(serviceSettings);
//keep only multiple settings value
const multipleSettings = this.getMultiplesOnly(settings);
const sortMultiples =
@ -999,6 +1062,7 @@ class Multiple {
.getAttribute(`data-${this.prefix}-action`) === "new"
) {
this.removePrevMultiples();
this.serviceName = "new";
this.addOneMultGroup();
}
} catch (err) {}
@ -1182,7 +1246,6 @@ class Multiple {
const multGroups = this.formContainer.querySelectorAll(
`[data-${this.prefix}-settings-multiple^="${att}"]`,
);
console.log(multGroups);
if (multGroups.length >= 2) return;
btn.click();
@ -1218,15 +1281,94 @@ class Multiple {
}
// Avoid multiple settings because it is handle by Multiple class
getSettingsMultiple(target) {
const servicesSettings = target
.closest("[data-services-service]")
.querySelector("[data-services-settings]")
.getAttribute("data-value");
const settings = JSON.parse(servicesSettings);
getSettingsMultiple(serviceSettings) {
const settings = JSON.parse(serviceSettings);
// We need to add security level
if (this.handleSecurityLevel) {
return this.addSecurityLevelToSettings(settings);
}
return settings;
}
addSecurityLevelToSettings(settings) {
// Retrieve security level and current level
const secLevel = document
.querySelector('[data-setting-select-text="security-level"]')
.getAttribute("data-value");
// Case custom, we don't have to use security level settings
if (secLevel === "custom") return settings;
// Case others security level, we need to remove multiple with method ui or default only and replace by security level settings
// We store remain names to avoid duplicate suffixe
const remainNames = [];
this.multSettingsName.forEach((name) => {
for (const [key, value] of Object.entries(settings)) {
if (
key.startsWith(name) &&
(value["method"] === "ui" || value["method"] === "default")
) {
delete settings[key];
}
if (
key.startsWith(name) &&
(value["method"] !== "ui" || value["method"] !== "default")
) {
remainNames.push(key);
}
}
});
// Retrieve multiple groups by security level
const secLevelMultSettingsEl = this.formContainer.querySelectorAll(
`[data-multiple-levels]`,
);
const settingsSecLevel = {};
secLevelMultSettingsEl.forEach((multEl) => {
const settingsGroup = JSON.parse(
multEl.getAttribute("data-multiple-levels").replaceAll(`'`, `"`),
);
// loop on each multiple groups
settingsGroup.forEach((levelGroups) => {
// define the suffixe number using remaining name
// loop on each dict on group
const levelGroup = levelGroups[secLevel];
for (const [key, value] of Object.entries(levelGroup)) {
let suffixe_num = 0;
// key has multiple "_", we want to delete only content after last "_"
// check if last element is a valid number to get right name
const splitKey = key.split("_");
const keyName = isNaN(splitKey[splitKey.length - 1])
? key
: splitKey.slice(0, splitKey.length - 1).join("_");
// Loop on remaining names to get the right suffixe number
remainNames.forEach((name) => {
if (name.startsWith(keyName)) {
const splitName = name.split("_");
if (!isNaN(splitName[splitName.length - 1]))
suffixe_num = Math.max(
suffixe_num,
+splitName[splitName.length - 1],
);
}
});
const newKey = `${keyName}_${suffixe_num + 1}`;
// don't forget to add new key to avoid override same key
remainNames.push(newKey);
// we need same format as settings
settingsSecLevel[newKey] = {
value: value,
method: "ui",
global: false,
};
}
});
});
const mergeSettings = { ...settings, ...settingsSecLevel };
// Merge level settings with current settings
return mergeSettings;
}
getMultiplesOnly(settings) {
//get schema settings
const multiples = {};
@ -1893,10 +2035,12 @@ const setFilterGlobal = new FilterSettings(
const setAdvancedMultiple = new Multiple(
"services",
`[data-advanced][data-services-modal-form]`,
false,
);
const setSimpleMultiple = new Multiple(
"services",
`[data-simple][data-services-modal-form]`,
true,
);
const checkServiceModalKeyword = new CheckNoMatchFilter(

View file

@ -11,22 +11,21 @@
{"plugin_id" : "general", "setting_id": "SERVER_NAME", "title" : "DEFINE HOST", "subtitle" : "We need this to connect BunkerWeb to your application. You need to set your domain name.", "levels" : {} },
{"plugin_id" : "security-level", "setting_id": "SECURITY_LEVEL", "title" : "DEFINE SECURITY LEVEL", "subtitle" : "This will determine default settings value for the next steps. You'll be allow to modify settings to match your case if needed.", "levels" : {}, "setting" : {'context': 'global', 'default': 'standard', 'help': 'Determine the default settings value. You can override them.', 'id': 'security-level', 'label': 'Security level', 'regex': '^(security_levels[0]|security_levels[1]|security_levels[2])$', 'type': 'select', 'select': [security_levels[0], security_levels[1], security_levels[2]]} },
{"plugin_id" : "limit", "setting_id": "LIMIT_REQ_URL", "title" : "Define header", "subtitle" : "test header multiple rendering", "levels" : [{
security_levels[0] : [
{
"LIMIT_REQ_URL": "/",
"LIMIT_REQ_RATE": "2r/s"
security_levels[0] : {
"LIMIT_REQ_URL_1": "/",
"LIMIT_REQ_RATE_1": "2r/s"
}
], security_levels[1] : [
{
"LIMIT_REQ_URL": "/",
"LIMIT_REQ_RATE": "2r/s"
, security_levels[1] : {
"LIMIT_REQ_URL_1": "/",
"LIMIT_REQ_RATE_1": "2r/s"
}
], security_levels[2] : [
{
"LIMIT_REQ_URL": "/",
"LIMIT_REQ_RATE": "2r/s"
, security_levels[2] : {
"LIMIT_REQ_URL_1": "/",
"LIMIT_REQ_RATE_1": "2r/s",
"LIMIT_REQ_URL_2": "/admin",
"LIMIT_REQ_RATE_2": "4r/s"
}
]}]
}]
},
],
"configs": []

View file

@ -4,7 +4,7 @@
{% for setting_simple in plugin_simple %}
{% set setting_input = { "name" : setting_simple.get('setting_id'), "multiples" : setting_simple.get("multiples", {}), "method" : setting_simple.get('setting').get("method", "default"), "help" : setting_simple.get('setting').get("help"), "label" : setting_simple.get('setting').get("label"), "id" : setting_simple.get('setting').get("id"), "type" : setting_simple.get('setting').get("type"), "default" : setting_simple.get('setting').get("default", "default"), "select" : setting_simple.get('setting').get("select"), "regex" : setting_simple.get('setting').get("regex"), "value" : setting_simple.get('setting').get("value"), "is_multiple" : True if setting_simple.get('setting').get("multiple", "") else False, "levels" : setting_simple.get('levels', {}) if not setting_simple.get('setting').get("multiples", "") else {}, "multiple_name" : setting_simple.get('setting').get('multiple') } %}
<div data-simple id="{{ setting_simple['plugin_id'] }}-simple"
class="w-full h-full px-1 mb-2 col-span-12 {% if not setting_input['is_multiple'] %} md:col-span-6 {% endif %} grid grid-cols-12 h-full items-end">
class="w-full h-full px-1 mt-4 mb-2 col-span-12 {% if not setting_input['is_multiple'] %} md:col-span-6 {% endif %} grid grid-cols-12 h-full items-end">
<!-- title and desc -->
<div class="col-span-12" data-setting-header>
<div class="flex flex-col justify-start items-start">
@ -17,7 +17,7 @@
{% if not setting_input.get('is_multiple') %}
<!-- end title and desc -->
<div class="w-full col-span-12">
<div data-setting-container data--simple-{{ current_endpoint }}-type="{{ setting_input['type'] }}" data--simple-{{ current_endpoint }}-context="{{ setting_input['context'] }}" class="relative mx-0 sm:mx-2 md:mx-3 lg:mx-4 my-2 col-span-12 md:my-3 md:col-span-6 2xl:my-3 2xl:col-span-4" id="form-edit--simple-{{ current_endpoint }}-{{ setting_input["id"] }}">
<div data-setting-container data-{{ current_endpoint }}-type="{{ setting_input['type'] }}" data-{{ current_endpoint }}-context="{{ setting_input['context'] }}" class="relative mx-0 sm:mx-2 md:mx-3 lg:mx-4 my-2 col-span-12 md:my-3 md:col-span-6 2xl:my-3 2xl:col-span-4" id="form-edit-{{ current_endpoint }}-{{ setting_input["id"] }}">
{% include "setting_header.html" %}
{% include "setting_input.html" %}
{% include "setting_select.html" %}
@ -72,7 +72,7 @@
<!-- custom configs -->
{% for config in configs %}
<div data-simple id="{{ config['type'] }}-simple"
class="w-full h-full px-1 mb-2 col-span-12 grid grid-cols-12 h-full items-end">
class="w-full h-full px-1 mt-4 mb-2 col-span-12 grid grid-cols-12 h-full items-end">
<!-- title and desc -->
<div class="col-span-12" data-setting-header>
<div class="flex flex-col justify-start items-start">

View file

@ -234,9 +234,23 @@ try:
assert_button_click(DRIVER, "//button[@data-services-modal-close='']/*[local-name() = 'svg']")
log_info("Setting updated, creating a new service ...")
log_info("Setting updated, creating a new service in advanced mode ...")
assert_button_click(DRIVER, "//button[@data-services-action='new']")
current_mode = DRIVER.execute_script("return document.querySelector('button[data-toggle-settings-mode-btn]').getAttribute('data-toggle-settings-mode-btn')")
if current_mode != "simple" :
log_error(f"""Default mode for new service need to be simple and not {current_mode}...""")
exit(1)
# Switch to advanced mode
DRIVER.execute_script("document.querySelector('button[data-toggle-settings-mode-btn]').click()")
current_mode = DRIVER.execute_script("return document.querySelector('button[data-toggle-settings-mode-btn]').getAttribute('data-toggle-settings-mode-btn')")
if current_mode != "advanced" :
log_error(f"""Switching mode needed to return advanced mode, but he have {current_mode}...""")
exit(1)
server_name_input = safe_get_element(DRIVER, By.ID, "SERVER_NAME")
assert isinstance(server_name_input, WebElement), "Input is not a WebElement"