keycloak_rack 1.0.0 → 1.1.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.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- keycloak_rack (1.0.0)
4
+ keycloak_rack (1.1.0)
5
5
  activesupport (>= 4.2)
6
6
  anyway_config (>= 2.1.0, < 3)
7
7
  dry-auto_inject
@@ -20,115 +20,112 @@ PATH
20
20
  GEM
21
21
  remote: https://rubygems.org/
22
22
  specs:
23
- actioncable (6.1.3.1)
24
- actionpack (= 6.1.3.1)
25
- activesupport (= 6.1.3.1)
23
+ actioncable (6.1.4.4)
24
+ actionpack (= 6.1.4.4)
25
+ activesupport (= 6.1.4.4)
26
26
  nio4r (~> 2.0)
27
27
  websocket-driver (>= 0.6.1)
28
- actionmailbox (6.1.3.1)
29
- actionpack (= 6.1.3.1)
30
- activejob (= 6.1.3.1)
31
- activerecord (= 6.1.3.1)
32
- activestorage (= 6.1.3.1)
33
- activesupport (= 6.1.3.1)
28
+ actionmailbox (6.1.4.4)
29
+ actionpack (= 6.1.4.4)
30
+ activejob (= 6.1.4.4)
31
+ activerecord (= 6.1.4.4)
32
+ activestorage (= 6.1.4.4)
33
+ activesupport (= 6.1.4.4)
34
34
  mail (>= 2.7.1)
35
- actionmailer (6.1.3.1)
36
- actionpack (= 6.1.3.1)
37
- actionview (= 6.1.3.1)
38
- activejob (= 6.1.3.1)
39
- activesupport (= 6.1.3.1)
35
+ actionmailer (6.1.4.4)
36
+ actionpack (= 6.1.4.4)
37
+ actionview (= 6.1.4.4)
38
+ activejob (= 6.1.4.4)
39
+ activesupport (= 6.1.4.4)
40
40
  mail (~> 2.5, >= 2.5.4)
41
41
  rails-dom-testing (~> 2.0)
42
- actionpack (6.1.3.1)
43
- actionview (= 6.1.3.1)
44
- activesupport (= 6.1.3.1)
42
+ actionpack (6.1.4.4)
43
+ actionview (= 6.1.4.4)
44
+ activesupport (= 6.1.4.4)
45
45
  rack (~> 2.0, >= 2.0.9)
46
46
  rack-test (>= 0.6.3)
47
47
  rails-dom-testing (~> 2.0)
48
48
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
49
- actiontext (6.1.3.1)
50
- actionpack (= 6.1.3.1)
51
- activerecord (= 6.1.3.1)
52
- activestorage (= 6.1.3.1)
53
- activesupport (= 6.1.3.1)
49
+ actiontext (6.1.4.4)
50
+ actionpack (= 6.1.4.4)
51
+ activerecord (= 6.1.4.4)
52
+ activestorage (= 6.1.4.4)
53
+ activesupport (= 6.1.4.4)
54
54
  nokogiri (>= 1.8.5)
55
- actionview (6.1.3.1)
56
- activesupport (= 6.1.3.1)
55
+ actionview (6.1.4.4)
56
+ activesupport (= 6.1.4.4)
57
57
  builder (~> 3.1)
58
58
  erubi (~> 1.4)
59
59
  rails-dom-testing (~> 2.0)
60
60
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
61
- activejob (6.1.3.1)
62
- activesupport (= 6.1.3.1)
61
+ activejob (6.1.4.4)
62
+ activesupport (= 6.1.4.4)
63
63
  globalid (>= 0.3.6)
64
- activemodel (6.1.3.1)
65
- activesupport (= 6.1.3.1)
66
- activerecord (6.1.3.1)
67
- activemodel (= 6.1.3.1)
68
- activesupport (= 6.1.3.1)
69
- activestorage (6.1.3.1)
70
- actionpack (= 6.1.3.1)
71
- activejob (= 6.1.3.1)
72
- activerecord (= 6.1.3.1)
73
- activesupport (= 6.1.3.1)
64
+ activemodel (6.1.4.4)
65
+ activesupport (= 6.1.4.4)
66
+ activerecord (6.1.4.4)
67
+ activemodel (= 6.1.4.4)
68
+ activesupport (= 6.1.4.4)
69
+ activestorage (6.1.4.4)
70
+ actionpack (= 6.1.4.4)
71
+ activejob (= 6.1.4.4)
72
+ activerecord (= 6.1.4.4)
73
+ activesupport (= 6.1.4.4)
74
74
  marcel (~> 1.0.0)
