Class: PetstoreApiClient::Authentication::Composite

Inherits:
Base
  • Object
show all
Defined in:
lib/petstore_api_client/authentication/composite.rb

Overview

Composite authentication strategy for applying multiple auth methods simultaneously

This authenticator implements the Composite pattern, allowing multiple authentication strategies to be applied to a single request. This is particularly useful during migration periods when transitioning from one auth method to another, or when an API accepts multiple authentication methods.

The Petstore API accepts both API Key and OAuth2 authentication. Using this composite authenticator, you can send both headers simultaneously, allowing the server to accept either authentication method.

All configured strategies are applied in the order they were added. Each strategy’s apply() method is called, allowing it to add its own headers to the request.

Examples:

Using both API Key and OAuth2

api_key_auth = ApiKey.new("special-key")
oauth2_auth = OAuth2.new(client_id: "id", client_secret: "secret")
composite = Composite.new([api_key_auth, oauth2_auth])

composite.apply(env)
# Request now has both:
# - api_key: special-key
# - Authorization: Bearer <token>

Building from configuration

strategies = []
strategies << ApiKey.new(config.api_key) if config.api_key
strategies << OAuth2.new(...) if config.oauth2_client_id
composite = Composite.new(strategies)

See Also:

Since:

  • 0.2.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#type

Constructor Details

#initialize(strategies = []) ⇒ Composite

Initialize composite authenticator with multiple strategies

rubocop:disable Lint/MissingSuper

Examples:

api_key = ApiKey.new("my-key")
oauth2 = OAuth2.new(client_id: "id", client_secret: "secret")
composite = Composite.new([api_key, oauth2])

Parameters:

  • (defaults to: [])

    List of authentication strategies Each strategy must respond to #apply(env) and #configured?

Raises:

  • if strategies is not an array

  • if any strategy doesn’t inherit from Base

Since:

  • 0.2.0



58
59
60
61
62
63
64
65
# File 'lib/petstore_api_client/authentication/composite.rb', line 58

def initialize(strategies = [])
  raise ArgumentError, "strategies must be an Array (got #{strategies.class})" unless strategies.is_a?(Array)

  validate_strategies!(strategies)
  @strategies = strategies
  # Performance optimization: cache configured strategies to avoid repeated checks
  @configured_strategies = @strategies.select(&:configured?)
end

Instance Attribute Details

#strategiesObject (readonly)

Since:

  • 0.2.0



42
43
44
# File 'lib/petstore_api_client/authentication/composite.rb', line 42

def strategies
  @strategies
end

Instance Method Details

#apply(env) ⇒ void

This method returns an undefined value.

Apply all configured authentication strategies to the request

Iterates through all strategies and calls apply() on each one if it’s configured. This allows multiple authentication headers to be added to the same request.

Examples:

composite = Composite.new([api_key_auth, oauth2_auth])
composite.apply(env)
# Both authentication methods are now applied

Parameters:

  • The Faraday request environment

Since:

  • 0.2.0



81
82
83
84
85
# File 'lib/petstore_api_client/authentication/composite.rb', line 81

def apply(env)
  # Performance optimization: use cached configured strategies
  # Avoids checking configured? on every request
  @configured_strategies.each { |strategy| strategy.apply(env) }
end

#configured?Boolean

Check if any authentication strategy is configured

Returns true if at least one strategy in the composite is configured. Returns false if no strategies are configured or if strategies array is empty.

Examples:

# No strategies configured
composite = Composite.new([])
composite.configured? # => false

# One strategy configured
api_key = ApiKey.new("my-key")
composite = Composite.new([api_key])
composite.configured? # => true

# Mixed (one configured, one not)
oauth2 = OAuth2.new # Not configured (no credentials)
composite = Composite.new([api_key, oauth2])
composite.configured? # => true (at least one is configured)

Returns:

  • true if at least one strategy is configured

Since:

  • 0.2.0



109
110
111
112
# File 'lib/petstore_api_client/authentication/composite.rb', line 109

def configured?
  # Performance optimization: use cached configured strategies
  !@configured_strategies.empty?
end

#configured_typesArray<String>

Get list of configured strategy types

Returns array of type names for strategies that are actually configured. Useful for debugging and logging.

Examples:

api_key = ApiKey.new("key")
oauth2 = OAuth2.new # Not configured
composite = Composite.new([api_key, oauth2])
composite.configured_types # => ["ApiKey"]

Returns:

  • List of configured strategy type names

Since:

  • 0.2.0



127
128
129
# File 'lib/petstore_api_client/authentication/composite.rb', line 127

def configured_types
  @strategies.select(&:configured?).map(&:type)
end

#inspectString Also known as: to_s

String representation showing all configured strategies

Examples:

composite = Composite.new([api_key, oauth2])
composite.inspect
# => "#<Composite strategies=[ApiKey, OAuth2] configured=[ApiKey, OAuth2]>"

Returns:

  • Human-readable representation

Since:

  • 0.2.0



140
141
142
143
144
145
146
# File 'lib/petstore_api_client/authentication/composite.rb', line 140

def inspect
  all_types = @strategies.map(&:type).join(", ")
  configured = configured_types.join(", ")
  configured = "none" if configured.empty?

  "#<#{self.class.name} strategies=[#{all_types}] configured=[#{configured}]>"
end