apill 4.0.3 → 4.1.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: f77db3956c72054749629446e1d098d3f7f97e64
4
- data.tar.gz: 52ab14155d33d4c52c11a71c50e6aa40abbcbaae
3
+ metadata.gz: 905997a468c58168a9f87fbae4df382ced3cc1fd
4
+ data.tar.gz: d354947d9ca949dadaad2d25969c5f7865b0652c
5
5
  SHA512:
6
- metadata.gz: b069207e88d408c5c88c5ee0389e5f61a04dc46b6403d8d7464c826ecb7a999cb7c1f9b567dd236376682d7d67e7d92a55555dde65ce803dacaaf2a25fc1f7eb
7
- data.tar.gz: 5920fac6396a11314058a7837f7fb01138f4d31bece28ac8fe4e028952ea4e273feab24fc7322d3c2796ea7bf73e35bf3c223703e40cd203ce61a2e441b10d57
6
+ metadata.gz: a8576261ae11512401546d1b2e22b6e435921ab67ec2efce00e0ddeabcfff846522d1a2b918dbeff6c7175166004aee450db10eb6fed6cd136487c6c568b867e
7
+ data.tar.gz: fdd74cbe6f6245d3b6caa3b730487cbbf04bb0c80c08deecc5a5dab7b84f216fe403732142191d57892a0313d2a65515b30c18474e6a41d5b388b9b1a249192a
@@ -9,13 +9,13 @@ class Subdomain
9
9
  end
10
10
 
11
11
  def matches?(request)
12
- self.request = request
12
+ self.request = Requests::Base.resolve(request)
13
13
 
14
14
  allowed_subdomains.include? request.subdomain
15
15
  end
16
16
 
17
17
  def matches_api_subdomain?(request)
18
- self.request = request
18
+ self.request = Requests::Base.resolve(request)
19
19
 
20
20
  allowed_api_subdomains.include? request.subdomain
21
21
  end
@@ -1,10 +1,15 @@
1
- require 'apill/tokens/invalid_request_authorization'
2
- require 'apill/tokens/request_authorization'
1
+ require 'apill/tokens/json_web_tokens/invalid'
2
+ require 'apill/tokens/json_web_token'
3
3
 
4
4
  module Apill
5
5
  module Requests
6
6
  class Base