75
- mini_mime (~> 1.0.2)
76
- activesupport (6.1.3.1)
75
+ mini_mime (>= 1.1.0)
76
+ activesupport (6.1.4.4)
77
77
  concurrent-ruby (~> 1.0, >= 1.0.2)
78
78
  i18n (>= 1.6, < 2)
79
79
  minitest (>= 5.1)
80
80
  tzinfo (~> 2.0)
81
81
  zeitwerk (~> 2.3)
82
- addressable (2.7.0)
82
+ addressable (2.8.0)
83
83
  public_suffix (>= 2.0.2, < 5.0)
84
- anyway_config (2.1.0)
85
- ruby-next-core (>= 0.11.0)
84
+ anyway_config (2.2.3)
85
+ ruby-next-core (>= 0.14.0)
86
86
  appraisal (2.4.0)
87
87
  bundler
88
88
  rake
89
89
  thor (>= 0.14.0)
90
90
  ast (2.4.2)
91
- backports (3.21.0)
91
+ backports (3.23.0)
92
92
  builder (3.2.4)
93
93
  coderay (1.1.3)
94
- concurrent-ruby (1.1.8)
94
+ concurrent-ruby (1.1.9)
95
95
  crack (0.4.5)
96
96
  rexml
97
97
  crass (1.0.6)
98
- diff-lcs (1.4.4)
99
- docile (1.3.5)
100
- dry-auto_inject (0.7.0)
98
+ diff-lcs (1.5.0)
99
+ docile (1.4.0)
100
+ dry-auto_inject (0.9.0)
101
101
  dry-container (>= 0.3.4)
102
- dry-configurable (0.12.1)
102
+ dry-configurable (0.14.0)
103
103
  concurrent-ruby (~> 1.0)
104
- dry-core (~> 0.5, >= 0.5.0)
105
- dry-container (0.7.2)
104
+ dry-core (~> 0.6)
105
+ dry-container (0.9.0)
106
106
  concurrent-ruby (~> 1.0)
107
- dry-configurable (~> 0.1, >= 0.1.3)
108
- dry-core (0.5.0)
107
+ dry-configurable (~> 0.13, >= 0.13.0)
108
+ dry-core (0.7.1)
109
109
  concurrent-ruby (~> 1.0)
110
- dry-effects (0.1.5)
110
+ dry-effects (0.2.0)
111
111
  concurrent-ruby (~> 1.0)
112
112
  dry-container (~> 0.7, >= 0.7.2)
113
- dry-core (~> 0.4, >= 0.4.7)
114
- dry-equalizer (~> 0.2, >= 0.2.2)
113
+ dry-core (~> 0.5, >= 0.5)
115
114
  dry-inflector (~> 0.1, >= 0.1.2)
116
115
  dry-initializer (~> 3.0)
117
- dry-equalizer (0.3.0)
118
- dry-inflector (0.2.0)
119
- dry-initializer (3.0.4)
116
+ dry-inflector (0.2.1)
117
+ dry-initializer (3.1.1)
120
118
  dry-logic (1.2.0)
121
119
  concurrent-ruby (~> 1.0)
122
120
  dry-core (~> 0.5, >= 0.5)
123
121
  dry-matcher (0.9.0)
124
122
  dry-core (~> 0.4, >= 0.4.8)
125
- dry-monads (1.3.5)
123
+ dry-monads (1.4.0)
126
124
  concurrent-ruby (~> 1.0)
127
- dry-core (~> 0.4, >= 0.4.4)
128
- dry-equalizer
129
- dry-schema (1.6.2)
125
+ dry-core (~> 0.7)
126
+ dry-schema (1.8.0)
130
127
  concurrent-ruby (~> 1.0)
