api-auth 1.5.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +10 -44
- data/.rubocop.yml +102 -0
- data/.travis.yml +1 -0
- data/Appraisals +8 -0
- data/CHANGELOG.md +8 -1
- data/Gemfile +3 -0
- data/README.md +33 -5
- data/VERSION +1 -1
- data/api_auth.gemspec +17 -17
- data/gemfiles/rails_23.gemfile +3 -0
- data/gemfiles/rails_30.gemfile +3 -0
- data/gemfiles/rails_31.gemfile +5 -0
- data/gemfiles/rails_32.gemfile +5 -0
- data/gemfiles/rails_4.gemfile +2 -0
- data/gemfiles/rails_41.gemfile +2 -0
- data/gemfiles/rails_42.gemfile +2 -0
- data/lib/api-auth.rb +1 -1
- data/lib/api_auth/base.rb +21 -25
- data/lib/api_auth/errors.rb +4 -3
- data/lib/api_auth/headers.rb +11 -27
- data/lib/api_auth/helpers.rb +2 -6
- data/lib/api_auth/railtie.rb +5 -50
- data/lib/api_auth/request_drivers/action_controller.rb +7 -13
- data/lib/api_auth/request_drivers/action_dispatch.rb +0 -6
- data/lib/api_auth/request_drivers/curb.rb +8 -14
- data/lib/api_auth/request_drivers/faraday.rb +11 -21
- data/lib/api_auth/request_drivers/httpi.rb +8 -14
- data/lib/api_auth/request_drivers/net_http.rb +8 -14
- data/lib/api_auth/request_drivers/rack.rb +10 -16
- data/lib/api_auth/request_drivers/rest_client.rb +9 -15
- data/spec/api_auth_spec.rb +90 -88
- data/spec/headers_spec.rb +69 -84
- data/spec/helpers_spec.rb +7 -9
- data/spec/railtie_spec.rb +42 -72
- data/spec/request_drivers/action_controller_spec.rb +53 -55
- data/spec/request_drivers/action_dispatch_spec.rb +52 -55
- data/spec/request_drivers/curb_spec.rb +25 -28
- data/spec/request_drivers/faraday_spec.rb +54 -56
- data/spec/request_drivers/httpi_spec.rb +42 -48
- data/spec/request_drivers/net_http_spec.rb +51 -53
- data/spec/request_drivers/rack_spec.rb +58 -60
- data/spec/request_drivers/rest_client_spec.rb +86 -89
- data/spec/spec_helper.rb +9 -9
- metadata +4 -11
- data/Gemfile.lock +0 -115
- data/gemfiles/rails_23.gemfile.lock +0 -70
- data/gemfiles/rails_30.gemfile.lock +0 -92
- data/gemfiles/rails_31.gemfile.lock +0 -98
- data/gemfiles/rails_32.gemfile.lock +0 -97
- data/gemfiles/rails_4.gemfile.lock +0 -94
- data/gemfiles/rails_41.gemfile.lock +0 -98
- data/gemfiles/rails_42.gemfile.lock +0 -115
@@ -1,9 +1,6 @@
|
|
1
1
|
module ApiAuth
|
2
|
-
|
3
2
|
module RequestDrivers # :nodoc:
|
4
|
-
|
5
3
|
class HttpiRequest # :nodoc:
|
6
|
-
|
7
4
|
include ApiAuth::Helpers
|
8
5
|
|
9
6
|
def initialize(request)
|
@@ -13,7 +10,7 @@ module ApiAuth
|
|
13
10
|
end
|
14
11
|
|
15
12
|
def set_auth_header(header)
|
16
|
-
@request.headers[
|
13
|
+
@request.headers['Authorization'] = header
|
17
14
|
fetch_headers
|
18
15
|
@request
|
19
16
|
end
|
@@ -24,7 +21,7 @@ module ApiAuth
|
|
24
21
|
|
25
22
|
def populate_content_md5
|
26
23
|
if @request.body
|
27
|
-
@request.headers[
|
24
|
+
@request.headers['Content-MD5'] = calculated_md5
|
28
25
|
fetch_headers
|
29
26
|
end
|
30
27
|
end
|
@@ -47,12 +44,12 @@ module ApiAuth
|
|
47
44
|
|
48
45
|
def content_type
|
49
46
|
value = find_header(%w(CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE))
|
50
|
-
value.nil? ?
|
47
|
+
value.nil? ? '' : value
|
51
48
|
end
|
52
49
|
|
53
50
|
def content_md5
|
54
51
|
value = find_header(%w(CONTENT-MD5 CONTENT_MD5))
|
55
|
-
value.nil? ?
|
52
|
+
value.nil? ? '' : value
|
56
53
|
end
|
57
54
|
|
58
55
|
def request_uri
|
@@ -60,27 +57,24 @@ module ApiAuth
|
|
60
57
|
end
|
61
58
|
|
62
59
|
def set_date
|
63
|
-
@request.headers[
|
60
|
+
@request.headers['DATE'] = Time.now.utc.httpdate
|
64
61
|
fetch_headers
|
65
62
|
end
|
66
63
|
|
67
64
|
def timestamp
|
68
65
|
value = find_header(%w(DATE HTTP_DATE))
|
69
|
-
value.nil? ?
|
66
|
+
value.nil? ? '' : value
|
70
67
|
end
|
71
68
|
|
72
69
|
def authorization_header
|
73
70
|
find_header %w(Authorization AUTHORIZATION HTTP_AUTHORIZATION)
|
74
71
|
end
|
75
72
|
|
76
|
-
|
73
|
+
private
|
77
74
|
|
78
75
|
def find_header(keys)
|
79
|
-
keys.map {|key| @headers[key] }.compact.first
|
76
|
+
keys.map { |key| @headers[key] }.compact.first
|
80
77
|
end
|
81
|
-
|
82
78
|
end
|
83
|
-
|
84
79
|
end
|
85
|
-
|
86
80
|
end
|
@@ -1,9 +1,6 @@
|
|
1
1
|
module ApiAuth
|
2
|
-
|
3
2
|
module RequestDrivers # :nodoc:
|
4
|
-
|
5
3
|
class NetHttpRequest # :nodoc:
|
6
|
-
|
7
4
|
include ApiAuth::Helpers
|
8
5
|
|
9
6
|
def initialize(request)
|
@@ -13,7 +10,7 @@ module ApiAuth
|
|
13
10
|
end
|
14
11
|
|
15
12
|
def set_auth_header(header)
|
16
|
-
@request[
|
13
|
+
@request['Authorization'] = header
|
17
14
|
@headers = fetch_headers
|
18
15
|
@request
|
19
16
|
end
|
@@ -31,7 +28,7 @@ module ApiAuth
|
|
31
28
|
|
32
29
|
def populate_content_md5
|
33
30
|
if @request.class::REQUEST_HAS_BODY
|
34
|
-
@request[
|
31
|
+
@request['Content-MD5'] = calculated_md5
|
35
32
|
end
|
36
33
|
end
|
37
34
|
|
@@ -53,12 +50,12 @@ module ApiAuth
|
|
53
50
|
|
54
51
|
def content_type
|
55
52
|
value = find_header(%w(CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE))
|
56
|
-
value.nil? ?
|
53
|
+
value.nil? ? '' : value
|
57
54
|
end
|
58
55
|
|
59
56
|
def content_md5
|
60
57
|
value = find_header(%w(CONTENT-MD5 CONTENT_MD5))
|
61
|
-
value.nil? ?
|
58
|
+
value.nil? ? '' : value
|
62
59
|
end
|
63
60
|
|
64
61
|
def request_uri
|
@@ -66,26 +63,23 @@ module ApiAuth
|
|
66
63
|
end
|
67
64
|
|
68
65
|
def set_date
|
69
|
-
@request[
|
66
|
+
@request['DATE'] = Time.now.utc.httpdate
|
70
67
|
end
|
71
68
|
|
72
69
|
def timestamp
|
73
70
|
value = find_header(%w(DATE HTTP_DATE))
|
74
|
-
value.nil? ?
|
71
|
+
value.nil? ? '' : value
|
75
72
|
end
|
76
73
|
|
77
74
|
def authorization_header
|
78
75
|
find_header %w(Authorization AUTHORIZATION HTTP_AUTHORIZATION)
|
79
76
|
end
|
80
77
|
|
81
|
-
|
78
|
+
private
|
82
79
|
|
83
80
|
def find_header(keys)
|
84
|
-
keys.map {|key| @headers[key] }.compact.first
|
81
|
+
keys.map { |key| @headers[key] }.compact.first
|
85
82
|
end
|
86
|
-
|
87
83
|
end
|
88
|
-
|
89
84
|
end
|
90
|
-
|
91
85
|
end
|
@@ -1,9 +1,6 @@
|
|
1
1
|
module ApiAuth
|
2
|
-
|
3
2
|
module RequestDrivers # :nodoc:
|
4
|
-
|
5
3
|
class RackRequest # :nodoc:
|
6
|
-
|
7
4
|
include ApiAuth::Helpers
|
8
5
|
|
9
6
|
def initialize(request)
|
@@ -13,7 +10,7 @@ module ApiAuth
|
|
13
10
|
end
|
14
11
|
|
15
12
|
def set_auth_header(header)
|
16
|
-
@request.env
|
13
|
+
@request.env['Authorization'] = header
|
17
14
|
fetch_headers
|
18
15
|
@request
|
19
16
|
end
|
@@ -29,14 +26,14 @@ module ApiAuth
|
|
29
26
|
end
|
30
27
|
|
31
28
|
def populate_content_md5
|
32
|
-
if
|
33
|
-
@request.env[
|
29
|
+
if %w(POST PUT).include?(@request.request_method)
|
30
|
+
@request.env['Content-MD5'] = calculated_md5
|
34
31
|
fetch_headers
|
35
32
|
end
|
36
33
|
end
|
37
34
|
|
38
35
|
def md5_mismatch?
|
39
|
-
if
|
36
|
+
if %w(POST PUT).include?(@request.request_method)
|
40
37
|
calculated_md5 != content_md5
|
41
38
|
else
|
42
39
|
false
|
@@ -53,12 +50,12 @@ module ApiAuth
|
|
53
50
|
|
54
51
|
def content_type
|
55
52
|
value = find_header(%w(CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE))
|
56
|
-
value.nil? ?
|
53
|
+
value.nil? ? '' : value
|
57
54
|
end
|
58
55
|
|
59
56
|
def content_md5
|
60
57
|
value = find_header(%w(CONTENT-MD5 CONTENT_MD5 HTTP-CONTENT-MD5 HTTP_CONTENT_MD5))
|
61
|
-
value.nil? ?
|
58
|
+
value.nil? ? '' : value
|
62
59
|
end
|
63
60
|
|
64
61
|
def request_uri
|
@@ -66,27 +63,24 @@ module ApiAuth
|
|
66
63
|
end
|
67
64
|
|
68
65
|
def set_date
|
69
|
-
@request.env
|
66
|
+
@request.env['DATE'] = Time.now.utc.httpdate
|
70
67
|
fetch_headers
|
71
68
|
end
|
72
69
|
|
73
70
|
def timestamp
|
74
71
|
value = find_header(%w(DATE HTTP_DATE))
|
75
|
-
value.nil? ?
|
72
|
+
value.nil? ? '' : value
|
76
73
|
end
|
77
74
|
|
78
75
|
def authorization_header
|
79
76
|
find_header %w(Authorization AUTHORIZATION HTTP_AUTHORIZATION)
|
80
77
|
end
|
81
78
|
|
82
|
-
|
79
|
+
private
|
83
80
|
|
84
81
|
def find_header(keys)
|
85
|
-
keys.map {|key| @headers[key] }.compact.first
|
82
|
+
keys.map { |key| @headers[key] }.compact.first
|
86
83
|
end
|
87
|
-
|
88
84
|
end
|
89
|
-
|
90
85
|
end
|
91
|
-
|
92
86
|
end
|
@@ -1,12 +1,9 @@
|
|
1
1
|
# give access to RestClient @processed_headers
|
2
|
-
module RestClient;class Request;attr_accessor :processed_headers;end;end
|
2
|
+
module RestClient; class Request; attr_accessor :processed_headers; end; end
|
3
3
|
|
4
4
|
module ApiAuth
|
5
|
-
|
6
5
|
module RequestDrivers # :nodoc:
|
7
|
-
|
8
6
|
class RestClientRequest # :nodoc:
|
9
|
-
|
10
7
|
include ApiAuth::Helpers
|
11
8
|
|
12
9
|
def initialize(request)
|
@@ -16,7 +13,7 @@ module ApiAuth
|
|
16
13
|
end
|
17
14
|
|
18
15
|
def set_auth_header(header)
|
19
|
-
@request.headers
|
16
|
+
@request.headers['Authorization'] = header
|
20
17
|
save_headers # enforce update of processed_headers based on last updated headers
|
21
18
|
@request
|
22
19
|
end
|
@@ -33,7 +30,7 @@ module ApiAuth
|
|
33
30
|
|
34
31
|
def populate_content_md5
|
35
32
|
if [:post, :put].include?(@request.method)
|
36
|
-
@request.headers[
|
33
|
+
@request.headers['Content-MD5'] = calculated_md5
|
37
34
|
save_headers
|
38
35
|
end
|
39
36
|
end
|
@@ -56,12 +53,12 @@ module ApiAuth
|
|
56
53
|
|
57
54
|
def content_type
|
58
55
|
value = find_header(%w(CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE))
|
59
|
-
value.nil? ?
|
56
|
+
value.nil? ? '' : value
|
60
57
|
end
|
61
58
|
|
62
59
|
def content_md5
|
63
60
|
value = find_header(%w(CONTENT-MD5 CONTENT_MD5))
|
64
|
-
value.nil? ?
|
61
|
+
value.nil? ? '' : value
|
65
62
|
end
|
66
63
|
|
67
64
|
def request_uri
|
@@ -69,32 +66,29 @@ module ApiAuth
|
|
69
66
|
end
|
70
67
|
|
71
68
|
def set_date
|
72
|
-
@request.headers
|
69
|
+
@request.headers['DATE'] = Time.now.utc.httpdate
|
73
70
|
save_headers
|
74
71
|
end
|
75
72
|
|
76
73
|
def timestamp
|
77
74
|
value = find_header(%w(DATE HTTP_DATE))
|
78
|
-
value.nil? ?
|
75
|
+
value.nil? ? '' : value
|
79
76
|
end
|
80
77
|
|
81
78
|
def authorization_header
|
82
79
|
find_header %w(Authorization AUTHORIZATION HTTP_AUTHORIZATION)
|
83
80
|
end
|
84
81
|
|
85
|
-
|
82
|
+
private
|
86
83
|
|
87
84
|
def find_header(keys)
|
88
|
-
keys.map {|key| @headers[key] }.compact.first
|
85
|
+
keys.map { |key| @headers[key] }.compact.first
|
89
86
|
end
|
90
87
|
|
91
88
|
def save_headers
|
92
89
|
@request.processed_headers = @request.make_headers(@request.headers)
|
93
90
|
@headers = fetch_headers
|
94
91
|
end
|
95
|
-
|
96
92
|
end
|
97
|
-
|
98
93
|
end
|
99
|
-
|
100
94
|
end
|
data/spec/api_auth_spec.rb
CHANGED
@@ -1,170 +1,172 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
3
3
|
|
4
|
-
describe
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
it "should generate secret keys" do
|
4
|
+
describe 'ApiAuth' do
|
5
|
+
describe 'generating secret keys' do
|
6
|
+
it 'should generate secret keys' do
|
9
7
|
ApiAuth.generate_secret_key
|
10
8
|
end
|
11
9
|
|
12
|
-
it
|
10
|
+
it 'should generate secret keys that are 88 characters' do
|
13
11
|
expect(ApiAuth.generate_secret_key.size).to be(88)
|
14
12
|
end
|
15
13
|
|
16
|
-
it
|
14
|
+
it 'should generate keys that have a Hamming Distance of at least 65' do
|
17
15
|
key1 = ApiAuth.generate_secret_key
|
18
16
|
key2 = ApiAuth.generate_secret_key
|
19
17
|
expect(Amatch::Hamming.new(key1).match(key2)).to be > 65
|
20
18
|
end
|
21
|
-
|
22
19
|
end
|
23
20
|
|
24
|
-
def hmac(secret_key, request, canonical_string = nil)
|
21
|
+
def hmac(secret_key, request, canonical_string = nil, digest = 'sha1')
|
25
22
|
canonical_string ||= ApiAuth::Headers.new(request).canonical_string
|
26
|
-
digest = OpenSSL::Digest.new(
|
23
|
+
digest = OpenSSL::Digest.new(digest)
|
27
24
|
ApiAuth.b64_encode(OpenSSL::HMAC.digest(digest, secret_key, canonical_string))
|
28
25
|
end
|
29
26
|
|
30
|
-
describe
|
31
|
-
let(:request){ RestClient::Request.new(:url =>
|
32
|
-
let(:headers){ ApiAuth::Headers.new(request) }
|
27
|
+
describe '.sign!' do
|
28
|
+
let(:request) { RestClient::Request.new(:url => 'http://google.com', :method => :get) }
|
29
|
+
let(:headers) { ApiAuth::Headers.new(request) }
|
33
30
|
|
34
|
-
it
|
31
|
+
it 'generates date header before signing' do
|
35
32
|
expect(ApiAuth::Headers).to receive(:new).and_return(headers)
|
36
33
|
|
37
34
|
expect(headers).to receive(:set_date).ordered
|
38
35
|
expect(headers).to receive(:sign_header).ordered
|
39
36
|
|
40
|
-
ApiAuth.sign!(request,
|
37
|
+
ApiAuth.sign!(request, 'abc', '123')
|
41
38
|
end
|
42
39
|
|
43
|
-
it
|
40
|
+
it 'generates content-md5 header before signing' do
|
44
41
|
expect(ApiAuth::Headers).to receive(:new).and_return(headers)
|
45
42
|
expect(headers).to receive(:calculate_md5).ordered
|
46
43
|
expect(headers).to receive(:sign_header).ordered
|
47
44
|
|
48
|
-
ApiAuth.sign!(request,
|
45
|
+
ApiAuth.sign!(request, 'abc', '123')
|
49
46
|
end
|
50
47
|
|
51
|
-
it
|
52
|
-
expect(ApiAuth.sign!(request,
|
48
|
+
it 'returns the same request object back' do
|
49
|
+
expect(ApiAuth.sign!(request, 'abc', '123')).to be request
|
53
50
|
end
|
54
51
|
|
55
|
-
it
|
56
|
-
ApiAuth.sign!(request,
|
57
|
-
signature = hmac(
|
52
|
+
it 'calculates the hmac_signature as expected' do
|
53
|
+
ApiAuth.sign!(request, '1044', '123')
|
54
|
+
signature = hmac('123', request)
|
58
55
|
expect(request.headers['Authorization']).to eq("APIAuth 1044:#{signature}")
|
59
56
|
end
|
60
57
|
|
61
|
-
context
|
62
|
-
let(:request)
|
63
|
-
Net::HTTP::Put.new(
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
58
|
+
context 'when passed the hmac digest option' do
|
59
|
+
let(:request) do
|
60
|
+
Net::HTTP::Put.new('/resource.xml?foo=bar&bar=foo',
|
61
|
+
'content-type' => 'text/plain',
|
62
|
+
'content-md5' => '1B2M2Y8AsgTpgAmY7PhCfg==',
|
63
|
+
'date' => Time.now.utc.httpdate
|
64
|
+
)
|
65
|
+
end
|
69
66
|
|
70
|
-
let(:canonical_string){ ApiAuth::Headers.new(request).
|
67
|
+
let(:canonical_string) { ApiAuth::Headers.new(request).canonical_string }
|
71
68
|
|
72
|
-
it
|
73
|
-
ApiAuth.sign!(request,
|
74
|
-
signature = hmac(
|
75
|
-
expect(request['Authorization']).to eq("APIAuth 1044:#{signature}")
|
69
|
+
it 'calculates the hmac_signature with http method' do
|
70
|
+
ApiAuth.sign!(request, '1044', '123', :digest => 'sha256')
|
71
|
+
signature = hmac('123', request, canonical_string, 'sha256')
|
72
|
+
expect(request['Authorization']).to eq("APIAuth-HMAC-SHA256 1044:#{signature}")
|
76
73
|
end
|
77
74
|
end
|
78
75
|
end
|
79
76
|
|
80
|
-
describe
|
81
|
-
let(:request)
|
82
|
-
new_request = Net::HTTP::Put.new(
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
77
|
+
describe '.authentic?' do
|
78
|
+
let(:request) do
|
79
|
+
new_request = Net::HTTP::Put.new('/resource.xml?foo=bar&bar=foo',
|
80
|
+
'content-type' => 'text/plain',
|
81
|
+
'content-md5' => '1B2M2Y8AsgTpgAmY7PhCfg==',
|
82
|
+
'date' => Time.now.utc.httpdate
|
83
|
+
)
|
87
84
|
|
88
|
-
signature = hmac(
|
89
|
-
new_request[
|
85
|
+
signature = hmac('123', new_request)
|
86
|
+
new_request['Authorization'] = "APIAuth 1044:#{signature}"
|
90
87
|
new_request
|
91
|
-
|
88
|
+
end
|
92
89
|
|
93
|
-
it
|
94
|
-
expect(ApiAuth.authentic?(request,
|
90
|
+
it 'validates that the signature in the request header matches the way we sign it' do
|
91
|
+
expect(ApiAuth.authentic?(request, '123')).to eq true
|
95
92
|
end
|
96
93
|
|
97
|
-
it
|
98
|
-
expect(ApiAuth.authentic?(request,
|
94
|
+
it 'fails to validate a non matching signature' do
|
95
|
+
expect(ApiAuth.authentic?(request, '456')).to eq false
|
99
96
|
end
|
100
97
|
|
101
|
-
it
|
98
|
+
it 'fails to validate non matching md5' do
|
102
99
|
request['content-md5'] = '12345'
|
103
|
-
expect(ApiAuth.authentic?(request,
|
100
|
+
expect(ApiAuth.authentic?(request, '123')).to eq false
|
104
101
|
end
|
105
102
|
|
106
|
-
it
|
103
|
+
it 'fails to validate expired requests' do
|
107
104
|
request['date'] = 16.minutes.ago.utc.httpdate
|
108
|
-
expect(ApiAuth.authentic?(request,
|
105
|
+
expect(ApiAuth.authentic?(request, '123')).to eq false
|
109
106
|
end
|
110
107
|
|
111
|
-
it
|
108
|
+
it 'fails to validate if the date is invalid' do
|
112
109
|
request['date'] = "٢٠١٤-٠٩-٠٨ ١٦:٣١:١٤ +٠٣٠٠"
|
113
|
-
expect(ApiAuth.authentic?(request,
|
110
|
+
expect(ApiAuth.authentic?(request, '123')).to eq false
|
114
111
|
end
|
115
112
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
113
|
+
|
114
|
+
it 'fails to validate if the request method differs' do
|
115
|
+
canonical_string = ApiAuth::Headers.new(request).canonical_string('POST')
|
116
|
+
signature = hmac('123', request, canonical_string)
|
117
|
+
request['Authorization'] = "APIAuth 1044:#{signature}"
|
118
|
+
expect(ApiAuth.authentic?(request, '123')).to eq false
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'when passed the hmac digest option' do
|
122
|
+
let(:request) do
|
123
|
+
new_request = Net::HTTP::Put.new('/resource.xml?foo=bar&bar=foo',
|
124
|
+
'content-type' => 'text/plain',
|
125
|
+
'content-md5' => '1B2M2Y8AsgTpgAmY7PhCfg==',
|
126
|
+
'date' => Time.now.utc.httpdate
|
127
|
+
)
|
128
|
+
canonical_string = ApiAuth::Headers.new(new_request).canonical_string
|
129
|
+
signature = hmac('123', new_request, canonical_string, 'sha256')
|
130
|
+
new_request['Authorization'] = "APIAuth-HMAC-SHA256 1044:#{signature}"
|
126
131
|
new_request
|
127
|
-
|
132
|
+
end
|
128
133
|
|
129
|
-
it
|
130
|
-
expect(ApiAuth.authentic?(request,
|
134
|
+
it 'validates for sha256 digest' do
|
135
|
+
expect(ApiAuth.authentic?(request, '123', :digest => 'sha256')).to eq true
|
131
136
|
end
|
132
137
|
|
133
|
-
it
|
134
|
-
|
135
|
-
signature = hmac("123", request, canonical_string)
|
136
|
-
request["Authorization"] = "APIAuth 1044:#{signature}"
|
137
|
-
expect(ApiAuth.authentic?(request, "123")).to eq false
|
138
|
+
it 'validates exception with wrong client digest' do
|
139
|
+
expect { ApiAuth.authentic?(request, '123', :digest => 'sha512') }.to raise_error(ApiAuth::InvalidRequestDigest)
|
138
140
|
end
|
139
141
|
end
|
140
142
|
end
|
141
143
|
|
142
|
-
describe
|
143
|
-
context
|
144
|
-
let(:request)
|
144
|
+
describe '.access_id' do
|
145
|
+
context 'normal APIAuth Auth header' do
|
146
|
+
let(:request) do
|
145
147
|
RestClient::Request.new(
|
146
|
-
:url =>
|
148
|
+
:url => 'http://google.com',
|
147
149
|
:method => :get,
|
148
|
-
:headers => {:authorization =>
|
150
|
+
:headers => { :authorization => 'APIAuth 1044:aGVsbG8gd29ybGQ=' }
|
149
151
|
)
|
150
|
-
|
152
|
+
end
|
151
153
|
|
152
|
-
it
|
153
|
-
expect(ApiAuth.access_id(request)).to eq(
|
154
|
+
it 'parses it from the Auth Header' do
|
155
|
+
expect(ApiAuth.access_id(request)).to eq('1044')
|
154
156
|
end
|
155
157
|
end
|
156
158
|
|
157
|
-
context
|
158
|
-
let(:request)
|
159
|
+
context 'Corporate prefixed APIAuth header' do
|
160
|
+
let(:request) do
|
159
161
|
RestClient::Request.new(
|
160
|
-
:url =>
|
162
|
+
:url => 'http://google.com',
|
161
163
|
:method => :get,
|
162
|
-
:headers => {:authorization =>
|
164
|
+
:headers => { :authorization => 'Corporate APIAuth 1044:aGVsbG8gd29ybGQ=' }
|
163
165
|
)
|
164
|
-
|
166
|
+
end
|
165
167
|
|
166
|
-
it
|
167
|
-
expect(ApiAuth.access_id(request)).to eq(
|
168
|
+
it 'parses it from the Auth Header' do
|
169
|
+
expect(ApiAuth.access_id(request)).to eq('1044')
|
168
170
|
end
|
169
171
|
end
|
170
172
|
end
|