7
- TOKEN_PATTERN = %r{\A(?:Token ([A-Za-z0-9_/\+\=\-\.]+))?\z}
7
+ BASE64_PATTERN = %r{[A-Za-z0-9_/\+\=\-\.]}
8
+ BASE64_TOKEN_PARAM_NAME = 'token_b64'.freeze
9
+ JSON_WEB_TOKEN_PARAM_NAME = 'token_jwt'.freeze
10
+ JSON_WEB_TOKEN_PATTERN = /(#{BASE64_PATTERN}+?\.){4}#{BASE64_PATTERN}+?/
11
+ BASE64_TOKEN_HEADER_PATTERN = /\A(?:Basic|Bearer)\s+(.*)\z/
12
+ JSON_WEB_TOKEN_HEADER_PATTERN = /\AToken\s+(.*)\z/
8
13
 
9
14
  attr_accessor :token_private_key,
10
15
  :request
@@ -85,18 +90,17 @@ class Base
85
90
  end
86
91
 
87
92
  def authorization_token_from_header
88
- return Tokens::InvalidRequestAuthorization.instance \
89
- unless raw_authorization_header.match(TOKEN_PATTERN)
90
-
91
- Tokens::RequestAuthorization.convert(
92
- token_private_key: token_private_key,
93
- raw_token: raw_authorization_token_from_header || '')
94
- end
95
-
96
- def authorization_token_from_params
97
- Tokens::RequestAuthorization.convert(
98
- token_private_key: token_private_key,
99
- raw_token: raw_authorization_token_from_params || '')
93
+ case raw_authorization_header
94
+ when JSON_WEB_TOKEN_HEADER_PATTERN
95
+ Tokens::JsonWebToken.convert(
96
+ token_private_key: token_private_key,
97
+ raw_token: raw_authorization_header[JSON_WEB_TOKEN_HEADER_PATTERN, 1])
98
+ when BASE64_TOKEN_HEADER_PATTERN
99
+ Tokens::Base64.convert(
100
+ raw_token: raw_authorization_header[BASE64_TOKEN_HEADER_PATTERN, 1])
101
+ else
102
+ Tokens::Null.instance
103
+ end
100
104
  end
101
105
 
102
106
  private
@@ -104,10 +108,6 @@ class Base
104
108
  def raw_host
105
109
  request.fetch('HTTP_HOST', '')
106
110
  end
107
-
108
- def raw_authorization_token_from_header
109
- raw_authorization_header[TOKEN_PATTERN, 1] || ''
110
- end
111
111
  end
112
112
  end
113
113
  end
@@ -1,12 +1,31 @@
1
1
  require 'apill/configuration'
2
2
  require 'apill/requests/base'
3
3
  require 'apill/accept_header'
4
+ require 'apill/tokens/json_web_token'
5
+ require 'apill/tokens/base64'
4
6
 
5
7
  module Apill
6
8
  module Requests
7
9
  class Rack < Base
8
- ACCEPT_PARAM_PATTERN = /(?:\A|&)accept=(.+?)(?=\z|&)/
9
- AUTH_TOKEN_PARAM_PATTERN = /(?:\A|&)auth_token=(.+?)(?=\z|&)/
10
+ ACCEPT_PARAM_PATTERN = /(?:\A|&)accept=(.+?)(?=\z|&)/
11
+ BASE64_TOKEN_PARAM_PATTERN = /(?:\A|&)#{BASE64_TOKEN_PARAM_NAME}=(.*)(?=\z|&)/
12
+ JSON_WEB_TOKEN_PARAM_PATTERN = /(?:\A|&)#{JSON_WEB_TOKEN_PARAM_NAME}=(.*)(?=\z|&)/
13
+
14
+ def authorization_token_from_params
15
+ case request['QUERY_STRING']
16
+ when JSON_WEB_TOKEN_PARAM_PATTERN
17
+ Tokens::JsonWebToken.convert(
18
+ token_private_key: token_private_key,
19
+ raw_token: request['QUERY_STRING'][JSON_WEB_TOKEN_PARAM_PATTERN, 1] || '',
20
+ )
21
+ when BASE64_TOKEN_PARAM_PATTERN
22
+ base64_token = request['QUERY_STRING'][BASE64_TOKEN_PARAM_PATTERN, 1]
23
+
24
+ Tokens::Base64.convert(raw_token: base64_token)
25
+ else
26
+ Tokens::Null.instance
27
+ end
28
+ end
10
29
 
11
30
  private
12
31
 
@@ -22,10 +41,6 @@ class Rack < Base
22
41
  request['HTTP_AUTHORIZATION'] || ''
23
42
  end
24
43
 
25
- def raw_authorization_token_from_params
26
- URI.unescape(request['QUERY_STRING'][AUTH_TOKEN_PARAM_PATTERN, 1] || '')
27
- end
28
-
29
44
  def raw_request_application_name
30
45
  request['HTTP_X_APPLICATION_NAME']
31
46
  end
@@ -1,10 +1,25 @@
1
1
  require 'apill/configuration'
2
2
  require 'apill/requests/base'
3
3
  require 'apill/accept_header'
4
+ require 'apill/tokens/json_web_token'
5
+ require 'apill/tokens/base64'
4
6
 
5
7
  module Apill
6
8
  module Requests
7
9
  class Rails < Base
10
+ def authorization_token_from_params
11
+ case
12
+ when request.params.key?(JSON_WEB_TOKEN_PARAM_NAME)
13
+ Tokens::JsonWebToken.convert(
14
+ token_private_key: token_private_key,
15
+ raw_token: request.params[JSON_WEB_TOKEN_PARAM_NAME] || '')
16
+ when request.params.key?(BASE64_TOKEN_PARAM_NAME)
17
+ Tokens::Base64.convert(raw_token: request.params[BASE64_TOKEN_PARAM_NAME] || '')
18
+ else
19
+ Tokens::Null.instance
20
+ end
21
+ end
22
+
8
23
  private
9
24
 
10
25
  def raw_accept_header_from_header
@@ -19,10 +34,6 @@ class Rails < Base
19
34
  request.headers['HTTP_AUTHORIZATION'] || ''
20
35
  end
21
36
 
22
- def raw_authorization_token_from_params
23
- request.params['auth_token'] || ''
24
- end
25
-
26
37
  def raw_request_application_name
27
38
  request.headers['X-Application-Name']
28
39
  end
@@ -0,0 +1,44 @@
1
+ require 'base64'
2
+ require 'apill/tokens/base64s/null'
3
+ require 'apill/tokens/base64s/invalid'
4
+
5
+ module Apill
6
+ module Tokens
7
+ class Base64
8
+ attr_accessor :token
9
+
10
+ def initialize(token:)
11
+ self.token = token
12
+ end
13
+
14
+ def valid?
15
+ true
16
+ end
17
+
18
+ def blank?
19
+ false
20
+ end
21
+
22
+ def to_h
23
+ [
24
+ {
25
+ 'token' => token,
26
+ },
27
+ {
28
+ 'typ' => 'base64',
29
+ },
30
+ ]
31
+ end
32
+
33
+ def self.convert(raw_token:)
34
+ return Base64s::Null.instance if raw_token.to_s == ''
35
+
36
+ ::Base64.strict_decode64(raw_token)
37
+
38
+ new(token: raw_token)
39
+ rescue ArgumentError
40
+ Base64s::Invalid.instance
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,13 @@
1
+ require 'apill/tokens/invalid'
2
+
3
+ module Apill
4
+ module Tokens
5
+ module Base64s
6
+ class Invalid < Tokens::Invalid
7
+ def to_h
8
+ [{}, {}]
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require 'apill/tokens/null'
2
+
3
+ module Apill
4
+ module Tokens
5
+ module Base64s
6
+ class Null < Tokens::Null
7
+ def to_h
8
+ [{}, {}]
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -2,7 +2,7 @@ require 'singleton'
2
2
 
3
3
  module Apill
4
4
  module Tokens
5
- class InvalidRequestAuthorization
5
+ class Invalid
6
6
  include Singleton
7
7
 
8
8
  def valid?
@@ -14,7 +14,11 @@ class InvalidRequestAuthorization
14
14
  end
15
15
 
16
16
  def to_h
17
- [{}, {}]
17
+ {}
18
+ end
19
+
20
+ def to_s
21
+ ''
18
22
  end
19
23
  end
20
24
  end
@@ -1,11 +1,11 @@
1
1
  require 'jwt'
2
2
  require 'json/jwt'
3
- require 'apill/tokens/invalid_request_authorization'
4
- require 'apill/tokens/null_request_authorization'
3
+ require 'apill/tokens/json_web_tokens/invalid'
4
+ require 'apill/tokens/json_web_tokens/null'
5
5
 
6
6
  module Apill
7
7
  module Tokens
8
- class RequestAuthorization
8
+ class JsonWebToken
9
9
  attr_accessor :token
10
10
 
11
11
  def initialize(token:)
@@ -25,7 +25,7 @@ class RequestAuthorization
25
25
  end
26
26
 
27
27
  def self.convert(raw_token:, token_private_key: Apill.configuration.token_private_key)
28
- return NullRequestAuthorization.instance if raw_token.to_s == ''
28
+ return JsonWebTokens::Null.instance if raw_token.to_s == ''
29
29
 
30
30
  decrypted_token = JSON::JWT.decode(raw_token, token_private_key).plain_text
31
31
  decoded_token = JWT.decode(decrypted_token,
@@ -55,7 +55,7 @@ class RequestAuthorization
55
55
  JWT::InvalidJtiError,
56
56
  OpenSSL::PKey::RSAError
57
57
 
58
- InvalidRequestAuthorization.instance
58
+ JsonWebTokens::Invalid.instance
59
59
  end
60
60
  end
61
61
  end
@@ -0,0 +1,13 @@
1
+ require 'apill/tokens/invalid'
2
+
3
+ module Apill
4
+ module Tokens
5
+ module JsonWebTokens
6
+ class Invalid < Tokens::Invalid
7
+ def to_h
8
+ [{}, {}]
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require 'apill/tokens/null'
2
+
3
+ module Apill
4
+ module Tokens
5
+ module JsonWebTokens
6
+ class Null < Tokens::Null
7
+ def to_h
8
+ [{}, {}]
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -2,7 +2,7 @@ require 'singleton'
2
2
 
3
3
  module Apill
4
4
  module Tokens
5
- class NullRequestAuthorization
5
+ class Null
6
6
  include Singleton
7
7
 
8
8
  def valid?
@@ -16,6 +16,10 @@ class NullRequestAuthorization
16
16
  def to_h
17
17
  [{}, {}]
18
18
  end
19
+
20
+ def to_s
21
+ ''
22
+ end
19
23
  end
20
24
  end
21
25
  end
@@ -1,3 +1,3 @@
1
1
  module Apill
2
- VERSION = '4.0.3'.freeze
2
+ VERSION = '4.1.0'.freeze
3
3
  end
@@ -132,7 +132,7 @@ describe ApiRequest, singletons: HumanError::Configuration do
132
132
  request = {
133
133
  'HTTP_HOST' => 'api.example.com',
134
134
  'HTTP_ACCEPT' => 'application/vnd.matrix+zion;version=1.0.0',
135
- 'HTTP_AUTHORIZATION' => "Token #{valid_token}",
135
+ 'HTTP_AUTHORIZATION' => "Token #{valid_jwt_token}",
136
136
  'QUERY_STRING' => 'accept=application/vnd.matrix+zion;version=1.0.0',
137
137
  }
138
138
 
@@ -150,7 +150,7 @@ describe ApiRequest, singletons: HumanError::Configuration do
150
150
  request = {
151
151
  'HTTP_HOST' => 'api.example.com',
152
152
  'HTTP_ACCEPT' => 'application/vnd.matrix+zion;version=1.0.0',
153
- 'HTTP_AUTHORIZATION' => "Token #{invalid_token}",
153
+ 'HTTP_AUTHORIZATION' => "Token #{invalid_jwt_token}",
154
154
  'QUERY_STRING' => 'accept=application/vnd.matrix+zion;version=1.0.0',
155
155
  }
156
156
 
@@ -54,7 +54,7 @@ describe Rack do
54
54
 
55
55
  it 'finds the authorization token from the header' do
56
56
  raw_request = {
57
- 'HTTP_AUTHORIZATION' => "Token #{valid_token}",
57
+ 'HTTP_AUTHORIZATION' => "Token #{valid_jwt_token}",
58
58
  'QUERY_STRING' => '',
59
59
  }
60
60
  request = Rack.new(token_private_key: test_private_key,
@@ -68,24 +68,52 @@ describe Rack do
68
68
  ])
69
69
  end
70
70
 
71
- it 'can process an authorization token if it is sent through incorrectly' do
71
+ it 'finds the Base64 token from the header' do
72
72
  raw_request = {
73
- 'HTTP_AUTHORIZATION' => "#{valid_token}",
73
+ 'HTTP_AUTHORIZATION' => "Basic #{valid_b64_token}",
74
74
  'QUERY_STRING' => '',
75
75
  }
76
76
  request = Rack.new(token_private_key: test_private_key,
77
77
  request: raw_request)
78
78
 
79
- expect(request.authorization_token).not_to be_valid
80
- expect(request.authorization_token.to_h).to eql([{}, {}])
79
+ expect(request.authorization_token).to be_valid
80
+ expect(request.authorization_token.to_h).to eql(
81
+ [
82
+ { 'token' => valid_b64_token },
83
+ { 'typ' => 'base64' },
84
+ ])
85
+ end
86
+
87
+ it 'finds a null token from the header if there is no header' do
88
+ raw_request = {
89
+ 'HTTP_AUTHORIZATION' => '',
90
+ 'QUERY_STRING' => '',
91
+ }
92
+ request = Rack.new(token_private_key: test_private_key,
93
+ request: raw_request)
94
+
95
+ expect(request.authorization_token).to be_valid
96
+ expect(request.authorization_token).to be_blank
97
+ end
98
+
99
+ it 'ignores incorrectly passed in tokens since we do not know what to do' do
100
+ raw_request = {
101
+ 'HTTP_AUTHORIZATION' => "#{valid_jwt_token}",
102
+ 'QUERY_STRING' => '',
103
+ }
104
+ request = Rack.new(token_private_key: test_private_key,
105
+ request: raw_request)
106
+
107
+ expect(request.authorization_token).to be_valid
108
+ expect(request.authorization_token).to be_blank
81
109
  end
82
110
 
83
111
  it 'finds the authorization token from the params if the authorization token from ' \
84
112
  'the header is invalid and the authorization token from the params is valid' do
85
113
 
86
114
  raw_request = {
87
- 'HTTP_AUTHORIZATION' => "Token #{invalid_token}",
88
- 'QUERY_STRING' => "auth_token=#{valid_token}",
115
+ 'HTTP_AUTHORIZATION' => "Token #{invalid_jwt_token}",
116
+ 'QUERY_STRING' => "token_jwt=#{valid_jwt_token}",
89
117
  }
90
118
  request = Rack.new(token_private_key: test_private_key,
91
119
  request: raw_request)
@@ -102,7 +130,7 @@ describe Rack do
102
130
  'the header is not present and the authorization token from the params is valid' do
103
131
 
104
132
  raw_request = {
105
- 'QUERY_STRING' => "auth_token=#{valid_token}",
133
+ 'QUERY_STRING' => "token_jwt=#{valid_jwt_token}",
106
134
  }
107
135
  request = Rack.new(token_private_key: test_private_key,
108
136
  request: raw_request)
@@ -126,9 +154,9 @@ describe Rack do
126
154
  expect(request.authorization_token.to_h).to eql([{}, {}])
127
155
  end
128
156
 
129
- it 'finds the authorization token from the params' do
157
+ it 'finds the JSON web token from the params' do
130
158
  raw_request = {
131
- 'QUERY_STRING' => "auth_token=#{valid_token}",
159
+ 'QUERY_STRING' => "token_jwt=#{valid_jwt_token}",
132
160
  }
133
161
  request = Rack.new(token_private_key: test_private_key,
134
162
  request: raw_request)
@@ -141,6 +169,65 @@ describe Rack do
141
169
  ])
