apill 4.0.1 → 4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 03e1a8c3d7621029eab5a87a4180786a121230f9
4
- data.tar.gz: 434bd913e8c60b006c33f4144a22a5ac5917ae28
3
+ metadata.gz: e1641afa6f8ba1b4980f0fa413f0d5a52fb95985
4
+ data.tar.gz: e0604ba7685db87663373263f091c5f166911cbd
5
5
  SHA512:
6
- metadata.gz: b9ac29a6cc63975df8d0b54b3b369fd54be33c675a81fad922221877c65812cf681d40346363c4b249341e3b91e78d8bc0b012c25e095a9be01a2d8a3340995a
7
- data.tar.gz: 79b641b0689d7ae9e4c2ed79f17c370b212ac775ae09a701e5c6563901d291088b9f8be4ce63cd19dc7052d1f72d3730467b503ecda8e25bf6f433b24be095ff
6
+ metadata.gz: 6f642704c7502d12a6f4404b7eea14df91cbcce17f2ad14f8cdb8d0e767ad985d79ccf3ba4a192d048742c0565415896d52f89e9c043b7f07091dd9bb2d8edaf
7
+ data.tar.gz: 463965f01869807e112368b3cd1208585697802d3170ff9facc6d04d6b5f5f07c836f18f2c184cdc7b2b6d5b9a9217cb3256118f2e80e6244a047f1e9344e77c
@@ -10,11 +10,13 @@ require 'apill/responses/invalid_token'
10
10
  module Apill
11
11
  module Middleware
12
12
  class ApiRequest
13
+ JSON_API_MIME_TYPE_PATTERN = %r{application/vnd\.api\+json(?=\z|;)}
14
+
13
15
  def initialize(app)
14
16
  @app = app
15
17
  end
16
18
 
17
- # rubocop:disable Metrics/LineLength
19
+ # rubocop:disable Metrics/LineLength, Metrics/AbcSize
18
20
  def call(env)
19
21
  env['HTTP_X_APPLICATION_NAME'] = Apill.configuration.application_name
20
22
 
@@ -23,21 +25,23 @@ class ApiRequest
23
25
  accept_header_matcher = Matchers::AcceptHeader.new
24
26
  token = request.authorization_token
25
27
 
26
- return Responses::InvalidSubdomain.call(env) unless subdomain_matcher.matches?(request)
27
- return Responses::InvalidApiRequest.call(env) unless !subdomain_matcher.matches_api_subdomain?(request) ||
28
- accept_header_matcher.matches?(request)
29
- return Responses::InvalidToken.call(env) unless token.valid?
30
-
31
- env['HTTP_X_JSON_WEB_TOKEN'] = token.to_h
32
- env['QUERY_STRING'] = Parameters.process(env['QUERY_STRING'])
28
+ return Responses::InvalidSubdomain.call(env) unless subdomain_matcher.matches?(request)
29
+ return Responses::InvalidApiRequest.call(env) unless !subdomain_matcher.matches_api_subdomain?(request) ||
30
+ accept_header_matcher.matches?(request)
31
+ return Responses::InvalidToken.call(env,
32
+ application_name: request.application_name) \
33
+ unless token.valid?
33
34
 
34
- if env['CONTENT_TYPE'] == 'application/vnd.api+json'
35
- env['CONTENT_TYPE'] = 'application/json'
36
- end
35
+ env['X_DECRYPTED_JSON_WEB_TOKEN'] = token.to_h
36
+ env['QUERY_STRING'] = Parameters.process(env['QUERY_STRING'])
37
+ env['CONTENT_TYPE'] = env['CONTENT_TYPE'].
38
+ to_s.
39
+ gsub! JSON_API_MIME_TYPE_PATTERN,
40
+ 'application/json'
37
41
 
38
42
  @app.call(env)
39
43
  end
40
- # rubocop:enable Metrics/LineLength
44
+ # rubocop:enable Metrics/LineLength, Metrics/AbcSize
41
45
  end
