forked from p15670423/monkey
Island: Implements basics of page redirection when island mode is set
This commit is contained in:
parent
b03c6d9f92
commit
5743f8ea98
|
@ -0,0 +1,31 @@
|
|||
import AuthComponent from "./AuthComponent";
|
||||
import React from "react";
|
||||
|
||||
export class Response{
|
||||
body: any
|
||||
status: number
|
||||
|
||||
constructor(body: any, status: number) {
|
||||
this.body = body
|
||||
this.status = status
|
||||
}
|
||||
}
|
||||
|
||||
class IslandHttpClient extends AuthComponent {
|
||||
post(endpoint: string, contents: any): Promise<Response>{
|
||||
return this.authFetch(endpoint,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify(contents)
|
||||
})
|
||||
.then(res => new Response(res.json(), res.status));
|
||||
}
|
||||
|
||||
get(endpoint: string): Promise<Response>{
|
||||
return this.authFetch(endpoint)
|
||||
.then(res => new Response(res.json(), res.status));
|
||||
}
|
||||
}
|
||||
|
||||
export default new IslandHttpClient();
|
|
@ -12,6 +12,7 @@ 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';
|
||||
|
@ -24,10 +25,10 @@ import 'react-toggle/style.css';
|
|||
import 'react-table/react-table.css';
|
||||
import {StandardLayoutComponent} from './layouts/StandardLayoutComponent';
|
||||
import LoadingScreen from './ui-components/LoadingScreen';
|
||||
import LandingPageComponent from "./pages/LandingPage";
|
||||
import {DisabledSidebarLayoutComponent} from "./layouts/DisabledSidebarLayoutComponent";
|
||||
import {CompletedSteps} from "./side-menu/CompletedSteps";
|
||||
import Timeout = NodeJS.Timeout;
|
||||
import IslandHttpClient from "./IslandHttpClient";
|
||||
|
||||
|
||||
let notificationIcon = require('../images/notification-logo-512x512.png');
|
||||
|
@ -35,6 +36,11 @@ let notificationIcon = require('../images/notification-logo-512x512.png');
|
|||
const reportZeroTrustRoute = '/report/zeroTrust';
|
||||
|
||||
|
||||
const Routes = {
|
||||
LandingPage: '/landing-page',
|
||||
GettingStartedPage: '/'
|
||||
}
|
||||
|
||||
class AppComponent extends AuthComponent {
|
||||
private interval: Timeout;
|
||||
|
||||
|
@ -43,7 +49,7 @@ class AppComponent extends AuthComponent {
|
|||
let completedSteps = new CompletedSteps(false);
|
||||
this.state = {
|
||||
completedSteps: completedSteps,
|
||||
islandMode: undefined,
|
||||
islandMode: null,
|
||||
noAuthLoginAttempted: undefined
|
||||
};
|
||||
this.interval = undefined;
|
||||
|
@ -70,35 +76,38 @@ class AppComponent extends AuthComponent {
|
|||
})
|
||||
}
|
||||
|
||||
this.checkMode();
|
||||
|
||||
if (res) {
|
||||
this.authFetch('/api')
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
// This check is used to prevent unnecessary re-rendering
|
||||
let isChanged = false;
|
||||
for (let step in this.state.completedSteps) {
|
||||
if (this.state.completedSteps[step] !== res['completed_steps'][step]) {
|
||||
isChanged = true;
|
||||
break;
|
||||
}
|
||||
this.checkMode()
|
||||
.then(() => {
|
||||
if(this.state.islandMode === null) {
|
||||
return
|
||||
}
|
||||
if (isChanged) {
|
||||
this.setState({completedSteps: res['completed_steps']});
|
||||
this.showInfectionDoneNotification();
|
||||
}
|
||||
});
|
||||
this.authFetch('/api')
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
// This check is used to prevent unnecessary re-rendering
|
||||
let isChanged = false;
|
||||
for (let step in this.state.completedSteps) {
|
||||
if (this.state.completedSteps[step] !== res['completed_steps'][step]) {
|
||||
isChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isChanged) {
|
||||
this.setState({completedSteps: res['completed_steps']});
|
||||
this.showInfectionDoneNotification();
|
||||
}
|
||||
});}
|
||||
)
|
||||
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
checkMode = () => {
|
||||
// TODO change to fetch the mode from UI
|
||||
this.authFetch('/api')
|
||||
.then(res => res.json())
|
||||
return IslandHttpClient.get('/api/island-mode')
|
||||
.then(res => {
|
||||
this.setState({IslandMode: undefined})
|
||||
this.setState({islandMode: res.body.mode});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -106,8 +115,10 @@ class AppComponent extends AuthComponent {
|
|||
let render_func = () => {
|
||||
switch (this.state.isLoggedIn) {
|
||||
case true:
|
||||
if(this.state.islandMode === undefined){
|
||||
return this.getLandingPage();
|
||||
if (this.state.islandMode === null && route_path !== Routes.LandingPage) {
|
||||
return <Redirect to={{pathname: Routes.LandingPage}}/>
|
||||
} else if(route_path === Routes.LandingPage && this.state.islandMode !== null){
|
||||
return <Redirect to={{pathname: Routes.GettingStartedPage}}/>
|
||||
}
|
||||
return page_component;
|
||||
case false:
|
||||
|
@ -131,12 +142,6 @@ class AppComponent extends AuthComponent {
|
|||
}
|
||||
};
|
||||
|
||||
getLandingPage() {
|
||||
return <DisabledSidebarLayoutComponent component={LandingPageComponent}
|
||||
completedSteps={new CompletedSteps()}
|
||||
onStatusChange={this.updateStatus}/>
|
||||
}
|
||||
|
||||
redirectTo = (userPath, targetPath) => {
|
||||
let pathQuery = new RegExp(userPath + '[/]?$', 'g');
|
||||
if (window.location.pathname.match(pathQuery)) {
|
||||
|
@ -160,7 +165,11 @@ class AppComponent extends AuthComponent {
|
|||
<Switch>
|
||||
<Route path='/login' render={() => (<LoginPageComponent onStatusChange={this.updateStatus}/>)}/>
|
||||
<Route path='/register' render={() => (<RegisterPageComponent onStatusChange={this.updateStatus}/>)}/>
|
||||
{this.renderRoute('/',
|
||||
{this.renderRoute(Routes.LandingPage,
|
||||
<DisabledSidebarLayoutComponent component={LandingPage}
|
||||
completedSteps={new CompletedSteps()}
|
||||
onStatusChange={this.updateStatus}/>)}
|
||||
{this.renderRoute(Routes.GettingStartedPage,
|
||||
<StandardLayoutComponent component={GettingStartedPage}
|
||||
completedSteps={this.state.completedSteps}
|
||||
onStatusChange={this.updateStatus}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react'
|
||||
import {Route} from 'react-router-dom'
|
||||
import SideNavComponent from '../SideNavComponent.tsx'
|
||||
import React from 'react';
|
||||
import {Route} from 'react-router-dom';
|
||||
import SideNavComponent from '../SideNavComponent.tsx';
|
||||
import {Col, Row} from 'react-bootstrap';
|
||||
|
||||
export const DisabledSidebarLayoutComponent = ({component: Component, ...rest}) => (
|
||||
|
|
|
@ -4,63 +4,72 @@ import {Link} from 'react-router-dom';
|
|||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||
import {faFileCode, faLightbulb} from '@fortawesome/free-solid-svg-icons';
|
||||
import '../../styles/pages/LandingPage.scss';
|
||||
import AuthComponent from '../AuthComponent';
|
||||
import IslandHttpClient from "../IslandHttpClient";
|
||||
|
||||
|
||||
class LandingPageComponent extends AuthComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
const LandingPageComponent = (props) => {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Col sm={{offset: 3, span: 9}} md={{offset: 3, span: 9}}
|
||||
lg={{offset: 3, span: 9}} xl={{offset: 2, span: 7}}
|
||||
className={'landing-page'}>
|
||||
<h1 className="page-title">Welcome to the Monkey Island Server</h1>
|
||||
<div style={{'fontSize': '1.2em'}}>
|
||||
<ScenarioButtons/>
|
||||
<br/>
|
||||
</div>
|
||||
</Col>
|
||||
);
|
||||
|
||||
function ScenarioButtons() {
|
||||
return (
|
||||
<Col sm={{offset: 3, span: 9}} md={{offset: 3, span: 9}}
|
||||
lg={{offset: 3, span: 9}} xl={{offset: 2, span: 7}}
|
||||
className={'landing-page'}>
|
||||
<h1 className="page-title">Welcome to the Monkey Island Server</h1>
|
||||
<div style={{'fontSize': '1.2em'}}>
|
||||
<ScenarioButtons />
|
||||
<br/>
|
||||
<section>
|
||||
<h2 className={'scenario-choice-title'}>Choose a scenario:</h2>
|
||||
<div className="container">
|
||||
<Row className="justify-content-center">
|
||||
<div className="col-lg-6 col-sm-6">
|
||||
<Link to="/run-monkey"
|
||||
className="px-4 py-5 bg-white shadow text-center d-block"
|
||||
onClick={() => {
|
||||
setScenario('ransomware')
|
||||
}}>
|
||||
<h4><FontAwesomeIcon icon={faFileCode}/> Ransomware</h4>
|
||||
<p>Simulate ransomware infection in the network.</p>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="col-lg-6 col-sm-6">
|
||||
<Link to="/configure"
|
||||
className="px-4 py-5 bg-white shadow text-center d-block"
|
||||
onClick={() => {
|
||||
setScenario('advanced')
|
||||
}}>
|
||||
<h4><FontAwesomeIcon icon={faLightbulb}/> Custom</h4>
|
||||
<p>Fine tune the simulation to your needs.</p>
|
||||
</Link>
|
||||
</div>
|
||||
</Row>
|
||||
<MonkeyInfo/>
|
||||
</div>
|
||||
</Col>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function ScenarioButtons() {
|
||||
return (
|
||||
<section>
|
||||
<h2 className={'scenario-choice-title'}>Choose a scenario:</h2>
|
||||
<div className="container">
|
||||
<Row className="justify-content-center">
|
||||
<div className="col-lg-6 col-sm-6">
|
||||
<Link to="/run-monkey" className="px-4 py-5 bg-white shadow text-center d-block">
|
||||
<h4><FontAwesomeIcon icon={faFileCode}/> Ransomware</h4>
|
||||
<p>Simulate ransomware infection in the network.</p>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="col-lg-6 col-sm-6">
|
||||
<Link to="/configure" className="px-4 py-5 bg-white shadow text-center d-block">
|
||||
<h4><FontAwesomeIcon icon={faLightbulb}/> Custom</h4>
|
||||
<p>Fine tune the simulation to your needs.</p>
|
||||
</Link>
|
||||
</div>
|
||||
</Row>
|
||||
<MonkeyInfo />
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
function setScenario(scenario: string) {
|
||||
IslandHttpClient.post('/api/island-mode', {'mode': scenario});
|
||||
props.onStatusChange();
|
||||
}
|
||||
}
|
||||
|
||||
function MonkeyInfo() {
|
||||
return (
|
||||
<>
|
||||
<h4 className={'monkey-description-title'}>What is Infection Monkey?</h4>
|
||||
<strong>Infection Monkey</strong> is an open-source security tool for testing a data center's resiliency to perimeter
|
||||
breaches and internal server infections. The Monkey uses various methods to propagate across a data center
|
||||
and reports to this Monkey Island Command and Control server.
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<h4 className={'monkey-description-title'}>What is Infection Monkey?</h4>
|
||||
<strong>Infection Monkey</strong> is an open-source security tool for testing a data center's resiliency to
|
||||
perimeter
|
||||
breaches and internal server infections. The Monkey uses various methods to propagate across a data center
|
||||
and reports to this Monkey Island Command and Control server.
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default LandingPageComponent;
|
||||
|
|
Loading…
Reference in New Issue