Module: KeycloakApiRails

Defined in:
lib/keycloak-api-rails.rb,
lib/keycloak-api-rails/helper.rb,
lib/keycloak-api-rails/railtie.rb,
lib/keycloak-api-rails/service.rb,
lib/keycloak-api-rails/testing.rb,
lib/keycloak-api-rails/version.rb,
lib/keycloak-api-rails/middleware.rb,
lib/keycloak-api-rails/http_client.rb,
lib/keycloak-api-rails/token_error.rb,
lib/keycloak-api-rails/configuration.rb,
lib/keycloak-api-rails/authentication.rb,
lib/keycloak-api-rails/public_key_resolver.rb,
lib/keycloak-api-rails/public_key_cached_resolver.rb

Defined Under Namespace

Modules: Authentication, Testing Classes: Configuration, HTTPClient, HTTPError, Helper, InvalidConfigurationError, Middleware, MissingPublicKeysError, PublicKeyCachedResolver, PublicKeyResolver, Railtie, Service, TokenError

Constant Summary collapse

MONITOR =

These objects are memoized lazily, on the first request each process serves -- which several threads of a threaded server reach at the same time. A Monitor rather than a Mutex: the memoizations nest, 'service' needing 'public_key_resolver', which needs 'http_client'.

Once memoized they are read without taking it: the assignment publishes an object that is fully built, and MRI reads an instance variable atomically. A 'configure' running while requests are already being served may then be picked up one request late, which is one more reason for it to belong in an initializer.

Monitor.new
VERSION =
"2.0.3"

Class Method Summary collapse

Class Method Details

.configObject



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

def self.config
  @configuration
end

.configureObject



33
34
35
36
37
38
# File 'lib/keycloak-api-rails.rb', line 33

def self.configure
  MONITOR.synchronize do
    yield @configuration ||= KeycloakApiRails::Configuration.new
    discard_configured_objects
  end
end

.http_clientObject



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

def self.http_client
  @http_client || MONITOR.synchronize { @http_client ||= KeycloakApiRails::HTTPClient.new(config, logger) }
end

.load_configurationObject



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/keycloak-api-rails.rb', line 78

def self.load_configuration
  configure do |config|
    config.server_url                             = nil
    config.realm_id                               = nil
    config.logger                                 = ::Logger.new(STDOUT)
    config.skip_paths                             = {}
    config.opt_in                                 = false
    config.token_expiration_tolerance_in_seconds  = 10
    config.public_key_cache_ttl                   = 86400
    config.custom_attributes                      = []
    config.ca_certificate_file                    = nil
    config.expected_audience                      = nil
    config.expected_token_type                    = nil
    config.verify_not_before                      = false
    config.allow_token_in_query_string            = false
    config.http_open_timeout                      = 5
    config.http_read_timeout                      = 5
    config.allowed_algorithms                     = KeycloakApiRails::Service::SUPPORTED_ALGORITHMS
  end
end

.loggerObject



74
75
76
# File 'lib/keycloak-api-rails.rb', line 74

def self.logger
  config.logger
end

.public_key_resolverObject



55
56
57
# File 'lib/keycloak-api-rails.rb', line 55

def self.public_key_resolver
  @public_key_resolver || MONITOR.synchronize { @public_key_resolver ||= PublicKeyCachedResolver.from_configuration(http_client, config) }
end

.public_key_resolver=(resolver) ⇒ Object

Mainly used by "keycloak-api-rails/testing" to validate tokens without a Keycloak server. Assigning nil restores the regular resolver. The memoized service is discarded, since it holds a reference to the resolver that is being replaced.



62
63
64
65
66
67
68
# File 'lib/keycloak-api-rails.rb', line 62

def self.public_key_resolver=(resolver)
  MONITOR.synchronize do
    @public_key_resolver          = resolver
    @public_key_resolver_assigned = !resolver.nil?
    @service                      = nil
  end
end

.serviceObject



70
71
72
# File 'lib/keycloak-api-rails.rb', line 70

def self.service
  @service || MONITOR.synchronize { @service ||= KeycloakApiRails::Service.new(public_key_resolver) }
end