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 AuthComponent from './AuthComponent';
import LoginPageComponent from './pages/LoginPage'; import LoginPageComponent from './pages/LoginPage';
import RegisterPageComponent from './pages/RegisterPage'; import RegisterPageComponent from './pages/RegisterPage';
import LandingPage from "./pages/LandingPage";
import Notifier from 'react-desktop-notification'; import Notifier from 'react-desktop-notification';
import NotFoundPage from './pages/NotFoundPage'; import NotFoundPage from './pages/NotFoundPage';
import GettingStartedPage from './pages/GettingStartedPage'; import GettingStartedPage from './pages/GettingStartedPage';
@ -24,10 +25,10 @@ import 'react-toggle/style.css';
import 'react-table/react-table.css'; import 'react-table/react-table.css';
import {StandardLayoutComponent} from './layouts/StandardLayoutComponent'; import {StandardLayoutComponent} from './layouts/StandardLayoutComponent';
import LoadingScreen from './ui-components/LoadingScreen'; import LoadingScreen from './ui-components/LoadingScreen';
import LandingPageComponent from "./pages/LandingPage";
import {DisabledSidebarLayoutComponent} from "./layouts/DisabledSidebarLayoutComponent"; import {DisabledSidebarLayoutComponent} from "./layouts/DisabledSidebarLayoutComponent";
import {CompletedSteps} from "./side-menu/CompletedSteps"; import {CompletedSteps} from "./side-menu/CompletedSteps";
import Timeout = NodeJS.Timeout; import Timeout = NodeJS.Timeout;
import IslandHttpClient from "./IslandHttpClient";
let notificationIcon = require('../images/notification-logo-512x512.png'); 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 reportZeroTrustRoute = '/report/zeroTrust';
const Routes = {
LandingPage: '/landing-page',
GettingStartedPage: '/'
}
class AppComponent extends AuthComponent { class AppComponent extends AuthComponent {
private interval: Timeout; private interval: Timeout;
@ -43,7 +49,7 @@ class AppComponent extends AuthComponent {
let completedSteps = new CompletedSteps(false); let completedSteps = new CompletedSteps(false);
this.state = { this.state = {
completedSteps: completedSteps, completedSteps: completedSteps,
islandMode: undefined, islandMode: null,
noAuthLoginAttempted: undefined noAuthLoginAttempted: undefined
}; };
this.interval = undefined; this.interval = undefined;
@ -70,9 +76,12 @@ class AppComponent extends AuthComponent {
}) })
} }
this.checkMode();
if (res) { if (res) {
this.checkMode()
.then(() => {
if(this.state.islandMode === null) {
return
}
this.authFetch('/api') this.authFetch('/api')
.then(res => res.json()) .then(res => res.json())
.then(res => { .then(res => {
@ -88,17 +97,17 @@ class AppComponent extends AuthComponent {
this.setState({completedSteps: res['completed_steps']}); this.setState({completedSteps: res['completed_steps']});
this.showInfectionDoneNotification(); this.showInfectionDoneNotification();
} }
}); });}
)
} }
}); });
}; };
checkMode = () => { checkMode = () => {
// TODO change to fetch the mode from UI return IslandHttpClient.get('/api/island-mode')
this.authFetch('/api')
.then(res => res.json())
.then(res => { .then(res => {
this.setState({IslandMode: undefined}) this.setState({islandMode: res.body.mode});
}); });
} }
@ -106,8 +115,10 @@ class AppComponent extends AuthComponent {
let render_func = () => { let render_func = () => {
switch (this.state.isLoggedIn) { switch (this.state.isLoggedIn) {
case true: case true:
if(this.state.islandMode === undefined){ if (this.state.islandMode === null && route_path !== Routes.LandingPage) {
return this.getLandingPage(); 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; return page_component;
case false: case false:
@ -131,12 +142,6 @@ class AppComponent extends AuthComponent {
} }
}; };
getLandingPage() {
return <DisabledSidebarLayoutComponent component={LandingPageComponent}
completedSteps={new CompletedSteps()}
onStatusChange={this.updateStatus}/>
}
redirectTo = (userPath, targetPath) => { redirectTo = (userPath, targetPath) => {
let pathQuery = new RegExp(userPath + '[/]?$', 'g'); let pathQuery = new RegExp(userPath + '[/]?$', 'g');
if (window.location.pathname.match(pathQuery)) { if (window.location.pathname.match(pathQuery)) {
@ -160,7 +165,11 @@ class AppComponent extends AuthComponent {
<Switch> <Switch>
<Route path='/login' render={() => (<LoginPageComponent onStatusChange={this.updateStatus}/>)}/> <Route path='/login' render={() => (<LoginPageComponent onStatusChange={this.updateStatus}/>)}/>
<Route path='/register' render={() => (<RegisterPageComponent 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} <StandardLayoutComponent component={GettingStartedPage}
completedSteps={this.state.completedSteps} completedSteps={this.state.completedSteps}
onStatusChange={this.updateStatus} onStatusChange={this.updateStatus}

View File

@ -1,6 +1,6 @@
import React from 'react' import React from 'react';
import {Route} from 'react-router-dom' import {Route} from 'react-router-dom';
import SideNavComponent from '../SideNavComponent.tsx' import SideNavComponent from '../SideNavComponent.tsx';
import {Col, Row} from 'react-bootstrap'; import {Col, Row} from 'react-bootstrap';
export const DisabledSidebarLayoutComponent = ({component: Component, ...rest}) => ( export const DisabledSidebarLayoutComponent = ({component: Component, ...rest}) => (

View File

@ -4,59 +4,68 @@ import {Link} from 'react-router-dom';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faFileCode, faLightbulb} from '@fortawesome/free-solid-svg-icons'; import {faFileCode, faLightbulb} from '@fortawesome/free-solid-svg-icons';
import '../../styles/pages/LandingPage.scss'; import '../../styles/pages/LandingPage.scss';
import AuthComponent from '../AuthComponent'; import IslandHttpClient from "../IslandHttpClient";
class LandingPageComponent extends AuthComponent { const LandingPageComponent = (props) => {
constructor(props) {
super(props);
}
render() {
return ( return (
<Col sm={{offset: 3, span: 9}} md={{offset: 3, span: 9}} <Col sm={{offset: 3, span: 9}} md={{offset: 3, span: 9}}
lg={{offset: 3, span: 9}} xl={{offset: 2, span: 7}} lg={{offset: 3, span: 9}} xl={{offset: 2, span: 7}}
className={'landing-page'}> className={'landing-page'}>
<h1 className="page-title">Welcome to the Monkey Island Server</h1> <h1 className="page-title">Welcome to the Monkey Island Server</h1>
<div style={{'fontSize': '1.2em'}}> <div style={{'fontSize': '1.2em'}}>
<ScenarioButtons /> <ScenarioButtons/>
<br/> <br/>
</div> </div>
</Col> </Col>
); );
}
}
function ScenarioButtons() { function ScenarioButtons() {
return ( return (
<section> <section>
<h2 className={'scenario-choice-title'}>Choose a scenario:</h2> <h2 className={'scenario-choice-title'}>Choose a scenario:</h2>
<div className="container"> <div className="container">
<Row className="justify-content-center"> <Row className="justify-content-center">
<div className="col-lg-6 col-sm-6"> <div className="col-lg-6 col-sm-6">
<Link to="/run-monkey" className="px-4 py-5 bg-white shadow text-center d-block"> <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> <h4><FontAwesomeIcon icon={faFileCode}/> Ransomware</h4>
<p>Simulate ransomware infection in the network.</p> <p>Simulate ransomware infection in the network.</p>
</Link> </Link>
</div> </div>
<div className="col-lg-6 col-sm-6"> <div className="col-lg-6 col-sm-6">
<Link to="/configure" className="px-4 py-5 bg-white shadow text-center d-block"> <Link to="/configure"
className="px-4 py-5 bg-white shadow text-center d-block"
onClick={() => {
setScenario('advanced')
}}>
<h4><FontAwesomeIcon icon={faLightbulb}/> Custom</h4> <h4><FontAwesomeIcon icon={faLightbulb}/> Custom</h4>
<p>Fine tune the simulation to your needs.</p> <p>Fine tune the simulation to your needs.</p>
</Link> </Link>
</div> </div>
</Row> </Row>
<MonkeyInfo /> <MonkeyInfo/>
</div> </div>
</section> </section>
); );
}
function setScenario(scenario: string) {
IslandHttpClient.post('/api/island-mode', {'mode': scenario});
props.onStatusChange();
}
} }
function MonkeyInfo() { function MonkeyInfo() {
return ( return (
<> <>
<h4 className={'monkey-description-title'}>What is Infection Monkey?</h4> <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 <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 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. and reports to this Monkey Island Command and Control server.
</> </>