escher 0.3.7 → 0.4.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
  SHA1:
3
- metadata.gz: b1c99900670a9017bfe4565037cffade7ea2b9a1
4
- data.tar.gz: e3e74a858ff3b42decd6367bfbf4e14ee92a80ee
3
+ metadata.gz: 3d4de4f3f3b3d16060cff1ca9157b781a2d5039a
4
+ data.tar.gz: a6982455c5ad1c086f4fbf99466dae4272e12f30
5
5
  SHA512:
6
- metadata.gz: 759ac6e2e5e05b4db8c084e7dcd2a337d785193e0ee76d4abef20b5076cc3e6f382927cc53fc35b9ae4486f5fae69b6b07689c2f9ea9716a52d06c7fb4934179
7
- data.tar.gz: d23ffaceb2d89564d48fad3f2e361c66d38c695d579b1c282dff0ba4470d4b30467e957b043a812867bf1f5dbdbaf26e319cffccec96c7c71512de3aa38816ba
6
+ metadata.gz: 0234c0322a91d4787e82945ba4ec4831cd2158829192d779773282b49fe51999328c1998fb349d1e336e655373af95b5861ab0cfc42bd91b67358511af8b16d1
7
+ data.tar.gz: 5c1e6281e2608991d4691565d1397a3db070cb4e565e6223ed28e8e2e1e7798176c07bd8297a6341fbe5887c1762f59d1d56d3423174e8aa2e3348e7175239c3
data/.gitignore CHANGED
@@ -10,6 +10,7 @@ Gemfile.lock
10
10
  # Ignore all logfiles and tempfiles.
