Skip to content

Commit

Permalink
add fingerprinting to scan command
Browse files Browse the repository at this point in the history
  • Loading branch information
emilwareus committed Oct 6, 2023
1 parent c878bd0 commit 3d3f0e7
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 18 deletions.
7 changes: 3 additions & 4 deletions internal/cmd/files/fingerprint/fingerprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ import (
var exclusions = file.DefaultExclusionsFingerprint()

const (
ExclusionFlag = "exclusion-fingerprint"
OutputFileName = ".debricked.fingerprints.wfp"
ExclusionFlag = "exclusion-fingerprint"
)

func NewFingerprintCmd(fingerprinter file.IFingerprint) *cobra.Command {
cmd := &cobra.Command{
Use: "fingerprint [path]",
Short: "Fingerprint files for identification in a given path and writes it to " + OutputFileName,
Short: "Fingerprint files for identification in a given path and writes it to " + file.OutputFileNameFingerprints,
Long: `Fingerprint files for identification in a given path.
This hashes all files and matches them against the Debricked knowledge base.`,
PreRun: func(cmd *cobra.Command, _ []string) {
Expand Down Expand Up @@ -65,7 +64,7 @@ func RunE(f file.IFingerprint) func(_ *cobra.Command, args []string) error {
return err
}

output.ToFile(OutputFileName)
output.ToFile(file.OutputFileNameFingerprints)

Check failure on line 67 in internal/cmd/files/fingerprint/fingerprint.go

View workflow job for this annotation

GitHub Actions / Lint

Error return value of `output.ToFile` is not checked (errcheck)

return nil
}
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/files/fingerprint/fingerprint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestNewFingerprintCmd(t *testing.T) {

func TestRunE(t *testing.T) {
defer func() {
os.Remove(OutputFileName)
os.Remove(file.OutputFileNameFingerprints)
}()
fingerprintMock := testdata.NewFingerprintMock()
runE := RunE(fingerprintMock)
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/root/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func TestNewRootCmd(t *testing.T) {
}
}
assert.Truef(t, match, "failed to assert that flag was present: "+AccessTokenFlag)
assert.Len(t, viperKeys, 13)
assert.Len(t, viperKeys, 14)
}

func TestPreRun(t *testing.T) {
Expand Down
5 changes: 4 additions & 1 deletion internal/cmd/scan/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var repositoryUrl string
var integrationName string
var exclusions = file.DefaultExclusions()
var noResolve bool
var noFingerprint bool
var passOnDowntime bool

const (
Expand All @@ -31,6 +32,7 @@ const (
IntegrationFlag = "integration"
ExclusionFlag = "exclusion"
NoResolveFlag = "no-resolve"
NoFingerprintFlag = "no-fingerprint"
PassOnTimeOut = "pass-on-timeout"
)

Expand Down Expand Up @@ -82,7 +84,7 @@ $ debricked scan . `+exampleFlags)
cmd.Flags().BoolVarP(&passOnDowntime, PassOnTimeOut, "p", false, "pass scan if there is a service access timeout")
cmd.Flags().BoolVar(&noResolve, NoResolveFlag, false, `disables resolution of manifest files that lack lock files. Resolving manifest files enables more accurate dependency scanning since the whole dependency tree will be analysed.
For example, if there is a "go.mod" in the target path, its dependencies are going to get resolved onto a lock file, and latter scanned.`)

cmd.Flags().BoolVar(&noFingerprint, NoFingerprintFlag, false, "disables fingerprinting for undeclared component identification. Can be run as a standalone command with more granular options.")
viper.MustBindEnv(RepositoryFlag)
viper.MustBindEnv(CommitFlag)
viper.MustBindEnv(BranchFlag)
Expand All @@ -103,6 +105,7 @@ func RunE(s *scan.IScanner) func(_ *cobra.Command, args []string) error {
options := scan.DebrickedOptions{
Path: path,
Resolve: !viper.GetBool(NoResolveFlag),
Fingerprint: !viper.GetBool(NoFingerprintFlag),
Exclusions: viper.GetStringSlice(ExclusionFlag),
RepositoryName: viper.GetString(RepositoryFlag),
CommitName: viper.GetString(CommitFlag),
Expand Down
4 changes: 4 additions & 0 deletions internal/file/fingerprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ var ECLUDED_FILES = []string{
"thumbs.db", "babel.config.js", "license.txt", "license.md", "copying.lib", "makefile",
}

const (
OutputFileNameFingerprints = ".debricked.fingerprints.wfp"
)

func isExcludedFile(filename string) bool {

filenameLower := strings.ToLower(filename)
Expand Down
22 changes: 17 additions & 5 deletions internal/scan/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,18 @@ type IScanner interface {
type IOptions interface{}

type DebrickedScanner struct {
client *client.IDebClient
finder file.IFinder
uploader *upload.IUploader
ciService ci.IService
resolver resolution.IResolver
client *client.IDebClient
finder file.IFinder
uploader *upload.IUploader
ciService ci.IService
resolver resolution.IResolver
fingerprint file.IFingerprint
}

type DebrickedOptions struct {
Path string
Resolve bool
Fingerprint bool
Exclusions []string
RepositoryName string
CommitName string
Expand All @@ -55,13 +57,15 @@ func NewDebrickedScanner(
uploader upload.IUploader,
ciService ci.IService,
resolver resolution.IResolver,
fingerprint file.IFingerprint,
) *DebrickedScanner {
return &DebrickedScanner{
c,
finder,
&uploader,
ciService,
resolver,
fingerprint,
}
}

Expand Down Expand Up @@ -125,6 +129,14 @@ func (dScanner *DebrickedScanner) scan(options DebrickedOptions, gitMetaObject g
}
}

if options.Fingerprint {
fingerprints, err := dScanner.fingerprint.FingerprintFiles(options.Path, file.DefaultExclusionsFingerprint())
if err != nil {
return nil, err
}
fingerprints.ToFile(file.OutputFileNameFingerprints)

Check failure on line 137 in internal/scan/scanner.go

View workflow job for this annotation

GitHub Actions / Lint

Error return value of `fingerprints.ToFile` is not checked (errcheck)
}

fileGroups, err := dScanner.finder.GetGroups(options.Path, options.Exclusions, false, file.StrictAll)
if err != nil {
return nil, err
Expand Down
52 changes: 46 additions & 6 deletions internal/scan/scanner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ func TestNewDebrickedScanner(t *testing.T) {
var finder file.IFinder
var uploader upload.IUploader
var resolver resolution.IResolver
s := NewDebrickedScanner(&debClient, finder, uploader, cis, resolver)
var fingerprint file.IFingerprint
s := NewDebrickedScanner(&debClient, finder, uploader, cis, resolver, fingerprint)

assert.NotNil(t, s)
}
Expand Down Expand Up @@ -120,7 +121,7 @@ func TestScan(t *testing.T) {

func TestScanFailingMetaObject(t *testing.T) {
var debClient client.IDebClient = testdata.NewDebClientMock()
scanner := NewDebrickedScanner(&debClient, nil, nil, ciService, nil)
scanner := NewDebrickedScanner(&debClient, nil, nil, ciService, nil, nil)
cwd, _ := os.Getwd()
path := testdataNpm
opts := DebrickedOptions{
Expand Down Expand Up @@ -167,7 +168,7 @@ func TestScanFailingNoFiles(t *testing.T) {

func TestScanBadOpts(t *testing.T) {
var c client.IDebClient
scanner := NewDebrickedScanner(&c, nil, nil, nil, nil)
scanner := NewDebrickedScanner(&c, nil, nil, nil, nil, nil)
var opts IOptions

err := scanner.Scan(opts)
Expand Down Expand Up @@ -226,7 +227,7 @@ func TestScanEmptyResult(t *testing.T) {

func TestScanInCiWithPathSet(t *testing.T) {
var debClient client.IDebClient = testdata.NewDebClientMock()
scanner := NewDebrickedScanner(&debClient, nil, nil, ciService, nil)
scanner := NewDebrickedScanner(&debClient, nil, nil, ciService, nil, nil)
cwd, _ := os.Getwd()
defer resetWd(t, cwd)
path := testdataNpm
Expand Down Expand Up @@ -508,7 +509,7 @@ func TestScanServiceDowntime(t *testing.T) {

var ciService ci.IService = ci.NewService(nil)

scanner := NewDebrickedScanner(&debClient, finder, nil, ciService, nil)
scanner := NewDebrickedScanner(&debClient, finder, nil, ciService, nil, nil)

path := testdataNpm
repositoryName := path
Expand Down Expand Up @@ -606,7 +607,7 @@ func makeScanner(clientMock *testdata.DebClientMock, resolverMock *resolveTestda

var cis ci.IService = ci.NewService(nil)

return NewDebrickedScanner(&debClient, finder, uploader, cis, resolverMock)
return NewDebrickedScanner(&debClient, finder, uploader, cis, resolverMock, nil)
}

func cleanUpResolution(t *testing.T, resolverMock resolveTestdata.ResolverMock) {
Expand All @@ -615,3 +616,42 @@ func cleanUpResolution(t *testing.T, resolverMock resolveTestdata.ResolverMock)
t.Error(err)
}
}

func TestScanWithFingerprint(t *testing.T) {
clientMock := testdata.NewDebClientMock()
addMockedFormatsResponse(clientMock, "yarn\\.lock")
addMockedFileUploadResponse(clientMock)
addMockedFinishResponse(clientMock, http.StatusNoContent)
addMockedStatusResponse(clientMock, http.StatusOK, 100)

resolverMock := resolveTestdata.ResolverMock{}
resolverMock.SetFiles([]string{"yarn.lock"})

scanner := makeScanner(clientMock, &resolverMock)
scanner.fingerprint = file.NewFingerprinter()

cwd, _ := os.Getwd()
defer resetWd(t, cwd)
// Clean up resolution must be done before wd reset, otherwise files cannot be deleted
defer cleanUpResolution(t, resolverMock)

path := testdataNpm
repositoryName := path
commitName := "testdata/npm-commit"
opts := DebrickedOptions{
Path: path,
Resolve: true,
Fingerprint: true,
Exclusions: nil,
RepositoryName: repositoryName,
CommitName: commitName,
BranchName: "",
CommitAuthor: "",
RepositoryUrl: "",
IntegrationName: "",
}
err := scanner.Scan(opts)
assert.NoError(t, err)
cwd, _ = os.Getwd()
assert.Contains(t, cwd, path)
}
1 change: 1 addition & 0 deletions internal/wire/cli_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ func (cc *CliContainer) wire() error {
cc.uploader,
cc.ciService,
cc.resolver,
cc.fingerprinter,
)

cc.licenseReporter = licenseReport.Reporter{DebClient: cc.debClient}
Expand Down
1 change: 1 addition & 0 deletions internal/wire/cli_container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,5 @@ func assertCliContainer(t *testing.T, cc *CliContainer) {
assert.NotNil(t, cc.Resolver())
assert.NotNil(t, cc.LicenseReporter())
assert.NotNil(t, cc.VulnerabilityReporter())
assert.NotNil(t, cc.Fingerprinter())
}

0 comments on commit 3d3f0e7

Please sign in to comment.