Class: LcpRuby::Authentication::OmniAuthBuilder
- Inherits:
-
Object
- Object
- LcpRuby::Authentication::OmniAuthBuilder
- Defined in:
- lib/lcp_ruby/authentication/omniauth_builder.rb
Overview
Translates Provider value objects into OmniAuth strategy registrations. Called from the lcp_ruby.omniauth engine initializer at boot.
Constant Summary collapse
- DISCOVERY_SUFFIX =
%r{/\.well-known/openid-configuration/?\z}.freeze
Class Method Summary collapse
-
.derive_issuer(discovery_url) ⇒ Object
Strips the discovery suffix so the strategy receives a bare issuer URL.
-
.install_middleware!(app) ⇒ Object
Engine entry point.
-
.normalized_mount_path ⇒ Object
Normalises ‘LcpRuby.configuration.mount_path` to the form expected by URL prefixes: empty string for root mounts, leading slash and no trailing slash otherwise.
-
.register(builder, provider) ⇒ Object
Registers an :openid_connect strategy on the given OmniAuth::Builder using config drawn from the provider entry.
Class Method Details
.derive_issuer(discovery_url) ⇒ Object
Strips the discovery suffix so the strategy receives a bare issuer URL. Examples:
https://login.microsoftonline.com/<tenant>/v2.0/.well-known/openid-configuration
→ https://login.microsoftonline.com/<tenant>/v2.0
https://accounts.google.com/.well-known/openid-configuration
→ https://accounts.google.com
Falls through unchanged when the suffix isn’t present (e.g. some IdPs publish a non-standard discovery path that the operator pasted as-is). Raises ConfigurationError on blank input — ‘omniauth_openid_connect` would silently accept `issuer: “”` and fail with an opaque error at the first request; AuthValidator already guarantees a non-blank discovery_url at boot, so reaching this with a blank value is a bug.
96 97 98 99 100 101 102 |
# File 'lib/lcp_ruby/authentication/omniauth_builder.rb', line 96 def derive_issuer(discovery_url) if discovery_url.to_s.strip.empty? raise LcpRuby::Authentication::ConfigurationError, "OmniAuthBuilder.derive_issuer requires a non-blank discovery_url" end discovery_url.to_s.sub(DISCOVERY_SUFFIX, "") end |
.install_middleware!(app) ⇒ Object
Engine entry point. Registers ‘OmniAuth::Builder` middleware on the given Rails application iff at least one OIDC provider is configured, and sets `OmniAuth.config.path_prefix` so the middleware listens at the engine-relative `<mount>/auth` URL (NOT the default `/auth`).
Returns true when middleware was added, false when the call was a no-op (the gate this method enforces is the contract relied on by built_in-only / :external / :none deployments — the middleware must not appear when nothing OIDC is configured).
Both the path_prefix and the redirect_uri are derived from ‘LcpRuby.configuration.mount_path` so they stay in sync. Hosts that mount the engine at a non-root path MUST set `config.mount_path` accordingly (validated by AuthValidator at boot for OIDC installs).
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/lcp_ruby/authentication/omniauth_builder.rb', line 33 def install_middleware!(app) return false unless ProviderRegistry.oidc_enabled? OmniAuth.config.failure_raise_out_environments = [] OmniAuth.config.path_prefix = "#{normalized_mount_path}/auth" oidc_providers = ProviderRegistry.all.select(&:oidc?) app.middleware.use OmniAuth::Builder do oidc_providers.each { |provider| OmniAuthBuilder.register(self, provider) } end true rescue LcpRuby::Authentication::ConfigurationError => e # In production, fail loud — a misconfigured auth.yml in prod must # not silently disable OIDC. In dev/test/CI, log a warning and skip # middleware so `rake lcp_ruby:validate` (which depends on # `:environment`) can run and surface the issue in its report. raise if defined?(Rails) && Rails.respond_to?(:env) && Rails.env.production? log_skipped_install(e) false end |
.normalized_mount_path ⇒ Object
Normalises ‘LcpRuby.configuration.mount_path` to the form expected by URL prefixes: empty string for root mounts, leading slash and no trailing slash otherwise. Single source of truth for both `path_prefix` and `build_redirect_uri`.
59 60 61 62 63 |
# File 'lib/lcp_ruby/authentication/omniauth_builder.rb', line 59 def normalized_mount_path mount = LcpRuby.configuration.mount_path.to_s mount = "/#{mount}" unless mount.start_with?("/") mount == "/" ? "" : mount.chomp("/") end |
.register(builder, provider) ⇒ Object
Registers an :openid_connect strategy on the given OmniAuth::Builder using config drawn from the provider entry. Discovery is enabled and ‘issuer` is derived from `discovery_url` (strip the well-known suffix); `omniauth_openid_connect` then calls `Config.discover!(issuer)`, which appends `/.well-known/openid-configuration` and pulls authorization / token / userinfo / jwks / end_session endpoints from the IdP.
71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/lcp_ruby/authentication/omniauth_builder.rb', line 71 def register(builder, provider) builder.provider :openid_connect, name: provider.name.to_sym, issuer: derive_issuer(provider.discovery_url), discovery: true, scope: provider.scopes.map(&:to_sym), response_type: provider.response_type.to_sym, response_mode: provider.response_mode.to_sym, send_nonce: true, pkce: provider.pkce, client_options: (provider) end |