diff --git a/monkey/monkey_island/cc/ui/src/components/AuthComponent.js b/monkey/monkey_island/cc/ui/src/components/AuthComponent.js index 9eb02a397..eb8427670 100644 --- a/monkey/monkey_island/cc/ui/src/components/AuthComponent.js +++ b/monkey/monkey_island/cc/ui/src/components/AuthComponent.js @@ -10,4 +10,10 @@ class AuthComponent extends React.Component { } } +export function authFetch(){ + const auth = new AuthService(); + const authFetch = auth.authFetch; + const jwtHeader = auth.jwtHeader(); +} + export default AuthComponent; diff --git a/monkey/monkey_island/cc/ui/src/components/Main.js b/monkey/monkey_island/cc/ui/src/components/Main.js index 7ef373f05..47116c5da 100644 --- a/monkey/monkey_island/cc/ui/src/components/Main.js +++ b/monkey/monkey_island/cc/ui/src/components/Main.js @@ -4,7 +4,7 @@ import {Container} from 'react-bootstrap'; import RunServerPage from 'components/pages/RunServerPage'; import ConfigurePage from 'components/pages/ConfigurePage'; -import RunMonkeyPage from 'components/pages/RunMonkeyPage'; +import RunMonkeyPage from 'components/pages/RunMonkeyPage/RunMonkeyPage'; import MapPage from 'components/pages/MapPage'; import TelemetryPage from 'components/pages/TelemetryPage'; import StartOverPage from 'components/pages/StartOverPage'; diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/CommandTypes.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/CommandTypes.js new file mode 100644 index 000000000..e69de29bb diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/InterfaceSelection.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/InterfaceSelection.js new file mode 100644 index 000000000..542edb568 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/InterfaceSelection.js @@ -0,0 +1,29 @@ +import React, {useEffect, useState} from 'react'; +import NextSelectionButton from '../../ui-components/inline-selection/NextSelectionButton'; +import InlineSelection from '../../ui-components/inline-selection/InlineSelection'; +import CommandSection from '../../ui-components/inline-selection/CommandSection'; +import LocalManualRunOptions from './LocalManualRunOptions'; + +function InterfaceSelection(props) { + return InlineSelection(getContents, props, LocalManualRunOptions) +} + +const getContents = (props) => { + const ips = props.ips.map((ip) => +
{ip}
+ ); + return (
{ips}
); +} + +const setCommandAsContent = (props) => { + let commandComponent = () => InlineSelection(CommandSection, + { + commands: win64commands, + setComponent: props.setComponent + }, + LocalManualRunOptions + ); + props.setComponent(commandComponent, props); +} + +export default InterfaceSelection; diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/LocalManualRunOptions.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/LocalManualRunOptions.js new file mode 100644 index 000000000..89275067a --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/LocalManualRunOptions.js @@ -0,0 +1,42 @@ +import React, {useEffect} from 'react'; +import NextSelectionButton from '../../ui-components/inline-selection/NextSelectionButton'; +import InlineSelection from '../../ui-components/inline-selection/InlineSelection'; +import CommandSection from '../../ui-components/inline-selection/CommandSection'; +import ManualRunOptions from './ManualRunOptions'; +import InterfaceSelection from './InterfaceSelection'; + +const LocalManualRunOptions = (props) => { + return InlineSelection(getContents, props, ManualRunOptions) +} + +const win64commands = [{name: "CMD", command: "monkey.exe m0nk3y -s 192.168.56.1"}] + +const getContents = (props) => { + return ( + <> + { + props.setComponent(InterfaceSelection('Windows64')) + }}/> + { + }}/> + { + }}/> + { + }}/> + + ) +} + +const setCommandAsContent = (props) => { + let commandComponent = () => InlineSelection(CommandSection, + { + commands: win64commands, + setComponent: props.setComponent + }, + LocalManualRunOptions + ); + props.setComponent(commandComponent, props); +} + +export default LocalManualRunOptions; diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/ManualRunOptions.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/ManualRunOptions.js new file mode 100644 index 000000000..0b84084ab --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/ManualRunOptions.js @@ -0,0 +1,58 @@ +import React, {useEffect, useState} from 'react'; +import NextSelectionButton from '../../ui-components/inline-selection/NextSelectionButton'; +import LocalManualRunOptions from './LocalManualRunOptions'; +import AuthComponent from '../../AuthComponent'; + +function ManualRunOptions(props) { + + const [currentContent, setCurrentContent] = useState(loadingContents()); + const [ips, setIps] = useState([]); + const [initialized, setInitialized] = useState(false); + + const authComponent = new AuthComponent({}) + + useEffect(() => { + if (initialized === false) { + authComponent.authFetch('/api') + .then(res => res.json()) + .then(res => { + setIps([res['ip_addresses']]); + setInitialized(true); + }); + } + }) + + useEffect(() => { + setCurrentContent(getDefaultContents()); + }, [initialized]) + + function setComponent(component, props) { + if (component === undefined) { + setCurrentContent(getDefaultContents()) + } else { + setCurrentContent(component({...props})) + } + } + + function loadingContents() { + return (
Loading
) + } + + function getDefaultContents() { + return ( +
+ { + setComponent(LocalManualRunOptions, {ips: ips, setComponent: setComponent}) + }}/> + { + }}/> + { + }}/> +
+ ); + } + + return currentContent; +} + +export default ManualRunOptions; diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunMonkeyPage.js similarity index 96% rename from monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js rename to monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunMonkeyPage.js index 48a11f008..19650fc19 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunMonkeyPage.js @@ -12,10 +12,11 @@ import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle'; import {faExclamationTriangle} from '@fortawesome/free-solid-svg-icons/faExclamationTriangle'; import {Link} from 'react-router-dom'; -import AuthComponent from '../AuthComponent'; -import AwsRunTable from '../run-monkey/AwsRunTable'; +import AuthComponent from '../../AuthComponent'; +import AwsRunTable from '../../run-monkey/AwsRunTable'; -import MissingBinariesModal from '../ui-components/MissingBinariesModal'; +import MissingBinariesModal from '../../ui-components/MissingBinariesModal'; +import ManualRunOptions from './ManualRunOptions'; const loading_css_override = css` display: block; @@ -329,22 +330,11 @@ class RunMonkeyPageComponent extends AuthComponent { showModal={this.state.showModal} onClose={this.closeModal} errorDetails={this.state.errorDetails}/> - { - // TODO: implement button functionality - /* - - */ - }

