@@ -310,13 +310,173 @@ func TestBuildEC2SSMIAMScript(t *testing.T) {
310310 }
311311}
312312
313+ func TestBuildAccessGraphCloudSyncIAMScript (t * testing.T ) {
314+ t .Parallel ()
315+ isBadParamErrFn := func (tt require.TestingT , err error , i ... any ) {
316+ require .True (tt , trace .IsBadParameter (err ), "expected bad parameter, got %v" , err )
317+ }
318+
319+ env := newWebPack (t , 1 )
320+
321+ // Unauthenticated client for script downloading.
322+ anonymousHTTPClient := env .proxies [0 ].newClient (t )
323+ pathVars := []string {
324+ "webapi" ,
325+ "scripts" ,
326+ "integrations" ,
327+ "configure" ,
328+ "access-graph-cloud-sync-iam.sh" ,
329+ }
330+ endpoint := anonymousHTTPClient .Endpoint (pathVars ... )
331+
332+ role := "myRole"
333+ awsAccountID := "123456789012"
334+ sqsUrl := "https://sqs.us-west-2.amazonaws.com/123456789012/queue-name"
335+ cloudTrailS3Bucket := "arn:aws:s3:::bucket-name"
336+ kmsKey1 := "arn:aws:kms:us-west-2:123456789012:key/00000000-1111-2222-3333-444444444444"
337+ kmsKey2 := "arn:aws:kms:us-west-2:123456789012:key/55555555-6666-7777-8888-999999999999"
338+
339+ tests := []struct {
340+ name string
341+ reqRelativeURL string
342+ reqQuery url.Values
343+ errCheck require.ErrorAssertionFunc
344+ expectedTeleportArgs string
345+ }{
346+ {
347+ name : "valid" ,
348+ reqQuery : url.Values {
349+ "kind" : []string {"aws-iam" },
350+ "role" : []string {role },
351+ "awsAccountID" : []string {awsAccountID },
352+ },
353+ errCheck : require .NoError ,
354+ expectedTeleportArgs : "integration configure access-graph aws-iam" +
355+ " --role=" + role +
356+ " --aws-account-id=" + awsAccountID ,
357+ },
358+ {
359+ name : "valid with cloud trail" ,
360+ reqQuery : url.Values {
361+ "kind" : []string {"aws-iam" },
362+ "role" : []string {role },
363+ "awsAccountID" : []string {awsAccountID },
364+ "sqsUrl" : []string {sqsUrl },
365+ "cloudTrailS3Bucket" : []string {cloudTrailS3Bucket },
366+ "kmsKeysARNs" : []string {kmsKey1 , kmsKey2 },
367+ },
368+ errCheck : require .NoError ,
369+ expectedTeleportArgs : "integration configure access-graph aws-iam" +
370+ " --role=" + role +
371+ " --aws-account-id=" + awsAccountID +
372+ " --sqs-queue-url=" + sqsUrl +
373+ " --cloud-trail-bucket=" + cloudTrailS3Bucket +
374+ " --kms-key=" + kmsKey1 +
375+ " --kms-key=" + kmsKey2 ,
376+ },
377+ {
378+ name : "valid with eks audit logs" ,
379+ reqQuery : url.Values {
380+ "kind" : []string {"aws-iam" },
381+ "role" : []string {role },
382+ "awsAccountID" : []string {awsAccountID },
383+ "eksAuditLogs" : []string {"true" },
384+ },
385+ errCheck : require .NoError ,
386+ expectedTeleportArgs : "integration configure access-graph aws-iam" +
387+ " --role=" + role +
388+ " --aws-account-id=" + awsAccountID +
389+ " --eks-audit-logs" ,
390+ },
391+ {
392+ name : "valid with cloud trail and eks audit logs" ,
393+ reqQuery : url.Values {
394+ "kind" : []string {"aws-iam" },
395+ "role" : []string {role },
396+ "awsAccountID" : []string {awsAccountID },
397+ "sqsUrl" : []string {sqsUrl },
398+ "cloudTrailS3Bucket" : []string {cloudTrailS3Bucket },
399+ "kmsKeysARNs" : []string {kmsKey1 , kmsKey2 },
400+ "eksAuditLogs" : []string {"true" },
401+ },
402+ errCheck : require .NoError ,
403+ expectedTeleportArgs : "integration configure access-graph aws-iam" +
404+ " --role=" + role +
405+ " --aws-account-id=" + awsAccountID +
406+ " --sqs-queue-url=" + sqsUrl +
407+ " --cloud-trail-bucket=" + cloudTrailS3Bucket +
408+ " --kms-key=" + kmsKey1 +
409+ " --kms-key=" + kmsKey2 +
410+ " --eks-audit-logs" ,
411+ },
412+ {
413+ name : "valid with symbols in role" ,
414+ reqQuery : url.Values {
415+ "kind" : []string {"aws-iam" },
416+ "role" : []string {"Test+1=2,3.4@5-6_7" },
417+ "awsAccountID" : []string {"123456789012" },
418+ },
419+ errCheck : require .NoError ,
420+ expectedTeleportArgs : "integration configure access-graph aws-iam " +
421+ "--role=Test\\ +1=2,3.4\\ @5-6_7 " +
422+ "--aws-account-id=123456789012" ,
423+ },
424+ {
425+ name : "missing kind" ,
426+ reqQuery : url.Values {
427+ "role" : []string {"myRole" },
428+ "awsAccountID" : []string {"123456789012" },
429+ },
430+ errCheck : isBadParamErrFn ,
431+ },
432+ {
433+ name : "missing role" ,
434+ reqQuery : url.Values {
435+ "kind" : []string {"aws-iam" },
436+ "awsAccountID" : []string {"123456789012" },
437+ },
438+ errCheck : isBadParamErrFn ,
439+ },
440+ {
441+ name : "missing awsAccountID" ,
442+ reqQuery : url.Values {
443+ "kind" : []string {"aws-iam" },
444+ "role" : []string {"myRole" },
445+ },
446+ errCheck : isBadParamErrFn ,
447+ },
448+ {
449+ name : "trying to inject escape sequence into query params" ,
450+ reqQuery : url.Values {
451+ "kind" : []string {"aws-iam" },
452+ "role" : []string {"'; rm -rf /tmp/dir; echo '" },
453+ "awsAccountID" : []string {"123456789012" },
454+ },
455+ errCheck : isBadParamErrFn ,
456+ },
457+ }
458+
459+ for _ , tc := range tests {
460+ t .Run (tc .name , func (t * testing.T ) {
461+ resp , err := anonymousHTTPClient .Get (t .Context (), endpoint , tc .reqQuery )
462+ tc .errCheck (t , err )
463+ if err != nil {
464+ return
465+ }
466+
467+ require .Contains (t , string (resp .Bytes ()),
468+ fmt .Sprintf ("entrypointArgs='%s'\n " , tc .expectedTeleportArgs ),
469+ )
470+ })
471+ }
472+ }
473+
313474func TestBuildAWSAppAccessConfigureIAMScript (t * testing.T ) {
314475 t .Parallel ()
315476 isBadParamErrFn := func (tt require.TestingT , err error , i ... any ) {
316477 require .True (tt , trace .IsBadParameter (err ), "expected bad parameter, got %v" , err )
317478 }
318479
319- ctx := context .Background ()
320480 env := newWebPack (t , 1 )
321481
322482 // Unauthenticated client for script downloading.
@@ -372,7 +532,7 @@ func TestBuildAWSAppAccessConfigureIAMScript(t *testing.T) {
372532
373533 for _ , tc := range tests {
374534 t .Run (tc .name , func (t * testing.T ) {
375- resp , err := anonymousHTTPClient .Get (ctx , endpoint , tc .reqQuery )
535+ resp , err := anonymousHTTPClient .Get (t . Context () , endpoint , tc .reqQuery )
376536 tc .errCheck (t , err )
377537 if err != nil {
378538 return
0 commit comments