http_signature 1.4.0 → 1.5.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: 6e13e2dd019cbe8bc7359f1b49cfcd16bd3bb0e11818c7a4709a5892e7a9b362
4
- data.tar.gz: 5879cc1525680c68286539b73d7091cdac20218727128af6e42cf2cff36e4c77
3
+ metadata.gz: 5c57222b061b994515d691691c87192a612eec84694085b03db51e3ea1fa2c75
4
+ data.tar.gz: ecc70179bb4d76a955b4711b6494e4e0a862ccf811b47d7d4aa3d46253f63066
5
5
  SHA512:
6
- metadata.gz: 69726bec8a75e3214a9d0c5b3f94f8d65e76c4c64746cc7ade2b11012f8d299d69ac33960f28feb486572702df2460f593cbcc04213f10bf42bd0706404763b8
7
- data.tar.gz: e0c993df95150e6698faa87327a806262d7fd7f2141e70cae917dfa89f40ba018acbe721a4b7744b8a5af4ae3e3063fbe4427afbb35a562972de396a05d30acd
6
+ metadata.gz: 0da5638c340b56fb03fda5aed0e827ef2881e1515da8217c87aa45312d5d81880be3e37179100c9ace8f6788d38b99c916ea6de5a60881d057125d61754d8745
7
+ data.tar.gz: 600dfb9d3d1a6b4e89c73b9717b5a023b2ccb72c6a38f63dec3ba503e85c417d1af2e7cf8a126192802b63edd547ff4a8a96888d3d933131cea7e28cadf3a7fe
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- http_signature (1.4.0)
4
+ http_signature (1.5.0)
5
5
  base64
6
6
  starry (~> 0.2)
7
7
 
