gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/github.com/securego/gosec/output/template.go (about)

     1  // (c) Copyright 2016 Hewlett Packard Enterprise Development LP
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package output
    16  
    17  const html = `
    18  <!doctype html>
    19  <html lang="en">
    20  <head>
    21    <meta charset="utf-8">
    22    <title>Go AST Scanner</title>
    23    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.2.1/css/bulma.min.css" integrity="sha256-DRcOKg8NK1KkSkcymcGmxOtS/lAn0lHWJXRa15gMHHk=" crossorigin="anonymous"/>
    24    <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>
    25    <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>
    26    <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>
    27    <style>
    28      div.issue div.tag, div.panel-block input[type="checkbox"] {
    29        margin-right: 0.5em;
    30      }
    31      
    32      label.disabled {
    33        text-decoration: line-through;
    34      }
    35      
    36      nav.panel select {
    37        width: 100%;
    38      }
    39  
    40      .break-word {
    41        word-wrap: break-word;
    42      }
    43    </style>
    44  </head>
    45  <body>
    46    <section class="section">
    47      <div class="container">
    48        <div id="content"></div>
    49      </div>
    50    </section>
    51    <script>
    52      var data = {{ . }};
    53    </script>
    54    <script type="text/babel">
    55      var IssueTag = React.createClass({
    56        render: function() {
    57          var level = ""
    58          if (this.props.level === "HIGH") {
    59            level = "is-danger";
    60          }
    61          if (this.props.level === "MEDIUM") {
    62            level = "is-warning";
    63          }
    64          return (
    65            <div className={ "tag " + level }>
    66              { this.props.label }: { this.props.level }
    67            </div>
    68          );
    69        }
    70      });
    71      
    72      var Issue = React.createClass({
    73        render: function() {
    74          return (
    75            <div className="issue box">
    76              <div className="is-pulled-right">
    77                <IssueTag label="Severity" level={ this.props.data.severity }/>
    78                <IssueTag label="Confidence" level={ this.props.data.confidence }/>
    79              </div>
    80              <p>
    81                <strong className="break-word">
    82                  { this.props.data.file } (line { this.props.data.line })
    83                </strong>
    84                <br/>
    85                { this.props.data.details }
    86              </p>
    87              <figure className="highlight">
    88                <pre>
    89                  <code className="golang hljs">
    90                    { this.props.data.code }
    91                  </code>
    92                </pre>
    93              </figure>
    94            </div>
    95          );
    96        }
    97      });
    98      
    99      var Stats = React.createClass({
   100        render: function() {
   101          return (
   102            <p className="help">
   103              Scanned { this.props.data.metrics.files.toLocaleString() } files
   104              with { this.props.data.metrics.lines.toLocaleString() } lines of code.
   105            </p>
   106          );
   107        }
   108      });
   109      
   110      var Issues = React.createClass({
   111        render: function() {
   112          if (this.props.data.metrics.files === 0) {
   113            return (
   114              <div className="notification">
   115                No source files found. Do you even Go?
   116              </div>
   117            );
   118          }
   119      
   120          if (this.props.data.issues.length === 0) {
   121            return (
   122              <div>
   123                <div className="notification">
   124                  Awesome! No issues found!
   125                </div>
   126                <Stats data={ this.props.data } />
   127              </div>
   128            );
   129          }
   130      
   131          var issues = this.props.data.issues
   132            .filter(function(issue) {
   133              return this.props.severity.includes(issue.severity);
   134            }.bind(this))
   135            .filter(function(issue) {
   136              return this.props.confidence.includes(issue.confidence);
   137            }.bind(this))
   138            .filter(function(issue) {
   139              if (this.props.issueType) {
   140                return issue.details.toLowerCase().startsWith(this.props.issueType.toLowerCase());
   141              } else {
   142                return true
   143              }
   144            }.bind(this))
   145            .map(function(issue) {
   146              return (<Issue data={issue} />);
   147            }.bind(this));
   148      
   149          if (issues.length === 0) {
   150            return (
   151              <div>
   152                <div className="notification">
   153                  No issues matched given filters
   154                  (of total { this.props.data.issues.length } issues).
   155                </div>
   156                <Stats data={ this.props.data } />
   157              </div>
   158            );
   159          }
   160      
   161          return (
   162            <div className="issues">
   163              { issues }
   164              <Stats data={ this.props.data } />
   165            </div>
   166          );
   167        }
   168      });
   169      
   170      var LevelSelector = React.createClass({
   171        handleChange: function(level) {
   172          return function(e) {
   173            var updated = this.props.selected
   174              .filter(function(item) { return item != level; });
   175            if (e.target.checked) {
   176              updated.push(level);
   177            }
   178            this.props.onChange(updated);
   179          }.bind(this);
   180        },
   181        render: function() {
   182          var highDisabled = !this.props.available.includes("HIGH");
   183          var mediumDisabled = !this.props.available.includes("MEDIUM");
   184          var lowDisabled = !this.props.available.includes("LOW");
   185       
   186          return (
   187            <span>
   188              <label className={"label checkbox " + (highDisabled ? "disabled" : "") }>
   189                <input
   190                  type="checkbox"
   191                  checked={ this.props.selected.includes("HIGH") }
   192                  disabled={ highDisabled }
   193                  onChange={ this.handleChange("HIGH") }/>
   194                High
   195              </label>
   196              <label className={"label checkbox " + (mediumDisabled ? "disabled" : "") }>
   197                <input
   198                  type="checkbox"
   199                  checked={ this.props.selected.includes("MEDIUM") }
   200                  disabled={ mediumDisabled }
   201                  onChange={ this.handleChange("MEDIUM") }/>
   202                Medium
   203              </label>
   204              <label className={"label checkbox " + (lowDisabled ? "disabled" : "") }>
   205                <input
   206                  type="checkbox"
   207                  checked={ this.props.selected.includes("LOW") }
   208                  disabled={ lowDisabled }
   209                  onChange={ this.handleChange("LOW") }/>
   210                Low
   211              </label>
   212            </span>
   213          );
   214        }
   215      });
   216      
   217      var Navigation = React.createClass({
   218        updateSeverity: function(vals) {
   219          this.props.onSeverity(vals);
   220        },
   221        updateConfidence: function(vals) {
   222          this.props.onConfidence(vals);
   223        },
   224        updateIssueType: function(e) {
   225          if (e.target.value == "all") {
   226            this.props.onIssueType(null);
   227          } else {
   228            this.props.onIssueType(e.target.value);
   229          }
   230        },
   231        render: function() {
   232          var issueTypes = this.props.allIssueTypes
   233            .map(function(it) {
   234              return (
   235                <option value={ it } selected={ this.props.issueType == it }>
   236                  { it }
   237                </option>
   238              );
   239            }.bind(this));
   240      
   241          return (
   242            <nav className="panel">
   243              <div className="panel-heading">
   244                Filters
   245              </div>
   246              <div className="panel-block">
   247                <strong>
   248                  Severity
   249                </strong>
   250              </div>
   251              <div className="panel-block">
   252                <LevelSelector 
   253                  selected={ this.props.severity }
   254                  available={ this.props.allSeverities }
   255                  onChange={ this.updateSeverity } />
   256              </div>
   257              <div className="panel-block">
   258                <strong>
   259                  Confidence
   260                </strong>
   261              </div>
   262              <div className="panel-block">
   263                <LevelSelector
   264                  selected={ this.props.confidence }
   265                  available={ this.props.allConfidences }
   266                  onChange={ this.updateConfidence } />
   267              </div>
   268              <div className="panel-block">
   269                <strong>
   270                  Issue Type
   271                </strong>
   272              </div>
   273              <div className="panel-block">
   274                <select onChange={ this.updateIssueType }>
   275                  <option value="all" selected={ !this.props.issueType }>
   276                    (all)
   277                  </option>
   278                  { issueTypes }
   279                </select>
   280              </div>
   281            </nav>
   282          );
   283        }
   284      });
   285      
   286      var IssueBrowser = React.createClass({
   287        getInitialState: function() {
   288          return {};
   289        },
   290        componentWillMount: function() {
   291          this.updateIssues(this.props.data);
   292        },
   293        handleSeverity: function(val) {
   294          this.updateIssueTypes(this.props.data.issues, val, this.state.confidence);
   295          this.setState({severity: val});
   296        },
   297        handleConfidence: function(val) {
   298          this.updateIssueTypes(this.props.data.issues, this.state.severity, val);
   299          this.setState({confidence: val});
   300        },
   301        handleIssueType: function(val) {
   302          this.setState({issueType: val});
   303        },
   304        updateIssues: function(data) {
   305          if (!data) {
   306            this.setState({data: data});
   307            return;
   308          }
   309      
   310          var allSeverities = data.issues
   311            .map(function(issue) {
   312              return issue.severity
   313            })
   314            .sort()
   315            .filter(function(item, pos, ary) {
   316              return !pos || item != ary[pos - 1];
   317            });
   318      
   319          var allConfidences = data.issues
   320            .map(function(issue) {
   321              return issue.confidence
   322            })
   323            .sort()
   324            .filter(function(item, pos, ary) {
   325              return !pos || item != ary[pos - 1];
   326            });
   327      
   328          var selectedSeverities = allSeverities;
   329          var selectedConfidences = allConfidences;
   330      
   331          this.updateIssueTypes(data.issues, selectedSeverities, selectedConfidences);
   332      
   333          this.setState({
   334            data: data,
   335            severity: selectedSeverities,
   336            allSeverities: allSeverities,
   337            confidence: selectedConfidences,
   338            allConfidences: allConfidences,
   339            issueType: null
   340          });
   341        },
   342        updateIssueTypes: function(issues, severities, confidences) {
   343          var allTypes = issues
   344            .filter(function(issue) {
   345              return severities.includes(issue.severity);
   346            })
   347            .filter(function(issue) {
   348              return confidences.includes(issue.confidence);
   349            })
   350            .map(function(issue) {
   351              return issue.details;
   352            })
   353            .sort()
   354            .filter(function(item, pos, ary) {
   355              return !pos || item != ary[pos - 1];
   356            });
   357      
   358          if (this.state.issueType && !allTypes.includes(this.state.issueType)) {
   359            this.setState({issueType: null});
   360          }
   361      
   362          this.setState({allIssueTypes: allTypes});
   363        },
   364        render: function() {
   365          return (
   366            <div className="content">
   367              <div className="columns">
   368                <div className="column is-one-quarter">
   369                  <Navigation
   370                    severity={ this.state.severity } 
   371                    confidence={ this.state.confidence }
   372                    issueType={ this.state.issueType }
   373                    allSeverities={ this.state.allSeverities } 
   374                    allConfidences={ this.state.allConfidences }
   375                    allIssueTypes={ this.state.allIssueTypes }
   376                    onSeverity={ this.handleSeverity } 
   377                    onConfidence={ this.handleConfidence } 
   378                    onIssueType={ this.handleIssueType }
   379                  />
   380                </div>
   381                <div className="column is-three-quarters">
   382                  <Issues
   383                    data={ this.props.data }
   384                    severity={ this.state.severity }
   385                    confidence={ this.state.confidence }
   386                    issueType={ this.state.issueType }
   387                  />
   388                </div>
   389              </div>
   390            </div>
   391          );
   392        }
   393      });
   394      
   395      ReactDOM.render(
   396        <IssueBrowser data={ data } />,
   397        document.getElementById("content")
   398      );
   399    </script>
   400  </body>
   401  </html>`