Class: Legate::Auth::ExconMiddleware
- Inherits:
-
Excon::Middleware::Base
- Object
- Excon::Middleware::Base
- Legate::Auth::ExconMiddleware
- Defined in:
- lib/legate/auth/excon_middleware.rb
Overview
Excon middleware for automatically handling authentication This middleware can be inserted into the Excon middleware stack to automatically apply authentication to requests and handle authentication errors.
Instance Attribute Summary collapse
-
#auto_retry ⇒ Object
readonly
Returns the value of attribute auto_retry.
-
#backoff_factor ⇒ Object
readonly
Returns the value of attribute backoff_factor.
-
#backoff_strategy ⇒ Object
readonly
Returns the value of attribute backoff_strategy.
-
#credential ⇒ Object
readonly
Attributes needed by the shell middleware when accessing the configured instance.
-
#max_retries ⇒ Object
readonly
Returns the value of attribute max_retries.
-
#retry_non_idempotent ⇒ Object
readonly
Returns the value of attribute retry_non_idempotent.
-
#retry_on ⇒ Object
readonly
Returns the value of attribute retry_on.
-
#scheme ⇒ Object
readonly
Attributes needed by the shell middleware when accessing the configured instance.
-
#token_manager ⇒ Object
readonly
Attributes needed by the shell middleware when accessing the configured instance.
-
#token_store ⇒ Object
readonly
Attributes needed by the shell middleware when accessing the configured instance.
Class Method Summary collapse
-
.new(*args) ⇒ Object
Class-level new method for both factory creation and Excon middleware stack.
Instance Method Summary collapse
-
#initialize(stack, options = {}) ⇒ ExconMiddleware
constructor
Initialize the middleware.
-
#request_call(datum) {|Hash| ... } ⇒ Hash
Called for each request in the Excon middleware stack.
-
#response_call(datum) {|Hash| ... } ⇒ Hash
Called after each response in the Excon middleware stack.
- #should_retry?(request_datum, response_details) ⇒ Boolean
Constructor Details
#initialize(stack, options = {}) ⇒ ExconMiddleware
Initialize the middleware
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/legate/auth/excon_middleware.rb', line 33 def initialize(stack, = {}) super(stack) @scheme = [:scheme] @credential = [:credential] @token_store = [:token_store] @token_manager = [:token_manager] @auto_retry = .fetch(:auto_retry, true) @max_retries = .fetch(:max_retries, 3) @backoff_strategy = .fetch(:backoff_strategy, :exponential) @backoff_factor = .fetch(:backoff_factor, 1.0) @retry_non_idempotent = .fetch(:retry_non_idempotent, false) @retry_on = Array(.fetch(:retry_on, [])) + [401, 403] if @scheme && @credential Legate.logger.debug("ExconMiddleware: Factory-created instance configured: #{@scheme.scheme_type}") if defined?(Legate.logger) register_token_lifecycle_callbacks if @token_manager && @token_manager.respond_to?(:register_callback) elsif defined?(Legate.logger) # This is the shell instance created by Excon Legate.logger.debug('ExconMiddleware: Shell instance initialized by Excon.') end end |
Instance Attribute Details
#auto_retry ⇒ Object (readonly)
Returns the value of attribute auto_retry.
28 29 30 |
# File 'lib/legate/auth/excon_middleware.rb', line 28 def auto_retry @auto_retry end |
#backoff_factor ⇒ Object (readonly)
Returns the value of attribute backoff_factor.
28 29 30 |
# File 'lib/legate/auth/excon_middleware.rb', line 28 def backoff_factor @backoff_factor end |
#backoff_strategy ⇒ Object (readonly)
Returns the value of attribute backoff_strategy.
28 29 30 |
# File 'lib/legate/auth/excon_middleware.rb', line 28 def backoff_strategy @backoff_strategy end |
#credential ⇒ Object (readonly)
Attributes needed by the shell middleware when accessing the configured instance
27 28 29 |
# File 'lib/legate/auth/excon_middleware.rb', line 27 def credential @credential end |
#max_retries ⇒ Object (readonly)
Returns the value of attribute max_retries.
28 29 30 |
# File 'lib/legate/auth/excon_middleware.rb', line 28 def max_retries @max_retries end |
#retry_non_idempotent ⇒ Object (readonly)
Returns the value of attribute retry_non_idempotent.
28 29 30 |
# File 'lib/legate/auth/excon_middleware.rb', line 28 def retry_non_idempotent @retry_non_idempotent end |
#retry_on ⇒ Object (readonly)
Returns the value of attribute retry_on.
28 29 30 |
# File 'lib/legate/auth/excon_middleware.rb', line 28 def retry_on @retry_on end |
#scheme ⇒ Object (readonly)
Attributes needed by the shell middleware when accessing the configured instance
27 28 29 |
# File 'lib/legate/auth/excon_middleware.rb', line 27 def scheme @scheme end |
#token_manager ⇒ Object (readonly)
Attributes needed by the shell middleware when accessing the configured instance
27 28 29 |
# File 'lib/legate/auth/excon_middleware.rb', line 27 def token_manager @token_manager end |
#token_store ⇒ Object (readonly)
Attributes needed by the shell middleware when accessing the configured instance
27 28 29 |
# File 'lib/legate/auth/excon_middleware.rb', line 27 def token_store @token_store end |
Class Method Details
.new(*args) ⇒ Object
Class-level new method for both factory creation and Excon middleware stack
15 16 17 18 19 20 21 22 23 24 |
# File 'lib/legate/auth/excon_middleware.rb', line 15 def self.new(*args) if args.length == 1 && args[0].is_a?(Array) # Called by Excon's middleware stack with just the stack super(args[0]) else # Called by our factory with options stack, = args super(stack, || {}) end end |
Instance Method Details
#request_call(datum) {|Hash| ... } ⇒ Hash
Called for each request in the Excon middleware stack
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/legate/auth/excon_middleware.rb', line 60 def request_call(datum) # Determine if this is the shell or the configured instance # The shell instance will have a non-nil @stack from Excon, # and its @scheme will be nil (as Excon doesn't pass those to initialize by default) is_shell_instance = @scheme.nil? && @stack if is_shell_instance config_instance = datum[:connection].data[:auth_middleware_config] unless config_instance Legate.logger.warn('ExconMiddleware (shell): No :auth_middleware_config found. Passing through.') if defined?(Legate.logger) return @stack.request_call(datum) end Legate.logger.debug('ExconMiddleware (shell) delegating to configured instance for request logic.') if defined?(Legate.logger) # Modify datum using logic from config_instance, then shell calls @stack apply_authentication_logic(datum, config_instance) result = @stack.request_call(datum) result[:request] = datum[:request] if datum[:request] result else # This is the factory-configured instance, being called directly (e.g. by the shell, or in tests) # It should not call @stack.request_call itself if its @stack is the factory-provided nil. Legate.logger.debug('ExconMiddleware (configured instance) applying auth logic directly.') if defined?(Legate.logger) apply_authentication_logic(datum, self) # Apply logic using its own config datum end end |
#response_call(datum) {|Hash| ... } ⇒ Hash
Called after each response in the Excon middleware stack
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/legate/auth/excon_middleware.rb', line 91 def response_call(datum) is_shell_instance = @scheme.nil? && @stack if is_shell_instance # Shell instance calls down the stack first response_datum = @stack.response_call(datum) config_instance = datum[:connection].data[:auth_middleware_config] unless config_instance Legate.logger.warn('ExconMiddleware (shell): No :auth_middleware_config for response. Passing through.') if defined?(Legate.logger) return response_datum end Legate.logger.debug('ExconMiddleware (shell) delegating to configured instance for response logic.') if defined?(Legate.logger) # Process response and handle retries if config_instance.auto_retry && should_retry?(response_datum[:request], response_datum[:response]) config_instance.token_manager.invalidate_token(config_instance.scheme, config_instance.credential) if config_instance.token_manager && authentication_error?(response_datum[:response]) # Re-apply authentication with fresh credentials apply_authentication_logic(response_datum, config_instance) end response_datum else # This is the factory-configured instance, being called by the shell. Legate.logger.debug('ExconMiddleware (configured instance) processing response logic directly.') if defined?(Legate.logger) # Process response and handle retries if @auto_retry && should_retry?(datum[:request], datum[:response]) @token_manager.invalidate_token(@scheme, @credential) if @token_manager && authentication_error?(datum[:response]) # Re-apply authentication with fresh credentials apply_authentication_logic(datum, self) end datum end end |
#should_retry?(request_datum, response_details) ⇒ Boolean
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/legate/auth/excon_middleware.rb', line 128 def should_retry?(request_datum, response_details) return false unless request_datum && response_details return false unless @auto_retry status = response_details[:status] return false unless status # Check if it's a non-idempotent request unless @retry_non_idempotent method = request_datum[:method]&.to_s&.upcase return false if method && !%w[GET HEAD OPTIONS].include?(method) end # Check retry conditions return true if @retry_on.include?(status) return true if authentication_error?(response_details) return true if (500..599).cover?(status) return true if response_details[:headers]&.key?('Retry-After') false end |