142
170
  end
143
171
 
172
+ it 'finds the generic Base64 web token from the params' do
173
+ raw_request = {
174
+ 'QUERY_STRING' => "token_b64=#{valid_b64_token}",
175
+ }
176
+ request = Rack.new(request: raw_request)
177
+
178
+ expect(request.authorization_token).to be_valid
179
+ expect(request.authorization_token.to_h).to eql(
180
+ [
181
+ { 'token' => valid_b64_token },
182
+ { 'typ' => 'base64' },
183
+ ])
184
+ end
185
+
186
+ it 'finds invalid tokens from the params' do
187
+ raw_request = {
188
+ 'QUERY_STRING' => 'token_b64=bla.h',
189
+ }
190
+ request = Rack.new(request: raw_request)
191
+
192
+ expect(request.authorization_token_from_params).not_to be_valid
193
+ expect(request.authorization_token_from_params).not_to be_blank
194
+
195
+ raw_request = {
196
+ 'QUERY_STRING' => "token_jwt=#{invalid_jwt_token}",
197
+ }
198
+ request = Rack.new(token_private_key: test_private_key,
199
+ request: raw_request)
200
+
201
+ expect(request.authorization_token_from_params).not_to be_valid
202
+ expect(request.authorization_token_from_params).not_to be_blank
203
+ end
204
+
205
+ it 'finds the null token from the params if nothing is passed in' do
206
+ raw_request = {
207
+ 'QUERY_STRING' => 'token_b64=',
208
+ }
209
+ request = Rack.new(request: raw_request)
210
+
211
+ expect(request.authorization_token_from_params).to be_valid
212
+ expect(request.authorization_token_from_params).to be_blank
213
+
214
+ raw_request = {
215
+ 'QUERY_STRING' => 'token_jwt=',
216
+ }
217
+ request = Rack.new(request: raw_request)
218
+
219
+ expect(request.authorization_token_from_params).to be_valid
220
+ expect(request.authorization_token_from_params).to be_blank
221
+
222
+ raw_request = {
223
+ 'QUERY_STRING' => '',
224
+ }
225
+ request = Rack.new(request: raw_request)
226
+
227
+ expect(request.authorization_token_from_params).to be_valid
228
+ expect(request.authorization_token_from_params).to be_blank
229
+ end
230
+
144
231
  it 'defaults to the application name in the configuration if none is found in ' \
