gitlab.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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. if err != nil {
  30. log.Error(err)
  31. }
  32. }
  33. return gitlabClient, err
  34. }
  35. // Audit will audit a github user or organization's repos.
  36. func (g *Gitlab) Audit() {
  37. var (
  38. projects []*gitlab.Project
  39. resp *gitlab.Response
  40. err error
  41. )
  42. page := 1
  43. listOpts := gitlab.ListOptions{
  44. PerPage: 100,
  45. Page: page,
  46. }
  47. for {
  48. var _projects []*gitlab.Project
  49. if g.manager.Opts.User != "" {
  50. glOpts := &gitlab.ListProjectsOptions{
  51. ListOptions: listOpts,
  52. }
  53. projects, resp, err = g.client.Projects.ListUserProjects(g.manager.Opts.User, glOpts)
  54. } else if g.manager.Opts.Organization != "" {
  55. glOpts := &gitlab.ListGroupProjectsOptions{
  56. ListOptions: listOpts,
  57. }
  58. projects, resp, err = g.client.Groups.ListGroupProjects(g.manager.Opts.Organization, glOpts)
  59. }
  60. if err != nil {
  61. log.Error(err)
  62. }
  63. projects = append(projects, _projects...)
  64. if resp == nil {
  65. break
  66. }
  67. if page >= resp.TotalPages {
  68. // exit when we've seen all pages
  69. break
  70. }
  71. page = resp.NextPage
  72. }
  73. // iterate of gitlab projects
  74. for _, p := range projects {
  75. r := audit.NewRepo(&g.manager)
  76. cloneOpts := g.manager.CloneOptions
  77. cloneOpts.URL = p.HTTPURLToRepo
  78. err := r.Clone(cloneOpts)
  79. // TODO handle clone retry with ssh like github host
  80. r.Name = p.Name
  81. if err = r.Audit(); err != nil {
  82. log.Error(err)
  83. }
  84. }
  85. }
  86. // AuditPR TODO not implemented
  87. func (g *Gitlab) AuditPR() {
  88. log.Error("AuditPR is not implemented in Gitlab host yet...")
  89. }