verikloak 0.1.5 → 0.2.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: 41b02d67b2d6182f8af59436549e9d68cccf08559ecdee0539793ee3baef77a7
4
- data.tar.gz: 5cd807c55d6635370149cf0090644698f470d15c9e01dc78a9332adb6659e2f8
3
+ metadata.gz: d175a574b17bd1ce5e096dbb69769d12a470f49c8444a5246881afd61d06fa52
4
+ data.tar.gz: 3c59a660bb142c194b6e0db2d338952c41c8a88afc479382203b4d767ab7691c
5
5
  SHA512:
6
- metadata.gz: eba3a601c8c67080326955bd0557cfcc8d8098469694ef42ffac590b10a91c48cf4c3cb7250645d6db39e8208a8a05bd0bfa8b59cbdb9ced6e57e55241aa4da1
7
- data.tar.gz: 553050d22b04de79bac27c00358f2c1a0779d380556297ffa2ca7bb5fa1944fe9ee55f9450ccc52cf004c7899c880484457b703d149404e80097079fff303341
6
+ metadata.gz: 92edd8a2df134f115c3f887683246278c5778291bb86bfff22ebc873b2b92d6ff09d9c85a1f798e2f49caa09adc8c3ef18ffc83309f95799997ebbdb54b58228
7
+ data.tar.gz: 0e223f0055e69448899be53fc22c9ac32c5d43c410aa041daa38761ed13a00aae8d655bcb6eaff521927a5a029937fcd480c7b90dcfccddf8e6b028aaf0bf555
data/CHANGELOG.md CHANGED
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ---
9
9
 
10
+ ## [0.2.0] - 2025-09-22
11
+
12
+ ### Added
13
+ - Middleware options `token_env_key` and `user_env_key` for customizing where the token and decoded claims are stored in the Rack env.
14
+ - Middleware option `realm` to change the `WWW-Authenticate` realm value emitted on 401 responses.
15
+ - Middleware option `logger` so unexpected internal errors can be sent to the host application's logger instead of STDERR.
16
+
17
+ ### Changed
18
+ - Update gem version to 0.2.0 to stay aligned with the rest of the Verikloak ecosystem gems.
19
+
20
+ ---
21
+
10
22
  ## [0.1.5] - 2025-09-21
11
23
 
12
24
  ### Added
