Class: Verikloak::Discovery
- Inherits:
-
Object
- Object
- Verikloak::Discovery
- Defined in:
- lib/verikloak/discovery.rb
Overview
Fetches and caches the OpenID Connect Discovery document.
This class retrieves the discovery metadata from an OpenID Connect provider (e.g., Keycloak) using the ‘.well-known/openid-configuration` endpoint. It validates required fields such as `jwks_uri` and `issuer`, and supports:
-
Dependency Injection of Faraday connection for testing and middleware
-
In-memory caching with configurable TTL
-
Thread safety via Mutex
-
Automatic handling of common HTTP statuses (including multi-hop redirects)
### Thread-safety ‘#fetch!` is synchronized, so concurrent callers share the same cached value and refresh.
### Errors Raises DiscoveryError with one of the following ‘code`s:
-
‘invalid_discovery_url`
-
‘discovery_metadata_fetch_failed`
-
‘discovery_metadata_invalid`
-
‘discovery_redirect_error`
Constant Summary collapse
- REQUIRED_FIELDS =
Required keys that must be present in the discovery document.
%w[jwks_uri issuer].freeze
Instance Method Summary collapse
-
#fetch! ⇒ Hash
Fetches and parses the discovery document, using the in-memory cache if fresh.
-
#initialize(discovery_url:, connection: Verikloak::HTTP.default_connection, cache_ttl: 3600) ⇒ Discovery
constructor
A new instance of Discovery.
Constructor Details
#initialize(discovery_url:, connection: Verikloak::HTTP.default_connection, cache_ttl: 3600) ⇒ Discovery
Returns a new instance of Discovery.
47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/verikloak/discovery.rb', line 47 def initialize(discovery_url:, connection: Verikloak::HTTP.default_connection, cache_ttl: 3600) unless discovery_url.is_a?(String) && discovery_url.strip.match?(%r{^https?://}) raise DiscoveryError.new('Invalid discovery URL: must be a non-empty HTTP(S) URL', code: 'invalid_discovery_url') end @discovery_url = discovery_url @conn = connection @cache_ttl = cache_ttl @cached_json = nil @fetched_at = nil @mutex = Mutex.new end |
Instance Method Details
#fetch! ⇒ Hash
Fetches and parses the discovery document, using the in-memory cache if fresh.
Cache freshness is determined by ‘cache_ttl` from initialization.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/verikloak/discovery.rb', line 67 def fetch! @mutex.synchronize do # Return cached if within TTL return @cached_json if @cached_json && (Time.now - @fetched_at) < @cache_ttl # Fetch fresh document json = with_error_handling { fetch_and_parse_json_from_url } validate_required_fields!(json) # Update cache @cached_json = json @fetched_at = Time.now json end end |