api-auth 2.1.0 → 2.2.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 +5 -5
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -40
- data/.travis.yml +10 -41
- data/Appraisals +16 -42
- data/Gemfile +1 -4
- data/README.md +28 -4
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/api_auth.gemspec +9 -10
- data/gemfiles/rails_5.gemfile +2 -2
- data/gemfiles/rails_51.gemfile +9 -0
- data/lib/api_auth/base.rb +10 -10
- data/lib/api_auth/headers.rb +9 -9
- data/lib/api_auth/helpers.rb +2 -11
- data/lib/api_auth/railtie.rb +5 -13
- data/lib/api_auth/request_drivers/action_controller.rb +8 -7
- data/lib/api_auth/request_drivers/curb.rb +8 -7
- data/lib/api_auth/request_drivers/faraday.rb +10 -9
- data/lib/api_auth/request_drivers/httpi.rb +8 -7
- data/lib/api_auth/request_drivers/net_http.rb +8 -7
- data/lib/api_auth/request_drivers/rack.rb +10 -9
- data/lib/api_auth/request_drivers/rest_client.rb +10 -9
- data/spec/.rubocop.yml +5 -0
- data/spec/api_auth_spec.rb +23 -12
- data/spec/headers_spec.rb +49 -12
- data/spec/railtie_spec.rb +33 -59
- data/spec/request_drivers/rack_spec.rb +17 -17
- data/spec/request_drivers/rest_client_spec.rb +44 -45
- metadata +27 -15
- data/gemfiles/rails_23.gemfile +0 -12
- data/gemfiles/rails_30.gemfile +0 -12
- data/gemfiles/rails_31.gemfile +0 -14
- data/gemfiles/rails_32.gemfile +0 -14
data/spec/railtie_spec.rb
CHANGED
@@ -13,28 +13,26 @@ describe 'Rails integration' do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
respond_to do |format|
|
16
|
-
format.xml { render :
|
17
|
-
format.json { render :
|
18
|
-
format.html { render :
|
16
|
+
format.xml { render xml: 'You are unauthorized to perform this action.', status: 401 }
|
17
|
+
format.json { render json: 'You are unauthorized to perform this action.', status: 401 }
|
18
|
+
format.html { render plain: 'You are unauthorized to perform this action', status: 401 }
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
class TestController < ApplicationController
|
24
|
-
|
24
|
+
before_action :require_api_auth, only: [:index]
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
ActionDispatch::Routing::RouteSet.new
|
29
|
-
end
|
26
|
+
def self._routes
|
27
|
+
ActionDispatch::Routing::RouteSet.new
|
30
28
|
end
|
31
29
|
|
32
30
|
def index
|
33
|
-
render :
|
31
|
+
render json: 'OK'
|
34
32
|
end
|
35
33
|
|
36
34
|
def public
|
37
|
-
render :
|
35
|
+
render json: 'OK'
|
38
36
|
end
|
39
37
|
|
40
38
|
def rescue_action(e)
|
@@ -42,31 +40,31 @@ describe 'Rails integration' do
|
|
42
40
|
end
|
43
41
|
end
|
44
42
|
|
45
|
-
unless defined?(ActionDispatch)
|
46
|
-
ActionController::Routing::Routes.draw { |map| map.resources :test }
|
47
|
-
end
|
48
|
-
|
49
43
|
def generated_response(request, action = :index)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
response
|
57
|
-
else
|
58
|
-
request.action = action.to_s
|
59
|
-
request.path = "/#{action}"
|
60
|
-
TestController.new.process(request, ActionController::TestResponse.new)
|
61
|
-
end
|
44
|
+
response = ActionDispatch::TestResponse.new
|
45
|
+
controller = TestController.new
|
46
|
+
controller.request = request
|
47
|
+
controller.response = response
|
48
|
+
controller.process(action)
|
49
|
+
response
|
62
50
|
end
|
63
51
|
|
64
|
-
|
52
|
+
def generated_request
|
65
53
|
request = if ActionController::TestRequest.respond_to?(:create)
|
66
|
-
|
54
|
+
if Gem.loaded_specs['actionpack'].version < Gem::Version.new('5.1.0')
|
55
|
+
ActionController::TestRequest.create
|
56
|
+
else
|
57
|
+
ActionController::TestRequest.create(TestController)
|
58
|
+
end
|
67
59
|
else
|
68
60
|
ActionController::TestRequest.new
|
69
61
|
end
|
62
|
+
request.accept = ['application/json']
|
63
|
+
request
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should permit a request with properly signed headers' do
|
67
|
+
request = generated_request
|
70
68
|
request.env['DATE'] = Time.now.utc.httpdate
|
71
69
|
ApiAuth.sign!(request, '1044', API_KEY_STORE['1044'])
|
72
70
|
response = generated_response(request, :index)
|
@@ -74,11 +72,7 @@ describe 'Rails integration' do
|
|
74
72
|
end
|
75
73
|
|
76
74
|
it 'should forbid a request with properly signed headers but timestamp > 15 minutes ago' do
|
77
|
-
request =
|
78
|
-
ActionController::TestRequest.create
|
79
|
-
else
|
80
|
-
ActionController::TestRequest.new
|
81
|
-
end
|
75
|
+
request = generated_request
|
82
76
|
request.env['DATE'] = 'Mon, 23 Jan 1984 03:29:56 GMT'
|
83
77
|
ApiAuth.sign!(request, '1044', API_KEY_STORE['1044'])
|
84
78
|
response = generated_response(request, :index)
|
@@ -86,11 +80,7 @@ describe 'Rails integration' do
|
|
86
80
|
end
|
87
81
|
|
88
82
|
it 'should forbid a request with properly signed headers but timestamp > 15 minutes in the future' do
|
89
|
-
request =
|
90
|
-
ActionController::TestRequest.create
|
91
|
-
else
|
92
|
-
ActionController::TestRequest.new
|
93
|
-
end
|
83
|
+
request = generated_request
|
94
84
|
request.env['DATE'] = 'Mon, 23 Jan 2100 03:29:56 GMT'
|
95
85
|
ApiAuth.sign!(request, '1044', API_KEY_STORE['1044'])
|
96
86
|
response = generated_response(request, :index)
|
@@ -98,42 +88,26 @@ describe 'Rails integration' do
|
|
98
88
|
end
|
99
89
|
|
100
90
|
it "should insert a DATE header in the request when one hasn't been specified" do
|
101
|
-
request =
|
102
|
-
ActionController::TestRequest.create
|
103
|
-
else
|
104
|
-
ActionController::TestRequest.new
|
105
|
-
end
|
91
|
+
request = generated_request
|
106
92
|
ApiAuth.sign!(request, '1044', API_KEY_STORE['1044'])
|
107
93
|
expect(request.headers['DATE']).not_to be_nil
|
108
94
|
end
|
109
95
|
|
110
96
|
it 'should forbid an unsigned request to a protected controller action' do
|
111
|
-
request =
|
112
|
-
ActionController::TestRequest.create
|
113
|
-
else
|
114
|
-
ActionController::TestRequest.new
|
115
|
-
end
|
97
|
+
request = generated_request
|
116
98
|
response = generated_response(request, :index)
|
117
99
|
expect(response.code).to eq('401')
|
118
100
|
end
|
119
101
|
|
120
102
|
it 'should forbid a request with a bogus signature' do
|
121
|
-
request =
|
122
|
-
ActionController::TestRequest.create
|
123
|
-
else
|
124
|
-
ActionController::TestRequest.new
|
125
|
-
end
|
103
|
+
request = generated_request
|
126
104
|
request.env['Authorization'] = 'APIAuth bogus:bogus'
|
127
105
|
response = generated_response(request, :index)
|
128
106
|
expect(response.code).to eq('401')
|
129
107
|
end
|
130
108
|
|
131
109
|
it 'should allow non-protected controller actions to function as before' do
|
132
|
-
request =
|
133
|
-
ActionController::TestRequest.create
|
134
|
-
else
|
135
|
-
ActionController::TestRequest.new
|
136
|
-
end
|
110
|
+
request = generated_request
|
137
111
|
response = generated_response(request, :public)
|
138
112
|
expect(response.code).to eq('200')
|
139
113
|
end
|
@@ -156,7 +130,7 @@ describe 'Rails integration' do
|
|
156
130
|
'Accept' => 'application/xml',
|
157
131
|
'DATE' => 'Mon, 23 Jan 1984 03:29:56 GMT'
|
158
132
|
},
|
159
|
-
{ :
|
133
|
+
{ id: '1' }.to_xml(root: 'test_resource')
|
160
134
|
end
|
161
135
|
expect(ApiAuth).to receive(:sign!).with(anything, '1044', API_KEY_STORE['1044'], {}).and_call_original
|
162
136
|
TestResource.find(1)
|
@@ -18,8 +18,8 @@ describe ApiAuth::RequestDrivers::RackRequest do
|
|
18
18
|
Rack::Request.new(
|
19
19
|
Rack::MockRequest.env_for(
|
20
20
|
request_path,
|
21
|
-
:
|
22
|
-
:
|
21
|
+
method: :put,
|
22
|
+
input: "hello\nworld"
|
23
23
|
).merge!(request_headers)
|
24
24
|
)
|
25
25
|
end
|
@@ -56,7 +56,7 @@ describe ApiAuth::RequestDrivers::RackRequest do
|
|
56
56
|
request = Rack::Request.new(
|
57
57
|
Rack::MockRequest.env_for(
|
58
58
|
request_path,
|
59
|
-
:
|
59
|
+
method: :put
|
60
60
|
).merge!(request_headers)
|
61
61
|
)
|
62
62
|
driven_request = ApiAuth::RequestDrivers::RackRequest.new(request)
|
@@ -70,7 +70,7 @@ describe ApiAuth::RequestDrivers::RackRequest do
|
|
70
70
|
Rack::Request.new(
|
71
71
|
Rack::MockRequest.env_for(
|
72
72
|
request_path,
|
73
|
-
:
|
73
|
+
method: :put
|
74
74
|
).merge!(request_headers)
|
75
75
|
)
|
76
76
|
end
|
@@ -85,7 +85,7 @@ describe ApiAuth::RequestDrivers::RackRequest do
|
|
85
85
|
Rack::Request.new(
|
86
86
|
Rack::MockRequest.env_for(
|
87
87
|
request_path,
|
88
|
-
:
|
88
|
+
method: :get
|
89
89
|
).merge!(request_headers)
|
90
90
|
)
|
91
91
|
end
|
@@ -110,7 +110,7 @@ describe ApiAuth::RequestDrivers::RackRequest do
|
|
110
110
|
Rack::Request.new(
|
111
111
|
Rack::MockRequest.env_for(
|
112
112
|
request_path,
|
113
|
-
:
|
113
|
+
method: :get
|
114
114
|
).merge!(request_headers)
|
115
115
|
)
|
116
116
|
end
|
@@ -126,8 +126,8 @@ describe ApiAuth::RequestDrivers::RackRequest do
|
|
126
126
|
Rack::Request.new(
|
127
127
|
Rack::MockRequest.env_for(
|
128
128
|
request_path,
|
129
|
-
:
|
130
|
-
:
|
129
|
+
method: :post,
|
130
|
+
input: "hello\nworld"
|
131
131
|
).merge!(request_headers)
|
132
132
|
)
|
133
133
|
end
|
@@ -148,8 +148,8 @@ describe ApiAuth::RequestDrivers::RackRequest do
|
|
148
148
|
Rack::Request.new(
|
149
149
|
Rack::MockRequest.env_for(
|
150
150
|
request_path,
|
151
|
-
:
|
152
|
-
:
|
151
|
+
method: :put,
|
152
|
+
input: "hello\nworld"
|
153
153
|
).merge!(request_headers)
|
154
154
|
)
|
155
155
|
end
|
@@ -170,7 +170,7 @@ describe ApiAuth::RequestDrivers::RackRequest do
|
|
170
170
|
Rack::Request.new(
|
171
171
|
Rack::MockRequest.env_for(
|
172
172
|
request_path,
|
173
|
-
:
|
173
|
+
method: :delete
|
174
174
|
).merge!(request_headers)
|
175
175
|
)
|
176
176
|
end
|
@@ -212,7 +212,7 @@ describe ApiAuth::RequestDrivers::RackRequest do
|
|
212
212
|
Rack::Request.new(
|
213
213
|
Rack::MockRequest.env_for(
|
214
214
|
request_path,
|
215
|
-
:
|
215
|
+
method: :get
|
216
216
|
).merge!(request_headers)
|
217
217
|
)
|
218
218
|
end
|
@@ -227,8 +227,8 @@ describe ApiAuth::RequestDrivers::RackRequest do
|
|
227
227
|
Rack::Request.new(
|
228
228
|
Rack::MockRequest.env_for(
|
229
229
|
request_path,
|
230
|
-
:
|
231
|
-
:
|
230
|
+
method: :post,
|
231
|
+
input: "hello\nworld"
|
232
232
|
).merge!(request_headers)
|
233
233
|
)
|
234
234
|
end
|
@@ -259,8 +259,8 @@ describe ApiAuth::RequestDrivers::RackRequest do
|
|
259
259
|
Rack::Request.new(
|
260
260
|
Rack::MockRequest.env_for(
|
261
261
|
request_path,
|
262
|
-
:
|
263
|
-
:
|
262
|
+
method: :put,
|
263
|
+
input: "hello\nworld"
|
264
264
|
).merge!(request_headers)
|
265
265
|
)
|
266
266
|
end
|
@@ -291,7 +291,7 @@ describe ApiAuth::RequestDrivers::RackRequest do
|
|
291
291
|
Rack::Request.new(
|
292
292
|
Rack::MockRequest.env_for(
|
293
293
|
request_path,
|
294
|
-
:
|
294
|
+
method: :delete
|
295
295
|
).merge!(request_headers)
|
296
296
|
)
|
297
297
|
end
|
@@ -16,10 +16,10 @@ describe ApiAuth::RequestDrivers::RestClientRequest do
|
|
16
16
|
|
17
17
|
let(:request) do
|
18
18
|
RestClient::Request.new(
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
19
|
+
url: '/resource.xml?foo=bar&bar=foo',
|
20
|
+
headers: request_headers,
|
21
|
+
method: :put,
|
22
|
+
payload: "hello\nworld"
|
23
23
|
)
|
24
24
|
end
|
25
25
|
|
@@ -53,9 +53,9 @@ describe ApiAuth::RequestDrivers::RestClientRequest do
|
|
53
53
|
|
54
54
|
it 'treats no body as empty string' do
|
55
55
|
request = RestClient::Request.new(
|
56
|
-
:
|
57
|
-
:
|
58
|
-
:
|
56
|
+
url: '/resource.xml?foo=bar&bar=foo',
|
57
|
+
headers: request_headers,
|
58
|
+
method: :put
|
59
59
|
)
|
60
60
|
driven_request = ApiAuth::RequestDrivers::RestClientRequest.new(request)
|
61
61
|
expect(driven_request.calculated_md5).to eq('1B2M2Y8AsgTpgAmY7PhCfg==')
|
@@ -66,9 +66,9 @@ describe ApiAuth::RequestDrivers::RestClientRequest do
|
|
66
66
|
context 'when put request' do
|
67
67
|
let(:request) do
|
68
68
|
RestClient::Request.new(
|
69
|
-
:
|
70
|
-
:
|
71
|
-
:
|
69
|
+
url: '/resource.xml?foo=bar&bar=foo',
|
70
|
+
headers: request_headers,
|
71
|
+
method: :put
|
72
72
|
)
|
73
73
|
end
|
74
74
|
|
@@ -80,9 +80,9 @@ describe ApiAuth::RequestDrivers::RestClientRequest do
|
|
80
80
|
context 'when get request' do
|
81
81
|
let(:request) do
|
82
82
|
RestClient::Request.new(
|
83
|
-
:
|
84
|
-
:
|
85
|
-
:
|
83
|
+
url: '/resource.xml?foo=bar&bar=foo',
|
84
|
+
headers: request_headers,
|
85
|
+
method: :get
|
86
86
|
)
|
87
87
|
end
|
88
88
|
|
@@ -104,9 +104,9 @@ describe ApiAuth::RequestDrivers::RestClientRequest do
|
|
104
104
|
context 'when getting' do
|
105
105
|
let(:request) do
|
106
106
|
RestClient::Request.new(
|
107
|
-
:
|
108
|
-
:
|
109
|
-
:
|
107
|
+
url: '/resource.xml?foo=bar&bar=foo',
|
108
|
+
headers: request_headers,
|
109
|
+
method: :get
|
110
110
|
)
|
111
111
|
end
|
112
112
|
|
@@ -119,10 +119,10 @@ describe ApiAuth::RequestDrivers::RestClientRequest do
|
|
119
119
|
context 'when posting' do
|
120
120
|
let(:request) do
|
121
121
|
RestClient::Request.new(
|
122
|
-
:
|
123
|
-
:
|
124
|
-
:
|
125
|
-
:
|
122
|
+
url: '/resource.xml?foo=bar&bar=foo',
|
123
|
+
headers: request_headers,
|
124
|
+
method: :post,
|
125
|
+
payload: "hello\nworld"
|
126
126
|
)
|
127
127
|
end
|
128
128
|
|
@@ -140,10 +140,10 @@ describe ApiAuth::RequestDrivers::RestClientRequest do
|
|
140
140
|
context 'when putting' do
|
141
141
|
let(:request) do
|
142
142
|
RestClient::Request.new(
|
143
|
-
:
|
144
|
-
:
|
145
|
-
:
|
146
|
-
:
|
143
|
+
url: '/resource.xml?foo=bar&bar=foo',
|
144
|
+
headers: request_headers,
|
145
|
+
method: :put,
|
146
|
+
payload: "hello\nworld"
|
147
147
|
)
|
148
148
|
end
|
149
149
|
|
@@ -161,9 +161,9 @@ describe ApiAuth::RequestDrivers::RestClientRequest do
|
|
161
161
|
context 'when deleting' do
|
162
162
|
let(:request) do
|
163
163
|
RestClient::Request.new(
|
164
|
-
:
|
165
|
-
:
|
166
|
-
:
|
164
|
+
url: '/resource.xml?foo=bar&bar=foo',
|
165
|
+
headers: request_headers,
|
166
|
+
method: :delete
|
167
167
|
)
|
168
168
|
end
|
169
169
|
|
@@ -203,9 +203,9 @@ describe ApiAuth::RequestDrivers::RestClientRequest do
|
|
203
203
|
context 'when getting' do
|
204
204
|
let(:request) do
|
205
205
|
RestClient::Request.new(
|
206
|
-
:
|
207
|
-
:
|
208
|
-
:
|
206
|
+
url: '/resource.xml?foo=bar&bar=foo',
|
207
|
+
headers: request_headers,
|
208
|
+
method: :get
|
209
209
|
)
|
210
210
|
end
|
211
211
|
|
@@ -217,10 +217,10 @@ describe ApiAuth::RequestDrivers::RestClientRequest do
|
|
217
217
|
context 'when posting' do
|
218
218
|
let(:request) do
|
219
219
|
RestClient::Request.new(
|
220
|
-
:
|
221
|
-
:
|
222
|
-
:
|
223
|
-
:
|
220
|
+
url: '/resource.xml?foo=bar&bar=foo',
|
221
|
+
headers: request_headers,
|
222
|
+
method: :post,
|
223
|
+
payload: "hello\nworld"
|
224
224
|
)
|
225
225
|
end
|
226
226
|
|
@@ -258,10 +258,10 @@ describe ApiAuth::RequestDrivers::RestClientRequest do
|
|
258
258
|
context 'when putting' do
|
259
259
|
let(:request) do
|
260
260
|
RestClient::Request.new(
|
261
|
-
:
|
262
|
-
:
|
263
|
-
:
|
264
|
-
:
|
261
|
+
url: '/resource.xml?foo=bar&bar=foo',
|
262
|
+
headers: request_headers,
|
263
|
+
method: :put,
|
264
|
+
payload: "hello\nworld"
|
265
265
|
)
|
266
266
|
end
|
267
267
|
|
@@ -299,9 +299,9 @@ describe ApiAuth::RequestDrivers::RestClientRequest do
|
|
299
299
|
context 'when deleting' do
|
300
300
|
let(:request) do
|
301
301
|
RestClient::Request.new(
|
302
|
-
:
|
303
|
-
:
|
304
|
-
:
|
302
|
+
url: '/resource.xml?foo=bar&bar=foo',
|
303
|
+
headers: request_headers,
|
304
|
+
method: :delete
|
305
305
|
)
|
306
306
|
end
|
307
307
|
|
@@ -316,10 +316,9 @@ describe ApiAuth::RequestDrivers::RestClientRequest do
|
|
316
316
|
headers = { 'Content-MD5' => 'e59ff97941044f85df5297e1c302d260',
|
317
317
|
:content_type => 'text/plain',
|
318
318
|
'Date' => 'Mon, 23 Jan 1984 03:29:56 GMT' }
|
319
|
-
request = RestClient::Request.new(:
|
320
|
-
:
|
321
|
-
:
|
322
|
-
headers = ApiAuth::Headers.new(request)
|
319
|
+
request = RestClient::Request.new(url: '/resource.xml?foo=bar&bar=foo',
|
320
|
+
headers: headers,
|
321
|
+
method: :put)
|
323
322
|
ApiAuth.sign!(request, 'some access id', 'some secret key')
|
324
323
|
expect(request.processed_headers).to have_key('Content-Type')
|
325
324
|
end
|