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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed681ad1ed9b0e334edab0c608c10beee1ea80f655340a2020853f924a473953
4
- data.tar.gz: 5d5674e195e7189d2c6f7e398388a00b6cc759c360cfe5a4a9f0d91f7c2eac6f
3
+ metadata.gz: f91ee25e50b0311776949593fd31d8d276de81f7c5a1530e205e85c3caa72a60
4
+ data.tar.gz: 10721eb994568d2ecbebfc38b091157abc444d99ab3e2c67290ba9482ba6fc40
5
5
  SHA512:
6
- metadata.gz: d8d0d08e443b6bc9aad9d8935b0da925df5a7130c41d1b1c9d7657f36dc7678cdb8bb7199cc456b09bb5f88d61af530eb447889e5b13de37bc677993e14548f0
7
- data.tar.gz: 18102fee551348688aa7614ddf065dfbd12fc0d02c9a174c5debbebe743de0a82ad809e8657e0bda773ea5d460ce0055bc0f88e2b2a11476c5ca87bbaa8cb94b
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", "~> 1.6"
23
+ spec.add_development_dependency "bundler", "~> 2.2.20"
24
24
  spec.add_development_dependency "rails"
25
25
 
26
- spec.add_development_dependency "rake", "~> 10"
27
- spec.add_development_dependency "rspec", "~> 2"
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.3"
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(@current_time)}/#{@credential_scope}, SignedHeaders=#{prepare_headers_to_sign headers_to_sign}, Signature=#{signature}")
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, @current_time || Time.now)
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(@current_time)}/#{@credential_scope}"],
140
- ['Date', long_date(@current_time)],
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(@current_time))
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' ? @current_time.utc.rfc2822.sub('-0000', 'GMT') : long_date(@current_time)
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(@current_time),
245
- short_date(@current_time) + '/' + @credential_scope,
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
@@ -1,3 +1,3 @@
1
1
  module Escher
2
- VERSION = '1.0.2'
2
+ VERSION = '2.0.5'
3
3
  end
data/repo-info.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "is_in_production": false,
3
+ "is_scannable": true,
4
+ "is_critical": false,
5
+ "contact": "G-GSUITE-Security@emarsys.com",
6
+ "hosted": null
7
+ }
@@ -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
@@ -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: 1.0.2
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: 2019-07-24 00:00:00.000000000 Z
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: '1.6'
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: '1.6'
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: '10'
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: '10'
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: '2'
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: '2'
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: '2.3'
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: '2.3'
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
- rubyforge_project:
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
@@ -1,13 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.2.3
4
- - 2.3.0
5
- before_script: ./scripts/checkout_test_suite.sh
6
- deploy:
7
- provider: rubygems
8
- api_key: ${RUBYGEMS_API_KEY}
9
- gem: escher
10
- gemspec: escher.gemspec
11
- skip_cleanup: true
12
- on:
13
- tags: true