scan_test.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. package scan_test
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "os"
  7. "path/filepath"
  8. "testing"
  9. "github.com/zricethezav/gitleaks/v7/config"
  10. "github.com/zricethezav/gitleaks/v7/options"
  11. "github.com/zricethezav/gitleaks/v7/scan"
  12. )
  13. const repoBasePath = "../testdata/repos/"
  14. const expectPath = "../testdata/expect/"
  15. func TestScan(t *testing.T) {
  16. err := moveDotGit("dotGit", ".git")
  17. if err != nil {
  18. t.Fatal(err)
  19. }
  20. defer moveDotGit(".git", "dotGit")
  21. tests := []struct {
  22. description string
  23. opts options.Options
  24. wantPath string
  25. }{
  26. {
  27. description: "test google api key leak AND square oauth leak",
  28. opts: options.Options{
  29. Path: filepath.Join(repoBasePath, "with_square_and_google"),
  30. Report: filepath.Join(expectPath, "results_square_and_google.json.got"),
  31. ReportFormat: "json",
  32. NoGit: true,
  33. },
  34. wantPath: filepath.Join(expectPath, "results_square_and_google.json"),
  35. },
  36. }
  37. for _, test := range tests {
  38. cfg, err := config.NewConfig(test.opts)
  39. if err != nil {
  40. t.Error(err)
  41. }
  42. scanner, err := scan.NewScanner(test.opts, cfg)
  43. if err != nil {
  44. t.Error(test.description, err)
  45. }
  46. scannerReport, err := scanner.Scan()
  47. if err != nil {
  48. t.Fatal(test.description, err)
  49. }
  50. err = scan.WriteReport(scannerReport, test.opts, cfg)
  51. if err != nil {
  52. t.Error(test.description, err)
  53. }
  54. if test.wantPath != "" {
  55. err := fileCheck(test.wantPath, test.opts.Report)
  56. if err != nil {
  57. t.Error(test.description, err)
  58. }
  59. }
  60. }
  61. }
  62. func moveDotGit(from, to string) error {
  63. repoDirs, err := ioutil.ReadDir("../testdata/repos")
  64. if err != nil {
  65. return err
  66. }
  67. for _, dir := range repoDirs {
  68. if to == ".git" {
  69. _, err := os.Stat(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), "dotGit"))
  70. if os.IsNotExist(err) {
  71. // dont want to delete the only copy of .git accidentally
  72. continue
  73. }
  74. os.RemoveAll(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), ".git"))
  75. }
  76. if !dir.IsDir() {
  77. continue
  78. }
  79. _, err := os.Stat(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), from))
  80. if os.IsNotExist(err) {
  81. continue
  82. }
  83. err = os.Rename(fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), from),
  84. fmt.Sprintf("%s/%s/%s", repoBasePath, dir.Name(), to))
  85. if err != nil {
  86. return err
  87. }
  88. }
  89. return nil
  90. }
  91. func fileCheck(wantPath, gotPath string) error {
  92. var (
  93. gotLeaks []scan.Leak
  94. wantLeaks []scan.Leak
  95. )
  96. want, err := ioutil.ReadFile(wantPath)
  97. if err != nil {
  98. return err
  99. }
  100. got, err := ioutil.ReadFile(gotPath)
  101. if err != nil {
  102. return err
  103. }
  104. err = json.Unmarshal(got, &gotLeaks)
  105. if err != nil {
  106. return err
  107. }
  108. err = json.Unmarshal(want, &wantLeaks)
  109. if err != nil {
  110. return err
  111. }
  112. if len(wantLeaks) != len(gotLeaks) {
  113. return fmt.Errorf("got %d leaks, want %d leaks", len(gotLeaks), len(wantLeaks))
  114. }
  115. for _, wantLeak := range wantLeaks {
  116. found := false
  117. for _, gotLeak := range gotLeaks {
  118. if same(gotLeak, wantLeak) {
  119. found = true
  120. }
  121. }
  122. if !found {
  123. return fmt.Errorf("unable to find %+v in %s", wantLeak, gotPath)
  124. }
  125. }
  126. if err := os.Remove(gotPath); err != nil {
  127. return err
  128. }
  129. return nil
  130. }
  131. func same(l1, l2 scan.Leak) bool {
  132. if l1.Commit != l2.Commit {
  133. return false
  134. }
  135. if l1.Offender != l2.Offender {
  136. return false
  137. }
  138. if l1.OffenderEntropy != l2.OffenderEntropy {
  139. return false
  140. }
  141. if l1.Line != l2.Line {
  142. return false
  143. }
  144. if l1.Tags != l2.Tags {
  145. return false
  146. }
  147. if l1.LineNumber != l2.LineNumber {
  148. return false
  149. }
  150. if l1.Author != l2.Author {
  151. return false
  152. }
  153. if l1.LeakURL != l2.LeakURL {
  154. return false
  155. }
  156. if l1.RepoURL != l2.RepoURL {
  157. return false
  158. }
  159. if l1.Repo != l2.Repo {
  160. return false
  161. }
  162. return true
  163. }