keycloak-api-rails 0.12.3 → 1.0.0

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: 834cdb0350ed3724a6f28aed40c36b3a51d96850f49ef8a0b9946a8135f1ca56
4
- data.tar.gz: 8ec6a52a53e688cb20feaf9762e17bde13fbbf483d0413bf95400833a79ac6e1
3
+ metadata.gz: c8848fb5696ab7e2962d8491b2df8e17c1bc88a3f08bb4b328b96e872b5858de
4
+ data.tar.gz: 9b2f8541d0a2e26f59cec67fcd6573e34c898db12a769335faa701a9c15b66be
5
5
  SHA512:
6
- metadata.gz: 947afe4ef457d63988f592b16a57b9dd8bf7a58e7c6f403525e5a228a992c49d51262541cd5feb6b7c3c7722fd7390f7447fb698c273f359448ed3f46b3d2fd8
7
- data.tar.gz: efb05a679ff2c389618534e975425276c9007651b495abc19a7f381116fe81fba490571e4d751cfbd69aa8a02c685d1738b543fabd99ca9fe07dcf9319a87701
6
+ metadata.gz: e7f9ca820ba2eb32fca2bcbf72c9a19e70ed2bc62e95f6f059fcd848f7aafbb40847017a012a93ff7b5f55fe029b4e7cd353f2376eb90c7a5c0b11f4fac4e310
7
+ data.tar.gz: 57a3a77dec4b4daeb697ee3b3d8f4ed4ad349c2b68e60ca7001e46be2809a358c1e24e6dd1a3e2d31270be9e0e8daaac0176511e7009ce9cca4ea591e8040ba7
@@ -0,0 +1,28 @@
1
+ name: Ruby
2
+
3
+ on:
4
+ push:
5
+ branches: [ "main" ]
6
+ pull_request:
7
+ branches: [ "main" ]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ubuntu-latest
15
+
16
+ strategy:
17
+ matrix:
18
+ ruby-version: ['3.2']
19
+
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ - name: Set up Ruby
23
+ uses: ruby/setup-ruby@v1
24
+ with:
25
+ ruby-version: ${{ matrix.ruby-version }}
26
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
27
+ - name: Run tests
28
+ run: bundle exec rspec
data/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@ 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.0.0] - 2025-06-20
9
+
10
+ * *[BREAKING CHANGE!]* Rename top-level module from `Keycloak` to `KeycloakApiRails` to avoid conflicts with other gems. (thanks to @eilers)
11
+ * *Migration: Please do a global find and replace of `Keycloak.` to `KeycloakApiRails.` in your application.*
12
+ * Automate tests on Github Actions
13
+ * Dependencies: Upgrade test dependencies: timecop, rspec and byebug.
14
+
15
+ ## [0.12.4] - 2024-06-20
16
+
17
+ * Log error when fetching the public keys from Keycloak
8
18
 
9
19
  ## [0.12.3] - 2024-06-20
10
20
 
data/Gemfile.lock CHANGED
@@ -1,228 +1,244 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- keycloak-api-rails (0.12.3)
4
+ keycloak-api-rails (1.0.0)
5
5
  json-jwt (>= 1.11.0)
6
6
  rails (>= 4.2)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- actioncable (7.1.3.4)
12
- actionpack (= 7.1.3.4)
13
- activesupport (= 7.1.3.4)
11
+ action_text-trix (2.1.15)
12
+ railties
13
+ actioncable (8.1.1)
14
+ actionpack (= 8.1.1)
15
+ activesupport (= 8.1.1)
14
16
  nio4r (~> 2.0)
15
17
  websocket-driver (>= 0.6.1)
16
18
  zeitwerk (~> 2.6)
17
- actionmailbox (7.1.3.4)
18
- actionpack (= 7.1.3.4)
19
- activejob (= 7.1.3.4)
20
- activerecord (= 7.1.3.4)
21
- activestorage (= 7.1.3.4)
22
- activesupport (= 7.1.3.4)
23
- mail (>= 2.7.1)
24
- net-imap
25
- net-pop
26
- net-smtp
27
- actionmailer (7.1.3.4)
28
- actionpack (= 7.1.3.4)
29
- actionview (= 7.1.3.4)
30
- activejob (= 7.1.3.4)
31
- activesupport (= 7.1.3.4)
32
- mail (~> 2.5, >= 2.5.4)
33
- net-imap
34
- net-pop
35
- net-smtp
19
+ actionmailbox (8.1.1)
20
+ actionpack (= 8.1.1)
21
+ activejob (= 8.1.1)
22
+ activerecord (= 8.1.1)
23
+ activestorage (= 8.1.1)
24
+ activesupport (= 8.1.1)
25
+ mail (>= 2.8.0)
26
+ actionmailer (8.1.1)
27
+ actionpack (= 8.1.1)
28
+ actionview (= 8.1.1)
29
+ activejob (= 8.1.1)
30
+ activesupport (= 8.1.1)
31
+ mail (>= 2.8.0)
36
32
  rails-dom-testing (~> 2.2)
