gitlab.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package hosts
  2. import (
  3. "context"
  4. "sync"
  5. "github.com/zricethezav/gitleaks/audit"
  6. "github.com/zricethezav/gitleaks/manager"
  7. "github.com/zricethezav/gitleaks/options"
  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 audit 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. // Audit will audit a github user or organization's repos.
  33. func (g *Gitlab) Audit() {
  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. projects = append(projects, _projects...)
  61. if resp == nil {
  62. break
  63. }
  64. if page >= resp.TotalPages {
  65. // exit when we've seen all pages
  66. break
  67. }
  68. page = resp.NextPage
  69. }
  70. // iterate of gitlab projects
  71. for _, p := range projects {
  72. r := audit.NewRepo(g.manager)
  73. cloneOpts := g.manager.CloneOptions
  74. cloneOpts.URL = p.HTTPURLToRepo
  75. err := r.Clone(cloneOpts)
  76. // TODO handle clone retry with ssh like github host
  77. r.Name = p.Name
  78. if err = r.Audit(); err != nil {
  79. log.Error(err)
  80. }
  81. }
  82. }
  83. // AuditPR TODO not implemented
  84. func (g *Gitlab) AuditPR() {
  85. log.Error("AuditPR is not implemented in Gitlab host yet...")
  86. }