@@ -379,6 +379,76 @@ def add_arguments(self, parser: ArgumentParser):
379379 ),
380380 )
381381
382+ @staticmethod
383+ def _validate_admin_auth_args (
384+ args : Namespace , oauth_mode : bool , admin_api_key , admin_insecure_mode
385+ ):
386+ """Validate admin authentication argument combinations.
387+
388+ Raises:
389+ ArgsParseError: if the admin auth flags are inconsistent.
390+
391+ """
392+ if not oauth_mode :
393+ if (admin_api_key and admin_insecure_mode ) or not (
394+ admin_api_key or admin_insecure_mode
395+ ):
396+ raise ArgsParseError (
397+ "Either --admin-api-key or --admin-insecure-mode "
398+ "must be set but not both, unless --oauth-enabled (or "
399+ "--oauth-jwks-uri / --oauth-introspection-endpoint) "
400+ "is configured."
401+ )
402+ return
403+
404+ if not (
405+ getattr (args , "oauth_jwks_uri" , None )
406+ or getattr (args , "oauth_introspection_endpoint" , None )
407+ ):
408+ raise ArgsParseError (
409+ "OAuth mode requires a token validation method: set "
410+ "--oauth-jwks-uri and/or --oauth-introspection-endpoint."
411+ )
412+ if getattr (args , "oauth_introspection_endpoint" , None ) and not getattr (
413+ args , "oauth_introspection_client_id" , None
414+ ):
415+ raise ArgsParseError (
416+ "--oauth-introspection-endpoint requires --oauth-introspection-client-id."
417+ )
418+ if getattr (args , "oauth_jwks_uri" , None ) and not getattr (
419+ args , "oauth_audience" , None
420+ ):
421+ # Without an expected audience, any signature-valid token from the
422+ # JWKS is accepted regardless of its intended recipient, allowing
423+ # token reuse / confused-deputy on a shared AS.
424+ raise ArgsParseError (
425+ "--oauth-jwks-uri requires --oauth-audience so that JWT "
426+ "access tokens are bound to this resource server (the "
427+ "'aud' claim is verified)."
428+ )
429+
430+ @staticmethod
431+ def _oauth_settings (args : Namespace , oauth_mode : bool ) -> dict :
432+ """Build the oauth.* settings map from parsed arguments."""
433+ settings = {}
434+ if oauth_mode :
435+ settings ["admin.oauth_enabled" ] = True
436+ settings ["oauth.http_timeout" ] = getattr (args , "oauth_http_timeout" , None )
437+
438+ arg_to_setting = {
439+ "oauth_jwks_uri" : "oauth.jwks_uri" ,
440+ "oauth_issuer" : "oauth.issuer" ,
441+ "oauth_audience" : "oauth.audience" ,
442+ "oauth_introspection_endpoint" : "oauth.introspection_endpoint" ,
443+ "oauth_introspection_client_id" : "oauth.introspection_client_id" ,
444+ "oauth_introspection_client_secret" : "oauth.introspection_client_secret" ,
445+ }
446+ for arg_name , setting_key in arg_to_setting .items ():
447+ value = getattr (args , arg_name , None )
448+ if value :
449+ settings [setting_key ] = value
450+ return settings
451+
382452 def get_settings (self , args : Namespace ):
383453 """Extract admin settings."""
384454 settings = {}
@@ -391,69 +461,13 @@ def get_settings(self, args: Namespace):
391461 or getattr (args , "oauth_introspection_endpoint" , None )
392462 )
393463
394- if not oauth_mode :
395- if (admin_api_key and admin_insecure_mode ) or not (
396- admin_api_key or admin_insecure_mode
397- ):
398- raise ArgsParseError (
399- "Either --admin-api-key or --admin-insecure-mode "
400- "must be set but not both, unless --oauth-enabled (or "
401- "--oauth-jwks-uri / --oauth-introspection-endpoint) "
402- "is configured."
403- )
404- else :
405- if not (
406- getattr (args , "oauth_jwks_uri" , None )
407- or getattr (args , "oauth_introspection_endpoint" , None )
408- ):
409- raise ArgsParseError (
410- "OAuth mode requires a token validation method: set "
411- "--oauth-jwks-uri and/or --oauth-introspection-endpoint."
412- )
413- if getattr (args , "oauth_introspection_endpoint" , None ) and not getattr (
414- args , "oauth_introspection_client_id" , None
415- ):
416- raise ArgsParseError (
417- "--oauth-introspection-endpoint requires "
418- "--oauth-introspection-client-id."
419- )
420- if getattr (args , "oauth_jwks_uri" , None ) and not getattr (
421- args , "oauth_audience" , None
422- ):
423- # Without an expected audience, any signature-valid token from
424- # the JWKS is accepted regardless of its intended recipient,
425- # allowing token reuse / confused-deputy on a shared AS.
426- raise ArgsParseError (
427- "--oauth-jwks-uri requires --oauth-audience so that JWT "
428- "access tokens are bound to this resource server (the "
429- "'aud' claim is verified)."
430- )
464+ self ._validate_admin_auth_args (
465+ args , oauth_mode , admin_api_key , admin_insecure_mode
466+ )
431467
432468 settings ["admin.admin_api_key" ] = admin_api_key
433469 settings ["admin.admin_insecure_mode" ] = admin_insecure_mode
434-
435- if oauth_mode :
436- settings ["admin.oauth_enabled" ] = True
437- settings ["oauth.http_timeout" ] = getattr (args , "oauth_http_timeout" , None )
438-
439- if getattr (args , "oauth_jwks_uri" , None ):
440- settings ["oauth.jwks_uri" ] = args .oauth_jwks_uri
441- if getattr (args , "oauth_issuer" , None ):
442- settings ["oauth.issuer" ] = args .oauth_issuer
443- if getattr (args , "oauth_audience" , None ):
444- settings ["oauth.audience" ] = args .oauth_audience
445- if getattr (args , "oauth_introspection_endpoint" , None ):
446- settings ["oauth.introspection_endpoint" ] = (
447- args .oauth_introspection_endpoint
448- )
449- if getattr (args , "oauth_introspection_client_id" , None ):
450- settings ["oauth.introspection_client_id" ] = (
451- args .oauth_introspection_client_id
452- )
453- if getattr (args , "oauth_introspection_client_secret" , None ):
454- settings ["oauth.introspection_client_secret" ] = (
455- args .oauth_introspection_client_secret
456- )
470+ settings .update (self ._oauth_settings (args , oauth_mode ))
457471
458472 settings ["admin.enabled" ] = True
459473 settings ["admin.host" ] = args .admin [0 ]
0 commit comments