mirror of
https://github.com/securego/gosec.git
synced 2024-12-25 12:05:52 +00:00
Update the design of HTML report
This commit is contained in:
parent
e72f54ed40
commit
91dae7fdce
1 changed files with 118 additions and 114 deletions
|
@ -20,30 +20,26 @@ const templateContent = `
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Golang Security Checker</title>
|
<title>Golang Security Checker</title>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.2.1/css/bulma.min.css" integrity="sha256-DRcOKg8NK1KkSkcymcGmxOtS/lAn0lHWJXRa15gMHHk=" crossorigin="anonymous"/>
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.2/css/bulma.min.css" integrity="sha512-byErQdWdTqREz6DLAA9pCnLbdoGGhXfU6gm1c8bkf7F51JVmUBlayGe2A31VpXWQP+eiJ3ilTAZHCR3vmMyybA==" crossorigin="anonymous"/>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/styles/default.min.css" integrity="sha512-kZqGbhf9JTB4bVJ0G8HCkqmaPcRgo88F0dneK30yku5Y/dep7CZfCnNml2Je/sY4lBoqoksXz4PtVXS4GHSUzQ==" crossorigin="anonymous"/>
|
||||||
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/highlight.min.js" integrity="sha512-s+tOYYcC3Jybgr9mVsdAxsRYlGNq4mlAurOrfNuGMQ/SCofNPu92tjE7YRZCsdEtWL1yGkqk15fU/ark206YTg==" crossorigin="anonymous"></script>
|
||||||
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/languages/go.min.js" integrity="sha512-+UYV2NyyynWEQcZ4sMTKmeppyV331gqvMOGZ61/dqc89Tn1H40lF05ACd03RSD9EWwGutNwKj256mIR8waEJBQ==" crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react.min.js" integrity="sha256-cLWs9L+cjZg8CjGHMpJqUgKKouPlmoMP/0wIdPtaPGs=" crossorigin="anonymous"></script>
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react.min.js" integrity="sha256-cLWs9L+cjZg8CjGHMpJqUgKKouPlmoMP/0wIdPtaPGs=" crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-dom.min.js" integrity="sha256-JIW8lNqN2EtqC6ggNZYnAdKMJXRQfkPMvdRt+b0/Jxc=" crossorigin="anonymous"></script>
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-dom.min.js" integrity="sha256-JIW8lNqN2EtqC6ggNZYnAdKMJXRQfkPMvdRt+b0/Jxc=" crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.17.0/babel.min.js" integrity="sha256-1IWWLlCKFGFj/cjryvC7GDF5wRYnf9tSvNVVEj8Bm+o=" crossorigin="anonymous"></script>
|
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.17.0/babel.min.js" integrity="sha256-1IWWLlCKFGFj/cjryvC7GDF5wRYnf9tSvNVVEj8Bm+o=" crossorigin="anonymous"></script>
|
||||||
<style>
|
<style>
|
||||||
div.issue div.tag, div.panel-block input[type="checkbox"] {
|
.field-label {
|
||||||
margin-right: 0.5em;
|
min-width: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
label.disabled {
|
|
||||||
text-decoration: line-through;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav.panel select {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.break-word {
|
.break-word {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.help {
|
.help {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
.tag {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -58,49 +54,63 @@ const templateContent = `
|
||||||
<script type="text/babel">
|
<script type="text/babel">
|
||||||
var IssueTag = React.createClass({
|
var IssueTag = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
var level = "tag "
|
var level = "tag"
|
||||||
if (this.props.level === "HIGH") {
|
if (this.props.level === "HIGH") {
|
||||||
level += "is-danger";
|
level += " is-danger";
|
||||||
} else if (this.props.level === "MEDIUM") {
|
} else if (this.props.level === "MEDIUM") {
|
||||||
level += "is-warning";
|
level += " is-warning";
|
||||||
|
} else if (this.props.level === "LOW") {
|
||||||
|
level += " is-info";
|
||||||
}
|
}
|
||||||
|
level +=" is-rounded";
|
||||||
return (
|
return (
|
||||||
<div className={ level }>
|
<div className="control">
|
||||||
{ this.props.label }: { this.props.level }
|
<div className="tags has-addons">
|
||||||
|
<span className="tag is-dark is-rounded">{ this.props.label }</span>
|
||||||
|
<span className={ level }>{ this.props.level }</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
var Highlight = React.createClass({
|
||||||
|
componentDidMount: function(){
|
||||||
|
var current = ReactDOM.findDOMNode(this);
|
||||||
|
hljs.highlightElement(current);
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<pre className="go"><code >{ this.props.code }</code></pre>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
var Issue = React.createClass({
|
var Issue = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div className="issue box">
|
<div className="issue box">
|
||||||
<div className="is-pulled-right">
|
<div className="columns">
|
||||||
|
<div className="column is-three-quarters">
|
||||||
|
<strong className="break-word">{ this.props.data.file } (line { this.props.data.line })</strong>
|
||||||
|
<p>{ this.props.data.details }</p>
|
||||||
|
</div>
|
||||||
|
<div className="column is-one-quarter">
|
||||||
|
<div className="field is-grouped is-grouped-multiline">
|
||||||
<IssueTag label="Severity" level={ this.props.data.severity }/>
|
<IssueTag label="Severity" level={ this.props.data.severity }/>
|
||||||
<IssueTag label="Confidence" level={ this.props.data.confidence }/>
|
<IssueTag label="Confidence" level={ this.props.data.confidence }/>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
</div>
|
||||||
<strong className="break-word">
|
</div>
|
||||||
{ this.props.data.file } (line { this.props.data.line })
|
<div className="highlight">
|
||||||
</strong>
|
<Highlight code={ this.props.data.code }/>
|
||||||
<br/>
|
</div>
|
||||||
{ this.props.data.details }
|
|
||||||
</p>
|
|
||||||
<figure className="highlight">
|
|
||||||
<pre>
|
|
||||||
<code className="go">{ this.props.data.code }</code>
|
|
||||||
</pre>
|
|
||||||
</figure>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var Stats = React.createClass({
|
var Stats = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<p className="help">
|
<p className="help is-pulled-right">
|
||||||
Gosec {this.props.data.GosecVersion} scanned { this.props.data.Stats.files.toLocaleString() } files
|
Gosec {this.props.data.GosecVersion} scanned { this.props.data.Stats.files.toLocaleString() } files
|
||||||
with { this.props.data.Stats.lines.toLocaleString() } lines of code.
|
with { this.props.data.Stats.lines.toLocaleString() } lines of code.
|
||||||
{ this.props.data.Stats.nosec ? '\n' + this.props.data.Stats.nosec.toLocaleString() + ' false positives (nosec) have been waived.' : ''}
|
{ this.props.data.Stats.nosec ? '\n' + this.props.data.Stats.nosec.toLocaleString() + ' false positives (nosec) have been waived.' : ''}
|
||||||
|
@ -108,7 +118,6 @@ const templateContent = `
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var Issues = React.createClass({
|
var Issues = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
if (this.props.data.Stats.files === 0) {
|
if (this.props.data.Stats.files === 0) {
|
||||||
|
@ -118,7 +127,6 @@ const templateContent = `
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.data.Issues.length === 0) {
|
if (this.props.data.Issues.length === 0) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -129,7 +137,6 @@ const templateContent = `
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var issues = this.props.data.Issues
|
var issues = this.props.data.Issues
|
||||||
.filter(function(issue) {
|
.filter(function(issue) {
|
||||||
return this.props.severity.includes(issue.severity);
|
return this.props.severity.includes(issue.severity);
|
||||||
|
@ -147,7 +154,6 @@ const templateContent = `
|
||||||
.map(function(issue) {
|
.map(function(issue) {
|
||||||
return (<Issue data={issue} />);
|
return (<Issue data={issue} />);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
if (issues.length === 0) {
|
if (issues.length === 0) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -159,7 +165,6 @@ const templateContent = `
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="issues">
|
<div className="issues">
|
||||||
{ issues }
|
{ issues }
|
||||||
|
@ -184,38 +189,36 @@ const templateContent = `
|
||||||
var highDisabled = !this.props.available.includes(HIGH);
|
var highDisabled = !this.props.available.includes(HIGH);
|
||||||
var mediumDisabled = !this.props.available.includes(MEDIUM);
|
var mediumDisabled = !this.props.available.includes(MEDIUM);
|
||||||
var lowDisabled = !this.props.available.includes(LOW);
|
var lowDisabled = !this.props.available.includes(LOW);
|
||||||
var on = "", off = "disabled";
|
|
||||||
var baseClassName = "label checkbox ";
|
|
||||||
var highClassName = baseClassName + (highDisabled ? off : on);
|
|
||||||
var mediumClassName = baseClassName + (mediumDisabled ? off : on);
|
|
||||||
var lowClassName = baseClassName + (lowDisabled ? off : on);
|
|
||||||
return (
|
return (
|
||||||
<span>
|
<div className="field">
|
||||||
<label className={ highClassName }>
|
<div className="control">
|
||||||
|
<label className="checkbox" disabled={ highDisabled }>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={ this.props.selected.includes(HIGH) }
|
checked={ this.props.selected.includes(HIGH) }
|
||||||
disabled={ highDisabled }
|
disabled={ highDisabled }
|
||||||
onChange={ this.handleChange(HIGH) }/>
|
onChange={ this.handleChange(HIGH) }/> High
|
||||||
High
|
|
||||||
</label>
|
</label>
|
||||||
<label className={mediumClassName}>
|
</div>
|
||||||
|
<div className="control">
|
||||||
|
<label className="checkbox" disabled={ mediumDisabled }>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={ this.props.selected.includes(MEDIUM) }
|
checked={ this.props.selected.includes(MEDIUM) }
|
||||||
disabled={ mediumDisabled }
|
disabled={ mediumDisabled }
|
||||||
onChange={ this.handleChange(MEDIUM) }/>
|
onChange={ this.handleChange(MEDIUM) }/> Medium
|
||||||
Medium
|
|
||||||
</label>
|
</label>
|
||||||
<label className={lowClassName}>
|
</div>
|
||||||
|
<div className="control">
|
||||||
|
<label className="checkbox" disabled={ lowDisabled }>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={ this.props.selected.includes(LOW) }
|
checked={ this.props.selected.includes(LOW) }
|
||||||
disabled={ lowDisabled }
|
disabled={ lowDisabled }
|
||||||
onChange={ this.handleChange(LOW) }/>
|
onChange={ this.handleChange(LOW) }/> Low
|
||||||
Low
|
|
||||||
</label>
|
</label>
|
||||||
</span>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -245,38 +248,36 @@ const templateContent = `
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
return (
|
return (
|
||||||
<nav className="panel">
|
<nav className="panel">
|
||||||
<div className="panel-heading">
|
<div className="panel-heading">Filters</div>
|
||||||
Filters
|
<div className="panel-block">
|
||||||
|
<div className="field is-horizontal">
|
||||||
|
<div className="field-label is-normal">
|
||||||
|
<label className="label is-pulled-left">Severity</label>
|
||||||
|
</div>
|
||||||
|
<div className="field-body">
|
||||||
|
<LevelSelector selected={ this.props.severity } available={ this.props.allSeverities } onChange={ this.updateSeverity } />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="panel-block">
|
<div className="panel-block">
|
||||||
<strong>
|
<div className="field is-horizontal">
|
||||||
Severity
|
<div className="field-label is-normal">
|
||||||
</strong>
|
<label className="label is-pulled-left">Confidence</label>
|
||||||
|
</div>
|
||||||
|
<div className="field-body">
|
||||||
|
<LevelSelector selected={ this.props.confidence } available={ this.props.allConfidences } onChange={ this.updateConfidence } />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="panel-block">
|
<div className="panel-block">
|
||||||
<LevelSelector
|
<div className="field is-horizontal">
|
||||||
selected={ this.props.severity }
|
<div className="field-label is-normal">
|
||||||
available={ this.props.allSeverities }
|
<label className="label is-pulled-left">Issue type</label>
|
||||||
onChange={ this.updateSeverity } />
|
|
||||||
</div>
|
</div>
|
||||||
<div className="panel-block">
|
<div className="field-body">
|
||||||
<strong>
|
<div className="field">
|
||||||
Confidence
|
<div className="control">
|
||||||
</strong>
|
<div className="select is-fullwidth">
|
||||||
</div>
|
|
||||||
<div className="panel-block">
|
|
||||||
<LevelSelector
|
|
||||||
selected={ this.props.confidence }
|
|
||||||
available={ this.props.allConfidences }
|
|
||||||
onChange={ this.updateConfidence } />
|
|
||||||
</div>
|
|
||||||
<div className="panel-block">
|
|
||||||
<strong>
|
|
||||||
Issue Type
|
|
||||||
</strong>
|
|
||||||
</div>
|
|
||||||
<div className="panel-block">
|
|
||||||
<div className="select">
|
|
||||||
<select onChange={ this.updateIssueType }>
|
<select onChange={ this.updateIssueType }>
|
||||||
<option value="all" selected={ !this.props.issueType }>
|
<option value="all" selected={ !this.props.issueType }>
|
||||||
(all)
|
(all)
|
||||||
|
@ -285,6 +286,10 @@ const templateContent = `
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -390,7 +395,6 @@ const templateContent = `
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<IssueBrowser data={ data } />,
|
<IssueBrowser data={ data } />,
|
||||||
document.getElementById("content")
|
document.getElementById("content")
|
||||||
|
|
Loading…
Reference in a new issue