145
232
  'the header' do
146
233
 
@@ -45,7 +45,7 @@ describe Rails do
45
45
  it 'finds the authorization token from the header' do
46
46
  raw_request = OpenStruct.new(
47
47
  headers: {
48
- 'HTTP_AUTHORIZATION' => "Token #{valid_token}",
48
+ 'HTTP_AUTHORIZATION' => "Token #{valid_jwt_token}",
49
49
  },
50
50
  params: {})
51
51
  request = Rails.new(token_private_key: test_private_key,
@@ -59,17 +59,45 @@ describe Rails do
59
59
  ])
60
60
  end
61
61
 
62
- it 'can process an authorization token if it is sent through incorrectly' do
62
+ it 'finds the Base64 token from the header' do
63
63
  raw_request = OpenStruct.new(
64
64
  headers: {
65
- 'HTTP_AUTHORIZATION' => "#{valid_token}",
65
+ 'HTTP_AUTHORIZATION' => "Basic #{valid_b64_token}",
66
66
  },
67
67
  params: {})
68
68
  request = Rails.new(token_private_key: test_private_key,
69
69
  request: raw_request)
70
70
 
71
- expect(request.authorization_token).not_to be_valid
72
- expect(request.authorization_token.to_h).to eql([{}, {}])
71
+ expect(request.authorization_token).to be_valid
72
+ expect(request.authorization_token.to_h).to eql(
73
+ [
74
+ { 'token' => valid_b64_token },
75
+ { 'typ' => 'base64' },
76
+ ])
77
+ end
78
+
79
+ it 'finds a null token from the header if there is no header' do
80
+ raw_request = OpenStruct.new(
81
+ headers: {},
82
+ params: {})
83
+ request = Rails.new(token_private_key: test_private_key,
84
+ request: raw_request)
85
+
86
+ expect(request.authorization_token).to be_valid
87
+ expect(request.authorization_token).to be_blank
88
+ end
89
+
90
+ it 'ignores incorrectly passed in tokens since we do not know what to do' do
91
+ raw_request = OpenStruct.new(
92
+ headers: {
93
+ 'HTTP_AUTHORIZATION' => "#{valid_jwt_token}",
94
+ },
95
+ params: {})
96
+ request = Rails.new(token_private_key: test_private_key,
97
+ request: raw_request)
98
+
99
+ expect(request.authorization_token).to be_valid
100
+ expect(request.authorization_token).to be_blank
73
101
  end
