gitlab.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package hosts
  2. import (
  3. "context"
  4. "sync"
  5. "github.com/zricethezav/gitleaks/v5/manager"
  6. "github.com/zricethezav/gitleaks/v5/options"
  7. "github.com/zricethezav/gitleaks/v5/scan"
  8. log "github.com/sirupsen/logrus"
  9. "github.com/xanzy/go-gitlab"
  10. )
  11. // Gitlab wraps a gitlab client and manager. This struct implements what the Host interface defines.
  12. type Gitlab struct {
  13. client *gitlab.Client
  14. manager *manager.Manager
  15. ctx context.Context
  16. wg sync.WaitGroup
  17. }
  18. // NewGitlabClient accepts a manager struct and returns a Gitlab host pointer which will be used to
  19. // perform a gitlab scan on an group or user.
  20. func NewGitlabClient(m *manager.Manager) (*Gitlab, error) {
  21. var err error
  22. gitlabClient := &Gitlab{
  23. manager: m,
  24. ctx: context.Background(),
  25. client: gitlab.NewClient(nil, options.GetAccessToken(m.Opts)),
  26. }
  27. if m.Opts.BaseURL != "" {
  28. err = gitlabClient.client.SetBaseURL(m.Opts.BaseURL)
  29. }
  30. return gitlabClient, err
  31. }
  32. // Scan will scan a github user or organization's repos.
  33. func (g *Gitlab) Scan() {
  34. var (
  35. projects []*gitlab.Project
  36. resp *gitlab.Response
  37. err error
  38. )
  39. page := 1
  40. listOpts := gitlab.ListOptions{
  41. PerPage: 100,
  42. Page: page,
  43. }
  44. for {
  45. var _projects []*gitlab.Project
  46. if g.manager.Opts.User != "" {
  47. glOpts := &gitlab.ListProjectsOptions{
  48. ListOptions: listOpts,
  49. }
  50. _projects, resp, err = g.client.Projects.ListUserProjects(g.manager.Opts.User, glOpts)
  51. } else if g.manager.Opts.Organization != "" {
  52. glOpts := &gitlab.ListGroupProjectsOptions{
  53. ListOptions: listOpts,
  54. }
  55. _projects, resp, err = g.client.Groups.ListGroupProjects(g.manager.Opts.Organization, glOpts)
  56. }
  57. if err != nil {
  58. log.Error(err)
  59. }
  60. for _, p := range _projects {
  61. if g.manager.Opts.ExcludeForks && p.ForkedFromProject != nil {
  62. log.Debugf("excluding forked repo: %s", p.Name)
  63. continue
  64. }
  65. projects = append(projects, p)
  66. }
  67. if resp == nil {
  68. break
  69. }
  70. if page >= resp.TotalPages {
  71. // exit when we've seen all pages
  72. break
  73. }
  74. page = resp.NextPage
  75. }
  76. // iterate of gitlab projects
  77. for _, p := range projects {
  78. r := scan.NewRepo(g.manager)
  79. cloneOpts := g.manager.CloneOptions
  80. cloneOpts.URL = p.HTTPURLToRepo
  81. err := r.Clone(cloneOpts)
  82. // TODO handle clone retry with ssh like github host
  83. r.Name = p.Name
  84. if err = r.Scan(); err != nil {
  85. log.Error(err)
  86. }
  87. }
  88. }
  89. // ScanPR TODO not implemented
  90. func (g *Gitlab) ScanPR() {
  91. log.Error("ScanPR is not implemented in Gitlab host yet...")
  92. }