config.go 2.7 KB

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