Island: Implements basics of page redirection when island mode is set

This commit is contained in:
VakarisZ 2021-07-14 17:08:17 +03:00
parent b03c6d9f92
commit 5743f8ea98
4 changed files with 130 additions and 81 deletions

View File

@ -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();

View File

@ -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}

View File

@ -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}) => (

View File

@ -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;