131
- dry-configurable (~> 0.8, >= 0.8.3)
128
+ dry-configurable (~> 0.13, >= 0.13.0)
132
129
  dry-core (~> 0.5, >= 0.5)
133
130
  dry-initializer (~> 3.0)
134
131
  dry-logic (~> 1.0)
@@ -143,96 +140,95 @@ GEM
143
140
  dry-core (~> 0.5, >= 0.5)
144
141
  dry-inflector (~> 0.1, >= 0.1.2)
145
142
  dry-logic (~> 1.0, >= 1.0.2)
146
- dry-validation (1.6.0)
143
+ dry-validation (1.7.0)
147
144
  concurrent-ruby (~> 1.0)
148
145
  dry-container (~> 0.7, >= 0.7.1)
149
- dry-core (~> 0.4)
150
- dry-equalizer (~> 0.2)
146
+ dry-core (~> 0.5, >= 0.5)
151
147
  dry-initializer (~> 3.0)
152
- dry-schema (~> 1.5, >= 1.5.2)
148
+ dry-schema (~> 1.8, >= 1.8.0)
153
149
  erubi (1.10.0)
154
150
  factory_bot (6.1.0)
155
151
  activesupport (>= 5.0.0)
156
- faker (2.17.0)
152
+ faker (2.19.0)
157
153
  i18n (>= 1.6, < 2)
158
- globalid (0.4.2)
159
- activesupport (>= 4.2.0)
154
+ globalid (1.0.0)
155
+ activesupport (>= 5.0)
160
156
  hashdiff (1.0.1)
161
- i18n (1.8.10)
157
+ i18n (1.9.1)
162
158
  concurrent-ruby (~> 1.0)
163
159
  ice_nine (0.11.2)
164
- jwt (2.2.3)
165
- loofah (2.9.1)
160
+ jwt (2.3.0)
161
+ loofah (2.13.0)
166
162
  crass (~> 1.0.2)
167
163
  nokogiri (>= 1.5.9)
168
164
  mail (2.7.1)
169
165
  mini_mime (>= 0.1.1)
170
- marcel (1.0.1)
166
+ marcel (1.0.2)
171
167
  method_source (1.0.0)
172
- mini_mime (1.0.3)
173
- mini_portile2 (2.5.1)
174
- minitest (5.14.4)
175
- nio4r (2.5.7)
176
- nokogiri (1.11.3)
177
- mini_portile2 (~> 2.5.0)
168
+ mini_mime (1.1.2)
169
+ mini_portile2 (2.7.1)
170
+ minitest (5.15.0)
171
+ nio4r (2.5.8)
172
+ nokogiri (1.13.1)
173
+ mini_portile2 (~> 2.7.0)
178
174
  racc (~> 1.4)
179
- nokogiri (1.11.3-x86_64-darwin)
175
+ nokogiri (1.13.1-x86_64-darwin)
180
176
  racc (~> 1.4)
181
- nokogiri (1.11.3-x86_64-linux)
177
+ nokogiri (1.13.1-x86_64-linux)
182
178
  racc (~> 1.4)
183
- parallel (1.20.1)
184
- parser (3.0.1.1)
179
+ parallel (1.21.0)
180
+ parser (3.1.0.0)
185
181
  ast (~> 2.4.1)
186
182
  pry (0.14.1)
187
183
  coderay (~> 1.1)
188
184
  method_source (~> 1.0)
189
185
  public_suffix (4.0.6)
190
- racc (1.5.2)
186
+ racc (1.6.0)
191
187
  rack (2.2.3)
192
188
  rack-test (1.1.0)
193
189
  rack (>= 1.0, < 3)