37
- actionpack (7.1.3.4)
38
- actionview (= 7.1.3.4)
39
- activesupport (= 7.1.3.4)
33
+ actionpack (8.1.1)
34
+ actionview (= 8.1.1)
35
+ activesupport (= 8.1.1)
40
36
  nokogiri (>= 1.8.5)
41
- racc
42
37
  rack (>= 2.2.4)
43
38
  rack-session (>= 1.0.1)
44
39
  rack-test (>= 0.6.3)
45
40
  rails-dom-testing (~> 2.2)
46
41
  rails-html-sanitizer (~> 1.6)
47
- actiontext (7.1.3.4)
48
- actionpack (= 7.1.3.4)
49
- activerecord (= 7.1.3.4)
50
- activestorage (= 7.1.3.4)
51
- activesupport (= 7.1.3.4)
42
+ useragent (~> 0.16)
43
+ actiontext (8.1.1)
44
+ action_text-trix (~> 2.1.15)
45
+ actionpack (= 8.1.1)
46
+ activerecord (= 8.1.1)
47
+ activestorage (= 8.1.1)
48
+ activesupport (= 8.1.1)
52
49
  globalid (>= 0.6.0)
53
50
  nokogiri (>= 1.8.5)
54
- actionview (7.1.3.4)
55
- activesupport (= 7.1.3.4)
51
+ actionview (8.1.1)
52
+ activesupport (= 8.1.1)
56
53
  builder (~> 3.1)
57
54
  erubi (~> 1.11)
58
55
  rails-dom-testing (~> 2.2)
59
56
  rails-html-sanitizer (~> 1.6)
60
- activejob (7.1.3.4)
61
- activesupport (= 7.1.3.4)
57
+ activejob (8.1.1)
58
+ activesupport (= 8.1.1)
62
59
  globalid (>= 0.3.6)
63
- activemodel (7.1.3.4)
64
- activesupport (= 7.1.3.4)
65
- activerecord (7.1.3.4)
66
- activemodel (= 7.1.3.4)
67
- activesupport (= 7.1.3.4)
60
+ activemodel (8.1.1)
61
+ activesupport (= 8.1.1)
62
+ activerecord (8.1.1)
63
+ activemodel (= 8.1.1)
64
+ activesupport (= 8.1.1)
68
65
  timeout (>= 0.4.0)
69
- activestorage (7.1.3.4)
70
- actionpack (= 7.1.3.4)
71
- activejob (= 7.1.3.4)
72
- activerecord (= 7.1.3.4)
73
- activesupport (= 7.1.3.4)
66
+ activestorage (8.1.1)
67
+ actionpack (= 8.1.1)
68
+ activejob (= 8.1.1)
69
+ activerecord (= 8.1.1)
70
+ activesupport (= 8.1.1)
74
71
  marcel (~> 1.0)
75
- activesupport (7.1.3.4)
72
+ activesupport (8.1.1)
76
73
  base64
77
74
  bigdecimal
78
- concurrent-ruby (~> 1.0, >= 1.0.2)
75
+ concurrent-ruby (~> 1.0, >= 1.3.1)
79
76
  connection_pool (>= 2.2.5)
80
77
  drb
81
78
  i18n (>= 1.6, < 2)
79
+ json
80
+ logger (>= 1.4.2)
82
81
  minitest (>= 5.1)
83
- mutex_m
84
- tzinfo (~> 2.0)
82
+ securerandom (>= 0.3)
83
+ tzinfo (~> 2.0, >= 2.0.5)
84
+ uri (>= 0.13.1)
85
85
  aes_key_wrap (1.1.0)
86
- base64 (0.2.0)
87
- bigdecimal (3.1.8)
88
- bindata (2.5.0)
86
+ base64 (0.3.0)
87
+ bigdecimal (3.3.1)
88
+ bindata (2.5.1)
89
89
  builder (3.3.0)
90
- byebug (11.1.3)
91
- concurrent-ruby (1.3.3)
92
- connection_pool (2.4.1)
90
+ byebug (12.0.0)
91
+ concurrent-ruby (1.3.5)
92
+ connection_pool (3.0.2)
93
93
  crass (1.0.6)
94
- date (3.3.4)
95
- diff-lcs (1.5.1)
96
- drb (2.2.1)
97
- erubi (1.13.0)
98
- faraday (2.9.2)
99
- faraday-net_http (>= 2.0, < 3.2)
100
- faraday-follow_redirects (0.3.0)
94
+ date (3.5.1)
95
+ diff-lcs (1.6.2)
96
+ drb (2.2.3)
97
+ erb (6.0.0)
98
+ erubi (1.13.1)
99
+ faraday (2.14.0)
100
+ faraday-net_http (>= 2.0, < 3.5)
101
+ json
102
+ logger
103
+ faraday-follow_redirects (0.4.0)
101
104
  faraday (>= 1, < 3)
