Skip to content

Commit

Permalink
pretty apparent 'protect' and 'detect' should be merged into one comm…
Browse files Browse the repository at this point in the history
…and (#1294)
  • Loading branch information
zricethezav committed Nov 19, 2023
1 parent 128b50f commit 221d5c4
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 259 deletions.
165 changes: 5 additions & 160 deletions cmd/detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,11 @@ package cmd

import (
"os"
"path/filepath"
"strings"
"time"

"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/zricethezav/gitleaks/v8/config"
"github.com/zricethezav/gitleaks/v8/detect"
"github.com/zricethezav/gitleaks/v8/report"
)
Expand All @@ -35,117 +30,22 @@ var detectCmd = &cobra.Command{
func runDetect(cmd *cobra.Command, args []string) {
initConfig()
var (
vc config.ViperConfig
findings []report.Finding
err error
)

// Load config
if err = viper.Unmarshal(&vc); err != nil {
log.Fatal().Err(err).Msg("Failed to load config")
}
cfg, err := vc.Translate()
if err != nil {
log.Fatal().Err(err).Msg("Failed to load config")
}
cfg.Path, _ = cmd.Flags().GetString("config")
// setup config (aka, the thing that defines rules)
cfg := Config(cmd)

// start timer
start := time.Now()

// Setup detector
detector := detect.NewDetector(cfg)
// set color flag at first
if detector.NoColor, err = cmd.Flags().GetBool("no-color"); err != nil {
log.Fatal().Err(err).Msg("")
}
// also init logger again without color
if detector.NoColor {
log.Logger = log.Output(zerolog.ConsoleWriter{
Out: os.Stderr,
NoColor: detector.NoColor,
})
}
detector.Config.Path, err = cmd.Flags().GetString("config")
if err != nil {
log.Fatal().Err(err).Msg("")
}
// grab source
source, err := cmd.Flags().GetString("source")
if err != nil {
log.Fatal().Err(err).Msg("")
}
// if config path is not set, then use the {source}/.gitleaks.toml path.
// note that there may not be a `{source}/.gitleaks.toml` file, this is ok.
if detector.Config.Path == "" {
detector.Config.Path = filepath.Join(source, ".gitleaks.toml")
}
// set verbose flag
if detector.Verbose, err = cmd.Flags().GetBool("verbose"); err != nil {
log.Fatal().Err(err).Msg("")
}
// set redact flag
if detector.Redact, err = cmd.Flags().GetUint("redact"); err != nil {
log.Fatal().Err(err).Msg("")
}
if detector.MaxTargetMegaBytes, err = cmd.Flags().GetInt("max-target-megabytes"); err != nil {
log.Fatal().Err(err).Msg("")
}
// set ignore gitleaks:allow flag
if detector.IgnoreGitleaksAllow, err = cmd.Flags().GetBool("ignore-gitleaks-allow"); err != nil {
log.Fatal().Err(err).Msg("")
}

gitleaksIgnorePath, err := cmd.Flags().GetString("gitleaks-ignore-path")
if err != nil {
log.Fatal().Err(err).Msg("could not get .gitleaksignore path")
}

if fileExists(gitleaksIgnorePath) {
if err = detector.AddGitleaksIgnore(gitleaksIgnorePath); err != nil {
log.Fatal().Err(err).Msg("could not call AddGitleaksIgnore")
}
}

if fileExists(filepath.Join(gitleaksIgnorePath, ".gitleaksignore")) {
if err = detector.AddGitleaksIgnore(filepath.Join(gitleaksIgnorePath, ".gitleaksignore")); err != nil {
log.Fatal().Err(err).Msg("could not call AddGitleaksIgnore")
}
}

if fileExists(filepath.Join(source, ".gitleaksignore")) {
if err = detector.AddGitleaksIgnore(filepath.Join(source, ".gitleaksignore")); err != nil {
log.Fatal().Err(err).Msg("could not call AddGitleaksIgnore")
}
}

// ignore findings from the baseline (an existing report in json format generated earlier)
baselinePath, _ := cmd.Flags().GetString("baseline-path")
if baselinePath != "" {
err = detector.AddBaseline(baselinePath, source)
if err != nil {
log.Error().Msgf("Could not load baseline. The path must point of a gitleaks report generated using the default format: %s", err)
}
}

// If set, only apply rules that are defined in the flag
rules, _ := cmd.Flags().GetStringSlice("enable-rule")
if len(rules) > 0 {
log.Info().Msg("Overriding enabled rules: " + strings.Join(rules, ", "))
ruleOverride := make(map[string]config.Rule)
for _, ruleName := range rules {
if rule, ok := cfg.Rules[ruleName]; ok {
ruleOverride[ruleName] = rule
} else {
log.Fatal().Msgf("Requested rule %s not found in rules", ruleName)
}
}
detector.Config.Rules = ruleOverride
}

// set follow symlinks flag
if detector.FollowSymlinks, err = cmd.Flags().GetBool("follow-symlinks"); err != nil {
log.Fatal().Err(err).Msg("")
}
detector := Detector(cmd, cfg, source)

// set exit code
exitCode, err := cmd.Flags().GetInt("exit-code")
Expand Down Expand Up @@ -192,61 +92,6 @@ func runDetect(cmd *cobra.Command, args []string) {
}
}

// log info about the scan
if err == nil {
log.Info().Msgf("scan completed in %s", FormatDuration(time.Since(start)))
if len(findings) != 0 {
log.Warn().Msgf("leaks found: %d", len(findings))
} else {
log.Info().Msg("no leaks found")
}
} else {
log.Warn().Msgf("partial scan completed in %s", FormatDuration(time.Since(start)))
if len(findings) != 0 {
log.Warn().Msgf("%d leaks found in partial scan", len(findings))
} else {
log.Warn().Msg("no leaks found in partial scan")
}
}

// write report if desired
reportPath, _ := cmd.Flags().GetString("report-path")
ext, _ := cmd.Flags().GetString("report-format")
if reportPath != "" {
if err := report.Write(findings, cfg, ext, reportPath); err != nil {
log.Fatal().Err(err).Msg("could not write")
}
}

if err != nil {
os.Exit(1)
}

if len(findings) != 0 {
os.Exit(exitCode)
}
findingSummaryAndExit(findings, cmd, cfg, exitCode, start, err)
}

func fileExists(fileName string) bool {
// check for a .gitleaksignore file
info, err := os.Stat(fileName)
if err != nil && !os.IsNotExist(err) {
return false
}

if info != nil && err == nil {
if !info.IsDir() {
return true
}
}
return false
}

func FormatDuration(d time.Duration) string {
scale := 100 * time.Second
// look for the max scale that is smaller than d
for scale > d {
scale = scale / 10
}
return d.Round(scale / 100).String()
}
105 changes: 6 additions & 99 deletions cmd/protect.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
package cmd

import (
"os"
"path/filepath"
"time"

"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/zricethezav/gitleaks/v8/config"
"github.com/zricethezav/gitleaks/v8/detect"
"github.com/zricethezav/gitleaks/v8/report"
)

func init() {
protectCmd.Flags().Bool("staged", false, "detect secrets in a --staged state")
protectCmd.Flags().String("log-opts", "", "git log options")
protectCmd.Flags().StringP("gitleaks-ignore-path", "i", ".", "path to .gitleaksignore file or folder containing one")
rootCmd.AddCommand(protectCmd)
}

Expand All @@ -30,85 +23,20 @@ var protectCmd = &cobra.Command{

func runProtect(cmd *cobra.Command, args []string) {
initConfig()
var vc config.ViperConfig
var err error

if err := viper.Unmarshal(&vc); err != nil {
log.Fatal().Err(err).Msg("Failed to load config")
}
cfg, err := vc.Translate()
if err != nil {
log.Fatal().Err(err).Msg("Failed to load config")
}
// setup config (aka, the thing that defines rules)
cfg := Config(cmd)

cfg.Path, _ = cmd.Flags().GetString("config")
exitCode, _ := cmd.Flags().GetInt("exit-code")
staged, _ := cmd.Flags().GetBool("staged")
start := time.Now()

// Setup detector
detector := detect.NewDetector(cfg)
// set color flag at first
if detector.NoColor, err = cmd.Flags().GetBool("no-color"); err != nil {
log.Fatal().Err(err).Msg("")
}
// also init logger again without color
if detector.NoColor {
log.Logger = log.Output(zerolog.ConsoleWriter{
Out: os.Stderr,
NoColor: detector.NoColor,
})
}
detector.Config.Path, err = cmd.Flags().GetString("config")
if err != nil {
log.Fatal().Err(err).Msg("")
}
source, err := cmd.Flags().GetString("source")
if err != nil {
log.Fatal().Err(err).Msg("")
}
// if config path is not set, then use the {source}/.gitleaks.toml path.
// note that there may not be a `{source}/.gitleaks.toml` file, this is ok.
if detector.Config.Path == "" {
detector.Config.Path = filepath.Join(source, ".gitleaks.toml")
}
// set verbose flag
if detector.Verbose, err = cmd.Flags().GetBool("verbose"); err != nil {
log.Fatal().Err(err).Msg("")
}
// set redact flag
if detector.Redact, err = cmd.Flags().GetUint("redact"); err != nil {
log.Fatal().Err(err).Msg("")
}
if detector.MaxTargetMegaBytes, err = cmd.Flags().GetInt("max-target-megabytes"); err != nil {
log.Fatal().Err(err).Msg("")
}
// set ignore gitleaks:allow flag
if detector.IgnoreGitleaksAllow, err = cmd.Flags().GetBool("ignore-gitleaks-allow"); err != nil {
log.Fatal().Err(err).Msg("")
}

gitleaksIgnorePath, err := cmd.Flags().GetString("gitleaks-ignore-path")
if err != nil {
log.Fatal().Err(err).Msg("could not get .gitleaksignore path")
}

if fileExists(gitleaksIgnorePath) {
if err = detector.AddGitleaksIgnore(gitleaksIgnorePath); err != nil {
log.Fatal().Err(err).Msg("could not call AddGitleaksIgnore")
}
}

if fileExists(filepath.Join(gitleaksIgnorePath, ".gitleaksignore")) {
if err = detector.AddGitleaksIgnore(filepath.Join(gitleaksIgnorePath, ".gitleaksignore")); err != nil {
log.Fatal().Err(err).Msg("could not call AddGitleaksIgnore")
}
}
start := time.Now()

if fileExists(filepath.Join(source, ".gitleaksignore")) {
if err = detector.AddGitleaksIgnore(filepath.Join(source, ".gitleaksignore")); err != nil {
log.Fatal().Err(err).Msg("could not call AddGitleaksIgnore")
}
}
detector := Detector(cmd, cfg, source)

// get log options for git scan
logOpts, err := cmd.Flags().GetString("log-opts")
Expand All @@ -123,27 +51,6 @@ func runProtect(cmd *cobra.Command, args []string) {
} else {
findings, err = detector.DetectGit(source, logOpts, detect.ProtectType)
}
if err != nil {
// don't exit on error, just log it
log.Error().Err(err).Msg("")
}

// log info about the scan
log.Info().Msgf("scan completed in %s", FormatDuration(time.Since(start)))
if len(findings) != 0 {
log.Warn().Msgf("leaks found: %d", len(findings))
} else {
log.Info().Msg("no leaks found")
}

reportPath, _ := cmd.Flags().GetString("report-path")
ext, _ := cmd.Flags().GetString("report-format")
if reportPath != "" {
if err = report.Write(findings, cfg, ext, reportPath); err != nil {
log.Fatal().Err(err).Msg("")
}
}
if len(findings) != 0 {
os.Exit(exitCode)
}
findingSummaryAndExit(findings, cmd, cfg, exitCode, start, err)
}
Loading

0 comments on commit 221d5c4

Please sign in to comment.