194
- rails (6.1.3.1)
195
- actioncable (= 6.1.3.1)
196
- actionmailbox (= 6.1.3.1)
197
- actionmailer (= 6.1.3.1)
198
- actionpack (= 6.1.3.1)
199
- actiontext (= 6.1.3.1)
200
- actionview (= 6.1.3.1)
201
- activejob (= 6.1.3.1)
202
- activemodel (= 6.1.3.1)
203
- activerecord (= 6.1.3.1)
204
- activestorage (= 6.1.3.1)
205
- activesupport (= 6.1.3.1)
190
+ rails (6.1.4.4)
191
+ actioncable (= 6.1.4.4)
192
+ actionmailbox (= 6.1.4.4)
193
+ actionmailer (= 6.1.4.4)
194
+ actionpack (= 6.1.4.4)
195
+ actiontext (= 6.1.4.4)
196
+ actionview (= 6.1.4.4)
197
+ activejob (= 6.1.4.4)
198
+ activemodel (= 6.1.4.4)
199
+ activerecord (= 6.1.4.4)
200
+ activestorage (= 6.1.4.4)
201
+ activesupport (= 6.1.4.4)
206
202
  bundler (>= 1.15.0)
207
- railties (= 6.1.3.1)
203
+ railties (= 6.1.4.4)
208
204
  sprockets-rails (>= 2.0.0)
209
205
  rails-dom-testing (2.0.3)
210
206
  activesupport (>= 4.2.0)
211
207
  nokogiri (>= 1.6)
212
- rails-html-sanitizer (1.3.0)
208
+ rails-html-sanitizer (1.4.2)
213
209
  loofah (~> 2.3)
214
- railties (6.1.3.1)
215
- actionpack (= 6.1.3.1)
216
- activesupport (= 6.1.3.1)
210
+ railties (6.1.4.4)
211
+ actionpack (= 6.1.4.4)
212
+ activesupport (= 6.1.4.4)
217
213
  method_source
218
- rake (>= 0.8.7)
214
+ rake (>= 0.13)
219
215
  thor (~> 1.0)
220
- rainbow (3.0.0)
221
- rake (13.0.3)
216
+ rainbow (3.1.1)
217
+ rake (13.0.6)
222
218
  redcarpet (3.5.1)
223
- regexp_parser (2.1.1)
219
+ regexp_parser (2.2.0)
224
220
  rexml (3.2.5)
225
221
  rspec (3.10.0)
226
222
  rspec-core (~> 3.10.0)
227
223
  rspec-expectations (~> 3.10.0)
228
224
  rspec-mocks (~> 3.10.0)
229
- rspec-core (3.10.1)
225
+ rspec-core (3.10.2)
230
226
  rspec-support (~> 3.10.0)
231
- rspec-expectations (3.10.1)
227
+ rspec-expectations (3.10.2)
232
228
  diff-lcs (>= 1.2.0, < 2.0)
233
229
  rspec-support (~> 3.10.0)
234
230
  rspec-json_expectations (2.2.0)
235
- rspec-mocks (3.10.2)
231
+ rspec-mocks (3.10.3)
236
232
  diff-lcs (>= 1.2.0, < 2.0)
237
233
  rspec-support (~> 3.10.0)
238
234
  rspec-rails (5.0.1)
@@ -243,7 +239,7 @@ GEM
243
239
  rspec-expectations (~> 3.10)
244
240
  rspec-mocks (~> 3.10)
245
241
  rspec-support (~> 3.10)
246
- rspec-support (3.10.2)
242
+ rspec-support (3.10.3)
247
243
  rubocop (1.13.0)
248
244
  parallel (~> 1.10)
249
245
  parser (>= 3.0.0.0)
@@ -253,38 +249,38 @@ GEM
253
249
  rubocop-ast (>= 1.2.0, < 2.0)
254
250
  ruby-progressbar (~> 1.7)
255
251
  unicode-display_width (>= 1.4.0, < 3.0)
256
- rubocop-ast (1.5.0)
252
+ rubocop-ast (1.15.1)
257
253
  parser (>= 3.0.1.1)
258
254
  rubocop-rake (0.5.1)
259
255
  rubocop
260
256
  rubocop-rspec (2.3.0)
261
257
  rubocop (~> 1.0)
262
258
  rubocop-ast (>= 1.1.0)
263
- ruby-next-core (0.12.0)
259
+ ruby-next-core (0.14.1)
264
260
  ruby-progressbar (1.11.0)
265
261
  simplecov (0.21.2)
266
262
  docile (~> 1.1)
267
263
  simplecov-html (~> 0.11)
268
264
  simplecov_json_formatter (~> 0.1)