102
- faraday-net_http (3.1.0)
103
- net-http
104
- globalid (1.2.1)
105
+ faraday-net_http (3.4.2)
106
+ net-http (~> 0.5)
107
+ globalid (1.3.0)
105
108
  activesupport (>= 6.1)
106
- i18n (1.14.5)
109
+ i18n (1.14.7)
107
110
  concurrent-ruby (~> 1.0)
108
- io-console (0.7.2)
109
- irb (1.13.2)
111
+ io-console (0.8.1)
112
+ irb (1.15.3)
113
+ pp (>= 0.6.0)
110
114
  rdoc (>= 4.0.0)
111
115
  reline (>= 0.4.2)
112
- json-jwt (1.16.6)
116
+ json (2.17.1)
117
+ json-jwt (1.17.0)
113
118
  activesupport (>= 4.2)
114
119
  aes_key_wrap
115
120
  base64
116
121
  bindata
117
122
  faraday (~> 2.0)
118
123
  faraday-follow_redirects
119
- loofah (2.22.0)
124
+ logger (1.7.0)
125
+ loofah (2.24.1)
120
126
  crass (~> 1.0.2)
121
127
  nokogiri (>= 1.12.0)
122
- mail (2.8.1)
128
+ mail (2.9.0)
129
+ logger
123
130
  mini_mime (>= 0.1.1)
124
131
  net-imap
125
132
  net-pop
126
133
  net-smtp
127
- marcel (1.0.4)
134
+ marcel (1.1.0)
128
135
  mini_mime (1.1.5)
129
- mini_portile2 (2.8.7)
130
- minitest (5.24.0)
131
- mutex_m (0.2.0)
132
- net-http (0.4.1)
133
- uri
134
- net-imap (0.4.13)
136
+ mini_portile2 (2.8.9)
137
+ minitest (5.26.2)
138
+ net-http (0.8.0)
139
+ uri (>= 0.11.1)
140
+ net-imap (0.5.12)
135
141
  date
136
142
  net-protocol
137
143
  net-pop (0.1.2)
138
144
  net-protocol
139
145
  net-protocol (0.2.2)
140
146
  timeout
141
- net-smtp (0.5.0)
147
+ net-smtp (0.5.1)
142
148
  net-protocol
143
- nio4r (2.7.3)
144
- nokogiri (1.16.6)
149
+ nio4r (2.7.5)
150
+ nokogiri (1.18.10)
145
151
  mini_portile2 (~> 2.8.2)
146
152
  racc (~> 1.4)
147
- psych (5.1.2)
153
+ pp (0.6.3)
154
+ prettyprint
155
+ prettyprint (0.2.0)
156
+ psych (5.3.0)
157
+ date
148
158
  stringio
149
- racc (1.8.0)
150
- rack (3.1.3)
151
- rack-session (2.0.0)
159
+ racc (1.8.1)
160
+ rack (3.2.4)
161
+ rack-session (2.1.1)
162
+ base64 (>= 0.1.0)
152
163
  rack (>= 3.0.0)
153
- rack-test (2.1.0)
164
+ rack-test (2.2.0)
154
165
  rack (>= 1.3)
155
- rackup (2.1.0)
166
+ rackup (2.3.1)
156
167
  rack (>= 3)
157
- webrick (~> 1.8)
158
- rails (7.1.3.4)
159
- actioncable (= 7.1.3.4)
160
- actionmailbox (= 7.1.3.4)
161
- actionmailer (= 7.1.3.4)
162
- actionpack (= 7.1.3.4)
163
- actiontext (= 7.1.3.4)
164
- actionview (= 7.1.3.4)
165
- activejob (= 7.1.3.4)
166
- activemodel (= 7.1.3.4)
167
- activerecord (= 7.1.3.4)
168
- activestorage (= 7.1.3.4)
169
- activesupport (= 7.1.3.4)
168
+ rails (8.1.1)
169
+ actioncable (= 8.1.1)
170
+ actionmailbox (= 8.1.1)
171
+ actionmailer (= 8.1.1)
172
+ actionpack (= 8.1.1)
173
+ actiontext (= 8.1.1)
174
+ actionview (= 8.1.1)
175
+ activejob (= 8.1.1)
176
+ activemodel (= 8.1.1)
177
+ activerecord (= 8.1.1)
178
+ activestorage (= 8.1.1)
179
+ activesupport (= 8.1.1)
170
180
  bundler (>= 1.15.0)
171
- railties (= 7.1.3.4)
172
- rails-dom-testing (2.2.0)
181
+ railties (= 8.1.1)
182
+ rails-dom-testing (2.3.0)
173
183
  activesupport (>= 5.0.0)
174
184
  minitest
175
185
  nokogiri (>= 1.6)
176
- rails-html-sanitizer (1.6.0)
186
+ rails-html-sanitizer (1.6.2)
177
187
  loofah (~> 2.21)