42
46
  end
43
47
  end
@@ -51,7 +51,9 @@ class Base
51
51
  end
52
52
 
53
53
  def self.resolve(original_request)
54
- if original_request.respond_to? :headers
54
+ if original_request.is_a? self
55
+ original_request
56
+ elsif original_request.respond_to? :headers
55
57
  rails_request_class.new(request: original_request)
56
58
  else
57
59
  rack_request_class.new(request: original_request)
@@ -3,12 +3,14 @@ require 'apill/errors/invalid_token'
3
3
  module Apill
4
4
  module Responses
5
5
  class InvalidToken
6
- def self.call(_env)
6
+ def self.call(_env, application_name:)
7
7
  error = Apill::Errors::InvalidToken.new
8
8
 
9
9
  [
10
10
  error.http_status, # HTTP Status Code
11
- {}, # Response Headers
11
+ { # Response Headers
12
+ 'WWW-Authenticate' => %Q{Token realm="#{application_name}"},
13
+ },
12
14
  [error.to_json], # Message
13
15
  ]
14
16
  end
@@ -14,7 +14,7 @@ class InvalidRequestAuthorization
14
14
  end
15
15
 
16
16
  def to_h
17
- {}
17
+ [{}, {}]
18
18
  end
19
19
  end
20
20
  end
@@ -14,7 +14,7 @@ class NullRequestAuthorization
14
14
  end
15
15
 
16
16
  def to_h
17
- {}
17
+ [{}, {}]
18
18
  end
19
19
  end
20
20
  end
data/lib/apill/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Apill
2
- VERSION = '4.0.1'.freeze
2
+ VERSION = '4.0.2'.freeze
3
3
  end
@@ -15,10 +15,10 @@ describe InvalidToken, singletons: HumanError::Configuration do
15
15
  }
16
16
 
17
17
  request = { 'HTTP_HOST' => 'api.example.com' }
18
- status, headers, response = InvalidToken.call(request)
18
+ status, headers, response = InvalidToken.call(request, application_name: 'my_app')
19
19
 
20
20
  expect(status).to eql 401