74
102
 
75
103
  it 'finds the authorization token from the params if the authorization token from ' \
@@ -77,9 +105,9 @@ describe Rails do
77
105
 
78
106
  raw_request = OpenStruct.new(
79
107
  headers: {
80
- 'HTTP_AUTHORIZATION' => "Token #{invalid_token}",
108
+ 'HTTP_AUTHORIZATION' => "Token #{invalid_jwt_token}",
81
109
  },
82
- params: { 'auth_token' => valid_token })
110
+ params: { 'token_jwt' => valid_jwt_token })
83
111
  request = Rails.new(token_private_key: test_private_key,
84
112
  request: raw_request)
85
113
 
@@ -96,7 +124,7 @@ describe Rails do
96
124
 
97
125
  raw_request = OpenStruct.new(
98
126
  headers: {},
99
- params: { 'auth_token' => valid_token })
127
+ params: { 'token_jwt' => valid_jwt_token })
100
128
  request = Rails.new(token_private_key: test_private_key,
101
129
  request: raw_request)
102
130
 
@@ -119,10 +147,10 @@ describe Rails do
119
147
  expect(request.authorization_token.to_h).to eql([{}, {}])
120
148
  end
121
149
 
122
- it 'finds the authorization token from the params' do
150
+ it 'finds the JSON web token from the params' do
123
151
  raw_request = OpenStruct.new(
124
152
  headers: {},
125
- params: { 'auth_token' => valid_token })
153
+ params: { 'token_jwt' => valid_jwt_token })
126
154
  request = Rails.new(token_private_key: test_private_key,
127
155
  request: raw_request)
