Skip to content
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

Remove Island mode logic from UI #3472

Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export enum APIEndpoint {
machines = '/api/machines',
nodes = '/api/nodes',
agentEvents = '/api/agent-events',
mode = '/api/island/mode',
monkey_exploitation = '/api/exploitations/monkey',
stolenCredentials = '/api/propagation-credentials/stolen-credentials',
linuxMasque = '/api/agent-binaries/linux/masque',
Expand Down
144 changes: 38 additions & 106 deletions monkey/monkey_island/cc/ui/src/components/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import LicensePage from './pages/LicensePage';
import AuthComponent from './AuthComponent';
import LoginPageComponent from './pages/LoginPage';
import RegisterPageComponent from './pages/RegisterPage';
import LandingPage from "./pages/LandingPage";
import Notifier from 'react-desktop-notification';
import NotFoundPage from './pages/NotFoundPage';
import GettingStartedPage from './pages/GettingStartedPage';
Expand All @@ -29,7 +28,6 @@ import LogoutPage from './pages/LogoutPage';
let notificationIcon = require('../images/notification-logo-512x512.png');

export const IslandRoutes = {
LandingPage: '/landing-page',
GettingStartedPage: '/',
Report: '/report',
SecurityReport: '/report/security',
Expand All @@ -55,10 +53,8 @@ class AppComponent extends AuthComponent {
super(props);
this.state = {
completedSteps: new CompletedSteps(false),
islandMode: undefined,
};
this.interval = undefined;
this.setMode();
}

updateStatus = () => {
Expand All @@ -84,72 +80,52 @@ class AppComponent extends AuthComponent {
}

if (res) {
this.setMode()
.then(() => {
if (this.state.islandMode === "unset") {
return
}

// update status: report generation
this.authFetch('/api/report-generation-status', {}, false)
shreyamalviya marked this conversation as resolved.
Show resolved Hide resolved
.then(res => res.json())
.then(res => {
this.setState({
completedSteps: new CompletedSteps(
this.state.completedSteps.runMonkey,
this.state.completedSteps.infectionDone,
res.report_done
)
});
})

// update status: if any agent ran
doesAnyAgentExist(false).then(anyAgentExists => {
this.setState({
completedSteps: new CompletedSteps(
anyAgentExists,
this.state.completedSteps.infectionDone,
this.state.completedSteps.reportDone
)
});
// update status: report generation
this.authFetch('/api/report-generation-status', {}, false)
.then(res => res.json())
.then(res => {
this.setState({
completedSteps: new CompletedSteps(
this.state.completedSteps.runMonkey,
this.state.completedSteps.infectionDone,
res.report_done
)
});
})

// update status: if infection (running and shutting down of all agents) finished
didAllAgentsShutdown(false).then(allAgentsShutdown => {
let infectionDone = this.state.completedSteps.runMonkey && allAgentsShutdown;
if(this.state.completedSteps.infectionDone === false
&& infectionDone){
this.showInfectionDoneNotification();
}
this.setState({
completedSteps: new CompletedSteps(
this.state.completedSteps.runMonkey,
infectionDone,
this.state.completedSteps.reportDone
)
});
});
// update status: if any agent ran
doesAnyAgentExist(false).then(anyAgentExists => {
this.setState({
completedSteps: new CompletedSteps(
anyAgentExists,
this.state.completedSteps.infectionDone,
this.state.completedSteps.reportDone
)
});
});

// update status: if infection (running and shutting down of all agents) finished
didAllAgentsShutdown(false).then(allAgentsShutdown => {
let infectionDone = this.state.completedSteps.runMonkey && allAgentsShutdown;
if(this.state.completedSteps.infectionDone === false
&& infectionDone){
this.showInfectionDoneNotification();
}
)
this.setState({
completedSteps: new CompletedSteps(
this.state.completedSteps.runMonkey,
infectionDone,
this.state.completedSteps.reportDone
)
});
});
}
};

setMode = () => {
return IslandHttpClient.getJSON(APIEndpoint.mode)
.then(res => {
this.setState({islandMode: res.body});
});
}

renderRoute = (route_path, page_component) => {
let render_func = () => {
switch (this.state.isLoggedIn) {
case true:
if (this.needsRedirectionToLandingPage(route_path)) {
return <Navigate replace to={IslandRoutes.LandingPage}/>;
} else if (this.needsRedirectionToGettingStarted(route_path)) {
return <Navigate replace to={IslandRoutes.GettingStartedPage}/>;
}
return page_component;
case false:
switch (this.state.needsRegistration) {
Expand All @@ -168,15 +144,6 @@ class AppComponent extends AuthComponent {
return <Route path={route_path} element={render_func()}/>;
};

needsRedirectionToLandingPage = (route_path) => {
return (this.state.islandMode === "unset" && route_path !== IslandRoutes.LandingPage)
}

needsRedirectionToGettingStarted = (route_path) => {
return route_path === IslandRoutes.LandingPage &&
this.state.islandMode !== "unset" && this.state.islandMode !== undefined
}

redirectTo = (userPath, targetPath) => {
let pathQuery = new RegExp(userPath + '[/]?$', 'g');
if (window.location.pathname.match(pathQuery)) {
Expand All @@ -194,36 +161,14 @@ class AppComponent extends AuthComponent {
}

getDefaultReport() {
if(this.state.islandMode === 'ransomware'){
return IslandRoutes.RansomwareReport;
} else {
return IslandRoutes.SecurityReport;
}
}

getIslandModeTitle(){
if(this.state.islandMode === 'ransomware'){
return this.formIslandModeTitle("Ransomware", faFileCode);
} else {
return this.formIslandModeTitle("Custom", faLightbulb);
}
}

formIslandModeTitle(title, icon){
return (<>
<h5 className={'text-muted'}>
<FontAwesomeIcon icon={icon} /> {title}
</h5>
</>)
return IslandRoutes.SecurityReport;
}

render() {

let defaultSideNavProps = {completedSteps: this.state.completedSteps,
onStatusChange: this.updateStatus,
islandMode: this.state.islandMode,
defaultReport: this.getDefaultReport(),
sideNavHeader: this.getIslandModeTitle(),
onLogout: () => {this.auth.logout()
.then(() => this.updateStatus())}};

Expand All @@ -234,12 +179,6 @@ class AppComponent extends AuthComponent {
<Route path={IslandRoutes.LoginPage} element={<LoginPageComponent onStatusChange={this.updateStatus}/>}/>
<Route path={IslandRoutes.Logout} element={<LogoutPage onStatusChange={this.updateStatus}/>}/>
<Route path={IslandRoutes.RegisterPage} element={<RegisterPageComponent onStatusChange={this.updateStatus}/>}/>
{this.renderRoute(IslandRoutes.LandingPage,
<SidebarLayoutComponent component={LandingPage}
sideNavShow={false}
sideNavDisabled={true}
completedSteps={new CompletedSteps()}
onStatusChange={this.updateStatus}/>)}
{this.renderRoute(IslandRoutes.GettingStartedPage,
<SidebarLayoutComponent component={GettingStartedPage} {...defaultSideNavProps}/>)}
{this.renderRoute(IslandRoutes.ConfigurePage,
Expand All @@ -253,15 +192,12 @@ class AppComponent extends AuthComponent {
{this.redirectToReport()}
{this.renderRoute(IslandRoutes.SecurityReport,
<SidebarLayoutComponent component={ReportPage}
islandMode={this.state.islandMode}
{...defaultSideNavProps}/>)}
{this.renderRoute(IslandRoutes.RansomwareReport,
<SidebarLayoutComponent component={ReportPage}
islandMode={this.state.islandMode}
{...defaultSideNavProps}/>)}
{this.renderRoute(IslandRoutes.LicensePage,
<SidebarLayoutComponent component={LicensePage}
islandMode={this.state.islandMode}
{...defaultSideNavProps}/>)}
<Route path='*' element={<NotFoundPage/>}/>
</Routes>
Expand All @@ -271,11 +207,7 @@ class AppComponent extends AuthComponent {
}

redirectToReport() {
if (this.state.islandMode === 'ransomware') {
return this.redirectTo(IslandRoutes.Report, IslandRoutes.RansomwareReport)
} else {
return this.redirectTo(IslandRoutes.Report, IslandRoutes.SecurityReport)
}
return this.redirectTo(IslandRoutes.Report, IslandRoutes.SecurityReport)
}

showInfectionDoneNotification() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const CONFIGURATION_TABS = {
ADVANCED: 'advanced'
};

const advancedModeConfigTabs = [
const CONFIGURATION_TABS_ORDER = [
CONFIGURATION_TABS.PROPAGATION,
CONFIGURATION_TABS.PAYLOADS,
CONFIGURATION_TABS.CREDENTIALS_COLLECTORS,
Expand All @@ -16,17 +16,4 @@ const advancedModeConfigTabs = [
CONFIGURATION_TABS.ADVANCED
];

const ransomwareModeConfigTabs = [
CONFIGURATION_TABS.PROPAGATION,
CONFIGURATION_TABS.PAYLOADS,
CONFIGURATION_TABS.MASQUERADE,
CONFIGURATION_TABS.POLYMORPHISM,
CONFIGURATION_TABS.ADVANCED
];

const CONFIGURATION_TABS_PER_MODE = {
'advanced': advancedModeConfigTabs,
'ransomware': ransomwareModeConfigTabs
};

export default CONFIGURATION_TABS_PER_MODE;
export default CONFIGURATION_TABS_ORDER;
19 changes: 3 additions & 16 deletions monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
import ConfigExportModal from '../configuration-components/ExportConfigModal';
import ConfigImportModal from '../configuration-components/ImportConfigModal';
import applyUiSchemaManipulators from '../configuration-components/UISchemaManipulators.tsx';
import CONFIGURATION_TABS_PER_MODE from '../configuration-components/ConfigurationTabs.js';
import CONFIGURATION_TABS_ORDER from '../configuration-components/ConfigurationTabs.js';
import {SCHEMA} from '../../services/configuration/configSchema.js';
import {
reformatConfig,
Expand Down Expand Up @@ -52,7 +52,7 @@ class ConfigurePageComponent extends AuthComponent {

constructor(props) {
super(props);
this.currentSection = this.getSectionsOrder()[0];
this.currentSection = CONFIGURATION_TABS_ORDER[0];
this.validator = customizeValidator( {customFormats: formValidationFormats});

this.state = {
Expand All @@ -72,13 +72,6 @@ class ConfigurePageComponent extends AuthComponent {
};
}

componentDidUpdate() {
if (!this.getSectionsOrder()?.includes(this.currentSection)) {
this.currentSection = this.getSectionsOrder()?.[0];
this.setState({selectedSection: this.currentSection});
}
}

setCredentialsState = (rows = [], errors = [], isRequiredToUpdateId) => {
let newState = {credentials: {credentialsData: rows, errors: errors, id: this.state.credentials.id}};
if(isRequiredToUpdateId) {
Expand All @@ -91,12 +84,6 @@ class ConfigurePageComponent extends AuthComponent {
this.setState({lastAction: 'none'});
}

getSectionsOrder() {
let islandModeSet = (this.props.islandMode !== 'unset' && this.props.islandMode !== undefined)
let islandMode = islandModeSet ? this.props.islandMode : 'advanced'
return CONFIGURATION_TABS_PER_MODE[islandMode];
}

componentDidMount = () => {
this.authFetch(SCHEMA_URL, {}, true).then(res => res.json())
.then((schema) => {
Expand All @@ -111,7 +98,7 @@ class ConfigurePageComponent extends AuthComponent {
let sections = [];
monkeyConfig = reformatConfig(monkeyConfig);

for (let sectionKey of this.getSectionsOrder()) {
for (let sectionKey of CONFIGURATION_TABS_ORDER) {
sections.push({
key: sectionKey,
title: SCHEMA.properties[sectionKey].title
Expand Down
Loading