keycloak-api-rails 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb67f66191b532371ed77f5677c4959a3d01cd8d4fa270dd984a119d796077b0
4
- data.tar.gz: 64f29e21b50fb2d6f46d2a136c299aa9864c78aea977c9e4f7dc6a4927a28dff
3
+ metadata.gz: 1f53bfe86f8f72911bac95192b9a21fc0cf1ec01868e00f2cdd8edfcc57811e3
4
+ data.tar.gz: 2ad644c2561e191e9dd858055a9442df69fff0af02d078360164f1d41283f633
5
5
  SHA512:
6
- metadata.gz: 2db5967b4c4b7e678763d015dd05567103cafb42bce12f0018c241df45400f8c4538309a59dd7526994bc14cf587aef3b7c51040d89ca2599c91c409b6acf8a5
7
- data.tar.gz: 847fc92280c17a54d7f10976197b4ea0b37fea4217ee7ef9dd6d7089399b261831a07d3d56d07ffce2827aaf86c4332da680b3eaa044a3c35d0cb2347f123043
6
+ metadata.gz: da17e6a76b47460200ea397c58346dbdd43975f7aecec34e973b77ad15ebd12739d2c5d533064af24204d5be7bd4cc0f3c74b3df98e6d2623289a0d66f1398ad
7
+ data.tar.gz: 1f1f0ed249c2963fec160fdbdb6910a8387024f54d9956c35729fb5438037b541989046aee9dab2936dcc585d8f5e9ca6cd1b3247c20fb4dcea62ff7e2fae253
@@ -0,0 +1,52 @@
1
+ name: Release
2
+
3
+ # Publishing is triggered by pushing a version tag, e.g.:
4
+ # git tag -a v1.2.0 -m "Version 1.2.0" && git push origin v1.2.0
5
+ #
6
+ # No RubyGems API key is stored in this repository: the gem is pushed through
7
+ # RubyGems' Trusted Publishing, which exchanges a short-lived GitHub OIDC token
8
+ # for a scoped RubyGems credential. This requires a trusted publisher declared on
9
+ # https://rubygems.org/gems/keycloak-api-rails pointing to this repository, this
10
+ # workflow file name and the 'release' environment.
11
+ on:
12
+ push:
13
+ tags: [ "v*" ]
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ release:
20
+ name: Push gem to RubyGems.org
21
+ # Pinned rather than 'ubuntu-latest', for the same reason as in ci.yml.
22
+ runs-on: ubuntu-24.04
23
+
24
+ environment: release
25
+
26
+ permissions:
27
+ contents: write # 'rake release' pushes the version tag when it does not exist yet
28
+ id-token: write # mandatory to request the OIDC token used by trusted publishing
29
+
30
+ steps:
31
+ - uses: actions/checkout@v4
32
+
33
+ - name: Set up Ruby
34
+ uses: ruby/setup-ruby@v1
35
+ with:
36
+ ruby-version: '3.4'
37
+ bundler-cache: true
38
+
39
+ - name: Check that the tag matches KeycloakApiRails::VERSION
40
+ run: |
41
+ tag="${GITHUB_REF_NAME#v}"
42
+ version="$(ruby -Ilib -r keycloak-api-rails/version -e 'print KeycloakApiRails::VERSION')"
43
+ if [ "$tag" != "$version" ]; then
44
+ echo "::error::Tag '${GITHUB_REF_NAME}' does not match KeycloakApiRails::VERSION '${version}'"
45
+ exit 1
46
+ fi
47
+
48
+ - name: Run tests
49
+ run: bundle exec rspec
50
+
51
+ # Builds the gem, pushes it to RubyGems.org and waits for it to be available.
52
+ - uses: rubygems/release-gem@v1
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  log/*.log
3
3
  .byebug_history
4
4
  *.gem
5
+ pkg/
5
6
  # This gem supports several Ruby versions, each of them resolving a different set of
6
7
  # dependencies (Ruby 2.7 caps Rails to 7.1, Ruby 3.1 to 7.2, Ruby 3.2+ resolves Rails 8.1).
7
8
  # A single committed lockfile cannot satisfy all of them.
data/CHANGELOG.md CHANGED
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.1.1] - 2026-07-31
9
+
10
+ * New test helpers, in `keycloak-api-rails/testing`: `KeycloakApiRails::Testing.stub_public_keys!` validates the tokens forged by `keycloak_token` and `keycloak_auth_headers`, so that controller and request tests can be authenticated without a Keycloak server, and without the boilerplate the README used to describe. This file is not loaded by `keycloak-api-rails` and has to be required explicitly
11
+ * Publish the gem to RubyGems from Github Actions when a `v*` tag is pushed, using RubyGems' Trusted Publishing
12
+
8
13
  ## [1.1.0] - 2026-07-31
9
14
 
10
15
  * Dependencies: Upgrade test dependency `timecop` to `0.9.11`
data/README.md CHANGED
@@ -18,7 +18,7 @@ the recommended path.
18
18
  ## Install
19
19
 
20
20
  ```ruby
21
- gem "keycloak-api-rails", "1.1.0"
21
+ gem "keycloak-api-rails", "1.1.1"
22
22
  ```
23
23
 
24
24
  ## Token validation
@@ -191,36 +191,60 @@ end
191
191
 
192
192
  ## Writing integration tests
193
193
 
194
- If you want to write controller tests in your codebase and that Keycloak is configured for these controllers, here is how to mock it.
194
+ If you want to write controller or request tests in your codebase and that Keycloak is configured for these controllers,
195
+ this gem provides the helpers that forge valid tokens, so that no Keycloak server is required.
196
+ These helpers are not loaded by `keycloak-api-rails`: they have to be required explicitly, so that nothing they define ends up in a production process.
195
197
  These lines are based on tests written using `rspec`.
196
198
 
197
- * First, create a private key. This key should be created once per test suite for performance matters.
198
199
  ```ruby
199
- config.before(:suite) do
200
- $private_key = OpenSSL::PKey::RSA.generate(1024)
200
+ # spec/rails_helper.rb
201
+ require "keycloak-api-rails/testing"
202
+
203
+ RSpec.configure do |config|
204
+ config.include KeycloakApiRails::Testing::Helpers
205
+ config.before(:suite) { KeycloakApiRails::Testing.stub_public_keys! }
201
206
  end
202
207
  ```
203
- * Then, in a `shared_context`, configure a lazy token based on your main user. (here, we assume you have a `user` variable with a `keycloak_id` property)
208
+
209
+ `stub_public_keys!` makes the library validate the tokens forged by these helpers, instead of fetching public keys from a Keycloak server.
210
+ `server_url` and `realm_id` therefore do not have to be configured in the test environment. Requests can then be authenticated with:
211
+
204
212
  ```ruby
205
- let(:jwt) do
206
- claims = {
207
- iat: Time.zone.now.to_i,
208
- exp: (Time.zone.now + 1.day).to_i,
209
- sub: user.keycloak_id,
210
- }
211
- token = JSON::JWT.new(claims)
212
- token.kid = "default"
213
- token.sign($private_key, :RS256).to_s
213
+ it "returns the current user" do
214
+ get "/me", headers: keycloak_auth_headers(sub: user.keycloak_id)
215
+
216
+ expect(response).to have_http_status(:ok)
214
217
  end
215
218
  ```
216
- * Finally, in the same `shared_context`, stub `KeycloakApiRails.public_key_resolver` to use a valid public key that is able to validate `jwt`:
219
+
220
+ `keycloak_auth_headers` returns an `Authorization` header, and `keycloak_token` returns the token alone.
221
+ Both accept the same optional parameters, one for each claim this library reads:
222
+
223
+ | Parameter | Claim | Default |
224
+ | --- | --- | --- |
225
+ | `sub` | `sub` | a random UUID |
226
+ | `email` | `email` | none |
227
+ | `locale` | `locale` | none |
228
+ | `authorized_party` | `azp` | none |
229
+ | `roles` | `realm_access.roles` | none |
230
+ | `resource_roles` | `resource_access` | none |
231
+ | `issued_at` | `iat` | now |
232
+ | `expires_at` | `exp` | one hour after `issued_at` |
233
+ | `claims` | any other claim | none |
234
+
235
+ For instance, to authenticate a request as a user having the realm role `admin`, the role `reader` on the client `a-client`,
236
+ and a `tenant_id` attribute declared in `config.custom_attributes`:
237
+
217
238
  ```ruby
218
- before(:each) do
219
- public_key_resolver = KeycloakApiRails.public_key_resolver
220
- allow(public_key_resolver).to receive(:find_public_keys) { JSON::JWK::Set.new(JSON::JWK.new($private_key, kid: "default")) }
221
- end
239
+ headers = keycloak_auth_headers(sub: user.keycloak_id,
240
+ roles: ["admin"],
241
+ resource_roles: { "a-client" => ["reader"] },
242
+ claims: { "tenant_id" => tenant.id })
222
243
  ```
223
244
 
245
+ An expired token is forged by passing an `expires_at` in the past, which is how a `401` can be tested.
246
+ Assigning `KeycloakApiRails.public_key_resolver = nil` restores the regular resolver.
247
+
224
248
  ## How to execute library tests
225
249
 
226
250
  From the `keycloak-rails-api` directory:
@@ -230,6 +254,25 @@ From the `keycloak-rails-api` directory:
230
254
  $ docker run -v `pwd`:/usr/src/app/ keycloak-rails-api:test bundle exec rspec spec
231
255
  ```
232
256
 
257
+ ## How to release a new version
258
+
259
+ Releases are published to [RubyGems](https://rubygems.org/gems/keycloak-api-rails) by GitHub Actions
260
+ (`.github/workflows/release.yml`), through [Trusted Publishing](https://guides.rubygems.org/trusted-publishing/):
261
+ no API key is stored in this repository, the workflow exchanges a short-lived GitHub OIDC token for a
262
+ scoped RubyGems credential.
263
+
264
+ 1. Update `KeycloakApiRails::VERSION` in `lib/keycloak-api-rails/version.rb` and the `CHANGELOG.md`
265
+ 2. Commit and push these changes to `main`
266
+ 3. Tag the commit and push the tag:
267
+
268
+ ```
269
+ $ git tag -a v1.2.0 -m "Version 1.2.0"
270
+ $ git push origin v1.2.0
271
+ ```
272
+
273
+ The workflow then checks that the tag matches `KeycloakApiRails::VERSION`, runs the tests, builds the gem
274
+ and pushes it. It only publishes tags starting with `v`.
275
+
233
276
  ## Next developments
234
277
 
235
278
  * Manage multiple realms
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -22,6 +22,8 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.add_development_dependency "rspec", "3.13.2"
24
24
  spec.add_development_dependency "timecop", "0.9.11"
25
+ # Required by 'rake release', which builds and publishes the gem from the CI.
26
+ spec.add_development_dependency "rake", ">= 13.0"
25
27
  # Not pinned to an exact version: byebug 12 requires Ruby >= 3.1, byebug 13 requires Ruby >= 3.2.
26
28
  # Older Rubies resolve to byebug 11.
27
29
  spec.add_development_dependency "byebug", ">= 11.1.3"
@@ -0,0 +1,118 @@
1
+ # Test helpers for the applications that authenticate their requests with this library.
2
+ #
3
+ # This file is *not* loaded by "keycloak-api-rails": it has to be required explicitly, so that
4
+ # nothing it defines can end up in a production process.
5
+ #
6
+ # # spec/rails_helper.rb
7
+ # require "keycloak-api-rails/testing"
8
+ #
9
+ # RSpec.configure do |config|
10
+ # config.include KeycloakApiRails::Testing::Helpers
11
+ # config.before(:suite) { KeycloakApiRails::Testing.stub_public_keys! }
12
+ # end
13
+ #
14
+ # Requests can then be authenticated without a running Keycloak, and without configuring
15
+ # 'server_url' or 'realm_id':
16
+ #
17
+ # get "/me", headers: keycloak_auth_headers(sub: user.keycloak_id, roles: ["admin"])
18
+
19
+ require_relative "../keycloak-api-rails"
20
+ require "securerandom"
21
+
22
+ module KeycloakApiRails
23
+ module Testing
24
+
25
+ KEY_SIZE = 2048
26
+ KEY_ID = "keycloak-api-rails-testing"
27
+ ALGORITHM = :RS256
28
+ DEFAULT_VALIDITY_IN_SECONDS = 3600
29
+
30
+ # Returns the public keys forged by this module, instead of fetching them from a Keycloak server.
31
+ class PublicKeyResolver
32
+ def initialize(public_keys)
33
+ @public_keys = public_keys
34
+ end
35
+
36
+ def find_public_keys
37
+ @public_keys
38
+ end
39
+ end
40
+
41
+ class << self
42
+ # The RSA key pair used to sign the tokens forged by this module. It is generated once per
43
+ # process: generating a key is by far the slowest operation of a test suite that uses tokens.
44
+ def private_key
45
+ @private_key ||= OpenSSL::PKey::RSA.generate(KEY_SIZE)
46
+ end
47
+
48
+ def signing_key
49
+ @signing_key ||= JSON::JWK.new(private_key, kid: KEY_ID)
50
+ end
51
+
52
+ def public_keys
53
+ @public_keys ||= JSON::JWK::Set.new(JSON::JWK.new(private_key.public_key, kid: KEY_ID))
54
+ end
55
+
56
+ # Makes the library validate the tokens forged by this module. Assigning
57
+ # 'KeycloakApiRails.public_key_resolver = nil' restores the regular resolver.
58
+ def stub_public_keys!
59
+ KeycloakApiRails.public_key_resolver = PublicKeyResolver.new(public_keys)
60
+ end
61
+
62
+ # Forges a signed token, similar to the ones emitted by Keycloak. Every claim this library
63
+ # reads has a dedicated parameter; any other claim can be passed through 'claims', which is
64
+ # also how the attributes declared in 'config.custom_attributes' are set.
65
+ def token_for(sub: SecureRandom.uuid,
66
+ email: nil,
67
+ locale: nil,
68
+ authorized_party: nil,
69
+ roles: [],
70
+ resource_roles: {},
71
+ issued_at: Time.now,
72
+ expires_at: nil,
73
+ claims: {})
74
+ payload = {
75
+ "sub" => sub,
76
+ "email" => email,
77
+ "locale" => locale,
78
+ "azp" => authorized_party,
79
+ "iat" => issued_at.to_i,
80
+ "exp" => (expires_at || (issued_at.to_i + DEFAULT_VALIDITY_IN_SECONDS)).to_i
81
+ }.reject { |_, value| value.nil? }
82
+
83
+ payload["realm_access"] = { "roles" => roles.map(&:to_s) } unless roles.nil? || roles.empty?
84
+ payload["resource_access"] = build_resource_access(resource_roles) unless resource_roles.nil? || resource_roles.empty?
85
+
86
+ claims.each { |name, value| payload[name.to_s] = value }
87
+
88
+ JSON::JWT.new(payload).sign(signing_key, ALGORITHM).to_s
89
+ end
90
+
91
+ # The 'Authorization' header a client would send, e.g. { "Authorization" => "Bearer eyJ0..." }.
92
+ # It accepts the same parameters as '.token_for'.
93
+ def auth_headers_for(**options)
94
+ { "Authorization" => "Bearer #{token_for(**options)}" }
95
+ end
96
+
97
+ private
98
+
99
+ def build_resource_access(resource_roles)
100
+ resource_roles.inject({}) do |resource_access, (name, roles)|
101
+ resource_access[name.to_s] = { "roles" => Array(roles).map(&:to_s) }
102
+ resource_access
103
+ end
104
+ end
105
+ end
106
+
107
+ # Meant to be included in a test suite, e.g. 'config.include KeycloakApiRails::Testing::Helpers'.
108
+ module Helpers
109
+ def keycloak_token(**options)
110
+ KeycloakApiRails::Testing.token_for(**options)
111
+ end
112
+
113
+ def keycloak_auth_headers(**options)
114
+ KeycloakApiRails::Testing.auth_headers_for(**options)
115
+ end
116
+ end
117
+ end
118
+ end
@@ -1,3 +1,3 @@
1
1
  module KeycloakApiRails
2
- VERSION = "1.1.0"
2
+ VERSION = "1.1.1"
3
3
  end
@@ -33,6 +33,14 @@ module KeycloakApiRails
33
33
  @public_key_resolver ||= PublicKeyCachedResolver.from_configuration(http_client, config)
34
34
  end
35
35
 
36
+ # Mainly used by "keycloak-api-rails/testing" to validate tokens without a Keycloak server.
37
+ # Assigning nil restores the regular resolver. The memoized service is discarded, since it holds
38
+ # a reference to the resolver that is being replaced.
39
+ def self.public_key_resolver=(resolver)
40
+ @public_key_resolver = resolver
41
+ @service = nil
42
+ end
43
+
36
44
  def self.service
37
45
  @service ||= KeycloakApiRails::Service.new(public_key_resolver)
38
46
  end
@@ -205,6 +205,12 @@ RSpec.describe KeycloakApiRails::Service do
205
205
  @result = service2.need_middleware_authentication?(method, path, headers)
206
206
  end
207
207
 
208
+ # The configuration is global: leaving 'opt_in' enabled would disable the authentication
209
+ # of every example running afterwards.
210
+ after do
211
+ KeycloakApiRails.config.opt_in = false
212
+ end
213
+
208
214
  it "should return false" do
209
215
  expect(@result).to be false
210
216
  end
@@ -0,0 +1,102 @@
1
+ require_relative "../../lib/keycloak-api-rails/testing"
2
+
3
+ RSpec.describe KeycloakApiRails::Testing do
4
+ include KeycloakApiRails::Testing::Helpers
5
+
6
+ # The tokens are validated by the real middleware and the real service, so that these examples
7
+ # fail if what this module forges stops being what the library expects.
8
+ let(:authenticated_env) { {} }
9
+ let(:app) do
10
+ downstream = lambda do |env|
11
+ authenticated_env.replace(env)
12
+ [200, {}, ["OK"]]
13
+ end
14
+ KeycloakApiRails::Middleware.new(downstream)
15
+ end
16
+
17
+ def get(headers)
18
+ app.call({
19
+ "REQUEST_METHOD" => "GET",
20
+ "PATH_INFO" => "/me",
21
+ "REQUEST_URI" => "http://example.org/me",
22
+ "HTTP_AUTHORIZATION" => headers["Authorization"]
23
+ })
24
+ end
25
+
26
+ before(:each) do
27
+ # The middleware only authenticates a request when the configuration tells it to, and the
28
+ # configuration is global: these examples cannot rely on what the other ones leave behind.
29
+ KeycloakApiRails.config.opt_in = false
30
+ KeycloakApiRails.config.skip_paths = {}
31
+ KeycloakApiRails::Testing.stub_public_keys!
32
+ end
33
+
34
+ after(:each) do
35
+ KeycloakApiRails.public_key_resolver = nil
36
+ end
37
+
38
+ describe ".stub_public_keys!" do
39
+ it "should validate the tokens forged by this module" do
40
+ status, _headers, _body = get(keycloak_auth_headers)
41
+
42
+ expect(status).to eq(200)
43
+ end
44
+
45
+ it "should not require a Keycloak server to be configured" do
46
+ expect(KeycloakApiRails.config.server_url).to be_nil
47
+ expect(KeycloakApiRails.config.realm_id).to be_nil
48
+
49
+ status, _headers, _body = get(keycloak_auth_headers)
50
+
51
+ expect(status).to eq(200)
52
+ end
53
+ end
54
+
55
+ describe ".token_for" do
56
+ it "should authenticate the given user" do
57
+ get(keycloak_auth_headers(sub: "a-keycloak-id"))
58
+
59
+ expect(KeycloakApiRails::Helper.current_user_id(authenticated_env)).to eq("a-keycloak-id")
60
+ end
61
+
62
+ it "should generate a different user for each token" do
63
+ first_token = JSON::JWT.decode(keycloak_token, KeycloakApiRails::Testing.public_keys)
64
+ second_token = JSON::JWT.decode(keycloak_token, KeycloakApiRails::Testing.public_keys)
65
+
66
+ expect(first_token["sub"]).not_to eq(second_token["sub"])
67
+ end
68
+
69
+ it "should expose every claim read by the library" do
70
+ get(keycloak_auth_headers(sub: "a-keycloak-id",
71
+ email: "an-email@keycloak.io",
72
+ locale: "fr",
73
+ authorized_party: "a-client",
74
+ roles: ["admin", "user"],
75
+ resource_roles: { "a-client" => ["reader"] }))
76
+
77
+ expect(KeycloakApiRails::Helper.current_user_id(authenticated_env)).to eq("a-keycloak-id")
78
+ expect(KeycloakApiRails::Helper.current_user_email(authenticated_env)).to eq("an-email@keycloak.io")
79
+ expect(KeycloakApiRails::Helper.current_user_locale(authenticated_env)).to eq("fr")
80
+ expect(KeycloakApiRails::Helper.current_authorized_party(authenticated_env)).to eq("a-client")
81
+ expect(KeycloakApiRails::Helper.current_user_roles(authenticated_env)).to eq(["admin", "user"])
82
+ expect(KeycloakApiRails::Helper.current_resource_roles(authenticated_env)).to eq({ "a-client" => ["reader"] })
83
+ end
84
+
85
+ it "should expose the claims declared as custom attributes" do
86
+ KeycloakApiRails.config.custom_attributes = ["tenant_id"]
87
+
88
+ get(keycloak_auth_headers(claims: { "tenant_id" => "a-tenant" }))
89
+
90
+ expect(KeycloakApiRails::Helper.current_user_custom_attributes(authenticated_env)).to eq({ "tenant_id" => "a-tenant" })
91
+ ensure
92
+ KeycloakApiRails.config.custom_attributes = []
93
+ end
94
+
95
+ it "should forge a token that is expired when 'expires_at' is in the past" do
96
+ status, _headers, body = get(keycloak_auth_headers(issued_at: Time.now - 7200, expires_at: Time.now - 3600))
97
+
98
+ expect(status).to eq(401)
99
+ expect(body.first).to include("JWT token is expired")
100
+ end
101
+ end
102
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keycloak-api-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorent Lempereur
@@ -65,6 +65,20 @@ dependencies:
65
65
  - - '='
66
66
  - !ruby/object:Gem::Version
67
67
  version: 0.9.11
68
+ - !ruby/object:Gem::Dependency
69
+ name: rake
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '13.0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '13.0'
68
82
  - !ruby/object:Gem::Dependency
69
83
  name: byebug
70
84
  requirement: !ruby/object:Gem::Requirement
@@ -87,6 +101,7 @@ extensions: []
87
101
  extra_rdoc_files: []
88
102
  files:
89
103
  - ".github/workflows/ci.yml"
104
+ - ".github/workflows/release.yml"
90
105
  - ".gitignore"
91
106
  - ".rspec"
92
107
  - CHANGELOG.md
@@ -94,6 +109,7 @@ files:
94
109
  - Gemfile
95
110
  - MIT-LICENSE
96
111
  - README.md
112
+ - Rakefile
97
113
  - keycloak-api-rails.gemspec
98
114
  - lib/keycloak-api-rails.rb
99
115
  - lib/keycloak-api-rails/authentication.rb
@@ -105,6 +121,7 @@ files:
105
121
  - lib/keycloak-api-rails/public_key_resolver.rb
106
122
  - lib/keycloak-api-rails/railtie.rb
107
123
  - lib/keycloak-api-rails/service.rb
124
+ - lib/keycloak-api-rails/testing.rb
108
125
  - lib/keycloak-api-rails/token_error.rb
109
126
  - lib/keycloak-api-rails/version.rb
110
127
  - spec/keycloak-api-rails/activesupport_free_spec.rb
@@ -113,6 +130,7 @@ files:
113
130
  - spec/keycloak-api-rails/helper_spec.rb
114
131
  - spec/keycloak-api-rails/public_key_cached_resolver_spec.rb
115
132
  - spec/keycloak-api-rails/service_spec.rb
133
+ - spec/keycloak-api-rails/testing_spec.rb
116
134
  - spec/spec_helper.rb
117
135
  - spec/support/activesupport_free_probe.rb
118
136
  - spec/support/public_key_cached_resolver_stub.rb
@@ -136,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
154
  - !ruby/object:Gem::Version
137
155
  version: '0'
138
156
  requirements: []
139
- rubygems_version: 4.0.17
157
+ rubygems_version: 3.6.9
140
158
  specification_version: 4
141
159
  summary: Rails middleware that validates Authorization token emitted by Keycloak
142
160
  test_files: []