269
265
  simplecov-html (0.12.3)
270
- simplecov_json_formatter (0.1.2)
266
+ simplecov_json_formatter (0.1.3)
271
267
  sprockets (4.0.2)
272
268
  concurrent-ruby (~> 1.0)
273
269
  rack (> 1, < 3)
274
- sprockets-rails (3.2.2)
275
- actionpack (>= 4.0)
276
- activesupport (>= 4.0)
270
+ sprockets-rails (3.4.2)
271
+ actionpack (>= 5.2)
272
+ activesupport (>= 5.2)
277
273
  sprockets (>= 3.0.0)
278
- thor (1.1.0)
274
+ thor (1.2.1)
279
275
  timecop (0.9.4)
280
276
  tzinfo (2.0.4)
281
277
  concurrent-ruby (~> 1.0)
282
- unicode-display_width (2.0.0)
278
+ unicode-display_width (2.1.0)
283
279
  webmock (3.12.2)
284
280
  addressable (>= 2.3.6)
285
281
  crack (>= 0.3.2)
286
282
  hashdiff (>= 0.4.0, < 2.0.0)
287
- websocket-driver (0.7.3)
283
+ websocket-driver (0.7.5)
288
284
  websocket-extensions (>= 0.1.0)
289
285
  websocket-extensions (0.1.5)
290
286
  yard (0.9.26)
@@ -292,7 +288,7 @@ GEM
292
288
  backports (>= 3.18)
293
289
  rainbow
294
290
  yard
295
- zeitwerk (2.4.2)
291
+ zeitwerk (2.5.4)
296
292
 
297
293
  PLATFORMS
298
294
  ruby
@@ -302,9 +298,8 @@ PLATFORMS
302
298
  DEPENDENCIES
303
299
  appraisal (= 2.4.0)
304
300
  factory_bot (~> 6.1.0)
305
- faker (= 2.17.0)
301
+ faker (= 2.19.0)
306
302
  keycloak_rack!
307
- nokogiri
308
303
  pry (= 0.14.1)
309
304
  rack-test (= 1.1.0)
310
305
  rails (>= 6.1.0, < 6.2.0)
@@ -323,4 +318,4 @@ DEPENDENCIES
323
318
  yard-junk
324
319
 
325
320
  BUNDLED WITH
326
- 2.2.16
321
+ 2.2.19
@@ -36,7 +36,7 @@ Gem::Specification.new do |spec|
36
36
 
37
37
  spec.add_development_dependency "appraisal", "2.4.0"
38
38
  spec.add_development_dependency "factory_bot", "~> 6.1.0"
39
- spec.add_development_dependency "faker", "2.17.0"
39
+ spec.add_development_dependency "faker", "2.19.0"
40
40
  spec.add_development_dependency "pry", "0.14.1"
41
41
  spec.add_development_dependency "rack-test", "1.1.0"
42
42
  spec.add_development_dependency "rake", ">= 13", "< 14"
@@ -50,20 +50,18 @@ module KeycloakRack
50
50
  include Dry::Monads[:do, :result]
51
51
 
52
52
  include Import[
53
- config: "keycloak-rack.config",
54
- key_resolver: "keycloak-rack.key_resolver",
53
+ decode_and_verify: "keycloak-rack.decode_and_verify",
55
54
  read_token: "keycloak-rack.read_token",
56
- skip_authentication: "keycloak-rack.skip_authentication"
55
+ skip_authentication: "keycloak-rack.skip_authentication",
56
+ wrap: "keycloak-rack.wrap_token",
57
57
  ]
58
58
 
59
- delegate :token_leeway, to: :config
60
-
61
59
  # @param [Hash] env the rack environment
62
60
  # @return [Dry::Monads::Success(:authenticated, KeycloakRack::DecodedToken)]
63
61
  # @return [Dry::Monads::Success(:skipped, String)]
64
62
  # @return [Dry::Monads::Success(:unauthenticated)]
65
63
  # @return [Dry::Monads::Failure(:expired, String, String, Exception)]
66
- # @return [Dry::Monads::Failure(:decoding_failed, String, String, Exception)]
64
+ # @return [Dry::Monads::Failure(:decoding_failed, String, Exception)]
67
65
  def call(env)