21
- expect(headers).to eql({})
21
+ expect(headers).to eql('WWW-Authenticate' => 'Token realm="my_app"')
22
22
  expect(JSON.load(response[0])).to include(
23
23
  'errors' => [
24
24
  include(
@@ -177,6 +177,42 @@ describe ApiRequest, singletons: HumanError::Configuration do
177
177
  'nice_to_meet=you-bob&' \
178
178
  'hows_the_weather=today-bob'
179
179
  end
180
+
181
+ it 'properly converts the content type for Rails when it is the only one' do
182
+ api_request_middleware = ApiRequest.new(app)
183
+
184
+ request = {
185
+ 'CONTENT_TYPE' => 'application/vnd.api+json',
186
+ 'HTTP_HOST' => 'matrix.example.com',
187
+ 'HTTP_ACCEPT' => '',
188
+ 'QUERY_STRING' => '',
189
+ }
190
+
191
+ allow(app).to receive(:call)
192
+
193
+ _response = api_request_middleware.call(request)
194
+
195
+ expect(app).to have_received(:call).
196
+ with(a_hash_including('CONTENT_TYPE' => 'application/json'))
197
+ end
198
+
199
+ it 'properly converts the content type for Rails when it is not the only one' do
200
+ api_request_middleware = ApiRequest.new(app)
201
+
202
+ request = {
203
+ 'CONTENT_TYPE' => 'application/vnd.api+json;other',
204
+ 'HTTP_HOST' => 'matrix.example.com',
205
+ 'HTTP_ACCEPT' => '',
206
+ 'QUERY_STRING' => '',
207
+ }
208
+
209
+ allow(app).to receive(:call)
210
+
211
+ _response = api_request_middleware.call(request)
212
+
213
+ expect(app).to have_received(:call).
214
+ with(a_hash_including('CONTENT_TYPE' => 'application/json;other'))
215
+ end
180
216
  end
181
217
  end
182
218
  end
@@ -0,0 +1,35 @@
1
+ require 'ostruct'
2
+ require 'spec_helper'
3
+ require 'apill/requests/base'
4
+
5
+ module Apill
6
+ module Requests
7
+ describe Base do
8
+ it 'can resolve itself by returning itself' do
9
+ raw_request = Base.new(token_private_key: '', request: {})
10
+ resolved_request = Base.resolve(raw_request)
11
+
12
+ expect(resolved_request).to eql raw_request
13
+ end
14
+
15
+ it 'can resolve a Rails request' do
16
+ raw_request = OpenStruct.new(
17
+ headers: {},
18
+ params: {})
19
+ resolved_request = Base.resolve(raw_request)
20
+
21
+ expect(resolved_request).to be_a Requests::Rails
22
+ end
23
+
24
+ it 'can resolve a Rack request' do
25
+ raw_request = {
26
+ 'HTTP_ACCEPT' => 'accept_string',
27
+ 'QUERY_STRING' => '',
28
+ }
29
+ resolved_request = Base.resolve(raw_request)
30
+
31
+ expect(resolved_request).to be_a Requests::Rack
32
+ end
33
+ end
34
+ end
35
+ end
@@ -77,7 +77,7 @@ describe Rack do
77
77
  request: raw_request)
78
78
 
79
79
  expect(request.authorization_token).not_to be_valid
80
- expect(request.authorization_token.to_h).to eql({})
80
+ expect(request.authorization_token.to_h).to eql([{}, {}])
81
81
  end
82
82
 
83
83
  it 'finds the authorization token from the params if the authorization token from ' \
@@ -123,7 +123,7 @@ describe Rack do
123
123
  request: raw_request)
124
124
 
125
125
  expect(request.authorization_token).to be_valid
126
- expect(request.authorization_token.to_h).to eql({})
126
+ expect(request.authorization_token.to_h).to eql([{}, {}])
127
127
  end
128
128
 
129
129
  it 'finds the authorization token from the params' do
@@ -69,7 +69,7 @@ describe Rails do
69
69
  request: raw_request)
70
70
 
71
71
  expect(request.authorization_token).not_to be_valid
72
- expect(request.authorization_token.to_h).to eql({})
72
+ expect(request.authorization_token.to_h).to eql([{}, {}])
73
73
  end
74
74
 
75
75
  it 'finds the authorization token from the params if the authorization token from ' \
@@ -116,7 +116,7 @@ describe Rails do
116
116
  request: raw_request)
117
117
 
118
118
  expect(request.authorization_token).to be_valid
119
- expect(request.authorization_token.to_h).to eql({})
119
+ expect(request.authorization_token.to_h).to eql([{}, {}])
120
120
  end
121
121
 
122
122
  it 'finds the authorization token from the params' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apill
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.1
4
+ version: 4.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - jfelchner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-19 00:00:00.000000000 Z
11
+ date: 2015-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: human_error
@@ -134,6 +134,7 @@ files:
134
134
  - spec/apill/matchers/version_spec.rb
135
135
  - spec/apill/middleware/api_request_spec.rb
136
136
  - spec/apill/parameters_spec.rb
137
+ - spec/apill/requests/base_spec.rb
137
138
  - spec/apill/requests/rack_spec.rb
138
139
  - spec/apill/requests/rails_spec.rb
139
140
  - spec/apill/resource/model_spec.rb
@@ -182,6 +183,7 @@ test_files:
182
183
  - spec/apill/matchers/version_spec.rb
183
184
  - spec/apill/middleware/api_request_spec.rb
184
185
  - spec/apill/parameters_spec.rb
186
+ - spec/apill/requests/base_spec.rb
185
187
  - spec/apill/requests/rack_spec.rb
186
188
  - spec/apill/requests/rails_spec.rb
187
189
  - spec/apill/resource/model_spec.rb