config.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package config
  2. import (
  3. _ "embed"
  4. "fmt"
  5. "regexp"
  6. "strings"
  7. )
  8. //go:embed gitleaks.toml
  9. var DefaultConfig string
  10. // ViperConfig is the config struct used by the Viper config package
  11. // to parse the config file. This struct does not include regular expressions.
  12. // It is used as an intermediary to convert the Viper config to the Config struct.
  13. type ViperConfig struct {
  14. Description string
  15. Rules []struct {
  16. ID string
  17. Description string
  18. Entropy float64
  19. SecretGroup int
  20. Regex string
  21. Keywords []string
  22. Path string
  23. Tags []string
  24. Allowlist struct {
  25. Regexes []string
  26. Paths []string
  27. Commits []string
  28. }
  29. }
  30. Allowlist struct {
  31. Regexes []string
  32. Paths []string
  33. Commits []string
  34. }
  35. }
  36. // Config is a configuration struct that contains rules and an allowlist if present.
  37. type Config struct {
  38. Path string
  39. Description string
  40. Rules []*Rule
  41. Allowlist Allowlist
  42. Keywords []string
  43. }
  44. func (vc *ViperConfig) Translate() (Config, error) {
  45. var (
  46. rules []*Rule
  47. keywords []string
  48. )
  49. for _, r := range vc.Rules {
  50. var allowlistRegexes []*regexp.Regexp
  51. for _, a := range r.Allowlist.Regexes {
  52. allowlistRegexes = append(allowlistRegexes, regexp.MustCompile(a))
  53. }
  54. var allowlistPaths []*regexp.Regexp
  55. for _, a := range r.Allowlist.Paths {
  56. allowlistPaths = append(allowlistPaths, regexp.MustCompile(a))
  57. }
  58. if r.Keywords == nil {
  59. r.Keywords = []string{}
  60. } else {
  61. for _, k := range r.Keywords {
  62. keywords = append(keywords, strings.ToLower(k))
  63. }
  64. }
  65. if r.Tags == nil {
  66. r.Tags = []string{}
  67. }
  68. var configRegex *regexp.Regexp
  69. var configPathRegex *regexp.Regexp
  70. if r.Regex == "" {
  71. configRegex = nil
  72. } else {
  73. configRegex = regexp.MustCompile(r.Regex)
  74. }
  75. if r.Path == "" {
  76. configPathRegex = nil
  77. } else {
  78. configPathRegex = regexp.MustCompile(r.Path)
  79. }
  80. r := &Rule{
  81. Description: r.Description,
  82. RuleID: r.ID,
  83. Regex: configRegex,
  84. Path: configPathRegex,
  85. SecretGroup: r.SecretGroup,
  86. Entropy: r.Entropy,
  87. Tags: r.Tags,
  88. Keywords: r.Keywords,
  89. Allowlist: Allowlist{
  90. Regexes: allowlistRegexes,
  91. Paths: allowlistPaths,
  92. Commits: r.Allowlist.Commits,
  93. },
  94. }
  95. if r.Regex != nil && r.SecretGroup > r.Regex.NumSubexp() {
  96. return Config{}, fmt.Errorf("%s invalid regex secret group %d, max regex secret group %d", r.Description, r.SecretGroup, r.Regex.NumSubexp())
  97. }
  98. rules = append(rules, r)
  99. }
  100. var allowlistRegexes []*regexp.Regexp
  101. for _, a := range vc.Allowlist.Regexes {
  102. allowlistRegexes = append(allowlistRegexes, regexp.MustCompile(a))
  103. }
  104. var allowlistPaths []*regexp.Regexp
  105. for _, a := range vc.Allowlist.Paths {
  106. allowlistPaths = append(allowlistPaths, regexp.MustCompile(a))
  107. }
  108. return Config{
  109. Description: vc.Description,
  110. Rules: rules,
  111. Allowlist: Allowlist{
  112. Regexes: allowlistRegexes,
  113. Paths: allowlistPaths,
  114. Commits: vc.Allowlist.Commits,
  115. },
  116. Keywords: keywords,
  117. }, nil
  118. }