8000 Placeholder in configuration UI by shreyamalviya · Pull Request #3310 · guardicore/monkey · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Placeholder in configuration UI #3310

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
### Added
- `PortScanData.open` property. #3238
- `{GET,PUT} /api/agent-binaries/<string:os>/masque`. #3249
- Placeholder values for empty plugin configuration fields having defaults. #3310

### Changed
- Renamed "Credential collector" to "Credentials collector". #3167
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {getDefaultFormState, ObjectFieldTemplateProps} from '@rjsf/utils';
import React, {useEffect, useState} from 'react';
import _ from 'lodash';
import ChildCheckboxContainer from '../ui-components/ChildCheckbox';
import {AdvancedMultiSelectHeader} from '../ui-components/AdvancedMultiSelect';
import {MasterCheckboxState} from '../ui-components/MasterCheckbox';
Expand All @@ -9,12 +8,13 @@ import {EXPLOITERS_PATH_PROPAGATION} from './PropagationConfig';
import MarkdownDescriptionTemplate from './MarkdownDescriptionTemplate';

export const CREDENTIALS_COLLECTORS_CONFIG_PATH = 'credentials_collectors';
const PLUGIN_SCHEMA_PATH = {'propagation': EXPLOITERS_PATH_PROPAGATION, 'credentials_collectors': CREDENTIALS_COLLECTORS_CONFIG_PATH}
const PLUGIN_SCHEMA_PATH = {'propagation': EXPLOITERS_PATH_PROPAGATION, 'credentials_collectors': CREDENTIALS_COLLECTORS_CONFIG_PATH};


export default function PluginSelectorTemplate(props: ObjectFieldTemplateProps) {

let [activePlugin, setActivePlugin] = useState(null);
const [defaultSchema,] = useState(generateDefaultConfig());

useEffect(() => updateUISchema(), [props.formContext.selectedPlugins]);

Expand Down Expand Up @@ -43,7 +43,7 @@ export default function PluginSelectorTemplate(props: ObjectFieldTemplateProps)
return selectorOptions;
}

