escher 1.0.2 → 2.0.5
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/.github/workflows/ruby.yml +33 -0
- data/escher.gemspec +4 -4
- data/lib/escher/auth.rb +22 -16
- data/lib/escher/version.rb +1 -1
- data/repo-info.json +7 -0
- data/spec/emarsys_test_suite_spec.rb +0 -6
- data/spec/escher/auth_spec.rb +2 -2
- metadata +13 -13
- data/.travis.yml +0 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f91ee25e50b0311776949593fd31d8d276de81f7c5a1530e205e85c3caa72a60
|
|
4
|
+
data.tar.gz: 10721eb994568d2ecbebfc38b091157abc444d99ab3e2c67290ba9482ba6fc40
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2af6931a12851430143b67ff12ca921b16d71f301a334c5db68c11fc537777fbedb9d9fd4458e94b0b788c86c7c02c21dca5cf51a4d2d25f2a0f3598ff7f3943
|
|
7
|
+
data.tar.gz: 5b1ad5329ab153d8d1f1f7ee5d006303d9548b0eb0e0481aa7dd0b72ea2331d673f4f1defe7c73d795124d2d88a7eed8cb063b3193510e66e270dcda8dc69f6b
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Ruby
|
|
2
|
+
|
|
3
|
+
on: [push]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
build:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
strategy:
|
|
9
|
+
matrix:
|
|
10
|
+
ruby-versions: ['2.6', '2.7', '3.0']
|
|
11
|
+
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v2
|
|
14
|
+
- uses: ruby/setup-ruby@v1
|
|
15
|
+
with:
|
|
16
|
+
ruby-version: ${{ matrix.ruby-versions }}
|
|
17
|
+
- name: Checkout testsuite
|
|
18
|
+
run: ./scripts/checkout_test_suite.sh
|
|
19
|
+
- name: Install dependencies
|
|
20
|
+
run: bundle install
|
|
21
|
+
- name: Run tests
|
|
22
|
+
run: bundle exec rake
|
|
23
|
+
- name: Deploy
|
|
24
|
+
if : github.event_name == 'push' && startsWith(github.ref, 'refs/tags') && matrix.ruby-versions == '3.0'
|
|
25
|
+
run: |
|
|
26
|
+
mkdir -p $HOME/.gem
|
|
27
|
+
touch $HOME/.gem/credentials
|
|
28
|
+
chmod 0600 $HOME/.gem/credentials
|
|
29
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
|
30
|
+
gem build *.gemspec
|
|
31
|
+
gem push *.gem
|
|
32
|
+
env:
|
|
33
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
data/escher.gemspec
CHANGED
|
@@ -20,14 +20,14 @@ Gem::Specification.new do |spec|
|
|
|
20
20
|
|
|
21
21
|
spec.required_ruby_version = '>= 1.9'
|
|
22
22
|
|
|
23
|
-
spec.add_development_dependency "bundler", "~>
|
|
23
|
+
spec.add_development_dependency "bundler", "~> 2.2.20"
|
|
24
24
|
spec.add_development_dependency "rails"
|
|
25
25
|
|
|
26
|
-
spec.add_development_dependency "rake", "~>
|
|
27
|
-
spec.add_development_dependency "rspec", "~>
|
|
26
|
+
spec.add_development_dependency "rake", "~> 13.0.6"
|
|
27
|
+
spec.add_development_dependency "rspec", "~> 3"
|
|
28
28
|
|
|
29
29
|
spec.add_development_dependency "rack"
|
|
30
30
|
spec.add_development_dependency "plissken"
|
|
31
31
|
|
|
32
|
-
spec.add_runtime_dependency "addressable", "~> 2.
|
|
32
|
+
spec.add_runtime_dependency "addressable", "~> 2.8.0"
|
|
33
33
|
end
|
data/lib/escher/auth.rb
CHANGED
|
@@ -17,15 +17,17 @@ module Escher
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def sign!(req, client, headers_to_sign = [])
|
|
20
|
+
current_time = @current_time || Time.now
|
|
21
|
+
|
|
20
22
|
headers_to_sign |= [@date_header_name.downcase, 'host']
|
|
21
23
|
|
|
22
24
|
request = wrap_request req
|
|
23
25
|
raise EscherError, 'The host header is missing' unless request.has_header? 'host'
|
|
24
26
|
|
|
25
|
-
request.set_header(@date_header_name.downcase, format_date_for_header) unless request.has_header? @date_header_name
|
|
27
|
+
request.set_header(@date_header_name.downcase, format_date_for_header(current_time)) unless request.has_header? @date_header_name
|
|
26
28
|
|
|
27
|
-
signature = generate_signature(client[:api_secret], request.body, request.headers, request.method, headers_to_sign, request.path, request.query_values)
|
|
28
|
-
request.set_header(@auth_header_name, "#{@algo_id} Credential=#{client[:api_key_id]}/#{short_date(
|
|
29
|
+
signature = generate_signature(client[:api_secret], request.body, request.headers, request.method, headers_to_sign, request.path, request.query_values, current_time)
|
|
30
|
+
request.set_header(@auth_header_name, "#{@algo_id} Credential=#{client[:api_key_id]}/#{short_date(current_time)}/#{@credential_scope}, SignedHeaders=#{prepare_headers_to_sign headers_to_sign}, Signature=#{signature}")
|
|
29
31
|
|
|
30
32
|
request.request
|
|
31
33
|
end
|
|
@@ -36,6 +38,8 @@ module Escher
|
|
|
36
38
|
begin
|
|
37
39
|
authenticate(*args)
|
|
38
40
|
return true
|
|
41
|
+
rescue EscherError
|
|
42
|
+
return false
|
|
39
43
|
rescue
|
|
40
44
|
return false
|
|
41
45
|
end
|
|
@@ -44,6 +48,7 @@ module Escher
|
|
|
44
48
|
|
|
45
49
|
|
|
46
50
|
def authenticate(req, key_db, mandatory_signed_headers = nil)
|
|
51
|
+
current_time = @current_time || Time.now
|
|
47
52
|
request = wrap_request req
|
|
48
53
|
method = request.method
|
|
49
54
|
body = request.body
|
|
@@ -80,7 +85,7 @@ module Escher
|
|
|
80
85
|
raise EscherError, 'The request method is invalid' unless valid_request_method?(method)
|
|
81
86
|
raise EscherError, "The request url shouldn't contains http or https" if path.match /^https?:\/\//
|
|
82
87
|
raise EscherError, 'Invalid date in authorization header, it should equal with date header' unless short_date(date) == short_date
|
|
83
|
-
raise EscherError, 'The request date is not within the accepted time range' unless is_date_within_range?(date, expires,
|
|
88
|
+
raise EscherError, 'The request date is not within the accepted time range' unless is_date_within_range?(date, expires, current_time)
|
|
84
89
|
raise EscherError, 'Invalid Credential Scope' unless credential_scope == @credential_scope
|
|
85
90
|
raise EscherError, 'The mandatorySignedHeaders parameter must be undefined or array of strings' unless mandatory_signed_headers_valid?(mandatory_signed_headers)
|
|
86
91
|
raise EscherError, 'The host header is not signed' unless signed_headers.include? 'host'
|
|
@@ -93,7 +98,7 @@ module Escher
|
|
|
93
98
|
raise EscherError, 'The date header is not signed' if !signature_from_query && !signed_headers.include?(@date_header_name.downcase)
|
|
94
99
|
|
|
95
100
|
escher = reconfig(algorithm, credential_scope, date)
|
|
96
|
-
expected_signature = escher.generate_signature(api_secret, body, headers, method, signed_headers, path, query_parts)
|
|
101
|
+
expected_signature = escher.generate_signature(api_secret, body, headers, method, signed_headers, path, query_parts, date)
|
|
97
102
|
raise EscherError, 'The signatures do not match' unless signature == expected_signature
|
|
98
103
|
api_key_id
|
|
99
104
|
end
|
|
@@ -115,6 +120,7 @@ module Escher
|
|
|
115
120
|
|
|
116
121
|
|
|
117
122
|
def generate_signed_url(url_to_sign, client, expires = 86400)
|
|
123
|
+
current_time = @current_time || Time.now
|
|
118
124
|
uri = Addressable::URI.parse(url_to_sign)
|
|
119
125
|
|
|
120
126
|
if (not uri.port.nil?) && (uri.port != uri.default_port)
|
|
@@ -136,13 +142,13 @@ module Escher
|
|
|
136
142
|
body = 'UNSIGNED-PAYLOAD'
|
|
137
143
|
query_parts += [
|
|
138
144
|
['Algorithm', @algo_id],
|
|
139
|
-
['Credentials', "#{client[:api_key_id]}/#{short_date(
|
|
140
|
-
['Date', long_date(
|
|
145
|
+
['Credentials', "#{client[:api_key_id]}/#{short_date(current_time)}/#{@credential_scope}"],
|
|
146
|
+
['Date', long_date(current_time)],
|
|
141
147
|
['Expires', expires.to_s],
|
|
142
148
|
['SignedHeaders', headers_to_sign.join(';')],
|
|
143
149
|
].map { |k, v| query_pair(k, v) }
|
|
144
150
|
|
|
145
|
-
signature = generate_signature(client[:api_secret], body, headers, 'GET', headers_to_sign, path, query_parts)
|
|
151
|
+
signature = generate_signature(client[:api_secret], body, headers, 'GET', headers_to_sign, path, query_parts, current_time)
|
|
146
152
|
query_parts_with_signature = (query_parts.map { |k, v| [uri_encode(k), uri_encode(v)] } << query_pair('Signature', signature))
|
|
147
153
|
"#{uri.scheme}://#{host}#{path}?#{query_parts_with_signature.map { |k, v| k + '=' + v }.join('&')}#{(fragment === nil ? '' : '#' + fragment)}"
|
|
148
154
|
end
|
|
@@ -188,11 +194,11 @@ module Escher
|
|
|
188
194
|
|
|
189
195
|
|
|
190
196
|
|
|
191
|
-
def generate_signature(api_secret, body, headers, method, signed_headers, path, query_parts)
|
|
197
|
+
def generate_signature(api_secret, body, headers, method, signed_headers, path, query_parts, current_time)
|
|
192
198
|
canonicalized_request = canonicalize(method, path, query_parts, body, headers, signed_headers.uniq)
|
|
193
|
-
string_to_sign = get_string_to_sign(canonicalized_request)
|
|
199
|
+
string_to_sign = get_string_to_sign(canonicalized_request, current_time)
|
|
194
200
|
|
|
195
|
-
signing_key = OpenSSL::HMAC.digest(@algo, @algo_prefix + api_secret, short_date(
|
|
201
|
+
signing_key = OpenSSL::HMAC.digest(@algo, @algo_prefix + api_secret, short_date(current_time))
|
|
196
202
|
@credential_scope.split('/').each { |data|
|
|
197
203
|
signing_key = OpenSSL::HMAC.digest(@algo, signing_key, data)
|
|
198
204
|
}
|
|
@@ -202,8 +208,8 @@ module Escher
|
|
|
202
208
|
|
|
203
209
|
|
|
204
210
|
|
|
205
|
-
def format_date_for_header
|
|
206
|
-
@date_header_name.downcase == 'date' ?
|
|
211
|
+
def format_date_for_header(current_time)
|
|
212
|
+
@date_header_name.downcase == 'date' ? current_time.utc.rfc2822.sub('-0000', 'GMT') : long_date(current_time)
|
|
207
213
|
end
|
|
208
214
|
|
|
209
215
|
|
|
@@ -238,11 +244,11 @@ module Escher
|
|
|
238
244
|
|
|
239
245
|
|
|
240
246
|
|
|
241
|
-
def get_string_to_sign(canonicalized_request)
|
|
247
|
+
def get_string_to_sign(canonicalized_request, current_time)
|
|
242
248
|
[
|
|
243
249
|
@algo_id,
|
|
244
|
-
long_date(
|
|
245
|
-
short_date(
|
|
250
|
+
long_date(current_time),
|
|
251
|
+
short_date(current_time) + '/' + @credential_scope,
|
|
246
252
|
@algo.new.hexdigest(canonicalized_request)
|
|
247
253
|
].join("\n")
|
|
248
254
|
end
|
data/lib/escher/version.rb
CHANGED
data/repo-info.json
ADDED
|
@@ -35,11 +35,5 @@ module Escher
|
|
|
35
35
|
expect(request).to eq(test_case.expected_request)
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
xspecify "every case in the test suite is being used" do
|
|
41
|
-
expect(::EmarsysTestSuiteHelpers::TestSuite.in_use_size).to eq ::EmarsysTestSuiteHelpers::TestSuite.size
|
|
42
|
-
end
|
|
43
|
-
|
|
44
38
|
end
|
|
45
39
|
end
|
data/spec/escher/auth_spec.rb
CHANGED
|
@@ -101,7 +101,7 @@ module Escher
|
|
|
101
101
|
headers_to_sign = headers.map { |k| k[0].downcase }
|
|
102
102
|
path, query_parts = escher.parse_uri(request_uri)
|
|
103
103
|
canonicalized_request = escher.canonicalize(method, path, query_parts, body, headers, headers_to_sign)
|
|
104
|
-
string_to_sign = escher.get_string_to_sign(canonicalized_request)
|
|
104
|
+
string_to_sign = escher.get_string_to_sign(canonicalized_request, Time.parse(date))
|
|
105
105
|
expect(string_to_sign).to eq(fixture(suite, test, 'sts'))
|
|
106
106
|
end
|
|
107
107
|
end
|
|
@@ -484,7 +484,7 @@ module Escher
|
|
|
484
484
|
|
|
485
485
|
it 'should convert dates' do
|
|
486
486
|
date_str = 'Fri, 09 Sep 2011 23:36:00 GMT'
|
|
487
|
-
expect(described_class.new('irrelevant', date_header_name: 'date', current_time: Time.parse(date_str)).format_date_for_header).to eq date_str
|
|
487
|
+
expect(described_class.new('irrelevant', date_header_name: 'date', current_time: Time.parse(date_str)).format_date_for_header(Time.parse(date_str))).to eq date_str
|
|
488
488
|
end
|
|
489
489
|
|
|
490
490
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: escher
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andras Barthazi
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-09-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: 2.2.20
|
|
20
20
|
type: :development
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
26
|
+
version: 2.2.20
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rails
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -44,28 +44,28 @@ dependencies:
|
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
47
|
+
version: 13.0.6
|
|
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:
|
|
54
|
+
version: 13.0.6
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: rspec
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
59
|
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
61
|
+
version: '3'
|
|
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: '
|
|
68
|
+
version: '3'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: rack
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -100,14 +100,14 @@ dependencies:
|
|
|
100
100
|
requirements:
|
|
101
101
|
- - "~>"
|
|
102
102
|
- !ruby/object:Gem::Version
|
|
103
|
-
version:
|
|
103
|
+
version: 2.8.0
|
|
104
104
|
type: :runtime
|
|
105
105
|
prerelease: false
|
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
107
|
requirements:
|
|
108
108
|
- - "~>"
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
|
-
version:
|
|
110
|
+
version: 2.8.0
|
|
111
111
|
description: Escher helps you creating secure HTTP requests (for APIs) by signing
|
|
112
112
|
HTTP(s) requests.
|
|
113
113
|
email:
|
|
@@ -116,8 +116,8 @@ executables: []
|
|
|
116
116
|
extensions: []
|
|
117
117
|
extra_rdoc_files: []
|
|
118
118
|
files:
|
|
119
|
+
- ".github/workflows/ruby.yml"
|
|
119
120
|
- ".gitignore"
|
|
120
|
-
- ".travis.yml"
|
|
121
121
|
- Gemfile
|
|
122
122
|
- LICENSE
|
|
123
123
|
- README.md
|
|
@@ -135,6 +135,7 @@ files:
|
|
|
135
135
|
- lib/escher/request/legacy_request.rb
|
|
136
136
|
- lib/escher/request/rack_request.rb
|
|
137
137
|
- lib/escher/version.rb
|
|
138
|
+
- repo-info.json
|
|
138
139
|
- scripts/checkout_test_suite.sh
|
|
139
140
|
- spec/aws4_testsuite/get-header-key-duplicate.authz
|
|
140
141
|
- spec/aws4_testsuite/get-header-key-duplicate.creq
|
|
@@ -340,8 +341,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
340
341
|
- !ruby/object:Gem::Version
|
|
341
342
|
version: '0'
|
|
342
343
|
requirements: []
|
|
343
|
-
|
|
344
|
-
rubygems_version: 2.7.7
|
|
344
|
+
rubygems_version: 3.2.22
|
|
345
345
|
signing_key:
|
|
346
346
|
specification_version: 4
|
|
347
347
|
summary: Library for HTTP request signing (Ruby implementation)
|
data/.travis.yml
DELETED