@@ -10,6 +10,7 @@ import (
10
10
"sync"
11
11
12
12
"github.com/go-errors/errors"
13
+ gogit "github.com/go-git/go-git/v5"
13
14
log "github.com/sirupsen/logrus"
14
15
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
15
16
"github.com/trufflesecurity/trufflehog/v3/pkg/giturl"
@@ -41,7 +42,7 @@ type Source struct {
41
42
jobSem * semaphore.Weighted
42
43
}
43
44
44
- // Ensure the Source satisfies the interface at compile time
45
+ // Ensure the Source satisfies the interface at compile time.
45
46
var _ sources.Source = (* Source )(nil )
46
47
47
48
// Type returns the type of source.
@@ -98,7 +99,7 @@ func (s *Source) Init(aCtx context.Context, name string, jobId, sourceId int64,
98
99
}
99
100
100
101
if len (s .url ) == 0 {
101
- //assuming not custom gitlab url
102
+ // Assuming not custom gitlab url.
102
103
s .url = "https://gitlab.com/"
103
104
}
104
105
@@ -123,7 +124,7 @@ func (s *Source) Init(aCtx context.Context, name string, jobId, sourceId int64,
123
124
}
124
125
125
126
func (s * Source ) newClient () (* gitlab.Client , error ) {
126
- // initialize a new api instance
127
+ // Initialize a new api instance.
127
128
switch s .authMethod {
128
129
case "OAUTH" :
129
130
apiClient , err := gitlab .NewOAuthClient (s .token , gitlab .WithBaseURL (s .url ))
@@ -158,7 +159,7 @@ func (s *Source) newClient() (*gitlab.Client, error) {
158
159
}
159
160
160
161
func (s * Source ) getAllProjects (apiClient * gitlab.Client ) ([]* gitlab.Project , error ) {
161
- // projects without repo will get user projects, groups projects, and subgroup projects.
162
+ // Projects without repo will get user projects, groups projects, and subgroup projects.
162
163
user , _ , err := apiClient .Users .CurrentUser ()
163
164
164
165
if err != nil {
@@ -187,7 +188,7 @@ func (s *Source) getAllProjects(apiClient *gitlab.Client) ([]*gitlab.Project, er
187
188
var groups []* gitlab.Group
188
189
189
190
listGroupsOptions := gitlab.ListGroupsOptions {
190
- AllAvailable : gitlab .Bool (false ), // This actually grabs public groups on public GitLab if set to true
191
+ AllAvailable : gitlab .Bool (false ), // This actually grabs public groups on public GitLab if set to true.
191
192
TopLevelOnly : gitlab .Bool (false ),
192
193
Owned : gitlab .Bool (false ),
193
194
}
@@ -262,125 +263,84 @@ func (s *Source) getRepos() ([]*url.URL, []error) {
262
263
263
264
func (s * Source ) scanRepos (ctx context.Context , chunksChan chan * sources.Chunk , repos []* url.URL ) []error {
264
265
wg := sync.WaitGroup {}
265
- errs := []error {}
266
+ var errs []error
266
267
var errsMut sync.Mutex
267
- if s .authMethod == "UNAUTHENTICATED" {
268
- for i , u := range repos {
269
- if common .IsDone (ctx ) {
270
- // We are returning nil instead of the scanErrors slice here because
271
- // we don't want to mark this scan as errored if we cancelled it.
272
- return nil
268
+
269
+ for i , u := range repos {
270
+ if common .IsDone (ctx ) {
271
+ // We are returning nil instead of the scanErrors slice here because
272
+ // we don't want to mark this scan as errored if we cancelled it.
273
+ return nil
274
+ }
275
+ if err := s .jobSem .Acquire (ctx , 1 ); err != nil {
276
+ log .WithError (err ).Debug ("could not acquire semaphore" )
277
+ continue
278
+ }
279
+ wg .Add (1 )
280
+ go func (ctx context.Context , repoURL * url.URL , i int ) {
281
+ defer s .jobSem .Release (1 )
282
+ defer wg .Done ()
283
+ if len (repoURL .String ()) == 0 {
284
+ return
273
285
}
274
- if err := s .jobSem .Acquire (ctx , 1 ); err != nil {
275
- log .WithError (err ).Debug ("could not acquire semaphore" )
276
- continue
286
+ s .SetProgressComplete (i , len (repos ), fmt .Sprintf ("Repo: %s" , repoURL ), "" )
287
+
288
+ var path string
289
+ var repo * gogit.Repository
290
+ var err error
291
+ if s .authMethod == "UNAUTHENTICATED" {
292
+ path , repo , err = git .CloneRepoUsingUnauthenticated (repoURL .String ())
293
+ } else {
294
+ path , repo , err = git .CloneRepoUsingToken (s .token , repoURL .String (), s .user )
277
295
}
278
- wg .Add (1 )
279
- go func (ctx context.Context , repoURL * url.URL , i int ) {
280
- defer s .jobSem .Release (1 )
281
- defer wg .Done ()
282
- if len (repoURL .String ()) == 0 {
283
- return
284
- }
285
- s .SetProgressComplete (i , len (repos ), fmt .Sprintf ("Repo: %s" , repoURL ), "" )
286
-
287
- path , repo , err := git .CloneRepoUsingUnauthenticated (repoURL .String ())
288
- defer os .RemoveAll (path )
289
- if err != nil {
290
- errsMut .Lock ()
291
- errs = append (errs , err )
292
- errsMut .Unlock ()
293
- return
294
- }
295
- log .Debugf ("Starting to scan repo %d/%d: %s" , i + 1 , len (repos ), repoURL .String ())
296
- err = s .git .ScanRepo (ctx , repo , path , git .NewScanOptions (), chunksChan )
297
- if err != nil {
298
- errsMut .Lock ()
299
- errs = append (errs , err )
300
- errsMut .Unlock ()
301
- return
302
- }
303
- log .Debugf ("Completed scanning repo %d/%d: %s" , i + 1 , len (repos ), repoURL .String ())
304
- }(ctx , u , i )
305
- }
306
-
307
- } else {
308
- for i , u := range repos {
309
- if common .IsDone (ctx ) {
310
- // We are returning nil instead of the scanErrors slice here because
311
- // we don't want to mark this scan as errored if we cancelled it.
312
- return nil
296
+ defer os .RemoveAll (path )
297
+ if err != nil {
298
+ errsMut .Lock ()
299
+ errs = append (errs , err )
300
+ errsMut .Unlock ()
301
+ return
313
302
}
314
- if err := s .jobSem .Acquire (ctx , 1 ); err != nil {
315
- log .WithError (err ).Debug ("could not acquire semaphore" )
316
- continue
303
+ log .Debugf ("Starting to scan repo %d/%d: %s" , i + 1 , len (repos ), repoURL .String ())
304
+ err = s .git .ScanRepo (ctx , repo , path , git .NewScanOptions (), chunksChan )
305
+ if err != nil {
306
+ errsMut .Lock ()
307
+ errs = append (errs , err )
308
+ errsMut .Unlock ()
309
+ return
317
310
}
318
- wg .Add (1 )
319
- go func (ctx context.Context , repoURL * url.URL , i int ) {
320
- defer s .jobSem .Release (1 )
321
- defer wg .Done ()
322
- if len (repoURL .String ()) == 0 {
323
- return
324
- }
325
- s .SetProgressComplete (i , len (repos ), fmt .Sprintf ("Repo: %s" , repoURL ), "" )
326
-
327
- // If a username is not provided we need to use a default one in order to clone a private repo.
328
- // Not setting "placeholder" as s.user on purpose in case any downstream services rely on a "" value for s.user.
329
- user := s .user
330
- if user == "" {
331
- user = "placeholder"
332
- }
333
- path , repo , err := git .CloneRepoUsingToken (s .token , repoURL .String (), user )
334
- defer os .RemoveAll (path )
335
- if err != nil {
336
- errsMut .Lock ()
337
- errs = append (errs , err )
338
- errsMut .Unlock ()
339
- return
340
- }
341
- log .Debugf ("Starting to scan repo %d/%d: %s" , i + 1 , len (repos ), repoURL .String ())
342
- err = s .git .ScanRepo (ctx , repo , path , git .NewScanOptions (), chunksChan )
343
- if err != nil {
344
- errsMut .Lock ()
345
- errs = append (errs , err )
346
- errsMut .Unlock ()
347
- return
348
- }
349
- log .Debugf ("Completed scanning repo %d/%d: %s" , i + 1 , len (repos ), repoURL .String ())
350
- }(ctx , u , i )
351
- }
311
+ log .Debugf ("Completed scanning repo %d/%d: %s" , i + 1 , len (repos ), repoURL .String ())
312
+ }(ctx , u , i )
352
313
}
353
-
354
314
wg .Wait ()
355
315
356
316
return errs
357
317
}
358
318
359
319
// Chunks emits chunks of bytes over a channel.
360
320
func (s * Source ) Chunks (ctx context.Context , chunksChan chan * sources.Chunk ) error {
361
- // start client
321
+ // Start client.
362
322
apiClient , err := s .newClient ()
363
323
if err != nil {
364
324
return errors .New (err )
365
325
}
366
- // get repo within target
326
+ // Get repo within target.
367
327
repos , errs := s .getRepos ()
368
328
for _ , repoErr := range errs {
369
329
log .WithError (repoErr ).Warn ("error getting repo" )
370
330
}
371
331
372
- // End early if we had errors getting specified repos but none were validated
332
+ // End early if we had errors getting specified repos but none were validated.
373
333
if len (errs ) > 0 && len (repos ) == 0 {
374
334
return errors .New ("All specified repos had validation issues, ending scan" )
375
335
}
376
336
377
- // get all repos if not specified
337
+ // Get all repos if not specified.
378
338
if repos == nil {
379
339
projects , err := s .getAllProjects (apiClient )
380
340
if err != nil {
381
341
return errors .New (err )
382
342
}
383
- // turn projects into URLs for Git cloner
343
+ // Turn projects into URLs for Git cloner.
384
344
for _ , prj := range projects {
385
345
u , err := url .Parse (prj .HTTPURLToRepo )
386
346
if err != nil {
0 commit comments