128
156
 
@@ -134,6 +162,65 @@ describe Rails do
134
162
  ])
135
163
  end
136
164
 
165
+ it 'finds the generic Base64 web token from the params' do
166
+ raw_request = OpenStruct.new(
167
+ headers: {},
168
+ params: { 'token_b64' => valid_b64_token })
169
+ request = Rails.new(request: raw_request)
170
+
171
+ expect(request.authorization_token).to be_valid
172
+ expect(request.authorization_token.to_h).to eql(
173
+ [
174
+ { 'token' => valid_b64_token },
175
+ { 'typ' => 'base64' },
176
+ ])
177
+ end
178
+
179
+ it 'finds invalid tokens from the params' do
180
+ raw_request = OpenStruct.new(
181
+ headers: {},
182
+ params: { 'token_b64' => 'bla.h' })
183
+ request = Rails.new(request: raw_request)
184
+
185
+ expect(request.authorization_token_from_params).not_to be_valid
186
+ expect(request.authorization_token_from_params).not_to be_blank
187
+
188
+ raw_request = OpenStruct.new(
189
+ headers: {},
190
+ params: { 'token_jwt' => invalid_jwt_token })
191
+ request = Rails.new(token_private_key: test_private_key,
192
+ request: raw_request)
193
+
194
+ expect(request.authorization_token_from_params).not_to be_valid
195
+ expect(request.authorization_token_from_params).not_to be_blank
196
+ end
197
+
198
+ it 'finds the null token from the params if nothing is passed in' do
199
+ raw_request = OpenStruct.new(
200
+ headers: {},
201
+ params: { 'token_b64' => '' })
202
+ request = Rails.new(request: raw_request)
203
+
204
+ expect(request.authorization_token_from_params).to be_valid
205
+ expect(request.authorization_token_from_params).to be_blank
206
+
207
+ raw_request = OpenStruct.new(
208
+ headers: {},
209
+ params: { 'token_jwt' => '' })
210
+ request = Rails.new(request: raw_request)
211
+
212
+ expect(request.authorization_token_from_params).to be_valid
213
+ expect(request.authorization_token_from_params).to be_blank
214
+
215
+ raw_request = OpenStruct.new(
216
+ headers: {},
217
+ params: {})
218
+ request = Rails.new(request: raw_request)
219
+
220
+ expect(request.authorization_token_from_params).to be_valid
221
+ expect(request.authorization_token_from_params).to be_blank
222
+ end
223
+
137
224
  it 'defaults to the application name in the configuration if none is found in ' \
