The Aho-Corasick wrapper we have tracks information about whether verification should be enabled on an individual detector basis, but that functionality isn't related to the matching functionality of Aho-Corasick, and including it complicates the implementation. This PR removes it to simplify some things. This PR removes some code that supported a potential future implementation of detector-specific verification settings, but that feature has not actually been implemented yet, so there's no loss of functionality. If we want that feature we can add it back on top of this in a more separated way.
154 lines
4.4 KiB
Go
154 lines
4.4 KiB
Go
package engine
|
|
|
|
import (
|
|
"os"
|
|
"runtime"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/decoders"
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/detectors"
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/source_metadatapb"
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/sources"
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/sources/git"
|
|
)
|
|
|
|
type expResult struct {
|
|
B string
|
|
LineNumber int64
|
|
Verified bool
|
|
}
|
|
|
|
type discardPrinter struct{}
|
|
|
|
func (p *discardPrinter) Print(context.Context, *detectors.ResultWithMetadata) error {
|
|
// This method intentionally does nothing.
|
|
return nil
|
|
}
|
|
|
|
func TestGitEngine(t *testing.T) {
|
|
ctx := context.Background()
|
|
repoUrl := "https://github.com/dustin-decker/secretsandstuff.git"
|
|
path, _, err := git.PrepareRepo(ctx, repoUrl)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
defer os.RemoveAll(path)
|
|
|
|
ctx, cancel := context.WithCancel(ctx)
|
|
defer cancel()
|
|
type testProfile struct {
|
|
expected map[string]expResult
|
|
branch string
|
|
base string
|
|
maxDepth int
|
|
filter *common.Filter
|
|
}
|
|
for tName, tTest := range map[string]testProfile{
|
|
"all_secrets": {
|
|
expected: map[string]expResult{
|
|
"70001020fab32b1fcf2f1f0e5c66424eae649826": {"AKIAXYZDQCEN4B6JSJQI", 2, true},
|
|
"84e9c75e388ae3e866e121087ea2dd45a71068f2": {"AKIAILE3JG6KMS3HZGCA", 4, true},
|
|
"8afb0ecd4998b1179e428db5ebbcdc8221214432": {"369963c1434c377428ca8531fbc46c0c43d037a0", 3, false},
|
|
"27fbead3bf883cdb7de9d7825ed401f28f9398f1": {"ffc7e0f9400fb6300167009e42d2f842cd7956e2", 7, false},
|
|
},
|
|
filter: common.FilterEmpty(),
|
|
},
|
|
"base_commit": {
|
|
expected: map[string]expResult{
|
|
"70001020fab32b1fcf2f1f0e5c66424eae649826": {"AKIAXYZDQCEN4B6JSJQI", 2, true},
|
|
},
|
|
filter: common.FilterEmpty(),
|
|
base: "2f251b8c1e72135a375b659951097ec7749d4af9",
|
|
},
|
|
} {
|
|
t.Run(tName, func(t *testing.T) {
|
|
e, err := Start(ctx,
|
|
WithConcurrency(1),
|
|
WithDecoders(decoders.DefaultDecoders()...),
|
|
WithDetectors(DefaultDetectors()...),
|
|
WithVerify(true),
|
|
WithPrinter(new(discardPrinter)),
|
|
)
|
|
assert.Nil(t, err)
|
|
|
|
cfg := sources.GitConfig{
|
|
RepoPath: path,
|
|
HeadRef: tTest.branch,
|
|
BaseRef: tTest.base,
|
|
MaxDepth: tTest.maxDepth,
|
|
Filter: tTest.filter,
|
|
}
|
|
if err := e.ScanGit(ctx, cfg); err != nil {
|
|
return
|
|
}
|
|
|
|
// Wait for all the chunks to be processed.
|
|
assert.Nil(t, e.Finish(ctx))
|
|
for result := range e.ResultsChan() {
|
|
switch meta := result.SourceMetadata.GetData().(type) {
|
|
case *source_metadatapb.MetaData_Git:
|
|
if tTest.expected[meta.Git.Commit].B != string(result.Raw) {
|
|
t.Errorf("%s: unexpected result. Got: %s, Expected: %s", tName, string(result.Raw), tTest.expected[meta.Git.Commit].B)
|
|
}
|
|
if tTest.expected[meta.Git.Commit].LineNumber != result.SourceMetadata.GetGit().Line {
|
|
t.Errorf("%s: unexpected line number. Got: %d, Expected: %d", tName, result.SourceMetadata.GetGit().Line, tTest.expected[meta.Git.Commit].LineNumber)
|
|
}
|
|
if tTest.expected[meta.Git.Commit].Verified != result.Verified {
|
|
t.Errorf("%s: unexpected verification. Got: %v, Expected: %v", tName, result.Verified, tTest.expected[meta.Git.Commit].Verified)
|
|
}
|
|
}
|
|
|
|
}
|
|
metrics := e.GetMetrics()
|
|
assert.Equal(t, len(tTest.expected), int(metrics.VerifiedSecretsFound)+int(metrics.UnverifiedSecretsFound))
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkGitEngine(b *testing.B) {
|
|
ctx := context.Background()
|
|
repoUrl := "https://github.com/dustin-decker/secretsandstuff.git"
|
|
path, _, err := git.PrepareRepo(ctx, repoUrl)
|
|
if err != nil {
|
|
b.Error(err)
|
|
}
|
|
defer os.RemoveAll(path)
|
|
|
|
ctx, cancel := context.WithCancel(ctx)
|
|
defer cancel()
|
|
|
|
e, err := Start(ctx,
|
|
WithConcurrency(uint8(runtime.NumCPU())),
|
|
WithDecoders(decoders.DefaultDecoders()...),
|
|
WithDetectors(DefaultDetectors()...),
|
|
WithVerify(false),
|
|
WithPrinter(new(discardPrinter)),
|
|
)
|
|
assert.Nil(b, err)
|
|
|
|
go func() {
|
|
resultCount := 0
|
|
for range e.ResultsChan() {
|
|
resultCount++
|
|
}
|
|
}()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
// TODO: this is measuring the time it takes to initialize the source
|
|
// and not to do the full scan
|
|
cfg := sources.GitConfig{
|
|
RepoPath: path,
|
|
Filter: common.FilterEmpty(),
|
|
}
|
|
if err := e.ScanGit(ctx, cfg); err != nil {
|
|
return
|
|
}
|
|
}
|
|
assert.Nil(b, e.Finish(ctx))
|
|
}
|