Skip to content

Commit

Permalink
Merge pull request #102 from scan-io-git/japroc/move-weburl-logic-fro…
Browse files Browse the repository at this point in the history
…m-template

#96: move weburl logic from template
  • Loading branch information
japroc authored Oct 16, 2024
2 parents c2fec61 + edf44ca commit 217ab1e
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 30 deletions.
5 changes: 2 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,5 @@ __debug_bin*
# reports
*.sarif
*.json
scanio-report.html
snyk-to-html-report.html
report.html
*report.html
*results.html
54 changes: 47 additions & 7 deletions cmd/to-html.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package cmd

import (
"html/template"
"os"
"path/filepath"
"strconv"
"time"

"github.com/owenrumney/go-sarif/v2/sarif"
"github.com/spf13/cobra"

"github.com/scan-io-git/scan-io/internal/git"
Expand Down Expand Up @@ -36,11 +37,16 @@ type ReportMetadata struct {
Time time.Time
SourceFolder string
SeverityInfo map[string]int
WebURL string
BranchURL string
CommitURL string
}

var execExampleToHTML = ` # Generate html report for semgrep sarif output
scanio to-html --input /tmp/juice-shop/semgrep.sarif --output /tmp/juice-shop/semgrep.html --source /tmp/juice-shop`

// generic function to convert git URL to web URL
// will implement vcs specific logic here if needed
func gitURLtoWebURL(gitURL string) string {
u, err := vcsurl.Parse(gitURL)
if err != nil {
Expand All @@ -49,6 +55,16 @@ func gitURLtoWebURL(gitURL string) string {
return u.HTTPRepoLink
}

// this function will implement vcs specific logic to generate web URL to branch
func buildWebURLToBranch(webURL, branch string) string {
return filepath.Join(webURL, "tree", branch)
}

// this function will implement vcs specific logic to generate web URL to commit
func buildWebURLToCommit(webURL, commit string) string {
return filepath.Join(webURL, "tree", commit)
}

// toHtmlCmd represents the toHtml command
var toHtmlCmd = &cobra.Command{
Use: "to-html -i /path/to/input/report.sarif -o /path/to/output/report.html -s /path/to/source/folder",
Expand All @@ -64,18 +80,39 @@ var toHtmlCmd = &cobra.Command{
return errors.NewCommandError(allToHTMLOptions, nil, err, 1)
}

// enrich sarif report with additional properties and remove duplicates from dataflow results
sarifReport.EnrichResultsProperties()
sarifReport.SortResultsByLevel()
sarifReport.RemoveDataflowDuplicates()

// collect metadata for the report template
repositoryMetadata, err := git.CollectRepositoryMetadata(allToHTMLOptions.SourceFolder)
if err != nil {
logger.Debug("can't collect repository metadata", "err", err)
}
logger.Debug("repositoryMetadata", "BranchName", *repositoryMetadata.BranchName, "CommitHash", *repositoryMetadata.CommitHash, "RepositoryFullName", *repositoryMetadata.RepositoryFullName, "Subfolder", repositoryMetadata.Subfolder, "RepoRootFolder", repositoryMetadata.RepoRootFolder)

webURL := gitURLtoWebURL(*repositoryMetadata.RepositoryFullName)

// a callback function to generate web url for location
// we need it because neither sarif nor git modules know anything about vcs web URL structures.
// so we should implement vcs scpecific logic here
// for beginning I started with generic/github implementation
locationWebURLCallback := func(location *sarif.Location) string {
// verify that location.PhysicalLocation.ArtifactLocation.Properties["URI"] is not nil
if location.PhysicalLocation.ArtifactLocation.Properties["URI"] == nil {
return ""
}
locationWebURL := filepath.Join(webURL, "blob", *repositoryMetadata.CommitHash, location.PhysicalLocation.ArtifactLocation.Properties["URI"].(string))
if location.PhysicalLocation.Region.StartLine != nil {
locationWebURL += "#L" + strconv.Itoa(*location.PhysicalLocation.Region.StartLine)
}
return locationWebURL
}

// enrich sarif report with additional properties and remove duplicates from dataflow results
sarifReport.EnrichResultsTitleProperty()
sarifReport.EnrichResultsCodeFlowProperty(locationWebURLCallback)
sarifReport.EnrichResultsLevelProperty()
sarifReport.EnrichResultsLocationURIProperty(locationWebURLCallback)
sarifReport.SortResultsByLevel()
sarifReport.RemoveDataflowDuplicates()

toolMetadata, err := sarifReport.ExtractToolNameAndVersion()
if err != nil {
return errors.NewCommandError(allToHTMLOptions, nil, err, 1)
Expand All @@ -96,6 +133,9 @@ var toHtmlCmd = &cobra.Command{
Time: time.Now().UTC(),
SourceFolder: metadataSourceFolder,
SeverityInfo: severityInfo,
WebURL: webURL,
BranchURL: buildWebURLToBranch(webURL, *repositoryMetadata.BranchName),
CommitURL: buildWebURLToCommit(webURL, *repositoryMetadata.CommitHash),
}
logger.Debug("metadata", "metadata", *metadata)

Expand All @@ -109,7 +149,7 @@ var toHtmlCmd = &cobra.Command{
return errors.NewCommandError(allToHTMLOptions, nil, err, 1)
}

tmpl, err := scaniotemplate.NewTemplate(templateFile, scaniotemplate.WithFuncs(template.FuncMap{"gitURLtoWebURL": gitURLtoWebURL}))
tmpl, err := scaniotemplate.NewTemplate(templateFile)
if err != nil {
return errors.NewCommandError(allToHTMLOptions, nil, err, 1)
}
Expand Down
23 changes: 12 additions & 11 deletions internal/sarif/sarif.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ func (r Report) readLineFromFile(loc *sarif.PhysicalLocation) (string, error) {
}

// EnrichResultsCodeFlowProperty function enriches code flow location properties with source code and URI values
func (r Report) EnrichResultsCodeFlowProperty() {
func (r Report) EnrichResultsCodeFlowProperty(locationWebURLCallback func(artifactLocation *sarif.Location) string) {

for _, result := range r.Runs[0].Results {

Expand All @@ -254,6 +254,11 @@ func (r Report) EnrichResultsCodeFlowProperty() {
r.logger.Debug("can't read source file", "err", err)
continue
}

if location.Location.Properties == nil {
location.Location.Properties = make(map[string]interface{})
}
location.Location.Properties["WebURL"] = locationWebURLCallback(location.Location)
}
}
}
Expand Down Expand Up @@ -288,7 +293,7 @@ func (r Report) EnrichResultsLevelProperty() {
}
}

func (r Report) EnrichResultsLocationURIProperty() {
func (r Report) EnrichResultsLocationURIProperty(locationWebURLCallback func(artifactLocation *sarif.Location) string) {
for _, result := range r.Runs[0].Results {
// if result location length is at least 1
if len(result.Locations) > 0 {
Expand All @@ -310,20 +315,16 @@ func (r Report) EnrichResultsLocationURIProperty() {
artifactLocation.Properties["URI"] = artifactLocation.Properties["URI"].(string)[1:]
}
}

if location.Properties == nil {
location.Properties = make(map[string]interface{})
}
location.Properties["WebURL"] = locationWebURLCallback(location)
}
}
}
}

// EnrichResultsProperties function enriches sarif results properties with title, description, location and level values
// for better html report representation
func (r Report) EnrichResultsProperties() {
r.EnrichResultsTitleProperty()
r.EnrichResultsCodeFlowProperty()
r.EnrichResultsLevelProperty()
r.EnrichResultsLocationURIProperty()
}

// SortResultsByLevel function sorts sarif results by level
func (r Report) SortResultsByLevel() {

Expand Down
2 changes: 1 addition & 1 deletion scripts/rules/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
gitpython==3.1.41
pyyaml==6.0
pyyaml==5.3.1
colorama==0.4.6
tqdm==4.65.0
21 changes: 13 additions & 8 deletions templates/tohtml/report.html
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,9 @@
{{ $repo := .Metadata.RepositoryMetadata.RepositoryFullName }}
{{ $branch := .Metadata.RepositoryMetadata.BranchName }}
{{ $commit := .Metadata.RepositoryMetadata.CommitHash }}

{{ $webURL := gitURLtoWebURL $repo }}
{{ $branchURL := .Metadata.BranchURL }}
{{ $commitURL := .Metadata.CommitURL }}
{{ $webURL := .Metadata.WebURL }}

<body>
<!-- header goes here -->
Expand Down Expand Up @@ -265,8 +266,8 @@
<p><b>Tool:</b> {{ .Metadata.ToolMetadata.Name }} {{if .Metadata.ToolMetadata.Version}}{{ .Metadata.ToolMetadata.Version }}{{end}}</p>
{{if .Metadata.SourceFolder}}<p><b>Source:</b> {{ .Metadata.SourceFolder }}</p>{{end}}
{{if $repo}}<p><b>Repository:</b> <a href="{{ $webURL }}">{{ $repo }}</a></p>{{end}}
{{if $branch}}<p><b>Branch:</b> {{if $webURL}}<a href="{{- $webURL -}}/tree/{{- $branch -}}">{{ $branch }}</a>{{else}}{{ $branch }}{{end}} </p>{{end}}
{{if $commit}}<p><b>Commit:</b> {{if $webURL}}<a href="{{- $webURL -}}/tree/{{- $commit -}}">{{ $commit }}</a>{{else}}{{ $commit }}{{end}} </p>{{end}}
{{if $branch}}<p><b>Branch:</b> {{if $branchURL}}<a href="{{- $branchURL -}}">{{ $branch }}</a>{{else}}{{ $branch }}{{end}} </p>{{end}}
{{if $commit}}<p><b>Commit:</b> {{if $commitURL}}<a href="{{- $commitURL -}}">{{ $commit }}</a>{{else}}{{ $commit }}{{end}} </p>{{end}}
{{if .Metadata.RepositoryMetadata.Subfolder}}<p><b>Subfolder:</b> {{ .Metadata.RepositoryMetadata.Subfolder }} </p>{{end}}
</div>
</div>
Expand All @@ -293,7 +294,8 @@ <h2 class="issue-card__title">{{index .Properties "Title"}}</h2>
{{ $location := index .Locations 0}}
{{ $locationURI := index $location.PhysicalLocation.ArtifactLocation.Properties "URI"}}
{{ $locationStartLine := $location.PhysicalLocation.Region.StartLine }}
<div class="issue-card__body__metadata__location">Location: <strong>{{if (and $webURL $commit)}}<a href="{{- $webURL -}}/blob/{{- $commit -}}/{{- $locationURI -}}#L{{- $locationStartLine -}}">{{$locationURI}} (line : {{$locationStartLine}})</a> {{else}} {{$locationURI}} (line : {{$locationStartLine}}){{end}}</strong></div>
{{ $locationWebURL := index $location.Properties "WebURL"}}
<div class="issue-card__body__metadata__location">Location: <strong>{{if $locationWebURL}}<a href="{{- $locationWebURL -}}">{{$locationURI}} (line : {{$locationStartLine}})</a> {{else}} {{$locationURI}} (line : {{$locationStartLine}}){{end}}</strong></div>
</div>
<div class="issue-card__body__dataflows">
<header class="card__body__dataflows__header">
Expand Down Expand Up @@ -331,15 +333,18 @@ <h2 class="issue-card__title">{{index .Properties "Title"}}</h2>
{{ $endLine := index .Location.PhysicalLocation.Region.Properties "EndLine" }}
{{ $startColumn := index .Location.PhysicalLocation.Region.Properties "StartColumn" }}
{{ $endColumn := index .Location.PhysicalLocation.Region.Properties "EndColumn" }}
{{ $locationWebURL := index $location.Properties "WebURL"}}
{{/* */}}

<div class="issue-card__body__dataflows__codeline">

{{if (and $webURL $commit)}}
<span class="issue-card__body__dataflows__codeline__linecol"><a href="{{- $webURL -}}/blob/{{- $commit -}}/{{- $curUri -}}#L{{- $startLine -}}">{{$startLine}}:{{$startColumn}}</a></span>
<span class="issue-card__body__dataflows__codeline__linecol">
{{if $locationWebURL}}
<a href="{{- $locationWebURL -}}">{{$startLine}}:{{$startColumn}}</a>
{{else}}
<span class="issue-card__body__dataflows__codeline__linecol">{{$startLine}}:{{$startColumn}}</span>
{{$startLine}}:{{$startColumn}}
{{end}}
</span>

{{if $code}}
<div class="issue-card__body__dataflows__codeline__linecol__code">
Expand Down

0 comments on commit 217ab1e

Please sign in to comment.