178
- nokogiri (~> 1.14)
179
- railties (7.1.3.4)
180
- actionpack (= 7.1.3.4)
181
- activesupport (= 7.1.3.4)
182
- irb
188
+ nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
189
+ railties (8.1.1)
190
+ actionpack (= 8.1.1)
191
+ activesupport (= 8.1.1)
192
+ irb (~> 1.13)
183
193
  rackup (>= 1.0.0)
184
194
  rake (>= 12.2)
185
195
  thor (~> 1.0, >= 1.2.2)
196
+ tsort (>= 0.2)
186
197
  zeitwerk (~> 2.6)
187
- rake (13.2.1)
188
- rdoc (6.7.0)
198
+ rake (13.3.1)
199
+ rdoc (6.17.0)
200
+ erb
189
201
  psych (>= 4.0.0)
190
- reline (0.5.9)
202
+ tsort
203
+ reline (0.6.3)
191
204
  io-console (~> 0.5)
192
- rspec (3.12.0)
193
- rspec-core (~> 3.12.0)
194
- rspec-expectations (~> 3.12.0)
195
- rspec-mocks (~> 3.12.0)
196
- rspec-core (3.12.3)
197
- rspec-support (~> 3.12.0)
198
- rspec-expectations (3.12.4)
205
+ rspec (3.13.2)
206
+ rspec-core (~> 3.13.0)
207
+ rspec-expectations (~> 3.13.0)
208
+ rspec-mocks (~> 3.13.0)
209
+ rspec-core (3.13.6)
210
+ rspec-support (~> 3.13.0)
211
+ rspec-expectations (3.13.5)
199
212
  diff-lcs (>= 1.2.0, < 2.0)
200
- rspec-support (~> 3.12.0)
201
- rspec-mocks (3.12.7)
213
+ rspec-support (~> 3.13.0)
214
+ rspec-mocks (3.13.7)
202
215
  diff-lcs (>= 1.2.0, < 2.0)
203
- rspec-support (~> 3.12.0)
204
- rspec-support (3.12.2)
205
- stringio (3.1.1)
206
- thor (1.3.1)
207
- timecop (0.9.6)
208
- timeout (0.4.1)
216
+ rspec-support (~> 3.13.0)
217
+ rspec-support (3.13.6)
218
+ securerandom (0.4.1)
219
+ stringio (3.1.9)
220
+ thor (1.4.0)
221
+ timecop (0.9.10)
222
+ timeout (0.5.0)
223
+ tsort (0.2.0)
209
224
  tzinfo (2.0.6)
210
225
  concurrent-ruby (~> 1.0)
211
- uri (0.13.0)
212
- webrick (1.8.1)
213
- websocket-driver (0.7.6)
226
+ uri (1.1.1)
227
+ useragent (0.16.11)
228
+ websocket-driver (0.8.0)
229
+ base64
214
230
  websocket-extensions (>= 0.1.0)
215
231
  websocket-extensions (0.1.5)
216
- zeitwerk (2.6.16)
232
+ zeitwerk (2.7.3)
217
233
 
218
234
  PLATFORMS
219
235
  ruby
220
236
 
221
237
  DEPENDENCIES
222
- byebug (= 11.1.3)
238
+ byebug (= 12.0.0)
223
239
  keycloak-api-rails!
224
- rspec (= 3.12.0)
225
- timecop (= 0.9.6)
240
+ rspec (= 3.13.2)
241
+ timecop (= 0.9.10)
226
242
 
227
243
  BUNDLED WITH
228
244
  2.4.13
data/README.md CHANGED
@@ -5,7 +5,7 @@ This gem validates Keycloak JWT token for Ruby On Rails APIs.
5
5
  ## Install
6
6
 
7
7
  ```ruby
8
- gem "keycloak-api-rails", "0.12.3"
8
+ gem "keycloak-api-rails", "1.0.0"
9
9
  ```
10
10
 
11
11
  ## Token validation
@@ -25,11 +25,11 @@ _If both method are used at the same time, The query string as a higher priority
25
25
 
26
26
  By default, Keycloak-api-rails installs as a Rack Middleware. It processes all requests before any application logic. URIs/Paths can be excluded (opted-out) from this validation using the 'skip_paths' config option
27
27
 
28
- Alternatively, it can be configured to `opt-in` to validation. In this case, no Rack middleware is used, and controllers can request (opt-in) by including the module `Keycloak::authentication` and calling `keycloak_authenticate`, for example in a `before_action`, like so:
28
+ Alternatively, it can be configured to `opt-in` to validation. In this case, no Rack middleware is used, and controllers can request (opt-in) by including the module `KeycloakApiRails::authentication` and calling `keycloak_authenticate`, for example in a `before_action`, like so:
29
29
 