68
66
  return Success[:skipped] if yield skip_authentication.call(env)
69
67
 
@@ -71,45 +69,11 @@ module KeycloakRack
71
69
 
72
70
  return Success[:unauthenticated] if token.blank?
73
71
 
74
- decoded_token = yield decode_and_verify token
75
-
76
- Success[:authenticated, decoded_token]
77
- end
78
-
79
- private
72
+ payload, headers = yield decode_and_verify.call token
80
73
 
81
- # @param [String] token
82
- # @return [Dry::Monads::Success(KeycloakRack::DecodedToken)]
83
- # @return [Dry::Monads::Failure(:expired, String, String, Exception)]
84
- # @return [Dry::Monads::Failure(:decoding_failed, String, String, Exception)]
85
- def decode_and_verify(token)
86
- jwks = yield key_resolver.find_public_keys
74
+ decoded_token = yield wrap.call payload, headers
87
75
 
88
- algorithms = yield algorithms_for jwks
89
-
90
- options = {
91
- algorithms: algorithms,
92
- leeway: token_leeway,
93
- jwks: jwks
94
- }
95
-
96
- payload, headers = JWT.decode token, nil, true, options
97
- rescue JWT::ExpiredSignature => e
98
- Failure[:expired, "JWT is expired", token, e]
99
- rescue JWT::DecodeError => e
100
- Failure[:decoding_failed, "Failed to decode JWT", token, e]
101
- else
102
- Success DecodedToken.new payload.merge(original_payload: payload, headers: headers)
103
- end
104
-
105
- # @param [{ Symbol => <{ Symbol => String }> }] jwks
106
- # @return [<String>]
107
- def algorithms_for(jwks)
108
- jwks.fetch(:keys, []).map do |k|
109
- k[:alg]
110
- end.uniq.compact.then do |algs|
111
- algs.present? ? Success(algs) : Failure[:no_algorithms, "Could not derive algorithms from JWKS"]
112
- end
76
+ Success[:authenticated, decoded_token]
113
77
  end
114
78
  end
115
79
  end
@@ -19,6 +19,10 @@ module KeycloakRack
19
19
  KeycloakRack::Authenticate.new
20
20
  end
21
21
 
22
+ register :decode_and_verify do
23
+ KeycloakRack::DecodeAndVerify.new
24
+ end
25
+
22
26
  register :http_client do
23
27
  KeycloakRack::HTTPClient.new
24
28
  end
@@ -48,6 +52,10 @@ module KeycloakRack
48
52
  register :x509_store do
49
53
  resolve(:config).build_x509_store
50
54
  end
55
+
56
+ register :wrap_token do
57
+ KeycloakRack::WrapToken.new
58
+ end
51
59
  end
52
60
  end
53
61
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KeycloakRack
4
+ # Accept an encoded JWT and return the raw token.
5
+ class DecodeAndVerify
6
+ include Dry::Monads[:do, :result]
7
+
8
+ include Import[
9
+ config: "keycloak-rack.config",
10
+ key_resolver: "keycloak-rack.key_resolver",
11
+ ]
12
+
13
+ delegate :token_leeway, to: :config
14
+
15
+ # @param [String] token
16
+ # @return [Dry::Monads::Success(Hash, Hash)] a tuple of the JWT payload and its headers
17
+ # @return [Dry::Monads::Failure(:expired, String, String, Exception)]
18
+ # @return [Dry::Monads::Failure(:decoding_failed, String, Exception)]
19
+ def call(token)
20
+ jwks = yield key_resolver.find_public_keys
21
+
22
+ algorithms = yield algorithms_for jwks
23
+
24
+ options = {
25
+ algorithms: algorithms,
26
+ leeway: token_leeway,
27
+ jwks: jwks
28
+ }
29
+
30
+ payload, headers = JWT.decode token, nil, true, options
31
+ rescue JWT::ExpiredSignature => e
32
+ Failure[:expired, "JWT is expired", token, e]
33
+ rescue JWT::DecodeError => e
34
+ Failure[:decoding_failed, "Failed to decode JWT", e]
35
+ else
36
+ Success[payload, headers]
37
+ end
38
+
39
+ private
40
+
41
+ # @param [{ Symbol => <{ Symbol => String }> }] jwks
42
+ # @return [<String>]
43
+ def algorithms_for(jwks)
44
+ jwks.fetch(:keys, []).map do |k|
45
+ k[:alg]
46
+ end.uniq.compact.then do |algs|
47
+ algs.present? ? Success(algs) : Failure[:no_algorithms, "Could not derive algorithms from JWKS"]
48
+ end
49
+ end
50
+ end
51
+ end
@@ -18,6 +18,8 @@ module KeycloakRack
18
18
 
