escher 0.4.3 → 2.0.2
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 +5 -5
- data/.github/workflows/ruby.yml +33 -0
- data/escher.gemspec +4 -4
- data/lib/escher/auth.rb +24 -21
- data/lib/escher/request/factory.rb +1 -1
- data/lib/escher/request.rb +0 -1
- 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
- data/spec/escher/request/factory_spec.rb +19 -7
- metadata +13 -16
- data/.travis.yml +0 -5
- data/lib/escher/request/action_dispatch_request.rb +0 -47
- data/spec/escher/request/action_dispatch_request_spec.rb +0 -120
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b18ad0e7492749391a2d41baab5ba09033def7a7c1399ce8f9725cd9786eab98
|
4
|
+
data.tar.gz: 6ac12253dbf9cab09ffb66b60539edb33f0648ebc0c0b4c9c2b746157236f9af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d1d465e795dab3645b727748ff4a2b0f00e448a214986c0c36c5abc9671d64f5aec2c7ad7275f38a8cca7729ca01a38fde3421697be5d2c91bfbc55365777e05
|
7
|
+
data.tar.gz: 5601a61b35a0700c80bbab5a42cc2e524643ae7aced341ad7073d17cb3cb51f3f333b811326aa519c19bee6f91bda7550881dfda53a84ee3689fddc41b694146
|
@@ -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')
|
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
@@ -6,7 +6,7 @@ module Escher
|
|
6
6
|
@algo_prefix = options[:algo_prefix] || 'ESR'
|
7
7
|
@vendor_key = options[:vendor_key] || 'Escher'
|
8
8
|
@hash_algo = options[:hash_algo] || 'SHA256'
|
9
|
-
@current_time = options[:current_time]
|
9
|
+
@current_time = options[:current_time]
|
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
12
|
@clock_skew = options[:clock_skew] || 300
|
@@ -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
|
@@ -44,6 +46,7 @@ module Escher
|
|
44
46
|
|
45
47
|
|
46
48
|
def authenticate(req, key_db, mandatory_signed_headers = nil)
|
49
|
+
current_time = @current_time || Time.now
|
47
50
|
request = wrap_request req
|
48
51
|
method = request.method
|
49
52
|
body = request.body
|
@@ -78,10 +81,9 @@ module Escher
|
|
78
81
|
raise EscherError, 'Invalid Escher key' unless api_secret
|
79
82
|
raise EscherError, 'Invalid hash algorithm, only SHA256 and SHA512 are allowed' unless %w(SHA256 SHA512).include?(algorithm)
|
80
83
|
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
84
|
raise EscherError, "The request url shouldn't contains http or https" if path.match /^https?:\/\//
|
83
85
|
raise EscherError, 'Invalid date in authorization header, it should equal with date header' unless short_date(date) == short_date
|
84
|
-
raise EscherError, 'The request date is not within the accepted time range' unless is_date_within_range?(date, expires)
|
86
|
+
raise EscherError, 'The request date is not within the accepted time range' unless is_date_within_range?(date, expires, current_time)
|
85
87
|
raise EscherError, 'Invalid Credential Scope' unless credential_scope == @credential_scope
|
86
88
|
raise EscherError, 'The mandatorySignedHeaders parameter must be undefined or array of strings' unless mandatory_signed_headers_valid?(mandatory_signed_headers)
|
87
89
|
raise EscherError, 'The host header is not signed' unless signed_headers.include? 'host'
|
@@ -94,7 +96,7 @@ module Escher
|
|
94
96
|
raise EscherError, 'The date header is not signed' if !signature_from_query && !signed_headers.include?(@date_header_name.downcase)
|
95
97
|
|
96
98
|
escher = reconfig(algorithm, credential_scope, date)
|
97
|
-
expected_signature = escher.generate_signature(api_secret, body, headers, method, signed_headers, path, query_parts)
|
99
|
+
expected_signature = escher.generate_signature(api_secret, body, headers, method, signed_headers, path, query_parts, date)
|
98
100
|
raise EscherError, 'The signatures do not match' unless signature == expected_signature
|
99
101
|
api_key_id
|
100
102
|
end
|
@@ -116,6 +118,7 @@ module Escher
|
|
116
118
|
|
117
119
|
|
118
120
|
def generate_signed_url(url_to_sign, client, expires = 86400)
|
121
|
+
current_time = @current_time || Time.now
|
119
122
|
uri = Addressable::URI.parse(url_to_sign)
|
120
123
|
|
121
124
|
if (not uri.port.nil?) && (uri.port != uri.default_port)
|
@@ -137,13 +140,13 @@ module Escher
|
|
137
140
|
body = 'UNSIGNED-PAYLOAD'
|
138
141
|
query_parts += [
|
139
142
|
['Algorithm', @algo_id],
|
140
|
-
['Credentials', "#{client[:api_key_id]}/#{short_date(
|
141
|
-
['Date', long_date(
|
143
|
+
['Credentials', "#{client[:api_key_id]}/#{short_date(current_time)}/#{@credential_scope}"],
|
144
|
+
['Date', long_date(current_time)],
|
142
145
|
['Expires', expires.to_s],
|
143
146
|
['SignedHeaders', headers_to_sign.join(';')],
|
144
147
|
].map { |k, v| query_pair(k, v) }
|
145
148
|
|
146
|
-
signature = generate_signature(client[:api_secret], body, headers, 'GET', headers_to_sign, path, query_parts)
|
149
|
+
signature = generate_signature(client[:api_secret], body, headers, 'GET', headers_to_sign, path, query_parts, current_time)
|
147
150
|
query_parts_with_signature = (query_parts.map { |k, v| [uri_encode(k), uri_encode(v)] } << query_pair('Signature', signature))
|
148
151
|
"#{uri.scheme}://#{host}#{path}?#{query_parts_with_signature.map { |k, v| k + '=' + v }.join('&')}#{(fragment === nil ? '' : '#' + fragment)}"
|
149
152
|
end
|
@@ -189,11 +192,11 @@ module Escher
|
|
189
192
|
|
190
193
|
|
191
194
|
|
192
|
-
def generate_signature(api_secret, body, headers, method, signed_headers, path, query_parts)
|
195
|
+
def generate_signature(api_secret, body, headers, method, signed_headers, path, query_parts, current_time)
|
193
196
|
canonicalized_request = canonicalize(method, path, query_parts, body, headers, signed_headers.uniq)
|
194
|
-
string_to_sign = get_string_to_sign(canonicalized_request)
|
197
|
+
string_to_sign = get_string_to_sign(canonicalized_request, current_time)
|
195
198
|
|
196
|
-
signing_key = OpenSSL::HMAC.digest(@algo, @algo_prefix + api_secret, short_date(
|
199
|
+
signing_key = OpenSSL::HMAC.digest(@algo, @algo_prefix + api_secret, short_date(current_time))
|
197
200
|
@credential_scope.split('/').each { |data|
|
198
201
|
signing_key = OpenSSL::HMAC.digest(@algo, signing_key, data)
|
199
202
|
}
|
@@ -203,8 +206,8 @@ module Escher
|
|
203
206
|
|
204
207
|
|
205
208
|
|
206
|
-
def format_date_for_header
|
207
|
-
@date_header_name.downcase == 'date' ?
|
209
|
+
def format_date_for_header(current_time)
|
210
|
+
@date_header_name.downcase == 'date' ? current_time.utc.rfc2822.sub('-0000', 'GMT') : long_date(current_time)
|
208
211
|
end
|
209
212
|
|
210
213
|
|
@@ -239,11 +242,11 @@ module Escher
|
|
239
242
|
|
240
243
|
|
241
244
|
|
242
|
-
def get_string_to_sign(canonicalized_request)
|
245
|
+
def get_string_to_sign(canonicalized_request, current_time)
|
243
246
|
[
|
244
247
|
@algo_id,
|
245
|
-
long_date(
|
246
|
-
short_date(
|
248
|
+
long_date(current_time),
|
249
|
+
short_date(current_time) + '/' + @credential_scope,
|
247
250
|
@algo.new.hexdigest(canonicalized_request)
|
248
251
|
].join("\n")
|
249
252
|
end
|
@@ -255,7 +258,7 @@ module Escher
|
|
255
258
|
when 'SHA256'
|
256
259
|
@algo = OpenSSL::Digest::SHA256.new
|
257
260
|
when 'SHA512'
|
258
|
-
@algo = OpenSSL::Digest::
|
261
|
+
@algo = OpenSSL::Digest::SHA512.new
|
259
262
|
else
|
260
263
|
raise EscherError, 'Unidentified hash algorithm'
|
261
264
|
end
|
@@ -275,8 +278,8 @@ module Escher
|
|
275
278
|
|
276
279
|
|
277
280
|
|
278
|
-
def is_date_within_range?(request_date, expires)
|
279
|
-
(request_date - @clock_skew .. request_date + expires + @clock_skew).cover?
|
281
|
+
def is_date_within_range?(request_date, expires, current_time)
|
282
|
+
(request_date - @clock_skew .. request_date + expires + @clock_skew).cover? current_time
|
280
283
|
end
|
281
284
|
|
282
285
|
|
@@ -6,7 +6,7 @@ module Escher
|
|
6
6
|
case request
|
7
7
|
|
8
8
|
when defined?(ActionDispatch::Request) && ActionDispatch::Request
|
9
|
-
|
9
|
+
RackRequest.new(Rack::Request.new(request.env))
|
10
10
|
|
11
11
|
when defined?(Rack::Request) && Rack::Request
|
12
12
|
RackRequest.new(request)
|
data/lib/escher/request.rb
CHANGED
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
|
|
@@ -7,19 +7,31 @@ require 'action_dispatch'
|
|
7
7
|
describe Escher::Request::Factory do
|
8
8
|
|
9
9
|
describe ".from_request" do
|
10
|
+
request_env = {Rack::PATH_INFO.to_s => "request-path"}
|
11
|
+
|
10
12
|
{
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
{uri: "request-path"} => Escher::Request::HashRequest,
|
15
|
+
Struct.new("Request", :uri).new("request-path") => Escher::Request::LegacyRequest,
|
16
|
+
Rack::Request.new(request_env) => Escher::Request::RackRequest,
|
17
|
+
ActionDispatch::Request.new(request_env) => Escher::Request::RackRequest
|
16
18
|
|
17
19
|
}.each do |request, expected_class|
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
+
context "the request to be wrapped is a #{request.class.name}" do
|
22
|
+
|
23
|
+
it "returns a #{expected_class.name}" do
|
24
|
+
wrapped_request = described_class.from_request request
|
25
|
+
|
26
|
+
expect(wrapped_request).to be_an_instance_of expected_class
|
27
|
+
end
|
28
|
+
|
29
|
+
it "wraps the path from the original request" do
|
30
|
+
wrapped_request = described_class.from_request request
|
31
|
+
|
32
|
+
expect(wrapped_request.path).to eq "request-path"
|
33
|
+
end
|
21
34
|
|
22
|
-
expect(described_class.from_request request).to eq "#{expected_class.name} wrapping request"
|
23
35
|
end
|
24
36
|
|
25
37
|
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.
|
4
|
+
version: 2.0.2
|
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-08-26 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
|
@@ -127,7 +127,6 @@ files:
|
|
127
127
|
- lib/escher/auth.rb
|
128
128
|
- lib/escher/escher_error.rb
|
129
129
|
- lib/escher/request.rb
|
130
|
-
- lib/escher/request/action_dispatch_request.rb
|
131
130
|
- lib/escher/request/base.rb
|
132
131
|
- lib/escher/request/dci.rb
|
133
132
|
- lib/escher/request/dci/rack_env.rb
|
@@ -136,6 +135,7 @@ files:
|
|
136
135
|
- lib/escher/request/legacy_request.rb
|
137
136
|
- lib/escher/request/rack_request.rb
|
138
137
|
- lib/escher/version.rb
|
138
|
+
- repo-info.json
|
139
139
|
- scripts/checkout_test_suite.sh
|
140
140
|
- spec/aws4_testsuite/get-header-key-duplicate.authz
|
141
141
|
- spec/aws4_testsuite/get-header-key-duplicate.creq
|
@@ -315,7 +315,6 @@ files:
|
|
315
315
|
- spec/emarsys_testsuite/post-header-value-spaces.sreq
|
316
316
|
- spec/emarsys_testsuite/post-header-value-spaces.sts
|
317
317
|
- spec/escher/auth_spec.rb
|
318
|
-
- spec/escher/request/action_dispatch_request_spec.rb
|
319
318
|
- spec/escher/request/factory_spec.rb
|
320
319
|
- spec/escher/request/hash_request_spec.rb
|
321
320
|
- spec/escher/request/rack_request_spec.rb
|
@@ -342,8 +341,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
342
341
|
- !ruby/object:Gem::Version
|
343
342
|
version: '0'
|
344
343
|
requirements: []
|
345
|
-
|
346
|
-
rubygems_version: 2.5.1
|
344
|
+
rubygems_version: 3.2.22
|
347
345
|
signing_key:
|
348
346
|
specification_version: 4
|
349
347
|
summary: Library for HTTP request signing (Ruby implementation)
|
@@ -526,7 +524,6 @@ test_files:
|
|
526
524
|
- spec/emarsys_testsuite/post-header-value-spaces.sreq
|
527
525
|
- spec/emarsys_testsuite/post-header-value-spaces.sts
|
528
526
|
- spec/escher/auth_spec.rb
|
529
|
-
- spec/escher/request/action_dispatch_request_spec.rb
|
530
527
|
- spec/escher/request/factory_spec.rb
|
531
528
|
- spec/escher/request/hash_request_spec.rb
|
532
529
|
- spec/escher/request/rack_request_spec.rb
|
data/.travis.yml
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
module Escher
|
2
|
-
module Request
|
3
|
-
class ActionDispatchRequest < Base
|
4
|
-
|
5
|
-
include Escher::Request::DCI::RackEnv
|
6
|
-
|
7
|
-
def headers
|
8
|
-
get_headers_by_rack_env(request.env)
|
9
|
-
end
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def method
|
14
|
-
request.request_method
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def body
|
20
|
-
case request.body
|
21
|
-
when StringIO
|
22
|
-
request.body.string
|
23
|
-
else
|
24
|
-
request.body.to_s
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
def path
|
31
|
-
request.env['REQUEST_PATH'] || request.path
|
32
|
-
end
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
def query_values
|
37
|
-
Addressable::URI.new(:query => request.env['QUERY_STRING']).query_values(Array) or []
|
38
|
-
end
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
def set_header(header_name, value)
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
@@ -1,120 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'action_dispatch'
|
4
|
-
|
5
|
-
describe Escher::Request::ActionDispatchRequest do
|
6
|
-
|
7
|
-
let(:request_params) { {"PATH_INFO" => "/", } }
|
8
|
-
let(:request) { ActionDispatch::Request.new(request_params) }
|
9
|
-
|
10
|
-
subject { described_class.new request }
|
11
|
-
|
12
|
-
describe "#request" do
|
13
|
-
it "should return the underlying request object" do
|
14
|
-
expect(subject.request).to eq request
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
|
19
|
-
describe "#headers" do
|
20
|
-
it "should return only the HTTP request headers" do
|
21
|
-
request_params.merge! 'HTTP_HOST' => 'some host',
|
22
|
-
'SOME_HEADER' => 'some header'
|
23
|
-
|
24
|
-
expect(subject.headers).to eq [['HOST', 'some host']]
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should replace underscores with dashes in the header name" do
|
28
|
-
request_params.merge! 'HTTP_HOST_NAME' => 'some host'
|
29
|
-
|
30
|
-
expect(subject.headers).to eq [['HOST-NAME', 'some host']]
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'should add the content-type and content-length to the headers' do
|
34
|
-
request_params.merge!( 'CONTENT_LENGTH' => '123', 'CONTENT_TYPE' => 'text/plain' )
|
35
|
-
|
36
|
-
expect(subject.headers).to eq [%w(CONTENT-LENGTH 123), %w(CONTENT-TYPE text/plain)]
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
|
41
|
-
describe "#has_header?" do
|
42
|
-
it "should return true if request has specified header, false otherwise" do
|
43
|
-
request_params.merge! 'HTTP_HOST_NAME' => 'some host'
|
44
|
-
|
45
|
-
expect(subject.has_header? 'host-name').to be_truthy
|
46
|
-
expect(subject.has_header? 'no-such-header').to be_falsey
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
|
51
|
-
describe "#header" do
|
52
|
-
it "should return the value for the requested header" do
|
53
|
-
request_params.merge! 'HTTP_HOST' => 'some host'
|
54
|
-
|
55
|
-
expect(subject.header 'host').to eq 'some host'
|
56
|
-
end
|
57
|
-
|
58
|
-
it "should return nil if no such header exists" do
|
59
|
-
expect(subject.header 'host').to be_nil
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
|
64
|
-
describe "#method" do
|
65
|
-
it "should return the request method" do
|
66
|
-
request_params.merge! 'REQUEST_METHOD' => 'GET'
|
67
|
-
|
68
|
-
expect(subject.method).to eq 'GET'
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
|
73
|
-
describe "#body" do
|
74
|
-
it "should return the request body" do
|
75
|
-
request_params.merge! 'rack.input' => 'request body'
|
76
|
-
|
77
|
-
expect(subject.body).to eq 'request body'
|
78
|
-
end
|
79
|
-
|
80
|
-
it "should return empty string for no body" do
|
81
|
-
expect(subject.body).to eq ''
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
|
86
|
-
describe "#path" do
|
87
|
-
it "should return the request path" do
|
88
|
-
request_params.merge! 'REQUEST_PATH' => '/resources/id///'
|
89
|
-
|
90
|
-
expect(subject.path).to eq '/resources/id///'
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
|
95
|
-
describe "#query_values" do
|
96
|
-
it "should return the request query parameters as an array of key-value pairs" do
|
97
|
-
request_params.merge! 'QUERY_STRING' => 'search=query¶m=value'
|
98
|
-
|
99
|
-
expect(subject.query_values).to eq [['search', 'query'], ['param', 'value']]
|
100
|
-
end
|
101
|
-
|
102
|
-
it "should return the query parameters regardless of fragments" do
|
103
|
-
request_params.merge! 'QUERY_STRING' => "@\#$%^&+=/,?><`\";:\\|][{}"
|
104
|
-
|
105
|
-
expect(subject.query_values).to eq [["@\#$%^"], ["+", "/,?><`\";:\\|][{}"]]
|
106
|
-
end
|
107
|
-
|
108
|
-
it "should return an empty array if the request has no query parameters" do
|
109
|
-
expect(subject.query_values).to eq []
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
|
114
|
-
describe "#set_header" do
|
115
|
-
it "should ignore calls" do
|
116
|
-
expect { subject.set_header 'test-header', 'test value' }.not_to raise_error
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
end
|