Module: LcpRuby::Authentication::TestSupport
- Defined in:
- lib/lcp_ruby/authentication/test_support.rb
Overview
Public test-support helper for Phase 2 bearer authentication.
Lets host-app specs sign valid (and invalid) JWTs that LCP’s bearer pipeline accepts, without spinning up a real IdP or stubbing engine internals. Loaded only under ‘Rails.env.test?` — `install_provider!` raises `NotInTestEnv` everywhere else as defense-in-depth against accidentally shipping the helper to production.
Stubs are installed via rspec-mocks’s ‘allow().to receive()`, so they auto-reset between examples — no manual teardown needed beyond `TestSupport.reset!` for the per-process keypair / provider cache.
Usage:
require "lcp_ruby/authentication/test_support"
RSpec.configure do |config|
config.before do
@oidc_signer = LcpRuby::Authentication::TestSupport.install_provider!(
"entra",
issuer: "https://test-issuer.example/",
audience: "api://lcp-test"
)
end
config.after { LcpRuby::Authentication::TestSupport.reset! }
end
it "lists deals via OIDC bearer" do
token = @oidc_signer.sign(sub: "user-1", roles: ["LCP.Admin"])
get "/api/deals", headers: { "Authorization" => "Bearer #{token}" }
expect(response).to have_http_status(:ok)
end
Negative-case helpers on the Signer:
signer.sign_expired(sub: "user-1") # exp in the past
signer.sign_wrong_audience(sub: "user-1") # aud mismatch
signer.sign_unknown_kid(sub: "user-1") # kid not in JWKS
signer.sign_tampered(sub: "user-1") # signature mutilated
Defined Under Namespace
Classes: NotInTestEnv, Signer, Stubber
Constant Summary collapse
- DEFAULT_KID =
"test-kid"
Class Method Summary collapse
-
.install_provider!(name, issuer:, audience:, kid: DEFAULT_KID) ⇒ Object
Installs a synthetic OIDC provider into LCP’s caches and returns a Signer for producing JWTs that the bearer pipeline will accept.
-
.reset! ⇒ Object
Clears the per-process provider/keypair cache and the JwksCache.
Class Method Details
.install_provider!(name, issuer:, audience:, kid: DEFAULT_KID) ⇒ Object
Installs a synthetic OIDC provider into LCP’s caches and returns a Signer for producing JWTs that the bearer pipeline will accept. Idempotent across multiple calls within the same example: each call adds its provider to the stubbed ‘oidc_providers` list. Must be called from inside an RSpec example or `before` hook (rspec-mocks is required).
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/lcp_ruby/authentication/test_support.rb', line 60 def install_provider!(name, issuer:, audience:, kid: DEFAULT_KID) ensure_test_env! ensure_rspec_mocks! name = name.to_s rsa_key = (keypairs[name] ||= OpenSSL::PKey::RSA.generate(2048)) public_jwk = JSON::JWK.new(rsa_key.public_key).merge(kid: kid, use: "sig", alg: "RS256") provider = build_provider(name: name, audience: audience) providers[name] = provider per_provider[name] = { provider: provider, issuer: issuer, kid: kid, public_jwk: public_jwk } install_stubs! register_oidc_resolver! Signer.new(provider: provider, issuer: issuer, audience: audience, kid: kid, rsa_key: rsa_key) end |
.reset! ⇒ Object
Clears the per-process provider/keypair cache and the JwksCache. rspec-mocks auto-resets between examples, so you typically only need this if you ‘install_provider!`-loop within a single example.
81 82 83 84 85 86 |
# File 'lib/lcp_ruby/authentication/test_support.rb', line 81 def reset! @providers = nil @per_provider = nil @keypairs = nil JwksCache.clear! if defined?(JwksCache) end |