11
11
  /log/*.log
12
12
  /tmp
13
+ /spec/emarsys_test_suite/
13
14
 
14
15
  .env
15
16
  .ruby-version
data/.travis.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
- - 2.1.2
5
- - 2.2.1
3
+ - 2.2.3
4
+ - 2.3.0
5
+ before_script: ./scripts/checkout_test_suite.sh
data/Rakefile CHANGED
@@ -9,3 +9,8 @@ RSpec::Core::RakeTask.new :spec do |task|
9
9
  end
10
10
 
11
11
  task :default => :spec
12
+
13
+ desc "Check out centralised test suite into spec/emarsys_test_suite."
14
+ task :checkout_test_suite do
15
+ `scripts/checkout_test_suite.sh`
16
+ end
data/escher.gemspec CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency "rspec", "~> 2"
28
28
 
29
29
  spec.add_development_dependency "rack"
30
+ spec.add_development_dependency "plissken"
30
31
 
31
32
  spec.add_runtime_dependency "addressable", "~> 2.3"
32
33
  end
data/lib/escher/auth.rb CHANGED
@@ -9,7 +9,7 @@ module Escher
9
9
  @current_time = options[:current_time] || Time.now
10
10
  @auth_header_name = options[:auth_header_name] || 'X-Escher-Auth'
11
11
  @date_header_name = options[:date_header_name] || 'X-Escher-Date'
12
- @clock_skew = options[:clock_skew] || 900
12
+ @clock_skew = options[:clock_skew] || 300
13
13
  @algo = create_algo
14
14
  @algo_id = @algo_prefix + '-HMAC-' + @hash_algo
15
15
  end
@@ -22,7 +22,7 @@ module Escher
22
22
  request = wrap_request req
23
23
  raise EscherError, 'The host header is missing' unless request.has_header? 'host'
24
24
 
25
- request.set_header(@date_header_name, format_date_for_header) unless request.has_header? @date_header_name
25
+ request.set_header(@date_header_name.downcase, format_date_for_header) unless request.has_header? @date_header_name
26
26
 
27
27
  signature = generate_signature(client[:api_secret], request.body, request.headers, request.method, headers_to_sign, request.path, request.query_values)
28
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}")
@@ -43,7 +43,7 @@ module Escher
43
43
 
44
44
 
45
45
 
46
- def authenticate(req, key_db)
46
+ def authenticate(req, key_db, mandatory_signed_headers = nil)
47
47
  request = wrap_request req
48
48
  method = request.method
49
49
  body = request.body
@@ -54,7 +54,7 @@ module Escher
54
54
  signature_from_query = get_signing_param('Signature', query_parts)
55
55
 
56
56
  (['Host'] + (signature_from_query ? [] : [@auth_header_name, @date_header_name])).each do |header|
57
- raise EscherError, 'The ' + header + ' header is missing' unless request.header header
57
+ raise EscherError, 'The ' + header.downcase + ' header is missing' unless request.header header
58
58
  end
59
59
 
60
60
  if method == 'GET' && signature_from_query
@@ -76,11 +76,20 @@ module Escher
76
76
  api_secret = key_db[api_key_id]
77
77
 
78
78
  raise EscherError, 'Invalid Escher key' unless api_secret
79
- raise EscherError, 'Only SHA256 and SHA512 hash algorithms are allowed' unless %w(SHA256 SHA512).include?(algorithm)
80
- raise EscherError, 'The ' + @auth_header_name + ' header\'s shortDate does not match with the request date' unless short_date(date) == short_date
79
+ raise EscherError, 'Invalid hash algorithm, only SHA256 and SHA512 are allowed' unless %w(SHA256 SHA512).include?(algorithm)
80
+ raise EscherError, 'The request method is invalid' unless valid_request_method?(method)
81
+ raise EscherError, "The request body shouldn't be empty if the request method is POST" if (method.upcase == 'POST' && body.empty?)
82
+ raise EscherError, "The request url shouldn't contains http or https" if path.match /^https?:\/\//
83
+ raise EscherError, 'Invalid date in authorization header, it should equal with date header' unless short_date(date) == short_date
81
84
  raise EscherError, 'The request date is not within the accepted time range' unless is_date_within_range?(date, expires)
82
- raise EscherError, 'The credential scope is invalid' unless credential_scope == @credential_scope
85
+ raise EscherError, 'Invalid Credential Scope' unless credential_scope == @credential_scope
86
+ raise EscherError, 'The mandatorySignedHeaders parameter must be undefined or array of strings' unless mandatory_signed_headers_valid?(mandatory_signed_headers)
83
87
  raise EscherError, 'The host header is not signed' unless signed_headers.include? 'host'
88
+ unless mandatory_signed_headers.nil?
89
+ mandatory_signed_headers.each do |header|
90
+ raise EscherError, "The #{header} header is not signed" unless signed_headers.include? header
91
+ end
92
+ end
84
93
  raise EscherError, 'Only the host header should be signed' if signature_from_query && signed_headers != ['host']
85
94
  raise EscherError, 'The date header is not signed' if !signature_from_query && !signed_headers.include?(@date_header_name.downcase)
86
95
 
@@ -163,7 +172,7 @@ module Escher
163
172
  def get_auth_parts_from_header(auth_header)
164
173
  m = /#{@algo_prefix}-HMAC-(?<algo>[A-Z0-9\,]+) Credential=(?<api_key_id>[A-Za-z0-9\-_]+)\/(?<short_date>[0-9]{8})\/(?<credentials>[A-Za-z0-9\-_ \/]+), SignedHeaders=(?<signed_headers>[A-Za-z\-;]+), Signature=(?<signature>[0-9a-f]+)$/
165
174
  .match auth_header
166
- raise EscherError, 'Could not parse auth header' unless m && m['credentials']
175
+ raise EscherError, 'Invalid auth header format' unless m && m['credentials']
167
176
  return m['algo'], m['api_key_id'], m['short_date'], m['credentials'], m['signed_headers'].split(';'), m['signature'], 0
168
177
  end
169
178
 
@@ -215,7 +224,7 @@ module Escher
215
224
 
216
225
 
217
226
  def prepare_headers_to_sign(headers_to_sign)
218
- headers_to_sign.sort.uniq.join(';')
227
+ headers_to_sign.sort.uniq.join(';').downcase
219
228
  end
220
229
 
221
230
 
@@ -272,6 +281,25 @@ module Escher
272
281
 
273
282
 
274
283
 
284
+ def valid_request_method?(method)
285
+ %w(OPTIONS GET HEAD POST PUT DELETE TRACE PATCH CONNECT).include? method.upcase
286
+ end
287
+
288
+
289
+
290
+ def mandatory_signed_headers_valid?(mandatory_signed_headers)
291
+ if mandatory_signed_headers.nil?
292
+ return true
293
+ else
294
+ return false unless mandatory_signed_headers.is_a? Array
295
+ return false unless mandatory_signed_headers.all? { |header| header.is_a? String }
296
+ end
297
+
298
+ true
299
+ end
300
+
301
+
302
+
275
303
  def parse_algo(algorithm)
276
304
  m = /^#{@algo_prefix}-HMAC-(?<algo>[A-Z0-9\,]+)$/.match(algorithm)
277
305
  m && m['algo']
@@ -308,7 +336,7 @@ module Escher
308
336
 
309
337
  def normalize_white_spaces(value)
310
338
  value.strip.split('"', -1).map.with_index { |piece, index|
311
- is_inside_of_quotes = (index % 2 === 1)
339
+ is_inside_of_quotes = (index % 2 == 1)
312
340
  is_inside_of_quotes ? piece : piece.gsub(/\s+/, ' ')
313
341
  }.join '"'
314
342
  end
@@ -10,7 +10,6 @@ module Escher
10
10
 
11
11
  def initialize(request)
12
12
  super request
13
- @uri = parse_uri request[:uri]
14
13
  end
15
14
 
16
15
 
@@ -41,27 +40,16 @@ module Escher
41
40
 
42
41
 
43
42
  def path
44
- @uri.path
43
+ request[:uri].match(URI_REGEXP)[1]
45
44
  end
46
45
 
47
46
 
48
47
 
49
48
  def query_values
50
- @uri.query_values(Array) or []
51
- end
52
-
53
-
54
-
55
- private
56
-
57
- def parse_uri(uri)
58
- uri.match URI_REGEXP do |match_data|
59
- Addressable::URI.new({:path => match_data[1],
60
- :query => match_data[3]})
61
- end
49
+ query = request[:uri].match(URI_REGEXP)[3]
50
+ (Addressable::URI.new query: query).query_values(Array) or []
62
51
  end
63
52
 
64
53
  end
65
-
66
54
  end
67
55
  end
@@ -1,3 +1,3 @@
1
1
  module Escher
2
- VERSION = '0.3.7'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env bash
2
+ rm -rf ./spec/emarsys_test_suite
3
+ svn export https://github.com/emartech/escher-test-suite/trunk/test_cases spec/emarsys_test_suite
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ module Escher
4
+ describe Auth, :emarsys_test_suite do
5
+
6
+ authentication_error_test_files.each do |test_case|
7
+ it "#{test_case[:title]}" do
8
+ expect { test_case.escher.authenticate(test_case[:request], test_case.key, test_case[:mandatory_signed_headers]) }
9
+ .to raise_error(EscherError, test_case[:expected][:error])
10
+ end
11
+ end
12
+
13
+
14
+ authentication_valid_test_files.each do |test_case|
15
+ it "#{test_case[:title]}" do
16
+ expect { test_case.escher.authenticate(test_case[:request], test_case.key) }.not_to raise_error
17
+ end
18
+ end
19
+
20
+
21
+ presign_url_test_files.each do |test_case|
22
+ it "#{test_case[:title]}" do
23
+ expect(test_case.escher.generate_signed_url(test_case[:request][:uri], test_case[:config], test_case[:request][:expires]))
24
+ .to eq(test_case[:expected][:url])
25
+ end
26
+ end
27
+
28
+
29
+ sign_request_valid_test_files.each do |test_case|
30
+ it "#{test_case[:title]}" do
31
+ request = test_case.escher.sign! test_case[:request], test_case[:config], test_case[:headers_to_sign]
32
+ request[:url] = request.delete :uri
33
+ request.each { |_, v| v.sort! if v.class.method_defined? :sort! }
34
+
35
+ expect(request).to eq(test_case.expected_request)
36
+ end
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
+ end
45
+ end
@@ -417,7 +417,7 @@ module Escher
417
417
  ['Date', 'Mon, 09 Sep 2011 23:36:00 GMT'],
418
418
  ['Authorization', 'AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-ea st-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470'],
419
419
  ]
420
- expect { call_validate(headers) }.to raise_error(EscherError, 'The credential scope is invalid')
420
+ expect { call_validate(headers) }.to raise_error(EscherError, 'Invalid Credential Scope')
421
421
  end
422
422
 
423
423
 
@@ -431,17 +431,6 @@ module Escher
431
431
  end
432
432
 
433
433
 
434
- it 'should detect if dates are not on the same day' do
435
- yesterday = '08'
436
- headers = [
437
- %w(Host host.foo.com),
438
- ['Date', "Mon, #{yesterday} Sep 2011 23:36:00 GMT"],
439
- ['Authorization', GOOD_AUTH_HEADER],
440
- ]
441
- expect { call_validate(headers) }.to raise_error(EscherError, 'The Authorization header\'s shortDate does not match with the request date')
442
- end
443
-
444
-
445
434
  it 'should detect if date is not within the 15 minutes range' do
446
435
  long_ago = '00'
447
436
  headers = [
@@ -453,40 +442,13 @@ module Escher
453
442
  end
454
443
 
455
444
 
456
- it 'should detect missing host header' do
457
- headers = [
458
- ['Date', 'Mon, 09 Sep 2011 23:36:00 GMT'],
459
- ['Authorization', GOOD_AUTH_HEADER],
460
- ]
461
- expect { call_validate(headers) }.to raise_error(EscherError, 'The Host header is missing')
462
- end
463
-
464
-
465
- it 'should detect missing date header' do
466
- headers = [
467
- %w(Host host.foo.com),
468
- ['Authorization', GOOD_AUTH_HEADER],
469
- ]
470
- expect { call_validate(headers) }.to raise_error(EscherError, 'The Date header is missing')
471
- end
472
-
473
-
474
- it 'should detect missing auth header' do
475
- headers = [
476
- %w(Host host.foo.com),
477
- ['Date', 'Mon, 09 Sep 2011 23:36:00 GMT'],
478
- ]
479
- expect { call_validate(headers) }.to raise_error(EscherError, 'The Authorization header is missing')
480
- end
481
-
482
-
483
445
  it 'should detect malformed auth header' do
484
446
  headers = [
485
447
  %w(Host host.foo.com),
486
448
  ['Date', 'Mon, 09 Sep 2011 23:36:00 GMT'],
487
449
  ['Authorization', 'AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=UNPARSABLE'],
488
450
  ]
489
- expect { call_validate(headers) }.to raise_error(EscherError, 'Could not parse auth header')
451
+ expect { call_validate(headers) }.to raise_error(EscherError, 'Invalid auth header format')
490
452
  end
491
453
 
492
454
 
@@ -496,7 +458,7 @@ module Escher
496
458
  ['Date', 'Mon, 09 Sep 2011 23:36:00 GMT'],
497
459
  ['Authorization', 'AWS4-HMAC-SHA256 Credential=BAD-CREDENTIAL-SCOPE, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470'],
498
460
  ]
499
- expect { call_validate(headers) }.to raise_error(EscherError, 'Could not parse auth header')
461
+ expect { call_validate(headers) }.to raise_error(EscherError, 'Invalid auth header format')
500
462
  end
501
463
 
502
464
 
@@ -520,26 +482,6 @@ module Escher
520
482
  end
521
483
 
522
484
 
523
- it 'should check algorithm' do
524
- headers = [
525
- %w(Host host.foo.com),
526
- ['Date', 'Mon, 09 Sep 2011 23:36:00 GMT'],
527
- ['Authorization', 'AWS4-HMAC-INVALID Credential=AKIDEXAMPLE/20110909/us-east-1/host/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470'],
528
- ]
529
- expect { call_validate(headers) }.to raise_error(EscherError, 'Only SHA256 and SHA512 hash algorithms are allowed')
530
- end
531
-
532
-
533
- it 'should check credential scope' do
534
- headers = [
535
- %w(Host host.foo.com),
536
- ['Date', 'Mon, 09 Sep 2011 23:36:00 GMT'],
537
- ['Authorization', 'AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/INVALID/aws4_request, SignedHeaders=date;host, Signature=b27ccfbfa7df52a200ff74193ca6e32d4b48b8856fab7ebf1c595d0670a7e470'],
538
- ]
539
- expect { call_validate(headers) }.to raise_error(EscherError, 'The credential scope is invalid')
540
- end
541
-
542
-
543
485
  it 'should convert dates' do
544
486
  date_str = 'Fri, 09 Sep 2011 23:36:00 GMT'
545
487
  expect(described_class.new('irrelevant', date_header_name: 'date', current_time: Time.parse(date_str)).format_date_for_header).to eq date_str
@@ -0,0 +1,43 @@
1
+ module EmarsysTestSuiteHelpers
2
+ class TestCase
3
+
4
+ def initialize(test_file)
5
+ @test_data = ::JSON.parse(File.read(test_file), symbolize_names: true).to_snake_keys
6
+ convert_naming
7
+ end
8
+
9
+
10
+
11
+ def [](arg)
12
+ @test_data[arg]
13
+ end
14
+
15
+
16
+
17
+ def key
18
+ {@test_data[:key_db].first[0] => @test_data[:key_db].first[1]}
19
+ end
20
+
21
+
22
+
23
+ def escher
24
+ @test_data[:config][:current_time] = Time.parse(@test_data[:config].delete :date)
25
+ @escher ||= ::Escher::Auth.new(@test_data[:config][:credential_scope], @test_data[:config])
26
+ end
27
+
28
+
29
+
30
+ def expected_request
31
+ @test_data[:expected][:request].each { |_, v| v.sort! if v.class.method_defined? :sort! }
32
+ end
33
+
34
+
35
+
36
+ private
37
+ def convert_naming
38
+ @test_data[:request][:uri] = @test_data[:request].delete :url
39
+ @test_data[:config][:api_key_id] = @test_data[:config].delete :access_key_id
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,18 @@
1
+ module EmarsysTestSuiteHelpers
2
+ class TestSuite
3
+
4
+ def self.size
5
+ Dir.glob('./spec/emarsys_test_suite/*').size
6
+ end
7
+
8
+
9
+
10
+ def self.in_use_size
11
+ size = Dir.glob('./spec/emarsys_test_suite/authenticate-error-*').size
12
+ size += Dir.glob('./spec/emarsys_test_suite/authenticate-valid-*').size
13
+ size += Dir.glob('./spec/emarsys_test_suite/presignurl-*').size
14
+ size + Dir.glob('./spec/emarsys_test_suite/signrequest-*').reject { |c| c.include? 'error' }.size
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ require 'json'
2
+ require 'plissken'
3
+ require 'escher'
4
+
5
+ module EmarsysTestSuiteHelpers
6
+
7
+ autoload :TestCase, 'helpers/emarsys_test_suite/test_case'
8
+ autoload :TestSuite, 'helpers/emarsys_test_suite/test_suite'
9
+
10
+
11
+
12
+ def create_test_case
13
+ ->(t) { TestCase.new t }
14
+ end
15
+
16
+
17
+
18
+ def authentication_error_test_files
19
+ Dir.glob('./spec/emarsys_test_suite/authenticate-error-*').map &create_test_case
20
+ end
21
+
22
+
23
+
24
+ def authentication_valid_test_files
25
+ Dir.glob('./spec/emarsys_test_suite/authenticate-valid-*').map &create_test_case
26
+ end
27
+
28
+
29
+
30
+ def presign_url_test_files
31
+ Dir.glob('./spec/emarsys_test_suite/presignurl-*').map &create_test_case
32
+ end
33
+
34
+
35
+
36
+ def sign_request_valid_test_files
37
+ files = Dir.glob('./spec/emarsys_test_suite/signrequest-*').reject { |c| c.include? 'error' }
38
+ files.map &create_test_case
39
+ end
40
+
41
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,10 @@
1
1
  lib = File.expand_path('../../lib', __FILE__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'escher'
3
+ require 'escher'
4
+
5
+
6
+ autoload :EmarsysTestSuiteHelpers, 'helpers/emarsys_test_suite_helpers'
7
+ RSpec.configure do |c|
8
+ c.treat_symbols_as_metadata_keys_with_true_values = true
9
+ c.extend EmarsysTestSuiteHelpers, :emarsys_test_suite
10
+ end
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: 0.3.7
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andras Barthazi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-14 00:00:00.000000000 Z
11
+ date: 2016-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: plissken
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: addressable
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +136,7 @@ files:
122
136
  - lib/escher/request/legacy_request.rb
123
137
  - lib/escher/request/rack_request.rb
124
138
  - lib/escher/version.rb
139
+ - scripts/checkout_test_suite.sh
125
140
  - spec/aws4_testsuite/get-header-key-duplicate.authz
126
141
  - spec/aws4_testsuite/get-header-key-duplicate.creq
127
142
  - spec/aws4_testsuite/get-header-key-duplicate.req
@@ -273,6 +288,7 @@ files:
273
288
  - spec/aws4_testsuite/post-x-www-form-urlencoded.req
274
289
  - spec/aws4_testsuite/post-x-www-form-urlencoded.sreq
275
290
  - spec/aws4_testsuite/post-x-www-form-urlencoded.sts
291
+ - spec/emarsys_test_suite_spec.rb
276
292
  - spec/emarsys_testsuite/get-header-key-duplicate.authz
277
293
  - spec/emarsys_testsuite/get-header-key-duplicate.creq
278
294
  - spec/emarsys_testsuite/get-header-key-duplicate.req
@@ -303,6 +319,9 @@ files:
303
319
  - spec/escher/request/factory_spec.rb
304
320
  - spec/escher/request/hash_request_spec.rb
305
321
  - spec/escher/request/rack_request_spec.rb
322
+ - spec/helpers/emarsys_test_suite/test_case.rb
323
+ - spec/helpers/emarsys_test_suite/test_suite.rb
324
+ - spec/helpers/emarsys_test_suite_helpers.rb
306
325
  - spec/spec_helper.rb
307
326
  homepage: http://escherauth.io/
308
327
  licenses:
@@ -324,7 +343,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
324
343
  version: '0'
325
344
  requirements: []
326
345
  rubyforge_project:
327
- rubygems_version: 2.4.5
346
+ rubygems_version: 2.4.5.1
328
347
  signing_key:
329
348
  specification_version: 4
330
349
  summary: Library for HTTP request signing (Ruby implementation)
@@ -480,6 +499,7 @@ test_files:
480
499
  - spec/aws4_testsuite/post-x-www-form-urlencoded.req
481
500
  - spec/aws4_testsuite/post-x-www-form-urlencoded.sreq
482
501
  - spec/aws4_testsuite/post-x-www-form-urlencoded.sts
502
+ - spec/emarsys_test_suite_spec.rb
483
503
  - spec/emarsys_testsuite/get-header-key-duplicate.authz
484
504
  - spec/emarsys_testsuite/get-header-key-duplicate.creq
485
505
  - spec/emarsys_testsuite/get-header-key-duplicate.req
@@ -510,4 +530,7 @@ test_files:
510
530
  - spec/escher/request/factory_spec.rb
511
531
  - spec/escher/request/hash_request_spec.rb
512
532
  - spec/escher/request/rack_request_spec.rb
533
+ - spec/helpers/emarsys_test_suite/test_case.rb
534
+ - spec/helpers/emarsys_test_suite/test_suite.rb
535
+ - spec/helpers/emarsys_test_suite_helpers.rb
513
536
  - spec/spec_helper.rb