138
225
  'the header' do
139
226
 
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'apill/tokens/base64'
3
+
4
+ module Apill
5
+ module Tokens
6
+ describe Base64 do
7
+ it 'is valid' do
8
+ expect(Base64.new(token: 'foo')).to be_valid
9
+ end
10
+
11
+ it 'is not blank' do
12
+ expect(Base64.new(token: 'foo')).not_to be_blank
13
+ end
14
+
15
+ it 'can convert itself into a hash' do
16
+ token = Base64.new(token: 'foo')
17
+
18
+ expect(token.to_h).to eql([
19
+ {
20
+ 'token' => 'foo',
21
+ },
22
+ {
23
+ 'typ' => 'base64',
24
+ },
25
+ ])
26
+ end
27
+
28
+ it 'can convert itself into a null token' do
29
+ token = Base64.convert(raw_token: nil)
30
+
31
+ expect(token).to be_valid
32
+ expect(token).to be_blank
33
+ end
34
+
35
+ it 'can convert itself into an invalid token' do
36
+ token = Base64.convert(raw_token: 'bla.h')
37
+
38
+ expect(token).not_to be_valid
39
+ expect(token).not_to be_blank
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+ require 'apill/tokens/json_web_token'
3
+
4
+ module Apill
5
+ module Tokens
6
+ describe JsonWebToken do
7
+ it 'can convert an empty token' do
8
+ token = JsonWebToken.convert(token_private_key: test_private_key,
9
+ raw_token: nil)
10
+
11
+ expect(token).to be_a JsonWebTokens::Null
12
+ end
13
+
14
+ it 'can convert an invalid token' do
15
+ token = JsonWebToken.convert(token_private_key: test_private_key,
16
+ raw_token: invalid_jwt_token)
17
+
18
+ expect(token).to be_a JsonWebTokens::Invalid
19
+ end
20
+
21
+ it 'can verify an expired token' do
22
+ expired_jwe = valid_jwt_token('exp' => 1.day.ago.to_i,
23
+ 'baz' => 'bar')
24
+ token = JsonWebToken.convert(
25
+ token_private_key: test_private_key,
26
+ raw_token: expired_jwe)
27
+
28
+ expect(token).to be_a JsonWebTokens::Invalid
29
+ end
30
+
31
+ it 'can convert an invalidly signed token' do
32
+ other_private_key = OpenSSL::PKey::RSA.new(2048)
33
+ token = JsonWebToken.convert(
34
+ token_private_key: other_private_key,
35
+ raw_token: valid_jwt_token)
36
+
37
+ expect(token).to be_a JsonWebTokens::Invalid
38
+ end
39
+
40
+ it 'can convert a valid token' do
41
+ token = JsonWebToken.convert(token_private_key: test_private_key,
42
+ raw_token: valid_jwt_token)
43
+
44
+ expect(token).to be_a JsonWebToken
45
+ expect(token.to_h).to eql([{ 'bar' => 'baz' }, { 'typ' => 'JWT', 'alg' => 'RS256' }])
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,10 +1,11 @@
1
1
  require 'json/jwt'
2
+ require 'base64'
2
3
 
3
4
  def test_private_key
4
5
  OpenSSL::PKey::RSA.new File.read(File.expand_path('../fixtures/test_rsa_key', __dir__))
5
6
  end
6
7
 
7
- def valid_token(payload = { 'bar' => 'baz' })
8
+ def valid_jwt_token(payload = { 'bar' => 'baz' })
8
9
  @valid_token ||= begin
9
10
  jwt = JSON::JWT.new(payload)
10
11
  jws = jwt.sign(test_private_key, :RS256)
@@ -14,6 +15,14 @@ def valid_token(payload = { 'bar' => 'baz' })
14
15
  end
15
16
  end
16
17
 
