diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index 2d89a15d5..251aa12fa 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -1,7 +1,6 @@ import React from 'react'; import Form from 'react-jsonschema-form-bs4'; -import {Col, Modal, Nav, Button} from 'react-bootstrap'; -import FileSaver from 'file-saver'; +import {Button, Col, Modal, Nav} from 'react-bootstrap'; import AuthComponent from '../AuthComponent'; import ConfigMatrixComponent from '../attack/ConfigMatrixComponent'; import UiSchema from '../configuration-components/UiSchema'; @@ -11,7 +10,8 @@ import {faExclamationCircle} from '@fortawesome/free-solid-svg-icons/faExclamati import {formValidationFormats} from '../configuration-components/ValidationFormats'; import transformErrors from '../configuration-components/ValidationErrorMessages'; import InternalConfig from '../configuration-components/InternalConfig'; -import UnsafeOptionsConfirmationModal from '../configuration-components/UnsafeOptionsConfirmationModal.js'; +import UnsafeOptionsConfirmationModal + from '../configuration-components/UnsafeOptionsConfirmationModal.js'; import UnsafeOptionsWarningModal from '../configuration-components/UnsafeOptionsWarningModal.js'; import isUnsafeOptionSelected from '../utils/SafeOptionValidator.js'; import ConfigExportModal from '../configuration-components/ExportConfigModal'; @@ -71,7 +71,10 @@ class ConfigurePageComponent extends AuthComponent { if (sectionKey === 'attack') { sections.push({key: sectionKey, title: 'ATT&CK'}) } else { - sections.push({key: sectionKey, title: monkeyConfig.schema.properties[sectionKey].title}); + sections.push({ + key: sectionKey, + title: monkeyConfig.schema.properties[sectionKey].title + }); } } this.setState({ @@ -91,10 +94,8 @@ class ConfigurePageComponent extends AuthComponent { onUnsafeConfirmationContinueClick = () => { this.setState({showUnsafeOptionsConfirmation: false}); - if (this.state.lastAction == 'submit_attempt') { + if (this.state.lastAction === 'submit_attempt') { this.configSubmit(); - } else if (this.state.lastAction == 'import_attempt') { - this.setConfigFromImportCandidate(); } } @@ -103,7 +104,7 @@ class ConfigurePageComponent extends AuthComponent { } - updateConfig = (callback=null) => { + updateConfig = (callback = null) => { this.authFetch(CONFIG_URL) .then(res => res.json()) .then(data => { @@ -120,6 +121,7 @@ class ConfigurePageComponent extends AuthComponent { } }; + // TODO add a safety check to config import canSafelySubmitConfig(config) { return !isUnsafeOptionSelected(this.state.schema, config); } @@ -226,7 +228,8 @@ class ConfigurePageComponent extends AuthComponent { renderConfigExportModal = () => { return ()} + onClick={this.onExport}/>) + } onExport = () => { this.setState({showConfigExportModal: false}) @@ -234,10 +237,18 @@ class ConfigurePageComponent extends AuthComponent { renderConfigImportModal = () => { return ()} + onClose={this.onClose}/>) + } - onImport = () => { - this.setState({showConfigImportModal: false}) + onClose = (importSuccessful) => { + if(importSuccessful === true){ + this.updateConfig(); + this.setState({lastAction: 'import_success', + showConfigImportModal: false}); + + } else { + this.setState({showConfigImportModal: false}); + } } renderAttackAlertModal = () => { @@ -358,47 +369,6 @@ class ConfigurePageComponent extends AuthComponent { this.authFetch(apiEndpoint, request_options); } - // TODO remove after import implementation - setConfigOnImport = (event) => { - try { - var newConfig = JSON.parse(event.target.result); - } catch (SyntaxError) { - this.setState({lastAction: 'import_failure'}); - return; - } - - this.setState({lastAction: 'import_attempt', importCandidateConfig: newConfig}, - () => { - if (this.canSafelySubmitConfig(newConfig)) { - this.setConfigFromImportCandidate(); - } else { - this.setState({showUnsafeOptionsConfirmation: true}); - } - } - ); - } - - // TODO remove after import implementation - setConfigFromImportCandidate(){ - this.setState({ - configuration: this.state.importCandidateConfig, - lastAction: 'import_success' - }, () => { - this.sendConfig(); - this.setInitialConfig(this.state.importCandidateConfig); - }); - this.currentFormData = {}; - } - - // TODO remove after export implementation - exportConfig = () => { - this.updateConfigSection(); - const configAsJson = JSON.stringify(this.state.configuration, null, 2); - const configAsBinary = new Blob([configAsJson], {type: 'text/plain;charset=utf-8'}); - - FileSaver.saveAs(configAsBinary, 'monkey.conf'); - }; - sendConfig() { return ( this.authFetch('/api/configuration/island', @@ -418,14 +388,6 @@ class ConfigurePageComponent extends AuthComponent { })); } - // TODO remove after import implementation - importConfig = (event) => { - let reader = new FileReader(); - reader.onload = this.setConfigOnImport; - reader.readAsText(event.target.files[0]); - event.target.value = null; - }; - renderMatrix = () => { return ( - + Submit - + Reset to defaults - {this.setState({showConfigImportModal: true})}} + { + this.setState({showConfigImportModal: true}) + }} className='btn btn-info btn-lg' style={{margin: '5px'}}> Import config {this.setState({showConfigExportModal: true})}} + onClick={() => { + this.setState({showConfigExportModal: true}) + }} className='btn btn-info btn-lg' style={{margin: '5px'}}> Export config @@ -552,12 +520,6 @@ class ConfigurePageComponent extends AuthComponent { Configuration saved successfully. : ''} - {this.state.lastAction === 'import_failure' ? - - - Failed importing configuration. Invalid config file. - - : ''} {this.state.lastAction === 'invalid_configuration' ?