linzer 0.6.0 → 0.6.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 +4 -4
- data/.standard.yml +1 -0
- data/CHANGELOG.md +8 -0
- data/lib/linzer/common.rb +21 -2
- data/lib/linzer/message.rb +52 -12
- data/lib/linzer/request.rb +2 -1
- data/lib/linzer/version.rb +1 -5
- metadata +18 -13
- data/linzer.gemspec +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2ec6a2a846f2bb066bdd658c2e50a869ceff52f65f3e5f8670cc5509af6069c
|
4
|
+
data.tar.gz: 5401df5ea61c39290b61a21cf19c4eaddc537abe908067a47688c1f209c982e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53c504c5c0f886d3e73332d7d8bf7072137519a218ca6a005824f8ad073fb589dd91f2e7980aa02b232c17dd80a87923141e57b094087fb4f412dddbf5588a9f
|
7
|
+
data.tar.gz: 0a99fc9611e6b26ae820fecfe09e10a6c610be20bdf8f9c3fd7c6fab031f82f6f7fa109359470a2a65b7d7cd9817c21259e59fe6f99e50a1c6326d965b0df944
|
data/.standard.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.6.1] - 2024-12-02
|
4
|
+
|
5
|
+
- Add more validation checks on HTTP field component identifiers and parameters.
|
6
|
+
|
7
|
+
- Relax rack version requirements.
|
8
|
+
|
9
|
+
- Update uri dependency to the latest version.
|
10
|
+
|
3
11
|
## [0.6.0] - 2024-04-06
|
4
12
|
|
5
13
|
- Support parameters on HTTP field component identifiers.
|
data/lib/linzer/common.rb
CHANGED
@@ -18,10 +18,29 @@ module Linzer
|
|
18
18
|
if components.include?("@signature-params")
|
19
19
|
raise Error.new "Invalid component in signature input"
|
20
20
|
end
|
21
|
+
|
21
22
|
msg = "Cannot verify signature. Missing component in message: %s"
|
22
|
-
components.each
|
23
|
+
components.each do |c|
|
24
|
+
raise Error.new msg % "\"#{c}\"" unless message.field?(c)
|
25
|
+
end
|
26
|
+
|
27
|
+
validate_uniqueness components
|
28
|
+
end
|
29
|
+
|
30
|
+
def validate_uniqueness(components)
|
23
31
|
msg = "Invalid signature. Duplicated component in signature input."
|
24
|
-
|
32
|
+
|
33
|
+
uniq_components =
|
34
|
+
components
|
35
|
+
.partition { |c| c.start_with?("@") }
|
36
|
+
.flat_map
|
37
|
+
.with_index do |group, idx|
|
38
|
+
group
|
39
|
+
.map { |comp| Starry.parse_item(idx.zero? ? comp[1..] : comp) }
|
40
|
+
.uniq { |comp| [comp.value, comp.parameters] }
|
41
|
+
end
|
42
|
+
|
43
|
+
raise Error.new msg if components.count != uniq_components.count
|
25
44
|
end
|
26
45
|
end
|
27
46
|
end
|
data/lib/linzer/message.rb
CHANGED
@@ -47,7 +47,6 @@ module Linzer
|
|
47
47
|
return nil if name.nil?
|
48
48
|
|
49
49
|
if field_name.start_with?("@")
|
50
|
-
return nil if name.parameters["tr"]
|
51
50
|
retrieve(name, :derived)
|
52
51
|
else
|
53
52
|
retrieve(name, :field)
|
@@ -79,13 +78,48 @@ module Linzer
|
|
79
78
|
nil
|
80
79
|
end
|
81
80
|
|
81
|
+
def validate_parameters(name, method)
|
82
|
+
has_unknown = name.parameters.any? { |p, _| !KNOWN_PARAMETERS.include?(p) }
|
83
|
+
return nil if has_unknown
|
84
|
+
|
85
|
+
has_name = name.parameters["name"]
|
86
|
+
has_req = name.parameters["req"]
|
87
|
+
has_sf = name.parameters["sf"] || name.parameters.key?("key")
|
88
|
+
has_bs = name.parameters["bs"]
|
89
|
+
value = name.value
|
90
|
+
|
91
|
+
# Section 2.2.8 of RFC 9421
|
92
|
+
return nil if has_name && value != :"query-param"
|
93
|
+
|
94
|
+
# No derived values come from trailers section
|
95
|
+
return nil if method == :derived && name.parameters["tr"]
|
96
|
+
|
97
|
+
# From: 2.1. HTTP Fields:
|
98
|
+
# The bs parameter, which requires the raw bytes of the field values
|
99
|
+
# from the message, is not compatible with the use of the sf or key
|
100
|
+
# parameters, which require the parsed data structures of the field
|
101
|
+
# values after combination
|
102
|
+
return nil if has_sf && has_bs
|
103
|
+
|
104
|
+
# req param only makes sense on responses with an associated request
|
105
|
+
return nil if has_req && (!response? || !attached_request?)
|
106
|
+
|
107
|
+
name
|
108
|
+
end
|
109
|
+
|
110
|
+
KNOWN_PARAMETERS = %w[sf key bs req tr name]
|
111
|
+
private_constant :KNOWN_PARAMETERS
|
112
|
+
|
82
113
|
def retrieve(name, method)
|
114
|
+
if !name.parameters.empty?
|
115
|
+
valid_params = validate_parameters(name, method)
|
116
|
+
return nil if !valid_params
|
117
|
+
end
|
118
|
+
|
83
119
|
has_req = name.parameters["req"]
|
84
120
|
has_sf = name.parameters["sf"] || name.parameters.key?("key")
|
85
121
|
has_bs = name.parameters["bs"]
|
86
122
|
|
87
|
-
return nil if has_req && (!response? || !attached_request?)
|
88
|
-
|
89
123
|
if has_req
|
90
124
|
name.parameters.delete("req")
|
91
125
|
return req(name, method)
|
@@ -93,10 +127,13 @@ module Linzer
|
|
93
127
|
|
94
128
|
value = send(method, name)
|
95
129
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
130
|
+
case
|
131
|
+
when has_sf
|
132
|
+
key = name.parameters["key"]
|
133
|
+
sf(value, key)
|
134
|
+
when has_bs then bs(value)
|
135
|
+
else value
|
136
|
+
end
|
100
137
|
end
|
101
138
|
|
102
139
|
def derived(name)
|
@@ -128,7 +165,8 @@ module Linzer
|
|
128
165
|
def derive(operation, method)
|
129
166
|
return nil unless operation.respond_to?(method)
|
130
167
|
value = operation.public_send(method)
|
131
|
-
return "?" + value
|
168
|
+
return "?" + value if method == :query_string
|
169
|
+
return value.downcase if %i[authority scheme].include?(method)
|
132
170
|
value
|
133
171
|
end
|
134
172
|
|
@@ -144,10 +182,12 @@ module Linzer
|
|
144
182
|
def sf(value, key = nil)
|
145
183
|
dict = Starry.parse_dictionary(value)
|
146
184
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
185
|
+
if key
|
186
|
+
obj = dict[key]
|
187
|
+
Starry.serialize(obj.is_a?(Starry::InnerList) ? [obj] : obj)
|
188
|
+
else
|
189
|
+
Starry.serialize(dict)
|
190
|
+
end
|
151
191
|
end
|
152
192
|
|
153
193
|
def bs(value)
|
data/lib/linzer/request.rb
CHANGED
@@ -11,7 +11,8 @@ module Linzer
|
|
11
11
|
request_method = Rack.const_get(verb.upcase)
|
12
12
|
args = {
|
13
13
|
"REQUEST_METHOD" => request_method,
|
14
|
-
"PATH_INFO" => uri.to_str
|
14
|
+
"PATH_INFO" => uri.to_str,
|
15
|
+
"rack.input" => StringIO.new
|
15
16
|
}
|
16
17
|
|
17
18
|
Rack::Request.new(build_rack_env(headers).merge(args))
|
data/lib/linzer/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: linzer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Landaeta
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: openssl
|
@@ -56,48 +56,54 @@ dependencies:
|
|
56
56
|
requirements:
|
57
57
|
- - "~>"
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version: '0.
|
59
|
+
version: '0.2'
|
60
60
|
type: :runtime
|
61
61
|
prerelease: false
|
62
62
|
version_requirements: !ruby/object:Gem::Requirement
|
63
63
|
requirements:
|
64
64
|
- - "~>"
|
65
65
|
- !ruby/object:Gem::Version
|
66
|
-
version: '0.
|
66
|
+
version: '0.2'
|
67
67
|
- !ruby/object:Gem::Dependency
|
68
68
|
name: rack
|
69
69
|
requirement: !ruby/object:Gem::Requirement
|
70
70
|
requirements:
|
71
|
-
- - "
|
71
|
+
- - ">="
|
72
72
|
- !ruby/object:Gem::Version
|
73
|
-
version: '
|
73
|
+
version: '2.2'
|
74
|
+
- - "<"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '4.0'
|
74
77
|
type: :runtime
|
75
78
|
prerelease: false
|
76
79
|
version_requirements: !ruby/object:Gem::Requirement
|
77
80
|
requirements:
|
78
|
-
- - "
|
81
|
+
- - ">="
|
79
82
|
- !ruby/object:Gem::Version
|
80
|
-
version: '
|
83
|
+
version: '2.2'
|
84
|
+
- - "<"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '4.0'
|
81
87
|
- !ruby/object:Gem::Dependency
|
82
88
|
name: uri
|
83
89
|
requirement: !ruby/object:Gem::Requirement
|
84
90
|
requirements:
|
85
91
|
- - "~>"
|
86
92
|
- !ruby/object:Gem::Version
|
87
|
-
version: '0
|
93
|
+
version: '1.0'
|
88
94
|
- - ">="
|
89
95
|
- !ruby/object:Gem::Version
|
90
|
-
version: 0.
|
96
|
+
version: 1.0.2
|
91
97
|
type: :runtime
|
92
98
|
prerelease: false
|
93
99
|
version_requirements: !ruby/object:Gem::Requirement
|
94
100
|
requirements:
|
95
101
|
- - "~>"
|
96
102
|
- !ruby/object:Gem::Version
|
97
|
-
version: '0
|
103
|
+
version: '1.0'
|
98
104
|
- - ">="
|
99
105
|
- !ruby/object:Gem::Version
|
100
|
-
version: 0.
|
106
|
+
version: 1.0.2
|
101
107
|
description:
|
102
108
|
email:
|
103
109
|
- miguel@miguel.cc
|
@@ -127,7 +133,6 @@ files:
|
|
127
133
|
- lib/linzer/signer.rb
|
128
134
|
- lib/linzer/verifier.rb
|
129
135
|
- lib/linzer/version.rb
|
130
|
-
- linzer.gemspec
|
131
136
|
homepage: https://github.com/nomadium/linzer
|
132
137
|
licenses:
|
133
138
|
- MIT
|
data/linzer.gemspec
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "lib/linzer/version"
|
4
|
-
|
5
|
-
Gem::Specification.new do |spec|
|
6
|
-
spec.name = "linzer"
|
7
|
-
spec.version = Linzer::VERSION
|
8
|
-
spec.authors = ["Miguel Landaeta"]
|
9
|
-
spec.email = %w[miguel@miguel.cc]
|
10
|
-
|
11
|
-
spec.summary = "An implementation of HTTP Messages Signatures (RFC9421)"
|
12
|
-
spec.homepage = "https://github.com/nomadium/linzer"
|
13
|
-
spec.license = "MIT"
|
14
|
-
spec.required_ruby_version = ">= 2.6.0"
|
15
|
-
|
16
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
17
|
-
spec.metadata["source_code_uri"] = spec.homepage
|
18
|
-
spec.metadata["changelog_uri"] = spec.homepage + "/blob/master/CHANGELOG.md"
|
19
|
-
|
20
|
-
# Specify which files should be added to the gem when it is released.
|
21
|
-
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
22
|
-
spec.files = Dir.chdir(__dir__) do
|
23
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
24
|
-
(File.expand_path(f) == __FILE__) ||
|
25
|
-
f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
|
26
|
-
end
|
27
|
-
end
|
28
|
-
spec.bindir = "exe"
|
29
|
-
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
30
|
-
spec.require_paths = ["lib"]
|
31
|
-
|
32
|
-
spec.add_runtime_dependency "openssl", "~> 3.0", ">= 3.0.0"
|
33
|
-
spec.add_runtime_dependency "ed25519", "~> 1.3", ">= 1.3.0"
|
34
|
-
spec.add_runtime_dependency "starry", "~> 0.1" unless Linzer.ruby_dev?
|
35
|
-
spec.add_runtime_dependency "rack", "~> 3.0"
|
36
|
-
spec.add_runtime_dependency "uri", "~> 0.12", ">= 0.12.0"
|
37
|
-
end
|