19
19
  private_constant :KEY_MAP
20
20
 
21
+ ALIAS_MAP = KEY_MAP.invert.freeze
22
+
21
23
  transform_keys do |k|
22
24
  KEY_MAP[k] || k.to_sym
23
25
  end
@@ -65,17 +67,17 @@ module KeycloakRack
65
67
  # @!attribute [r] expires_at
66
68
  # The `exp` claim
67
69
  # @return [Time]
68
- attribute :expires_at, Types::Timestamp
70
+ attribute? :expires_at, Types::Timestamp
69
71
 
70
72
  # @!attribute [r] issued_at
71
73
  # The `iat` claim
72
74
  # @return [Time]
73
- attribute :issued_at, Types::Timestamp
75
+ attribute? :issued_at, Types::Timestamp
74
76
 
75
77
  # @!attribute [r] authorized_at
76
78
  # The `auth_time` value from Keycloak.
77
79
  # @return [Time]
78
- attribute :authorized_at, Types::Timestamp
80
+ attribute? :authorized_at, Types::Timestamp
79
81
 
80
82
  # @!attribute [r] jti
81
83
  # @return [String]
@@ -93,20 +95,20 @@ module KeycloakRack
93
95
  # @!attribute [r] authorized_party
94
96
  # The `azp` claim
95
97
  # @return [String]
96
- attribute :authorized_party, Types::String
98
+ attribute? :authorized_party, Types::String
97
99
 
98
100
  # @!attribute [r] nonce
99
101
  # Cryptographic nonce for the token
100
102
  # @return [String]
101
- attribute :nonce, Types::String
103
+ attribute? :nonce, Types::String
102
104
 
103
105
  # @!attribute [r] scope
104
106
  # @return [String]
105
- attribute :scope, Types::String
107
+ attribute? :scope, Types::String
106
108
 
107
109
  # @!attribute [r] session_state
108
110
  # @return [String]
109
- attribute :session_state, Types::String
111
+ attribute? :session_state, Types::String
110
112
 
111
113
  # @!attribute [r] locale
112
114
  # @return [String, nil]
@@ -114,7 +116,7 @@ module KeycloakRack
114
116
 
115
117
  # @!attribute [r] allowed_origins
116
118
  # @return [<String>]
117
- attribute :allowed_origins, Types::StringList
119
+ attribute? :allowed_origins, Types::StringList
118
120
 
119
121
  # @!attribute [r] headers
120
122
  # The JWT headers, provided for debugging
@@ -187,5 +189,13 @@ module KeycloakRack
187
189
  # An error raised by {KeycloakRack::DecodedToken#fetch} when
188
190
  # trying to fetch something the token doesn't know about
189
191
  class UnknownAttribute < KeyError; end
192
+
193
+ class << self
194
+ # @param [Symbol] key
195
+ # @return [Symbol]
196
+ def maybe_unalias_key(key)
197
+ ALIAS_MAP.fetch(key, key).to_sym
198
+ end
199
+ end
190
200
  end
191
201
  end
@@ -84,7 +84,7 @@ module KeycloakRack
84
84
  401
85
85
  in Failure[:expired, String, String, Exception]
86
86
  403
87
- in Failure[Symbol, String, String, Exception]
87
+ in Failure[Symbol, String, Exception]
88
88
  400
89
89
  else
90
90
  500
@@ -2,5 +2,5 @@
2
2
 
3
3
  module KeycloakRack
4
4
  # Gem version
5
- VERSION = "1.0.0"
5
+ VERSION = "1.1.0"
6
6
  end