3
3
package repo
4
4
5
5
import (
6
+ "net/url"
6
7
"os"
7
8
"path/filepath"
8
9
"testing"
9
10
11
+ "github.com/go-git/go-git/v5"
10
12
"github.com/stretchr/testify/assert"
11
13
"github.com/stretchr/testify/require"
12
14
@@ -22,7 +24,7 @@ import (
22
24
)
23
25
24
26
func TestNewArtifact (t * testing.T ) {
25
- ts := gittest .NewTestServer (t )
27
+ ts := gittest .NewTestServer (t , gittest. Options {} )
26
28
defer ts .Close ()
27
29
28
30
type args struct {
@@ -164,7 +166,7 @@ func TestNewArtifact(t *testing.T) {
164
166
}
165
167
166
168
func TestArtifact_Inspect (t * testing.T ) {
167
- ts := gittest .NewTestServer (t )
169
+ ts := gittest .NewTestServer (t , gittest. Options {} )
168
170
defer ts .Close ()
169
171
170
172
tests := []struct {
@@ -330,6 +332,178 @@ func TestArtifact_Inspect(t *testing.T) {
330
332
}
331
333
}
332
334
335
+ // setupAuthTestServer creates a test server with authentication and returns parsed URL with /test-repo.git path
336
+ func setupAuthTestServer (t * testing.T , username , password string ) * url.URL {
337
+ t .Helper ()
338
+ ts := gittest .NewTestServer (t , gittest.Options {
339
+ Username : username ,
340
+ Password : password ,
341
+ })
342
+ t .Cleanup (ts .Close )
343
+
344
+ tsURL , err := url .Parse (ts .URL )
345
+ require .NoError (t , err )
346
+ tsURL .Path = "/test-repo.git"
347
+
348
+ return tsURL
349
+ }
350
+
351
+ // testInspectArtifact is a helper function to inspect an artifact and assert the results
352
+ func testInspectArtifact (t * testing.T , target , wantRepoURL , wantErr string ) {
353
+ t .Helper ()
354
+ art , cleanup , err := NewArtifact (target , cache .NewMemoryCache (), walker .NewFS (), artifact.Option {})
355
+ t .Cleanup (cleanup )
356
+
357
+ if wantErr != "" {
358
+ require .ErrorContains (t , err , wantErr )
359
+ return
360
+ }
361
+ require .NoError (t , err )
362
+
363
+ // Verify Inspect works
364
+ ref , err := art .Inspect (t .Context ())
365
+ require .NoError (t , err )
366
+
367
+ // Verify the RepoURL
368
+ assert .Equal (t , wantRepoURL , ref .RepoMetadata .RepoURL )
369
+
370
+ // Verify we have blob IDs (indicating successful scan)
371
+ assert .NotEmpty (t , ref .BlobIDs )
372
+ }
373
+
374
+ func TestArtifact_InspectWithAuth (t * testing.T ) {
375
+ const (
376
+ testUsername = "testuser"
377
+ testPassword = "testpass"
378
+ )
379
+
380
+ // Test with environment variable authentication (GITHUB_TOKEN, GITLAB_TOKEN)
381
+ t .Run ("environment variable authentication" , func (t * testing.T ) {
382
+ const testGitUsername = "fanal-aquasecurity-scan" // This is the username used by Trivy
383
+
384
+ // Setup test server with authentication
385
+ tsURL := setupAuthTestServer (t , testGitUsername , testPassword )
386
+
387
+ tests := []struct {
388
+ name string
389
+ target string
390
+ envVars map [string ]string
391
+ wantErr string
392
+ wantRepoURL string
393
+ }{
394
+ {
395
+ name : "success with GITHUB_TOKEN" ,
396
+ target : tsURL .String (),
397
+ envVars : map [string ]string {
398
+ "GITHUB_TOKEN" : testPassword ,
399
+ },
400
+ wantRepoURL : tsURL .String (),
401
+ },
402
+ {
403
+ name : "success with GITLAB_TOKEN" ,
404
+ target : tsURL .String (),
405
+ envVars : map [string ]string {
406
+ "GITLAB_TOKEN" : testPassword ,
407
+ },
408
+ wantRepoURL : tsURL .String (),
409
+ },
410
+ {
411
+ name : "failure without token" ,
412
+ target : tsURL .String (),
413
+ wantErr : "authentication required" ,
414
+ },
415
+ {
416
+ name : "failure with wrong token" ,
417
+ target : tsURL .String (),
418
+ envVars : map [string ]string {
419
+ "GITHUB_TOKEN" : "wrongpassword" ,
420
+ },
421
+ wantErr : "authentication required" ,
422
+ },
423
+ }
424
+
425
+ for _ , tt := range tests {
426
+ t .Run (tt .name , func (t * testing.T ) {
427
+ // Set test environment variables
428
+ for key , value := range tt .envVars {
429
+ t .Setenv (key , value )
430
+ }
431
+
432
+ // Test using helper function
433
+ testInspectArtifact (t , tt .target , tt .wantRepoURL , tt .wantErr )
434
+ })
435
+ }
436
+ })
437
+
438
+ // Test with URL-embedded authentication
439
+ t .Run ("URL embedded authentication" , func (t * testing.T ) {
440
+ // Setup test server with authentication
441
+ tsURL := setupAuthTestServer (t , testUsername , testPassword )
442
+
443
+ // Helper function to generate target URL with credentials
444
+ makeTarget := func (username , password string ) string {
445
+ u := * tsURL // Copy the URL
446
+ if username != "" && password != "" {
447
+ u .User = url .UserPassword (username , password )
448
+ }
449
+ return u .String ()
450
+ }
451
+
452
+ tests := []struct {
453
+ name string
454
+ target string
455
+ wantRepoURL string
456
+ wantErr string
457
+ }{
458
+ {
459
+ name : "success with embedded credentials" ,
460
+ target : makeTarget (testUsername , testPassword ),
461
+ wantRepoURL : makeTarget (testUsername , testPassword ), // TODO: username/password should be stripped
462
+ },
463
+ {
464
+ name : "failure with wrong password" ,
465
+ target : makeTarget (testUsername , "wrongpass" ),
466
+ wantErr : "authentication required" ,
467
+ },
468
+ {
469
+ name : "failure without credentials" ,
470
+ target : makeTarget ("" , "" ),
471
+ wantErr : "authentication required" ,
472
+ },
473
+ }
474
+
475
+ for _ , tt := range tests {
476
+ t .Run (tt .name , func (t * testing.T ) {
477
+ // Test using helper function
478
+ testInspectArtifact (t , tt .target , tt .wantRepoURL , tt .wantErr )
479
+ })
480
+ }
481
+ })
482
+
483
+ // Test cloning with embedded credentials and then scanning the local directory
484
+ t .Run ("clone with credentials then scan local" , func (t * testing.T ) {
485
+ // Setup test server with authentication
486
+ tsURL := setupAuthTestServer (t , testUsername , testPassword )
487
+
488
+ // Add credentials to URL
489
+ tsURL .User = url .UserPassword (testUsername , testPassword )
490
+ targetWithCreds := tsURL .String ()
491
+
492
+ // Clone the repository with URL-embedded credentials
493
+ cloneDir := filepath .Join (t .TempDir (), "cloned-repo" )
494
+
495
+ // Use go-git directly to clone with URL-embedded credentials
496
+ _ , err := git .PlainClone (cloneDir , false , & git.CloneOptions {
497
+ URL : targetWithCreds ,
498
+ })
499
+ require .NoError (t , err )
500
+
501
+ // Scan and verify the local cloned directory
502
+ // TODO: The credentials in the URL should be stripped in the RepoURL
503
+ testInspectArtifact (t , cloneDir , targetWithCreds , "" )
504
+ })
505
+ }
506
+
333
507
func Test_newURL (t * testing.T ) {
334
508
type args struct {
335
509
rawurl string
0 commit comments