Module: KeycloakApiRails::Testing
- Defined in:
- lib/keycloak-api-rails/testing.rb
Defined Under Namespace
Modules: Helpers Classes: PublicKeyResolver
Constant Summary collapse
- KEY_SIZE =
2048- KEY_ID =
"keycloak-api-rails-testing"- ALGORITHM =
:RS256- DEFAULT_VALIDITY_IN_SECONDS =
3600- MONITOR =
Monitor.new
Class Method Summary collapse
-
.auth_headers_for(**options) ⇒ Object
The 'Authorization' header a client would send, e.g.
-
.private_key ⇒ Object
The RSA key pair used to sign the tokens forged by this module.
- .public_keys ⇒ Object
- .signing_key ⇒ Object
-
.stub_public_keys! ⇒ Object
Makes the library validate the tokens forged by this module.
-
.token_for(sub: SecureRandom.uuid, email: nil, locale: nil, authorized_party: nil, roles: [], resource_roles: {}, issued_at: Time.now, expires_at: nil, claims: {}) ⇒ Object
Forges a signed token, similar to the ones emitted by Keycloak.
Class Method Details
.auth_headers_for(**options) ⇒ Object
The 'Authorization' header a client would send, e.g. { "Authorization" => "Bearer eyJ0..." }. It accepts the same parameters as '.token_for'.
103 104 105 |
# File 'lib/keycloak-api-rails/testing.rb', line 103 def auth_headers_for(**) { "Authorization" => "Bearer #{token_for(**)}" } end |
.private_key ⇒ Object
The RSA key pair used to sign the tokens forged by this module. It is generated once per process: generating a key is by far the slowest operation of a test suite that uses tokens.
48 49 50 |
# File 'lib/keycloak-api-rails/testing.rb', line 48 def private_key MONITOR.synchronize { @private_key ||= OpenSSL::PKey::RSA.generate(KEY_SIZE) } end |
.public_keys ⇒ Object
56 57 58 |
# File 'lib/keycloak-api-rails/testing.rb', line 56 def public_keys MONITOR.synchronize { @public_keys ||= JSON::JWK::Set.new(JSON::JWK.new(private_key.public_key, kid: KEY_ID)) } end |
.signing_key ⇒ Object
52 53 54 |
# File 'lib/keycloak-api-rails/testing.rb', line 52 def signing_key MONITOR.synchronize { @signing_key ||= JSON::JWK.new(private_key, kid: KEY_ID) } end |
.stub_public_keys! ⇒ Object
Makes the library validate the tokens forged by this module. Assigning 'KeycloakApiRails.public_key_resolver = nil' restores the regular resolver.
62 63 64 |
# File 'lib/keycloak-api-rails/testing.rb', line 62 def stub_public_keys! KeycloakApiRails.public_key_resolver = PublicKeyResolver.new(public_keys) end |
.token_for(sub: SecureRandom.uuid, email: nil, locale: nil, authorized_party: nil, roles: [], resource_roles: {}, issued_at: Time.now, expires_at: nil, claims: {}) ⇒ Object
Forges a signed token, similar to the ones emitted by Keycloak. Every claim this library reads has a dedicated parameter; any other claim can be passed through 'claims', which is also how the attributes declared in 'config.custom_attributes' are set.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/keycloak-api-rails/testing.rb', line 69 def token_for(sub: SecureRandom.uuid, email: nil, locale: nil, authorized_party: nil, roles: [], resource_roles: {}, issued_at: Time.now, expires_at: nil, claims: {}) payload = { "sub" => sub, "email" => email, "locale" => locale, "azp" => , "iat" => issued_at.to_i, "exp" => (expires_at || (issued_at.to_i + DEFAULT_VALIDITY_IN_SECONDS)).to_i }.reject { |_, value| value.nil? } payload["realm_access"] = { "roles" => roles.map(&:to_s) } unless roles.nil? || roles.empty? payload["resource_access"] = build_resource_access(resource_roles) unless resource_roles.nil? || resource_roles.empty? unless claims.key?(:iss) || claims.key?("iss") config_realm_id = KeycloakApiRails.config.realm_id realm_id = config_realm_id.is_a?(String) ? config_realm_id : "master" payload["iss"] = File.join(KeycloakApiRails.config.server_url.to_s, "realms", realm_id) end claims.each { |name, value| payload[name.to_s] = value } JSON::JWT.new(payload).sign(signing_key, ALGORITHM).to_s end |