escher 1.0.2 → 2.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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