UI: add agent and island log download buttons to map

This commit is contained in:
vakarisz 2022-01-31 10:56:36 +02:00
parent ead3068202
commit 3d25c56a6e
3 changed files with 90 additions and 57 deletions

View File

@ -4,8 +4,11 @@ import {faHandPointLeft} from '@fortawesome/free-solid-svg-icons/faHandPointLeft
import {faQuestionCircle} from '@fortawesome/free-solid-svg-icons/faQuestionCircle'
import Toggle from 'react-toggle';
import {OverlayTrigger, Tooltip} from 'react-bootstrap';
import download from 'downloadjs'
import AuthComponent from '../../AuthComponent';
import {
AgentLogDownloadButton,
IslandLogDownloadButton
} from '../../ui-components/LogDownloadButtons';
class PreviewPaneComponent extends AuthComponent {
@ -13,7 +16,7 @@ class PreviewPaneComponent extends AuthComponent {
return (
<OverlayTrigger placement="top"
overlay={<Tooltip id="tooltip">{text}</Tooltip>}
delay={{ show: 250, hide: 400 }}>
delay={{show: 250, hide: 400}}>
<a><FontAwesomeIcon icon={faQuestionCircle} style={{'marginRight': '0.5em'}}/></a>
</OverlayTrigger>
);
@ -94,43 +97,29 @@ class PreviewPaneComponent extends AuthComponent {
);
}
unescapeLog(st) {
return st.substr(1, st.length - 2) // remove quotation marks on beginning and end of string.
.replace(/\\n/g, '\n')
.replace(/\\r/g, '\r')
.replace(/\\t/g, '\t')
.replace(/\\b/g, '\b')
.replace(/\\f/g, '\f')
.replace(/\\"/g, '"')
.replace(/\\'/g, '\'')
.replace(/\\&/g, '&');
}
downloadLog(asset) {
this.authFetch('/api/log?id=' + asset.id)
.then(res => res.json())
.then(res => {
let timestamp = res['timestamp'];
timestamp = timestamp.substr(0, timestamp.indexOf('.'));
let filename = res['monkey_label'].split(':').join('-') + ' - ' + timestamp + '.log';
let logContent = this.unescapeLog(res['log']);
download(logContent, filename, 'text/plain');
});
}
downloadLogRow(asset) {
downloadLogsRow(asset) {
return (
<tr>
<th>
Download Log
</th>
<td>
<a type='button'
className={asset.has_log ? 'btn btn-primary' : 'btn btn-primary disabled'}
onClick={() => this.downloadLog(asset)}>Download</a>
</td>
</tr>
<>
<tr>
<th>
Download Monkey Agent Log
</th>
<td>
<AgentLogDownloadButton url={'/api/log?id=' + asset.id}
variant={asset.has_log ? undefined : 'disabled'}/>
</td>
</tr>
{(asset['group'].includes('island')) &&
<tr>
<th>
Download Island Server Log
</th>
<td>
<IslandLogDownloadButton url={'/api/log/island/download'} />
</td>
</tr>
}
</>
);
}
@ -194,7 +183,7 @@ class PreviewPaneComponent extends AuthComponent {
{this.servicesRow(asset)}
{this.accessibleRow(asset)}
{this.forceKillRow(asset)}
{this.downloadLogRow(asset)}
{this.downloadLogsRow(asset)}
</tbody>
</table>
{this.exploitsTimeline(asset)}

View File

@ -1,12 +1,10 @@
import React from 'react';
import {Button, Col} from 'react-bootstrap';
import {Col} from 'react-bootstrap';
import AuthService from '../../services/AuthService';
import download from 'downloadjs';
import TelemetryLogTable from '../ui-components/TelemetryLogTable'
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import '../../styles/pages/TelemetryPage.scss';
import {faDownload} from '@fortawesome/free-solid-svg-icons/faDownload';
import {IslandLogDownloadButton} from '../ui-components/LogDownloadButtons';
class TelemetryPageComponent extends React.Component {
@ -19,16 +17,6 @@ class TelemetryPageComponent extends React.Component {
};
}
downloadIslandLog = () => {
this.authFetch('/api/log/island/download')
.then(res => res.json())
.then(res => {
let filename = 'Island_log';
let logContent = (res['log_file']);
download(logContent, filename, 'text/plain');
});
};
render() {
return (
<Col sm={{offset: 3, span: 9}} md={{offset: 3, span: 9}}
@ -42,10 +30,7 @@ class TelemetryPageComponent extends React.Component {
<h1 className="page-title"> Monkey Island Logs </h1>
<div className="text-center" style={{marginBottom: '20px'}}>
<p style={{'marginBottom': '2em', 'fontSize': '1.2em'}}> Download Monkey Island internal log file </p>
<Button bsSize="large" onClick={() => {
this.downloadIslandLog();
}}>
<FontAwesomeIcon icon={faDownload}/> Download </Button>
<IslandLogDownloadButton url={'/api/log/island/download'}/>
</div>
</div>
</Col>

View File

@ -0,0 +1,59 @@
import React from 'react';
import AuthComponent from '../AuthComponent';
import download from 'downloadjs';
import {Button} from 'react-bootstrap';
const authComponent = new AuthComponent({})
type Props = { url: string, filename: string, variant?: string}
export const AgentLogDownloadButton = ({ url, variant = 'primary'}: Props) => {
function unescapeLog(st) {
return st.substr(1, st.length - 2) // remove quotation marks on beginning and end of string.
.replace(/\\n/g, '\n')
.replace(/\\r/g, '\r')
.replace(/\\t/g, '\t')
.replace(/\\b/g, '\b')
.replace(/\\f/g, '\f')
.replace(/\\"/g, '"')
.replace(/\\'/g, '\'')
.replace(/\\&/g, '&');
}
function downloadAgentLog() {
authComponent.authFetch(url)
.then(res => res.json())
.then(res => {
let timestamp = res['timestamp'];
timestamp = timestamp.substr(0, timestamp.indexOf('.'));
let filename = res['monkey_label'].split(':').join('-') + ' - ' + timestamp + '.log';
let logContent = unescapeLog(res['log']);
download(logContent, filename, 'text/plain');
});
}
return (<Button variant={variant}
onClick={downloadAgentLog}>
Download Log
</Button>);
}
export const IslandLogDownloadButton = ({ url, variant = 'primary'}: Props) => {
function downloadIslandLog() {
authComponent.authFetch(url)
.then(res => res.json())
.then(res => {
let filename = 'Island_log';
let logContent = (res['log_file']);
download(logContent, filename, 'text/plain');
});
}
return (<Button variant={variant}
onClick={downloadIslandLog}>
Download Log
</Button>);
}