24
24
import io .swagger .v3 .oas .models .media .ArraySchema ;
25
25
import io .swagger .v3 .oas .models .media .Schema ;
26
26
import io .swagger .v3 .oas .models .responses .ApiResponse ;
27
+ import io .swagger .v3 .oas .models .security .SecurityRequirement ;
28
+ import io .swagger .v3 .oas .models .security .SecurityScheme ;
27
29
import org .openapitools .codegen .CodegenConfig ;
28
30
import org .openapitools .codegen .CodegenConstants ;
29
31
import org .openapitools .codegen .CodegenModel ;
@@ -414,9 +416,38 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
414
416
}
415
417
}
416
418
}
419
+
420
+ // Add a vendor extension attribute that provides a map of auth methods and the scopes
421
+ // which are expected by the operation. This map is then used by postProcessOperationsWithModels
422
+ // to build another vendor extension that provides a subset of the auth methods with only
423
+ // the scopes required by the operation.
424
+ final List <SecurityRequirement > securities = operation .getSecurity ();
425
+ if (securities != null && securities .size () > 0 ) {
426
+ final Map <String , SecurityScheme > securitySchemes = openAPI .getComponents () != null ? openAPI .getComponents ().getSecuritySchemes () : null ;
427
+ final List <SecurityRequirement > globalSecurities = openAPI .getSecurity ();
428
+
429
+ Map <String , List <String >> scopes = getAuthScopes (securities , securitySchemes );
430
+ if (scopes .isEmpty () && globalSecurities != null ) {
431
+ scopes = getAuthScopes (globalSecurities , securitySchemes );
432
+ }
433
+ op .vendorExtensions .put ("x-scopes" , scopes );
434
+ }
417
435
return op ;
418
436
}
419
437
438
+ private Map <String , List <String >> getAuthScopes (List <SecurityRequirement > securities , Map <String , SecurityScheme > securitySchemes ) {
439
+ final Map <String , List <String >> scopes = new HashMap <>();
440
+ for (SecurityRequirement requirement : securities ) {
441
+ for (String key : requirement .keySet ()) {
442
+ SecurityScheme securityScheme = securitySchemes .get (key );
443
+ if (securityScheme != null ) {
444
+ scopes .put (key , requirement .get (key ));
445
+ }
446
+ }
447
+ }
448
+ return scopes ;
449
+ }
450
+
420
451
@ SuppressWarnings ("unchecked" )
421
452
@ Override
422
453
public Map <String , Object > postProcessOperationsWithModels (Map <String , Object > objs , List <Object > allModels ) {
@@ -449,7 +480,14 @@ public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> o
449
480
p .dataType = "Swagger.File_Part_Type" ;
450
481
}
451
482
}
452
- postProcessAuthMethod (op1 .authMethods );
483
+
484
+ // Given the operation scopes and the auth methods, build a list of auth methods that only
485
+ // describe the auth methods and scopes required by the operation.
486
+ final Map <String , List <String >> scopes = (Map <String , List <String >>) op1 .vendorExtensions .get ("x-scopes" );
487
+ List <CodegenSecurity > opScopes = postProcessAuthMethod (op1 .authMethods , scopes );
488
+ if (opScopes != null ) {
489
+ op1 .vendorExtensions .put ("x-auth-scopes" , opScopes );
490
+ }
453
491
454
492
/*
455
493
* Scan the path parameter to construct a x-path-index that tells the index of
@@ -584,7 +622,7 @@ public Map<String, Object> postProcessSupportingFileData(Map<String, Object> obj
584
622
* Collect the scopes to generate unique identifiers for each of them.
585
623
*/
586
624
List <CodegenSecurity > authMethods = (List <CodegenSecurity >) objs .get ("authMethods" );
587
- postProcessAuthMethod (authMethods );
625
+ postProcessAuthMethod (authMethods , null );
588
626
589
627
return super .postProcessSupportingFileData (objs );
590
628
}
@@ -593,8 +631,11 @@ public Map<String, Object> postProcessSupportingFileData(Map<String, Object> obj
593
631
* Collect the scopes to generate a unique identifier for each of them.
594
632
*
595
633
* @param authMethods the auth methods with their scopes.
634
+ * @param scopes the optional auth methods and scopes required by an operation
635
+ * @return the authMethods to be used by the operation with its required scopes.
596
636
*/
597
- private void postProcessAuthMethod (List <CodegenSecurity > authMethods ) {
637
+ private List <CodegenSecurity > postProcessAuthMethod (List <CodegenSecurity > authMethods , Map <String , List <String >> scopes ) {
638
+ List <CodegenSecurity > result = (scopes == null ) ? null : new ArrayList <CodegenSecurity >();
598
639
if (authMethods != null ) {
599
640
for (CodegenSecurity authMethod : authMethods ) {
600
641
if (authMethod .scopes != null ) {
@@ -620,8 +661,39 @@ private void postProcessAuthMethod(List<CodegenSecurity> authMethods) {
620
661
}
621
662
}
622
663
}
664
+
665
+ // If we have operation scopes, filter the auth method to describe the operation auth
666
+ // method with only the scope that it requires. We have to create a new auth method
667
+ // instance because the original object must not be modified.
668
+ List <String > opScopes = (scopes == null ) ? null : scopes .get (authMethod .name );
623
669
authMethod .name = org .openapitools .codegen .utils .StringUtils .camelize (sanitizeName (authMethod .name ), true );
670
+ if (opScopes != null ) {
671
+ CodegenSecurity opSecurity = new CodegenSecurity ();
672
+ opSecurity .name = authMethod .name ;
673
+ opSecurity .type = authMethod .type ;
674
+ opSecurity .hasMore = false ;
675
+ opSecurity .isBasic = authMethod .isBasic ;
676
+ opSecurity .isApiKey = authMethod .isApiKey ;
677
+ opSecurity .isKeyInCookie = authMethod .isKeyInCookie ;
678
+ opSecurity .isKeyInHeader = authMethod .isKeyInHeader ;
679
+ opSecurity .isKeyInQuery = authMethod .isKeyInQuery ;
680
+ opSecurity .flow = authMethod .flow ;
681
+ opSecurity .tokenUrl = authMethod .tokenUrl ;
682
+ List <Map <String , Object >> opAuthScopes = new ArrayList <Map <String , Object >>();
683
+ for (String opScopeName : opScopes ) {
684
+ for (Map <String , Object > scope : authMethod .scopes ) {
685
+ String name = (String ) scope .get ("scope" );
686
+ if (opScopeName .equals (name )) {
687
+ opAuthScopes .add (scope );
688
+ break ;
689
+ }
690
+ }
691
+ }
692
+ opSecurity .scopes = opAuthScopes ;
693
+ result .add (opSecurity );
694
+ }
624
695
}
625
696
}
697
+ return result ;
626
698
}
627
699
}
0 commit comments