gitlab.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package hosts
  2. import (
  3. "context"
  4. log "github.com/sirupsen/logrus"
  5. "github.com/xanzy/go-gitlab"
  6. "github.com/zricethezav/gitleaks/audit"
  7. "github.com/zricethezav/gitleaks/manager"
  8. "github.com/zricethezav/gitleaks/options"
  9. "sync"
  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 {
  21. return &Gitlab{
  22. manager: m,
  23. ctx: context.Background(),
  24. client: gitlab.NewClient(nil, options.GetAccessToken(m.Opts)),
  25. }
  26. }
  27. // Audit will audit a github user or organization's repos.
  28. func (g *Gitlab) Audit() {
  29. var (
  30. projects []*gitlab.Project
  31. resp *gitlab.Response
  32. err error
  33. )
  34. page := 1
  35. listOpts := gitlab.ListOptions{
  36. PerPage: 100,
  37. Page: page,
  38. }
  39. for {
  40. var _projects []*gitlab.Project
  41. if g.manager.Opts.User != "" {
  42. glOpts := &gitlab.ListProjectsOptions{
  43. ListOptions: listOpts,
  44. }
  45. projects, resp, err = g.client.Projects.ListUserProjects(g.manager.Opts.User, glOpts)
  46. } else if g.manager.Opts.Organization != "" {
  47. glOpts := &gitlab.ListGroupProjectsOptions{
  48. ListOptions: listOpts,
  49. }
  50. projects, resp, err = g.client.Groups.ListGroupProjects(g.manager.Opts.Organization, glOpts)
  51. }
  52. if err != nil {
  53. log.Error(err)
  54. }
  55. projects = append(projects, _projects...)
  56. if resp == nil {
  57. break
  58. }
  59. if page >= resp.TotalPages {
  60. // exit when we've seen all pages
  61. break
  62. }
  63. page = resp.NextPage
  64. }
  65. // iterate of gitlab projects
  66. for _, p := range projects {
  67. r := audit.NewRepo(&g.manager)
  68. cloneOpts := g.manager.CloneOptions
  69. cloneOpts.URL = p.HTTPURLToRepo
  70. err := r.Clone(cloneOpts)
  71. // TODO handle clone retry with ssh like github host
  72. r.Name = p.Name
  73. if err = r.Audit(); err != nil {
  74. log.Error(err)
  75. }
  76. }
  77. }
  78. // AuditPR TODO not implemented
  79. func (g *Gitlab) AuditPR() {
  80. log.Error("AuditPR is not implemented in Gitlab host yet...")
  81. }