data/README.md CHANGED
@@ -94,6 +94,26 @@ config.middleware.use Verikloak::Middleware,
94
94
  ```
95
95
  This makes the configuration secure and flexible across environments.
96
96
 
97
+ #### Advanced middleware options
98
+
99
+ `Verikloak::Middleware` exposes a few optional knobs that help integrate with
100
+ different Rack stacks:
101
+
102
+ - `token_env_key` (default: `"verikloak.token"`) — where the raw JWT is stored in the Rack env
103
+ - `user_env_key` (default: `"verikloak.user"`) — where decoded claims are stored
104
+ - `realm` (default: `"verikloak"`) — value used in the `WWW-Authenticate` header for 401 responses
105
+ - `logger` — an object responding to `error` (and optionally `debug`) that receives unexpected 500-level failures
106
+
107
+ ```ruby
108
+ config.middleware.use Verikloak::Middleware,
109
+ discovery_url: ENV.fetch("DISCOVERY_URL"),
110
+ audience: ENV.fetch("CLIENT_ID"),
111
+ token_env_key: "rack.session.token",
112
+ user_env_key: "rack.session.claims",
113
+ realm: "my-api",
114
+ logger: Rails.logger
115
+ ```
116
+
97
117
  ### Accessing claims in controllers
98
118
 
99
119
  Once the middleware is enabled, Verikloak adds the decoded token and raw JWT to the Rack environment.
@@ -349,6 +349,10 @@ module Verikloak
349
349
  include SkipPathMatcher
350
350
  include MiddlewareTokenVerification
351
351
 
352
+ DEFAULT_REALM = 'verikloak'
353
+ DEFAULT_TOKEN_ENV_KEY = 'verikloak.token'
354
+ DEFAULT_USER_ENV_KEY = 'verikloak.user'
355
+
352
356
  # @param app [#call] downstream Rack app
353
357
  # @param discovery_url [String] OIDC discovery endpoint URL
354
358
  # @param audience [String, #call] Expected `aud` claim. When a callable is provided it
@@ -362,6 +366,7 @@ module Verikloak
362
366
  # @param token_verify_options [Hash] Additional JWT verification options passed through
363
367
  # to TokenDecoder.
364
368
  # e.g., { verify_iat: false, leeway: 10 }
369
+ # rubocop:disable Metrics/ParameterLists
365
370
  def initialize(app,
366
371
  discovery_url:,
367
372
  audience:,
@@ -370,7 +375,11 @@ module Verikloak
370
375
  jwks_cache: nil,
371
376
  connection: nil,
372
377
  leeway: Verikloak::TokenDecoder::DEFAULT_LEEWAY,
373
- token_verify_options: {})
378
+ token_verify_options: {},
379
+ token_env_key: DEFAULT_TOKEN_ENV_KEY,
380
+ user_env_key: DEFAULT_USER_ENV_KEY,
381
+ realm: DEFAULT_REALM,
382
+ logger: nil)
374
383
  @app = app
375
384
  @connection = connection || Verikloak::HTTP.default_connection
376
385
  @audience_source = audience
@@ -381,9 +390,14 @@ module Verikloak
381
390
  @issuer = nil
382
391
  @mutex = Mutex.new
383
392
  @decoder_cache = {}
393
+ @token_env_key = normalize_env_key(token_env_key, 'token_env_key')
394
+ @user_env_key = normalize_env_key(user_env_key, 'user_env_key')
395
+ @realm = normalize_realm(realm)
396
+ @logger = logger
384
397
 
385
398
  compile_skip_paths(skip_paths)
386
399
  end
400
+ # rubocop:enable Metrics/ParameterLists
387
401
 
388
402
  # Rack entrypoint.
389
403
  #
@@ -418,8 +432,8 @@ module Verikloak
418
432
  # @return [Array(Integer, Hash, Array<String>)] Rack response triple
419
433
  def handle_request(env, token)
420
434
  claims = decode_token(env, token)
421
- env['verikloak.token'] = token
422
- env['verikloak.user'] = claims
435
+ env[@token_env_key] = token
436
+ env[@user_env_key] = claims
423
437
  @app.call(env)
424
438
  end
425
439
 
@@ -475,7 +489,7 @@ module Verikloak
475
489
  headers = { 'Content-Type' => 'application/json' }
476
490
  if status == 401
477
491
  headers['WWW-Authenticate'] =
478
- %(Bearer realm="verikloak", error="#{code}", error_description="#{message.gsub('"', '\\"')}")
492
+ %(Bearer realm="#{@realm}", error="#{code}", error_description="#{message.gsub('"', '\\"')}")
479
493
  end
480
494
  [status, headers, [body]]
481
495
  end
@@ -485,8 +499,62 @@ module Verikloak
485
499
  # @param error [Exception]
486
500
  # @return [void]
487
501
  def log_internal_error(error)
488
- warn "[verikloak] Internal error: #{error.class} - #{error.message}"
489
- warn error.backtrace.join("\n") if error.backtrace
502
+ message = "[verikloak] Internal error: #{error.class} - #{error.message}"
503
+ backtrace = error.backtrace&.join("\n")
504
+
505
+ if logger_available?
506
+ log_with_logger(message, backtrace)
507
+ else
508
+ warn message
509
+ warn backtrace if backtrace
510
+ end
511
+ end
512
+
513
+ def logger_available?
514
+ return false unless @logger
515
+
516
+ @logger.respond_to?(:error) || @logger.respond_to?(:warn) || @logger.respond_to?(:debug)
517
+ end
518
+
519
+ def log_with_logger(message, backtrace)
520
+ log_message(@logger, message)
521
+ log_backtrace(@logger, backtrace)
522
+ end
523
+
524
+ def log_message(logger, message)
525
+ if logger.respond_to?(:error)
526
+ logger.error(message)
527
+ elsif logger.respond_to?(:warn)
528
+ logger.warn(message)
529
+ end
530
+ end
531
+
532
+ def log_backtrace(logger, backtrace)
533
+ return unless backtrace
534
+
535
+ if logger.respond_to?(:debug)
536
+ logger.debug(backtrace)
537
+ elsif logger.respond_to?(:error)
538
+ logger.error(backtrace)
539
+ elsif logger.respond_to?(:warn)
540
+ logger.warn(backtrace)
541
+ end
542
+ end
543
+
544
+ def normalize_env_key(value, option_name)
545
+ normalized = value.to_s.strip
546
+ raise ArgumentError, "#{option_name} cannot be blank" if normalized.empty?
547
+
548
+ normalized
549
+ end
550
+
551
+ def normalize_realm(value)
552
+ return DEFAULT_REALM if value.nil?
553
+
554
+ normalized = value.to_s.strip
555
+ raise ArgumentError, 'realm cannot be blank' if normalized.empty?
556
+
557
+ normalized
490
558
  end
491
559
  end
492
560
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Verikloak
4
4
  # Defines the current version of the Verikloak gem.
5
- VERSION = '0.1.5'
5
+ VERSION = '0.2.0'
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: verikloak
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - taiyaky
@@ -109,7 +109,7 @@ metadata:
109
109
  source_code_uri: https://github.com/taiyaky/verikloak
110
110
  changelog_uri: https://github.com/taiyaky/verikloak/blob/main/CHANGELOG.md
111
111
  bug_tracker_uri: https://github.com/taiyaky/verikloak/issues
112
- documentation_uri: https://rubydoc.info/gems/verikloak/0.1.5
112
+ documentation_uri: https://rubydoc.info/gems/verikloak/0.2.0
113
113
  rubygems_mfa_required: 'true'
114
114
  rdoc_options: []
115
115
  require_paths: