Skip to content

Commit

Permalink
Implementing example for go-sec pipeline.
Browse files Browse the repository at this point in the history
  • Loading branch information
andream16 committed Nov 8, 2024
1 parent 7e533e2 commit 3681410
Show file tree
Hide file tree
Showing 7 changed files with 505 additions and 0 deletions.
3 changes: 3 additions & 0 deletions examples/pipelines/golang-project/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SMITHY_INSTANCE_ID=8d719c1c-c569-4078-87b3-4951bd4012ee
SMITHY_LOG_LEVEL=debug
SMITHY_BACKEND_STORE_TYPE=local
39 changes: 39 additions & 0 deletions examples/pipelines/golang-project/enricher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

import (
"context"
"encoding/json"
"slices"

"github.com/go-errors/errors"

ocsf "github.com/smithy-security/smithy/sdk/gen/com/github/ocsf/ocsf_schema/v1"
)

type (
customAnnotationEnricher struct{}

CustomAnnotation struct {
Foo string `json:"foo"`
}
)

func (m *customAnnotationEnricher) Annotate(
ctx context.Context,
findings []*ocsf.VulnerabilityFinding,
) ([]*ocsf.VulnerabilityFinding, error) {
var newFindings = slices.Clone(findings)

for idx := range newFindings {
b, err := json.Marshal(CustomAnnotation{Foo: "bar"})
if err != nil {
return nil, errors.Errorf("could not json marshal custom annotation: %w", err)
}
newFindings[idx].Enrichments = append(newFindings[idx].Enrichments, &ocsf.Enrichment{
Name: "custom-annotation",
Value: string(b),
})
}

return newFindings, nil
}
99 changes: 99 additions & 0 deletions examples/pipelines/golang-project/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package main

import (
"context"
"fmt"
"log"
"os"
"time"

"github.com/smithy-security/smithy/sdk/component"
)

const (
repoPath = "govwa"
)

func main() {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()

if err := Main(ctx); err != nil {
log.Fatal(err)
}
}

func Main(ctx context.Context) error {
if err := migrate(); err != nil {
log.Fatalf("failed to migrate: %v", err)
}

defer func() {
if err := os.RemoveAll("smithy.db"); err != nil {
log.Printf("failed to remove sqlite db: %v\n", err)
}
}()

if err := os.Mkdir(repoPath, os.ModePerm); err != nil {
return fmt.Errorf("failed to create clone path %s: %v", repoPath, err)
}

defer func() {
if err := os.RemoveAll(repoPath); err != nil {
log.Printf("failed to remove clone path %s: %v\n", repoPath, err)
}
}()

gitClone, err := NewGitCloneTarget("https://github.com/0c34/govwa.git", repoPath)
if err != nil {
return fmt.Errorf("failed to create git clone target: %w", err)
}

goSec, err := NewGoSecScanner(repoPath)
if err != nil {
return fmt.Errorf("failed to create gosec scanner: %w", err)
}

var (
customAnnotation = &customAnnotationEnricher{}
jsonLogger = &jsonReporter{}
)

if err := component.RunTarget(
ctx,
gitClone,
component.RunnerWithComponentName("git-clone"),
); err != nil {
return fmt.Errorf("target failed: %w", err)
}

if err := component.RunScanner(
ctx,
goSec,
component.RunnerWithComponentName("go-sec"),
); err != nil {
return fmt.Errorf("scanner failed: %w", err)
}

if err := component.RunEnricher(
ctx,
customAnnotation,
component.RunnerWithComponentName("custom-annotation"),
); err != nil {
return fmt.Errorf("enricher failed: %w", err)
}

if err := component.RunReporter(
ctx,
jsonLogger,
component.RunnerWithComponentName("json-logger"),
); err != nil {
return fmt.Errorf("reporter failed: %w", err)
}

return nil
}

func ptr[T any](v T) *T {
return &v
}
32 changes: 32 additions & 0 deletions examples/pipelines/golang-project/migrate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

import (
"database/sql"
"fmt"
)

func migrate() error {
db, err := sql.Open("sqlite3", "smithy.db")
if err != nil {
return fmt.Errorf("could not open sqlite db: %w", err)
}

stmt, err := db.Prepare(`
CREATE TABLE IF NOT EXISTS finding (
id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
instance_id UUID NOT NULL UNIQUE,
findings TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
`)
if err != nil {
return fmt.Errorf("could not prepare statement for creating table: %w", err)
}

if _, err := stmt.Exec(); err != nil {
return fmt.Errorf("could not create table: %w", err)
}

return stmt.Close()
}
30 changes: 30 additions & 0 deletions examples/pipelines/golang-project/reporter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"context"
"log/slog"

"github.com/go-errors/errors"
"google.golang.org/protobuf/encoding/protojson"

"github.com/smithy-security/smithy/sdk/component"
ocsf "github.com/smithy-security/smithy/sdk/gen/com/github/ocsf/ocsf_schema/v1"
)

type jsonReporter struct{}

func (j jsonReporter) Report(
ctx context.Context,
findings []*ocsf.VulnerabilityFinding,
) error {
logger := component.LoggerFromContext(ctx)
for _, finding := range findings {
b, err := protojson.Marshal(finding)
if err != nil {
return errors.Errorf("could not json marshal finding: %w", err)
}
logger.Info("found finding", slog.String("finding", string(b)))
}

return nil
}
Loading

0 comments on commit 3681410

Please sign in to comment.