OR

+

+ ) +} + +backButton.propTypes = { + onClick: PropTypes.func +} diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/CommandSection.js b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/CommandSection.js new file mode 100644 index 000000000..ec4a53f0e --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/CommandSection.js @@ -0,0 +1,19 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + + +export default function CommandSection(props){ + return ( +

+ {props.commands[0].name} + {props.commands[0].command} +
+ ) +} + +CommandSection.propTypes = { + commands: PropTypes.arrayOf(PropTypes.exact({ + name: PropTypes.string, + command: PropTypes.string + })) +} diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/InlineSelection.js b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/InlineSelection.js new file mode 100644 index 000000000..97bb82d99 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/InlineSelection.js @@ -0,0 +1,28 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import BackButton from './BackButton'; +import ManualRunOptions from '../../pages/RunMonkeyPage/ManualRunOptions'; + + +export default function InlineSelection(WrappedComponent, props, previousComponent){ + return ( +
+ {previousComponent === undefined ? '' : + {setPreviousComponent(props, previousComponent)}}/>} + +
+ ) +} + +function setPreviousComponent(props, previousComponent) { + if(previousComponent === ManualRunOptions){ + return props.setComponent() + } else { + return props.setComponent(previousComponent) + } +} + +InlineSelection.propTypes = { + setComponent: PropTypes.func, + ips: PropTypes.arrayOf(PropTypes.string) +} diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/NextSelectionButton.js b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/NextSelectionButton.js new file mode 100644 index 000000000..6f6ac4cb7 --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/NextSelectionButton.js @@ -0,0 +1,17 @@ +import {Button} from 'react-bootstrap'; +import React from 'react'; +import PropTypes from 'prop-types'; + +export default function nextSelectionButton(props) { + return ( + + ) +} + +nextSelectionButton.propTypes = { + text: PropTypes.string, + onButtonClick: PropTypes.func +} diff --git a/monkey/monkey_island/cc/ui/src/styles/Main.scss b/monkey/monkey_island/cc/ui/src/styles/Main.scss index 6b6096a3f..2fb672693 100644 --- a/monkey/monkey_island/cc/ui/src/styles/Main.scss +++ b/monkey/monkey_island/cc/ui/src/styles/Main.scss @@ -11,6 +11,7 @@ @import 'components/InfoPane'; @import 'components/PreviewPane'; @import 'components/AdvancedMultiSelect'; +@import 'components/InlineSelection'; // Define custom elements after bootstrap import diff --git a/monkey/monkey_island/cc/ui/src/styles/components/InlineSelection.scss b/monkey/monkey_island/cc/ui/src/styles/components/InlineSelection.scss new file mode 100644 index 000000000..c264344de --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/styles/components/InlineSelection.scss @@ -0,0 +1,8 @@ +.inline-selection-component.container { + display: flex; + justify-content: center; +} + +.inline-selection-component.container .selection-button{ + margin: 0 5px 0 5px; +}