17
- def invalid_token
18
- @invalid_token ||= valid_token.tr('a', 'f')
18
+ def invalid_jwt_token
19
+ @invalid_token ||= valid_jwt_token.tr('a', 'f')
20
+ end
21
+
22
+ def valid_b64_token(payload = 'hereisacoollittlestring')
23
+ @valid_b64_token ||= Base64.encode64(payload).chomp
24
+ end
25
+
26
+ def invalid_b64_token
27
+ @invalid_b64_token ||= valid_b64_token.tr('abcdefghijklmnop', '$o#m$k#i$g#e$c#a')
19
28
  end
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.3
4
+ version: 4.1.0
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-21 00:00:00.000000000 Z
11
+ date: 2015-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: human_error
@@ -119,9 +119,14 @@ files:
119
119
  - lib/apill/responses/invalid_subdomain.rb
120
120
  - lib/apill/responses/invalid_token.rb
121
121
  - lib/apill/serializers/json_api.rb
122
- - lib/apill/tokens/invalid_request_authorization.rb
123
- - lib/apill/tokens/null_request_authorization.rb
124
- - lib/apill/tokens/request_authorization.rb
122
+ - lib/apill/tokens/base64.rb
123
+ - lib/apill/tokens/base64s/invalid.rb
124
+ - lib/apill/tokens/base64s/null.rb
125
+ - lib/apill/tokens/invalid.rb
126
+ - lib/apill/tokens/json_web_token.rb
127
+ - lib/apill/tokens/json_web_tokens/invalid.rb
128
+ - lib/apill/tokens/json_web_tokens/null.rb
129
+ - lib/apill/tokens/null.rb
125
130
  - lib/apill/version.rb
126
131
  - spec/apill/accept_header_spec.rb
127
132
  - spec/apill/errors/invalid_api_request_spec.rb
@@ -142,7 +147,8 @@ files:
142
147
  - spec/apill/resource/processors/indexing_spec.rb
143
148
  - spec/apill/resource/processors/paging_spec.rb
144
149
  - spec/apill/resource/processors/sorting_spec.rb
145
- - spec/apill/tokens/request_authorization_spec.rb
150
+ - spec/apill/tokens/base64_spec.rb
151
+ - spec/apill/tokens/json_web_token_spec.rb
146
152
  - spec/fixtures/test_rsa_key
147
153
  - spec/fixtures/test_rsa_key.pub
148
154
  - spec/spec_helper.rb
@@ -191,7 +197,8 @@ test_files:
191
197
  - spec/apill/resource/processors/indexing_spec.rb
192
198
  - spec/apill/resource/processors/paging_spec.rb
193
199
  - spec/apill/resource/processors/sorting_spec.rb
194
- - spec/apill/tokens/request_authorization_spec.rb
200
+ - spec/apill/tokens/base64_spec.rb
201
+ - spec/apill/tokens/json_web_token_spec.rb
195
202
  - spec/fixtures/test_rsa_key
196
203
  - spec/fixtures/test_rsa_key.pub
197
204
  - spec/spec_helper.rb
@@ -1,49 +0,0 @@
1
- require 'spec_helper'
2
- require 'apill/tokens/request_authorization'
3
-
4
- module Apill
5
- module Tokens
6
- describe RequestAuthorization do
7
- it 'can convert an empty token' do
8
- token = RequestAuthorization.convert(token_private_key: test_private_key,
9
- raw_token: nil)
10
-
11
- expect(token).to be_a NullRequestAuthorization
12
- end
13
-
14
- it 'can convert an invalid token' do
15
- token = RequestAuthorization.convert(token_private_key: test_private_key,
16
- raw_token: invalid_token)
17
-
18
- expect(token).to be_a InvalidRequestAuthorization
19
- end
20
-
21
- it 'can verify an expired token' do
22
- expired_jwe = valid_token('exp' => 1.day.ago.to_i,
23
- 'baz' => 'bar')
24
- token = RequestAuthorization.convert(
25
- token_private_key: test_private_key,
26
- raw_token: expired_jwe)
27
-
28
- expect(token).to be_a InvalidRequestAuthorization
29
- end
30
-
31
- it 'can convert an invalidly signed token' do
32
- other_private_key = OpenSSL::PKey::RSA.new(2048)
33
- token = RequestAuthorization.convert(
34
- token_private_key: other_private_key,
35
- raw_token: valid_token)
36
-
37
- expect(token).to be_a InvalidRequestAuthorization
38
- end
39
-
40
- it 'can convert a valid token' do
41
- token = RequestAuthorization.convert(token_private_key: test_private_key,
42
- raw_token: valid_token)
43
-
44
- expect(token).to be_a RequestAuthorization
45
- expect(token.to_h).to eql([{ 'bar' => 'baz' }, { 'typ' => 'JWT', 'alg' => 'RS256' }])
46
- end
47
- end
48
- end
49
- end