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

Class Method Summary collapse

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'.



93
94
95
# File 'lib/keycloak-api-rails/testing.rb', line 93

def auth_headers_for(**options)
  { "Authorization" => "Bearer #{token_for(**options)}" }
end

.private_keyObject

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.



44
45
46
# File 'lib/keycloak-api-rails/testing.rb', line 44

def private_key
  @private_key ||= OpenSSL::PKey::RSA.generate(KEY_SIZE)
end

.public_keysObject



52
53
54
# File 'lib/keycloak-api-rails/testing.rb', line 52

def public_keys
  @public_keys ||= JSON::JWK::Set.new(JSON::JWK.new(private_key.public_key, kid: KEY_ID))
end

.signing_keyObject



48
49
50
# File 'lib/keycloak-api-rails/testing.rb', line 48

def signing_key
  @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.



58
59
60
# File 'lib/keycloak-api-rails/testing.rb', line 58

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.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/keycloak-api-rails/testing.rb', line 65

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"    => authorized_party,
    "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?

  claims.each { |name, value| payload[name.to_s] = value }

  JSON::JWT.new(payload).sign(signing_key, ALGORITHM).to_s
end