data/README.md CHANGED
@@ -57,6 +57,7 @@ HTTPSignature.create(
57
57
  created: Time.now.to_i, # Default: Time.now.to_i
58
58
  expires: Time.now.to_i + 600, # Default: nil
59
59
  nonce: "1", # Default: nil
60
+ tag: "web-bot-auth", # Default: nil
60
61
  label: "sig1", # Default: "sig1"
61
62
  query_string_params: {pet2: "cat"}, # Default: {}, you can pass query string params both here and in the `url` param
62
63
  algorithm: "hmac-sha512", # Default: "hmac-sha256"
@@ -175,7 +176,7 @@ HTTPSignature.valid?(
175
176
  body: request_body, # Default: ""
176
177
  key: "secret", # Default: nil, uses key_resolver or configured keys if nil
177
178
  key_resolver: ->(key_id) { find_key(key_id) }, # Default: nil, called with the key_id from Signature-Input
178
- label: "sig1", # Default: "sig1"
179
+ label: "sig1", # Default: nil (uses first)
179
180
  query_string_params: {}, # Default: {}
180
181
  max_age: 300, # Default: nil, reject signatures older than N seconds
181
182
  algorithm: "hmac-sha256", # Default: nil, uses alg from Signature-Input or hmac-sha256
@@ -318,7 +319,7 @@ conn = Faraday.new("http://example.com") do |f|
318
319
  end
319
320
  ```
320
321
 
321
- The middleware also accepts the params: `created:`, `expires:`, `nonce:`, `label:`, `algorithm:`, and `include_alg:`.
322
+ The middleware also accepts the params: `created:`, `expires:`, `nonce:`, `tag:`, `label:`, `algorithm:`, and `include_alg:`.
322
323
 
323
324
  ### HTTParty
324
325
 
@@ -422,6 +423,16 @@ class Api::BaseController < ApplicationController
422
423
  end
423
424
  ```
424
425
 
426
+ To enforce a specific signature label or age limit, use a block:
427
+
428
+ ```ruby
429
+ class Api::BaseController < ApplicationController
430
+ include HTTPSignature::Rails::Controller
431
+
432
+ before_action -> { verify_http_signature!(label: "sig2", max_age: 300) }
433
+ end
434
+ ```
435
+
425
436
  Set the keys in an initializer
426
437
  ```ruby
427
438
  # config/initializers/http_signature.rb
@@ -61,7 +61,7 @@ class HTTPSignature::Faraday < Faraday::Middleware
61
61
  end
62
62
 
63
63
  def create_options(options)
64
- options.slice(:created, :expires, :nonce, :label, :include_alg, :algorithm)
64
+ options.slice(:created, :expires, :nonce, :tag, :label, :include_alg, :algorithm)
65
65
  .reject { |_key, value| value.nil? }
66
66
  end
67
67
  end
@@ -11,7 +11,7 @@ module HTTPSignature
11
11
  private
12
12
 
13
13
  # Use as a Rails before_action to enforce HTTP Message Signatures on an action.
14
- def verify_http_signature!
14
+ def verify_http_signature!(label: nil, max_age: nil)
15
15
  request_headers = normalized_request_headers
16
16
  signature_input_header = request_headers["signature-input"]
17
17
  signature_header = request_headers["signature"]
@@ -25,7 +25,9 @@ module HTTPSignature
25
25
  method: request.request_method,
26
26
  headers: request_headers,
27
27
  body: request_body || "",
28
- key_resolver: ->(key_id) { HTTPSignature.key(key_id) }
28
+ key_resolver: ->(key_id) { HTTPSignature.key(key_id) },
29
+ label:,
30
+ max_age:
29
31
  )
30
32
 
31
33
  nil
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HTTPSignature
4
- VERSION = "1.4.0"
4
+ VERSION = "1.5.0"
5
5
  end
@@ -63,6 +63,7 @@ module HTTPSignature
63
63
  # @param created [Integer] Unix timestamp for signature creation (default: Time.now.to_i)
64
64
  # @param expires [Integer, nil] Unix timestamp when signature expires (default: nil)
65
65
  # @param nonce [String, nil] Random value for signature uniqueness (default: nil)
66
+ # @param tag [String, nil] Application-specific tag parameter included in signature metadata (default: nil)
66
67
  # @param label [String] Signature label in headers (default: "sig1")
67
68
  # @param query_string_params [Hash] Additional query params to merge into URL (default: {})
68
69
  # @param include_alg [Boolean] Whether to include alg in signature metadata (default: true)
@@ -84,6 +85,7 @@ module HTTPSignature
84
85
  created: Time.now.to_i,
85
86
  expires: nil,
86
87
  nonce: nil,
88
+ tag: nil,
87
89
  label: DEFAULT_LABEL,
88
90
  query_string_params: {},
89
91
  include_alg: true,
@@ -136,6 +138,7 @@ module HTTPSignature
136
138
  key_id:,
137
139
  alg: include_alg ? algorithm : nil,
138
140
  nonce:,
141
+ tag:,
139
142
  canonical_components:
140
143
  )
141
144
 
@@ -249,6 +252,7 @@ module HTTPSignature
249
252
  key_id:,
250
253
  alg: parsed_input[:params][:alg],
251
254
  nonce: parsed_input[:params][:nonce],
255
+ tag: parsed_input[:params][:tag],
252
256
  canonical_components:
253
257
  )
254
258
 
@@ -349,7 +353,11 @@ module HTTPSignature
349
353
  def self.verify_content_digest!(header_value, body)
350
354
  verified = false
351
355
 
352
- header_value.scan(/([a-z0-9-]+)=:([A-Za-z0-9+\/=]+):/).each do |alg, encoded_digest|
356
+ split_header(header_value).each do |entry|
357
+ alg, digest_value = entry.split("=", 2)
358
+ next unless alg && digest_value&.start_with?(":") && digest_value.end_with?(":")
359
+
360
+ encoded_digest = digest_value[1...-1]
353
361
  digest = case alg
354
362
  when "sha-256" then Digest::SHA256.digest(body)
355
363
  when "sha-512" then Digest::SHA512.digest(body)
@@ -501,6 +509,7 @@ module HTTPSignature
501
509
  key_id:,
502
510
  alg:,
503
511
  nonce:,
512
+ tag:,
504
513
  canonical_components:
505
514
  )
506
515
  component_tokens = components.map { |c| serialize_component_id(c) }.join(" ")
@@ -509,6 +518,7 @@ module HTTPSignature
509
518
  params << %(keyid="#{escape_structured_string(key_id)}")
510
519
  params << %(alg="#{escape_structured_string(alg)}") if alg
511
520
  params << %(nonce="#{escape_structured_string(nonce)}") if nonce
521
+ params << %(tag="#{escape_structured_string(tag)}") if tag
512
522
 
513
523
  signature_params = "(#{component_tokens});#{params.join(";")}"
514
524
  signature_input_header = "#{label}=#{signature_params}"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http_signature
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Larsson