30
30
  ```ruby
31
31
  class MyApiController < ActionController::Base
32
- include Keycloak::Authentication
32
+ include KeycloakApiRails::Authentication
33
33
 
34
34
  before_action :keycloak_authenticate
35
35
  end
@@ -41,7 +41,7 @@ In Rails controller, the request `env` variables has two more properties:
41
41
  * `keycloak:keycloak_id`
42
42
  * `keycloak:roles`
43
43
 
44
- They can be accessed using `Keycloak::Helper` methods.
44
+ They can be accessed using `KeycloakApiRails::Helper` methods.
45
45
 
46
46
  ## Overall configuration options
47
47
 
@@ -93,13 +93,13 @@ Once this gem is configured in your Rails project, you can read, validate and us
93
93
 
94
94
  ### Keycloak Id
95
95
 
96
- If you identify users using their Keycloak Id, this value can be read from your controllers using `Keycloak::Helper.current_user_id(request.env)`.
96
+ If you identify users using their Keycloak Id, this value can be read from your controllers using `KeycloakApiRails::Helper.current_user_id(request.env)`.
97
97
 
98
98
  ```ruby
99
99
  class AuthenticatedController < ApplicationController
100
100
 
101
101
  def user
102
- keycloak_id = Keycloak::Helper.current_user_id(request.env)
102
+ keycloak_id = KeycloakApiRails::Helper.current_user_id(request.env)
103
103
  User.active.find_by(keycloak_id: keycloak_id)
104
104
  end
105
105
  end
@@ -108,12 +108,12 @@ end
108
108
  Or if using opt-in mode, the controller can request validation conditionally:
109
109
  ```ruby
110
110
  class MostlyAuthenticatedController < ApplicationController
111
- include Keycloak::Authentication
111
+ include KeycloakApiRails::Authentication
112
112
 
113
113
  before_action :keycloak_authenticate, only: show
114
114
 
115
115
  def show
116
- keycloak_id = Keycloak::Helper.current_user_id(request.env)
116
+ keycloak_id = KeycloakApiRails::Helper.current_user_id(request.env)
117
117
  User.active.find_by(keycloak_id: keycloak_id)
118
118
  end
119
119
 
@@ -125,7 +125,7 @@ end
125
125
 
126
126
  ### Roles
127
127
 
128
- `Keycloak::Helper.current_user_roles` can be use against a Rails request to read user's roles.
128
+ `KeycloakApiRails::Helper.current_user_roles` can be use against a Rails request to read user's roles.
129
129
 
130
130
  For example, a controller can require users to be administrator (considering you defined an `application-admin` role):
131
131
 
@@ -143,18 +143,18 @@ class AdminController < ApplicationController
143
143
  private
144
144
 
145
145
  def current_user_roles
146
- Keycloak::Helper.current_user_roles(request.env)
146
+ KeycloakApiRails::Helper.current_user_roles(request.env)
147
147
  end
148
148
  end
149
149
  ```
150
150
 
151
151
  ### Create an URL where the token must be passed via query string
152
152
 
153
- `Keycloak::Helper.create_url_with_token` method can be used to build an url from another, by adding a token as query string.
153
+ `KeycloakApiRails::Helper.create_url_with_token` method can be used to build an url from another, by adding a token as query string.
154
154
 
155
155
  ```ruby
156
156
  def example
157
- Keycloak::Helper.create_url_with_token("https://api.pouet.io/api/more-pouets", "myToken")
157
+ KeycloakApiRails::Helper.create_url_with_token("https://api.pouet.io/api/more-pouets", "myToken")
158
158
  end
159
159
  ```
160
160
 
@@ -163,7 +163,7 @@ This should output `https://api.pouet.io/api/more-pouets?authorizationToken=myTo
163
163
 
164
164
  ### Accessing Keycloak Service
165
165
 
166
- A lazy-loaded service Keycloak::Service can be accessed using `Keycloak.service`.
166
+ A lazy-loaded service KeycloakApiRails::Service can be accessed using `Keycloak.service`.
167
167
  For instance, to read a provided token:
168
168
  ```ruby
169
169
  class RenderTokenController < ApplicationController
@@ -216,8 +216,8 @@ From the `keycloak-rails-api` directory:
216
216
  $ docker build . -t keycloak-rails-api:test
217
217
  $ docker run -v `pwd`:/usr/src/app/ keycloak-rails-api:test bundle exec rspec spec
218
218
  ```
219
-
219
+ rspe
220
220
  ## Next developments
221
221
 
222
222
  * Manage multiple realms
223
- * Avoid duplicate code in Keycloak::Middleware and `Keycloak::Authentication`
223
+ * Avoid duplicate code in KeycloakApiRails::Middleware and `KeycloakApiRails::Authentication`
@@ -4,7 +4,7 @@ require "keycloak-api-rails/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "keycloak-api-rails"
7
- spec.version = Keycloak::VERSION
7
+ spec.version = KeycloakApiRails::VERSION
8
8
  spec.authors = ["Lorent Lempereur"]
9
9
  spec.email = ["lorent.lempereur.dev@gmail.com"]
10
10
  spec.homepage = "https://github.com/looorent/keycloak-api-rails"
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.add_dependency "rails", ">= 4.2"
19
19
  spec.add_dependency "json-jwt", ">= 1.11.0"
20
20
 
21
- spec.add_development_dependency "rspec", "3.12.0"
22
- spec.add_development_dependency "timecop", "0.9.6"
23
- spec.add_development_dependency "byebug", "11.1.3"
21
+ spec.add_development_dependency "rspec", "3.13.2"
22
+ spec.add_development_dependency "timecop", "0.9.10"
23
+ spec.add_development_dependency "byebug", "12.0.0"
24
24
  end
@@ -1,4 +1,4 @@
1
- module Keycloak
1
+ module KeycloakApiRails
2
2
  module Authentication
3
3
  extend ActiveSupport::Concern
4
4
 
@@ -16,16 +16,16 @@ module Keycloak
16
16
  path = env["PATH_INFO"]
17
17
  uri = env["REQUEST_URI"]
18
18
 
19
- Keycloak.logger.debug("Start authentication for #{method} : #{path}")
20
- token = Keycloak.service.read_token(uri, env)
21
- decoded_token = Keycloak.service.decode_and_verify(token)
19
+ KeycloakApiRails.logger.debug("Start authentication for #{method} : #{path}")
20
+ token = KeycloakApiRails.service.read_token(uri, env)
21
+ decoded_token = KeycloakApiRails.service.decode_and_verify(token)
22
22
  authentication_succeeded(env, decoded_token)
23
23
  rescue TokenError => e
24
24
  authentication_failed(e.message)
25
25
  end
26
26
 
27
27
  def authentication_failed(message)
28
- Keycloak.logger.info(message)
28
+ KeycloakApiRails.logger.info(message)
29
29
  render status: :unauthorized, json: { error: message }
30
30
  end
31
31
 
@@ -34,7 +34,7 @@ module Keycloak
34
34
  Helper.assign_current_authorized_party(env, decoded_token)
35
35
  Helper.assign_current_user_email(env, decoded_token)
36
36
  Helper.assign_current_user_locale(env, decoded_token)
37
- Helper.assign_current_user_custom_attributes(env, decoded_token, Keycloak.config.custom_attributes)
37
+ Helper.assign_current_user_custom_attributes(env, decoded_token, KeycloakApiRails.config.custom_attributes)
38
38
  Helper.assign_realm_roles(env, decoded_token)
39
39
  Helper.assign_resource_roles(env, decoded_token)
40
40
  Helper.assign_keycloak_token(env, decoded_token)
@@ -1,4 +1,4 @@
1
- module Keycloak
1
+ module KeycloakApiRails
2
2
  class Configuration
3
3
  include ActiveSupport::Configurable
4
4
  config_accessor :server_url
@@ -1,4 +1,4 @@
1
- module Keycloak
1
+ module KeycloakApiRails
2
2
  class Helper
3
3
 
4
4
  CURRENT_USER_ID_KEY = "keycloak:keycloak_id"
@@ -1,8 +1,9 @@
1
- module Keycloak
1
+ module KeycloakApiRails
2
2
  class HTTPClient
3
- def initialize(configuration)
3
+ def initialize(configuration, logger)
4
4
  @server_url = configuration.server_url
5
5
  @ca_certificate_file = configuration.ca_certificate_file
6
+ @logger = logger
6
7
  @x509_store = OpenSSL::X509::Store.new
7
8
  @x509_store.set_default_paths
8
9
  @x509_store.add_file(@ca_certificate_file) if @ca_certificate_file
@@ -14,7 +15,13 @@ module Keycloak
14
15
  Net::HTTP.start(uri.host, uri.port, :use_ssl => use_ssl, :cert_store => @x509_store) do |http|
15
16
  request = Net::HTTP::Get.new(uri)
16
17
  response = http.request(request)
17
- JSON.parse(response.body)
18
+
19
+ begin
20
+ response.value
21
+ JSON.parse(response.body)
22
+ rescue
23
+ @logger.error("KeycloakApiRails responded with an error when calling '#{path}'. Status #{response.code}. Payload: #{response.body}")
24
+ end
18
25
  end
19
26
  end
20
27
 
@@ -1,4 +1,4 @@
1
- module Keycloak
1
+ module KeycloakApiRails
2
2
 
3
3
  class Middleware
4
4
  def initialize(app)
@@ -41,15 +41,15 @@ module Keycloak
41
41
  end
42
42
 
43
43
  def service
44
- Keycloak.service
44
+ KeycloakApiRails.service
45
45
  end
46
46
 
47
47
  def logger
48
- Keycloak.logger
48
+ KeycloakApiRails.logger
49
49
  end
50
50
 
51
51
  def config
52
- Keycloak.config
52
+ KeycloakApiRails.config
53
53
  end
54
54
  end
55
55
  end
@@ -1,4 +1,4 @@
1
- module Keycloak
1
+ module KeycloakApiRails
2
2
  class PublicKeyCachedResolver
3
3
  attr_reader :cached_public_key_retrieved_at
4
4
 
@@ -1,4 +1,4 @@
1
- module Keycloak
1
+ module KeycloakApiRails
2
2
  class PublicKeyResolver
3
3
  def initialize(http_client, realm_id)
4
4
  @realm_id = realm_id
@@ -1,9 +1,9 @@
1
- module Keycloak
1
+ module KeycloakApiRails
2
2
  class Railtie < Rails::Railtie
3
3
  railtie_name :keycloak_api_rails
4
4
 
5
5
  initializer("keycloak.insert_middleware") do |app|
6
- app.config.middleware.use(Keycloak::Middleware)
6
+ app.config.middleware.use(KeycloakApiRails::Middleware)
7
7
  end
8
8
  end
9
9
  end
@@ -1,12 +1,12 @@
1
- module Keycloak
1
+ module KeycloakApiRails
2
2
  class Service
3
3
 
4
4
  def initialize(key_resolver)
5
5
  @key_resolver = key_resolver
6
- @skip_paths = Keycloak.config.skip_paths
7
- @opt_in = Keycloak.config.opt_in
8
- @logger = Keycloak.config.logger
9
- @token_expiration_tolerance_in_seconds = Keycloak.config.token_expiration_tolerance_in_seconds
6
+ @skip_paths = KeycloakApiRails.config.skip_paths
7
+ @opt_in = KeycloakApiRails.config.opt_in
8
+ @logger = KeycloakApiRails.config.logger
9
+ @token_expiration_tolerance_in_seconds = KeycloakApiRails.config.token_expiration_tolerance_in_seconds
10
10
  end
11
11
 
12
12
  def decode_and_verify(token)
@@ -1,3 +1,3 @@
1
- module Keycloak
2
- VERSION = "0.12.3"
1
+ module KeycloakApiRails
2
+ VERSION = "1.0.0"
3
3
  end
@@ -15,10 +15,10 @@ require_relative "keycloak-api-rails/service"
15
15
  require_relative "keycloak-api-rails/middleware"
16
16
  require_relative "keycloak-api-rails/railtie" if defined?(Rails)
17
17
 
18
- module Keycloak
18
+ module KeycloakApiRails
19
19
 
20
20
  def self.configure
21
- yield @configuration ||= Keycloak::Configuration.new
21
+ yield @configuration ||= KeycloakApiRails::Configuration.new
22
22
  end
23
23
 
24
24
  def self.config
@@ -26,7 +26,7 @@ module Keycloak
26
26
  end
27
27
 
28
28
  def self.http_client
29
- @http_client ||= Keycloak::HTTPClient.new(config)
29
+ @http_client ||= KeycloakApiRails::HTTPClient.new(config, logger)
30
30
  end
31
31
 
32
32
  def self.public_key_resolver
@@ -34,7 +34,7 @@ module Keycloak
34
34
  end
35
35
 
36
36
  def self.service
37
- @service ||= Keycloak::Service.new(public_key_resolver)
37
+ @service ||= KeycloakApiRails::Service.new(public_key_resolver)
38
38
  end
39
39
 
40
40
  def self.logger
@@ -1,10 +1,10 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Keycloak::Authentication do
3
+ describe KeycloakApiRails::Authentication do
4
4
  class ExampleController < ActionController::Base
5
- include Keycloak::Authentication
5
+ include KeycloakApiRails::Authentication
6
6
  # Mark protected methods public so they may be called in tests
7
- public(*Keycloak::Authentication.protected_instance_methods)
7
+ public(*KeycloakApiRails::Authentication.protected_instance_methods)
8
8
  end
9
9
 
10
10
  let(:controller) { ExampleController.new }
@@ -24,7 +24,7 @@ describe Keycloak::Authentication do
24
24
  end
25
25
 
26
26
  it "it authenticates with request header" do
27
- expect_any_instance_of(Keycloak::Service).to receive(:decode_and_verify).with(token).and_return("A User")
27
+ expect_any_instance_of(KeycloakApiRails::Service).to receive(:decode_and_verify).with(token).and_return("A User")
28
28
  expect(controller).to receive(:authentication_succeeded)
29
29
  controller.keycloak_authenticate
30
30
  end
@@ -1,11 +1,11 @@
1
- RSpec.describe Keycloak::Helper do
1
+ RSpec.describe KeycloakApiRails::Helper do
2
2
  describe "#create_url_with_token" do
3
3
 
4
4
  let(:uri) { "http://www.an-url.io" }
5
5
  let(:token) { "aToken" }
6
6
 
7
7
  before(:each) do
8
- @url_with_token = Keycloak::Helper.create_url_with_token(uri, token)
8
+ @url_with_token = KeycloakApiRails::Helper.create_url_with_token(uri, token)
9
9
  end
10
10
 
11
11
  context "when the uri has no query string yet" do
@@ -1,12 +1,12 @@
1
- RSpec.describe Keycloak::Service do
1
+ RSpec.describe KeycloakApiRails::Service do
2
2
 
3
3
  let(:public_key_cache_ttl) { 86400 }
4
4
  let(:server_url) { "whatever:8080" }
5
5
  let(:realm_id) { "pouet" }
6
- let!(:resolver) { Keycloak::PublicKeyCachedResolver.new(server_url, realm_id, public_key_cache_ttl) }
6
+ let!(:resolver) { KeycloakApiRails::PublicKeyCachedResolver.new(server_url, realm_id, public_key_cache_ttl) }
7
7
 
8
8
  before(:each) do
9
- resolver.instance_variable_set(:@resolver, Keycloak::PublicKeyResolverStub.new)
9
+ resolver.instance_variable_set(:@resolver, KeycloakApiRails::PublicKeyResolverStub.new)
10
10
  now = Time.local(2018, 1, 9, 12, 0, 0)
11
11
  Timecop.freeze(now)
12
12
  end
@@ -1,9 +1,9 @@
1
- RSpec.describe Keycloak::Service do
1
+ RSpec.describe KeycloakApiRails::Service do
2
2
 
3
3
  let!(:private_key) { OpenSSL::PKey::RSA.generate(2048) }
4
4
  let!(:public_key) { private_key.public_key }
5
- let!(:key_resolver) { Keycloak::PublicKeyCachedResolverStub.new(public_key) }
6
- let!(:service) { Keycloak::Service.new(key_resolver) }
5
+ let!(:key_resolver) { KeycloakApiRails::PublicKeyCachedResolverStub.new(public_key) }
6
+ let!(:service) { KeycloakApiRails::Service.new(key_resolver) }
7
7
 
8
8
  before(:each) do
9
9
  now = Time.local(2018, 1, 9, 12, 0, 0)
@@ -17,7 +17,7 @@ RSpec.describe Keycloak::Service do
17
17
  describe "#decode_and_verify" do
18
18
  def create_token(private_key, expiration_date, algorithm)
19
19
  claim = {
20
- iss: "Keycloak",
20
+ iss: "KeycloakApiRails",
21
21
  exp: expiration_date,
22
22
  nbf: Time.local(2018, 1, 1, 0, 0, 0)
23
23
  }
@@ -111,7 +111,7 @@ RSpec.describe Keycloak::Service do
111
111
 
112
112
 
113
113
  before(:each) do
114
- Keycloak.config.skip_paths = {
114
+ KeycloakApiRails.config.skip_paths = {
115
115
  post: [/^\/skip/],
116
116
  get: [/^\/skip/]
117
117
  }
@@ -178,8 +178,8 @@ RSpec.describe Keycloak::Service do
178
178
 
179
179
  context "when configured as opt_in" do
180
180
  before do
181
- Keycloak.config.opt_in = true
182
- service2 = Keycloak::Service.new(key_resolver)
181
+ KeycloakApiRails.config.opt_in = true
182
+ service2 = KeycloakApiRails::Service.new(key_resolver)
183
183
  @result = service2.need_middleware_authentication?(method, path, headers)
184
184
  end
185
185
 
@@ -1,4 +1,4 @@
1
- module Keycloak
1
+ module KeycloakApiRails
2
2
  class PublicKeyCachedResolverStub
3
3
  def initialize(public_key)
4
4
  @public_key = public_key
@@ -1,4 +1,4 @@
1
- module Keycloak
1
+ module KeycloakApiRails
2
2
  class PublicKeyResolverStub
3
3
  def find_public_keys
4
4
  OpenSSL::PKey::RSA.generate(1024).public_key
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keycloak-api-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorent Lempereur
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-19 00:00:00.000000000 Z
11
+ date: 2025-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -44,42 +44,42 @@ dependencies:
44
44
  requirements:
45
45
  - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: 3.12.0
47
+ version: 3.13.2
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: 3.12.0
54
+ version: 3.13.2
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: timecop
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: 0.9.6
61
+ version: 0.9.10
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: 0.9.6
68
+ version: 0.9.10
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: byebug
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: 11.1.3
75
+ version: 12.0.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: 11.1.3
82
+ version: 12.0.0
83
83
  description: Rails middleware that validates Authorization token emitted by Keycloak
84
84
  email:
85
85
  - lorent.lempereur.dev@gmail.com
@@ -87,6 +87,7 @@ executables: []
87
87
  extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
+ - ".github/workflows/ci.yml"
90
91
  - ".gitignore"
91
92
  - ".rspec"
92
93
  - CHANGELOG.md
@@ -120,7 +121,7 @@ homepage: https://github.com/looorent/keycloak-api-rails
120
121
  licenses:
121
122
  - MIT
122
123
  metadata: {}
123
- post_install_message:
124
+ post_install_message:
124
125
  rdoc_options: []
125
126
  require_paths:
126
127
  - lib
@@ -135,8 +136,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
136
  - !ruby/object:Gem::Version
136
137
  version: '0'
137
138
  requirements: []
138
- rubygems_version: 3.5.11
139
- signing_key:
139
+ rubygems_version: 3.0.3.1
140
+ signing_key:
140
141
  specification_version: 4
141
142
  summary: Rails middleware that validates Authorization token emitted by Keycloak
142
143
  test_files: []