function togglePluggin(pluginName) {
function togglePlugin(pluginName) {
let plugins = new Set(props.formContext.selectedPlugins);
if (props.formContext.selectedPlugins.has(pluginName)) {
plugins.delete(pluginName);
Expand All @@ -53,16 +53,12 @@ export default function PluginSelectorTemplate(props: ObjectFieldTemplateProps)
props.formContext.setSelectedPlugins(plugins, props.formContext.section);
}

function updateUISchema(){
let uiSchema = _.cloneDeep(props.uiSchema);
for(let pluginName of Object.keys(generateDefaultConfig())) {
if(!props.formContext.selectedPlugins.has(pluginName)){
uiSchema[pluginName] = {"ui:readonly": true,
'ui:DescriptionFieldTemplate': MarkdownDescriptionTemplate};
} else {
uiSchema[pluginName] = {'ui:DescriptionFieldTemplate': MarkdownDescriptionTemplate};
}
const updateUISchema = () => {
let uiSchema = {...props.uiSchema};
for (let pluginName of Object.keys(defaultSchema)) {
uiSchema[pluginName] = Object.assign({...uiSchema[pluginName]}, {'ui:readonly': !props.formContext.selectedPlugins.has(pluginName)});
}

props.formContext.setUiSchema(uiSchema, PLUGIN_SCHEMA_PATH[props.formContext.section]);
}

Expand Down Expand Up @@ -90,7 +86,7 @@ export default function PluginSelectorTemplate(props: ObjectFieldTemplateProps)
if (checkboxState == MasterCheckboxState.ALL) {
props.formContext.setSelectedPlugins(new Set(), selectedSection);
} else {
props.formContext.setSelectedPlugins(new Set(Object.keys(generateDefaultConfig())), selectedSection);
props.formContext.setSelectedPlugins(new Set(Object.keys(defaultSchema)), selectedSection);
}
}

Expand Down Expand Up @@ -127,7 +123,7 @@ export default function PluginSelectorTemplate(props: ObjectFieldTemplateProps)
<ChildCheckboxContainer multiple={true} required={false}
autoFocus={true}
selectedValues={[...props.formContext.selectedPlugins]}
class="x x-first x-last">togglePluggin}
class="x x-first x-last">togglePlugin}
isSafe={isPluginSafe}
>
enumOptions={getOptions()}/>
Expand Down
10000
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
import pluginsManipulator from "./UISchemaPluginsManipulator";

const manipulatorList = [ransomwareDirManipulator]
const CREDENTIAL_COLLECTORS_TAB = 'credential_collectors';
const PAYLOADS_TAB = 'payloads';
const PROPAGATION_TAB = 'propagation';

function applyUiSchemaManipulators(selectedSection,

const manipulatorList = [ransomwareDirManipulator, pluginsDirManipulator]

export default function applyUiSchemaManipulators(selectedSection,
formData,
uiSchema) {
uiSchema,
JSONSchema) {
for(let i = 0; i < manipulatorList.length; i++){
manipulatorList[i](selectedSection, formData, uiSchema);
manipulatorList[i](selectedSection, formData, uiSchema, JSONSchema);
}
}

function ransomwareDirManipulator(selectedSection,
formData,
uiSchema) {
if (selectedSection === 'payloads'){
if (selectedSection === PAYLOADS_TAB){
uiSchema.ransomware.encryption.directories =
{'ui:disabled': !formData['ransomware']['encryption']['enabled']};
}
}

export default applyUiSchemaManipulators;
function pluginsDirManipulator(selectedSection, formData, uiSchema, JSONSchema) {
if (selectedSection === PROPAGATION_TAB) {
pluginsManipulator(uiSchema?.exploitation?.exploiters, JSONSchema?.properties?.exploitation?.properties?.exploiters?.properties)
} else if (selectedSection === CREDENTIAL_COLLECTORS_TAB) {
pluginsManipulator(uiSchema?.credentials_collectors, JSONSchema?.properties?.credential_collectors?.properties)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import MarkdownDescriptionTemplate from './MarkdownDescriptionTemplate';

const DEFAULT_VALUE_FIELD = 'default';
const UI_SCHEMA_PLACEHOLDER_FIELD = 'ui:placeholder';

const pluginsManipulator = (uiSchema, JSONSchema) => {
for (let pluginName of Object.keys(JSONSchema)) {
uiSchema[pluginName] = {'ui:DescriptionFieldTemplate': MarkdownDescriptionTemplate, 'ui:readonly': false};
}

traversePlugins(uiSchema, JSONSchema);
}

const getObjectByPath = (root, path) => {
let obj = root
for (let i = 0; i < path.length; i++) {
obj = obj[path[i]]
}
return obj;
}

const updateUiSchemaForDynamicComponentsAttributes = (pluginsPaths, uiSchema, JSONSchema) => {
Object.entries(pluginsPaths).forEach(entry => {
const [pluginName, paths] = entry;
// @ts-ignore
paths?.forEach(path => {
const pluginObj = getObjectByPath(JSONSchema[pluginName], path);
Object.entries(pluginObj).forEach(([currField, data]) => {
if (Object.hasOwn(data, DEFAULT_VALUE_FIELD)) {
uiSchema[pluginName][currField] = {};
uiSchema[pluginName][currField][UI_SCHEMA_PLACEHOLDER_FIELD] = data[DEFAULT_VALUE_FIELD];
}
});
});
});
}

const buildPluginsPaths = (JSONSchema) => {
let pluginsPaths = {};
for (let pluginName of Object.keys(JSONSchema)) {
let pluginObject = JSONSchema[pluginName];
pluginsPaths[pluginName] = getPropertiesPaths(pluginObject, []);
}

return pluginsPaths;
}

const getPropertiesPaths = (root, currentPath = []) => {
const paths = [];

for (const key in root) {
const newPath = [...currentPath, key];
if (key === 'properties') {
paths.push(...getPropertiesPaths(root[key], newPath));
if (typeof root[key] === 'object' && root[key] !== null && root[newPath[newPath.length - 1] + 1] === undefined) {
paths.push(newPath);
}
} else if (typeof root[key] === 'object' && root[key] !== null) {
paths.push(...getPropertiesPaths(root[key], newPath));
}
}

return paths.filter(path => path[0] === 'properties');
}

const traversePlugins = (uiSchema, JSONSchema) => {
const pluginsPaths = buildPluginsPaths(JSONSchema);
updateUiSchemaForDynamicComponentsAttributes(pluginsPaths, uiSchema, JSONSchema);
}

export default pluginsManipulator;
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,8 @@ class ConfigurePageComponent extends AuthComponent {

applyUiSchemaManipulators(this.state.selectedSection,
formProperties['formData'],
fullUiSchema);
fullUiSchema,
formProperties?.schema);
if (this.state.selectedSection === 'propagation') {
delete Object.assign(formProperties, {'configuration': formProperties.formData}).formData;
return (<PropagationConfig {...formProperties}
Expand Down
0