Add login page, and auto redirection to/from login page

This commit is contained in:
Itay Mizeretz 2018-02-22 15:23:47 +02:00
parent 52d75de864
commit c9d644f88a
3 changed files with 128 additions and 34 deletions

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import {NavLink, Route, BrowserRouter as Router} from 'react-router-dom'; import {BrowserRouter as Router, NavLink, Redirect, Route} from 'react-router-dom';
import {Col, Grid, Row} from 'react-bootstrap'; import {Col, Grid, Row} from 'react-bootstrap';
import {Icon} from 'react-fa'; import {Icon} from 'react-fa';
@ -11,6 +11,8 @@ import TelemetryPage from 'components/pages/TelemetryPage';
import StartOverPage from 'components/pages/StartOverPage'; import StartOverPage from 'components/pages/StartOverPage';
import ReportPage from 'components/pages/ReportPage'; import ReportPage from 'components/pages/ReportPage';
import LicensePage from 'components/pages/LicensePage'; import LicensePage from 'components/pages/LicensePage';
import AuthComponent from 'components/AuthComponent';
import LoginPageComponent from 'components/pages/LoginPage';
require('normalize.css/normalize.css'); require('normalize.css/normalize.css');
require('react-data-components/css/table-twbs.css'); require('react-data-components/css/table-twbs.css');
@ -22,21 +24,9 @@ let logoImage = require('../images/monkey-icon.svg');
let infectionMonkeyImage = require('../images/infection-monkey.svg'); let infectionMonkeyImage = require('../images/infection-monkey.svg');
let guardicoreLogoImage = require('../images/guardicore-logo.png'); let guardicoreLogoImage = require('../images/guardicore-logo.png');
class AppComponent extends React.Component { class AppComponent extends AuthComponent {
constructor(props) {
super(props);
this.state = {
completedSteps: {
run_server: true,
run_monkey: false,
infection_done: false,
report_done: false
}
};
}
updateStatus = () => { updateStatus = () => {
fetch('/api') this.authFetch('/api')
.then(res => res.json()) .then(res => res.json())
.then(res => { .then(res => {
// This check is used to prevent unnecessary re-rendering // This check is used to prevent unnecessary re-rendering
@ -53,6 +43,34 @@ class AppComponent extends React.Component {
}); });
}; };
renderRoute = (route_path, page_component, is_exact_path = false) => {
let render_func = (props) => {
if (this.auth.loggedIn()) {
return page_component;
} else {
return <Redirect to={{pathname: '/login'}}/>;
}
};
if (is_exact_path) {
return <Route exact path={route_path} render={render_func}/>;
} else {
return <Route path={route_path} render={render_func}/>;
}
};
constructor(props) {
super(props);
this.state = {
completedSteps: {
run_server: true,
run_monkey: false,
infection_done: false,
report_done: false
}
};
}
componentDidMount() { componentDidMount() {
this.updateStatus(); this.updateStatus();
this.interval = setInterval(this.updateStatus, 2000); this.interval = setInterval(this.updateStatus, 2000);
@ -78,7 +96,7 @@ class AppComponent extends React.Component {
<NavLink to="/" exact={true}> <NavLink to="/" exact={true}>
<span className="number">1.</span> <span className="number">1.</span>
Run C&C Server Run C&C Server
{ this.state.completedSteps.run_server ? {this.state.completedSteps.run_server ?
<Icon name="check" className="pull-right checkmark text-success"/> <Icon name="check" className="pull-right checkmark text-success"/>
: ''} : ''}
</NavLink> </NavLink>
@ -87,7 +105,7 @@ class AppComponent extends React.Component {
<NavLink to="/run-monkey"> <NavLink to="/run-monkey">
<span className="number">2.</span> <span className="number">2.</span>
Run Monkey Run Monkey
{ this.state.completedSteps.run_monkey ? {this.state.completedSteps.run_monkey ?
<Icon name="check" className="pull-right checkmark text-success"/> <Icon name="check" className="pull-right checkmark text-success"/>
: ''} : ''}
</NavLink> </NavLink>
@ -96,7 +114,7 @@ class AppComponent extends React.Component {
<NavLink to="/infection/map"> <NavLink to="/infection/map">
<span className="number">3.</span> <span className="number">3.</span>
Infection Map Infection Map
{ this.state.completedSteps.infection_done ? {this.state.completedSteps.infection_done ?
<Icon name="check" className="pull-right checkmark text-success"/> <Icon name="check" className="pull-right checkmark text-success"/>
: ''} : ''}
</NavLink> </NavLink>
@ -105,7 +123,7 @@ class AppComponent extends React.Component {
<NavLink to="/report"> <NavLink to="/report">
<span className="number">4.</span> <span className="number">4.</span>
Security Report Security Report
{ this.state.completedSteps.report_done ? {this.state.completedSteps.report_done ?
<Icon name="check" className="pull-right checkmark text-success"/> <Icon name="check" className="pull-right checkmark text-success"/>
: ''} : ''}
</NavLink> </NavLink>
@ -136,14 +154,15 @@ class AppComponent extends React.Component {
</div> </div>
</Col> </Col>
<Col sm={9} md={10} smOffset={3} mdOffset={2} className="main"> <Col sm={9} md={10} smOffset={3} mdOffset={2} className="main">
<Route exact path="/" render={(props) => ( <RunServerPage onStatusChange={this.updateStatus} /> )} /> <Route path='/login' render={(props) => (<LoginPageComponent onStatusChange={this.updateStatus}/>)}/>
<Route path="/configure" render={(props) => ( <ConfigurePage onStatusChange={this.updateStatus} /> )} /> {this.renderRoute('/', <RunServerPage onStatusChange={this.updateStatus}/>, true)}
<Route path="/run-monkey" render={(props) => ( <RunMonkeyPage onStatusChange={this.updateStatus} /> )} /> {this.renderRoute('/configure', <ConfigurePage onStatusChange={this.updateStatus}/>)}
<Route path="/infection/map" render={(props) => ( <MapPage onStatusChange={this.updateStatus} /> )} /> {this.renderRoute('/run-monkey', <RunMonkeyPage onStatusChange={this.updateStatus}/>)}
<Route path="/infection/telemetry" render={(props) => ( <TelemetryPage onStatusChange={this.updateStatus} /> )} /> {this.renderRoute('/infection/map', <MapPage onStatusChange={this.updateStatus}/>)}
<Route path="/start-over" render={(props) => ( <StartOverPage onStatusChange={this.updateStatus} /> )} /> {this.renderRoute('/infection/telemetry', <TelemetryPage onStatusChange={this.updateStatus}/>)}
<Route path="/report" render={(props) => ( <ReportPage onStatusChange={this.updateStatus} /> )} /> {this.renderRoute('/start-over', <StartOverPage onStatusChange={this.updateStatus}/>)}
<Route path="/license" render={(props) => ( <LicensePage onStatusChange={this.updateStatus} /> )} /> {this.renderRoute('/report', <ReportPage onStatusChange={this.updateStatus}/>)}
{this.renderRoute('/license', <LicensePage onStatusChange={this.updateStatus}/>)}
</Col> </Col>
</Row> </Row>
</Grid> </Grid>

View File

@ -0,0 +1,78 @@
import React from 'react';
import {Col} from 'react-bootstrap';
import AuthService from '../../services/AuthService'
class LoginPageComponent extends React.Component {
login = () => {
this.auth.login(this.username, this.password).then(res => {
if (res['result']) {
this.redirectToHome();
} else {
this.setState({failed: true});
}
});
};
updateUsername = (evt) => {
this.username = evt.target.value;
};
updatePassword = (evt) => {
this.password = evt.target.value;
};
redirectToHome = () => {
window.location.href = '/';
};
constructor(props) {
super(props);
this.username = '';
this.password = '';
this.auth = new AuthService();
this.state = {
failed: false
};
if (this.auth.loggedIn()) {
this.redirectToHome();
}
}
render() {
return (
<Col xs={12} lg={8}>
<h1 className="page-title">Login</h1>
<div className="col-sm-6 col-sm-offset-3" style={{'fontSize': '1.2em'}}>
<div className="panel panel-default">
<div className="panel-heading text-center">
<b>Login</b>
</div>
<div className="panel-body">
<div className="input-group center-block text-center">
<input type="text" className="form-control" placeholder="Username"
onChange={evt => this.updateUsername(evt)}/>
<input type="password" className="form-control" placeholder="Password"
onChange={evt => this.updatePassword(evt)}/>
<button type="button" className="btn btn-primary btn-lg" style={{margin: '5px'}}
onClick={() => {
this.login()
}}>
Login
</button>
{
this.state.failed ?
<div className="alert alert-danger" role="alert">Login failed. Bad credentials.</div>
:
''
}
</div>
</div>
</div>
</div>
</Col>
);
}
}
export default LoginPageComponent;

View File

@ -2,22 +2,18 @@ import React from 'react';
import {Col} from 'react-bootstrap'; import {Col} from 'react-bootstrap';
import {Link} from 'react-router-dom'; import {Link} from 'react-router-dom';
import AuthService from '../../services/AuthService'
class RunServerPageComponent extends React.Component { class RunServerPageComponent extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
} }
render() { render() {
// TODO: something real
let auth = new AuthService();
auth.login('monkey', 'infectio1n');
return ( return (
<Col xs={12} lg={8}> <Col xs={12} lg={8}>
<h1 className="page-title">1. Monkey Island C&C Server</h1> <h1 className="page-title">1. Monkey Island C&C Server</h1>
<div style={{'fontSize': '1.2em'}}> <div style={{'fontSize': '1.2em'}}>
<p style={{'marginTop': '30px'}}>Congrats! You have successfully set up the Monkey Island server. &#x1F44F; &#x1F44F;</p> <p style={{'marginTop': '30px'}}>Congrats! You have successfully set up the Monkey Island
server. &#x1F44F; &#x1F44F;</p>
<p> <p>
The Infection Monkey is an open source security tool for testing a data center's resiliency to perimeter The Infection Monkey is an open source security tool for testing a data center's resiliency to perimeter
breaches and internal server infections. breaches and internal server infections.
@ -25,7 +21,8 @@ class RunServerPageComponent extends React.Component {
center and reports to this Command and Control (C&C) server. center and reports to this Command and Control (C&C) server.
</p> </p>
<p> <p>
To read more about the Monkey, visit <a href="http://infectionmonkey.com" target="_blank">infectionmonkey.com</a> To read more about the Monkey, visit <a href="http://infectionmonkey.com"
target="_blank">infectionmonkey.com</a>
</p> </p>
<p> <p>
Go ahead and <Link to="/run-monkey">run the monkey</Link>. Go ahead and <Link to="/run-monkey">run the monkey</Link>.