apill 3.1.3 → 4.0.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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/lib/apill/configuration.rb +2 -1
  3. data/lib/apill/errors/{invalid_api_request_error.rb → invalid_api_request.rb} +1 -1
  4. data/lib/apill/errors/{invalid_subdomain_error.rb → invalid_subdomain.rb} +1 -1
  5. data/lib/apill/errors/invalid_token.rb +21 -0
  6. data/lib/apill/matchers/accept_header.rb +13 -0
  7. data/lib/apill/matchers/{generic_matcher.rb → generic.rb} +5 -9
  8. data/lib/apill/matchers/{subdomain_matcher.rb → subdomain.rb} +3 -9
  9. data/lib/apill/matchers/{version_matcher.rb → version.rb} +4 -6
  10. data/lib/apill/middleware/api_request.rb +22 -21
  11. data/lib/apill/parameters/index.rb +1 -1
  12. data/lib/apill/parameters/page.rb +1 -1
  13. data/lib/apill/parameters/sort.rb +1 -1
  14. data/lib/apill/requests/base.rb +86 -10
  15. data/lib/apill/requests/rack.rb +34 -0
  16. data/lib/apill/requests/rails.rb +31 -0
  17. data/lib/apill/resource/model.rb +1 -1
  18. data/lib/apill/resource/processors/filtering.rb +2 -0
  19. data/lib/apill/resource/processors/indexing.rb +2 -0
  20. data/lib/apill/resource/processors/paging.rb +2 -0
  21. data/lib/apill/resource/processors/sorting.rb +2 -0
  22. data/lib/apill/responses/{invalid_subdomain_response.rb → invalid_api_request.rb} +3 -3
  23. data/lib/apill/responses/{invalid_api_request_response.rb → invalid_subdomain.rb} +3 -3
  24. data/lib/apill/responses/invalid_token.rb +17 -0
  25. data/lib/apill/tokens/invalid_request_authorization.rb +21 -0
  26. data/lib/apill/tokens/null_request_authorization.rb +21 -0
  27. data/lib/apill/tokens/request_authorization.rb +62 -0
  28. data/lib/apill/version.rb +1 -1
  29. data/lib/apill.rb +5 -5
  30. data/spec/apill/accept_header_spec.rb +1 -1
  31. data/spec/apill/errors/{invalid_api_request_error_spec.rb → invalid_api_request_spec.rb} +6 -6
  32. data/spec/apill/errors/{invalid_subdomain_error_spec.rb → invalid_subdomain_spec.rb} +6 -6
  33. data/spec/apill/errors/invalid_token_spec.rb +23 -0
  34. data/spec/apill/{invalid_subdomain_response_spec.rb → invalid_subdomain_spec.rb} +7 -7
  35. data/spec/apill/invalid_token_spec.rb +42 -0
  36. data/spec/apill/matchers/{accept_header_matcher_spec.rb → accept_header_spec.rb} +32 -24
  37. data/spec/apill/matchers/subdomain_spec.rb +81 -0
  38. data/spec/apill/matchers/{version_matcher_spec.rb → version_spec.rb} +31 -20
  39. data/spec/apill/middleware/api_request_spec.rb +36 -38
  40. data/spec/apill/parameters_spec.rb +1 -1
  41. data/spec/apill/requests/rack_spec.rb +159 -0
  42. data/spec/apill/requests/rails_spec.rb +151 -0
  43. data/spec/apill/resource/model_spec.rb +1 -1
  44. data/spec/apill/resource/processors/filtering_spec.rb +1 -1
  45. data/spec/apill/resource/processors/indexing_spec.rb +1 -1
  46. data/spec/apill/resource/processors/paging_spec.rb +1 -1
  47. data/spec/apill/resource/processors/sorting_spec.rb +1 -1
  48. data/spec/apill/tokens/request_authorization_spec.rb +49 -0
  49. data/spec/fixtures/test_rsa_key +27 -0
  50. data/spec/fixtures/test_rsa_key.pub +9 -0
  51. data/spec/spec_helper.rb +3 -0
  52. data/spec/support/private_keys.rb +19 -0
  53. metadata +75 -29
  54. data/lib/apill/matchers/accept_header_matcher.rb +0 -15
  55. data/lib/apill/requests/rack_request.rb +0 -37
  56. data/lib/apill/requests/rails_request.rb +0 -29
  57. data/spec/apill/matchers/subdomain_matcher_spec.rb +0 -72
  58. data/spec/apill/requests/rack_request_spec.rb +0 -70
  59. data/spec/apill/requests/rails_request_spec.rb +0 -59
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d4626664836143aaf78bf2b5b3484ba7da329a7d
4
- data.tar.gz: 70758012561218a831754e3a6f85678f92da35c7
3
+ metadata.gz: a868c1d22d4ed7815afb667e309f54dafcbf70c9
4
+ data.tar.gz: 70eb9a1d4ea3c9b061febe6eeb6c1fd975abc43f
5
5
  SHA512:
6
- metadata.gz: e4fe0941c2ce6d10a1cf60950bd4742a78a6cb3fd3f5a17701932b1b35ec95c177637eddcd9caf75a0ad19ff872252266dda004c028d7cc254d2d247bd3b7c50
7
- data.tar.gz: d021d2ebc2314c817889df412c77fa2718433b4f314a6066a6a74b503620f8512e0e99f31c767d03fbfb7e4d83750f379391d09c1519df392d7efe2d156d5ef9
6
+ metadata.gz: 92c289f7396d2523847834b5f7a25074c71384387434d987b8eb65fc174d44df7487adde5004eac3521d1493d410bea739588b7fd0ba9e867ad0b897194d9c95
7
+ data.tar.gz: d63a1ec7bbfa94244eba6c3f706c6fa71dee5260bd51c7c40cf8042f148ebf24787f73c4a2f2a47a8f45730c2a57772dd4c009d6d05f69e5d56981ce6a6cc9f6
@@ -4,7 +4,8 @@ module Apill
4
4
  :allowed_subdomains,
5
5
  :allowed_api_subdomains,
6
6
  :application_name,
7
- :default_api_version
7
+ :default_api_version,
8
+ :token_private_key
8
9
 
9
10
  def to_h
10
11
  {
@@ -2,7 +2,7 @@ require 'human_error'
2
2
 
3
3
  module Apill
4
4
  module Errors
5
- class InvalidApiRequestError < RuntimeError
5
+ class InvalidApiRequest < RuntimeError
6
6
  include HumanError::Error
7
7
 
8
8
  attr_accessor :accept_header
@@ -2,7 +2,7 @@ require 'human_error'
2
2
 
3
3
  module Apill
4
4
  module Errors
5
- class InvalidSubdomainError < RuntimeError
5
+ class InvalidSubdomain < RuntimeError
6
6
  include HumanError::Error
7
7
 
8
8
  attr_accessor :http_host
@@ -0,0 +1,21 @@
1
+ require 'human_error'
2
+
3
+ module Apill
4
+ module Errors
5
+ class InvalidToken < RuntimeError
6
+ include HumanError::Error
7
+
8
+ def http_status
9
+ 401
10
+ end
11
+
12
+ def title
13
+ 'Invalid or Unauthorized Token'
14
+ end
15
+
16
+ def detail
17
+ 'Either the token you passed is invalid or is not allowed to perform this action.'
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ require 'apill/matchers/generic'
2
+
3
+ module Apill
4
+ module Matchers
5
+ class AcceptHeader
6
+ include Generic
7
+
8
+ def matches?
9
+ accept_header.valid?
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,20 +1,16 @@
1
- require 'apill/accept_header'
2
- require 'apill/requests/base'
3
-
4
1
  module Apill
5
2
  module Matchers
6
- module GenericMatcher
3
+ module Generic
7
4
  attr_accessor :application,
8
- :accept_header
5
+ :accept_header,
6
+ :request
9
7
 
10
- def initialize(**args)
8
+ def initialize(request:, **args)
11
9
  args.each do |variable, value|
12
10
  __send__("#{variable}=", value)
13
11
  end
14
- end
15
12
 
16
- def matches?(request)
17
- request = Requests::Base.resolve(request)
13
+ self.request = request
18
14
  self.application = request.application_name
19
15
  self.accept_header = request.accept_header
20
16
  end
@@ -1,6 +1,6 @@
1
1
  module Apill
2
2
  module Matchers
3
- class SubdomainMatcher
3
+ class Subdomain
4
4
  def initialize(allowed_subdomains: Apill.configuration.allowed_subdomains,
5
5
  allowed_api_subdomains: Apill.configuration.allowed_api_subdomains,
6
6
  request:)
@@ -11,11 +11,11 @@ class SubdomainMatcher
11
11
  end
12
12
 
13
13
  def matches?
14
- allowed_subdomains.include? request_subdomain
14
+ allowed_subdomains.include? request.subdomain
15
15
  end
16
16
 
17
17
  def matches_api_subdomain?
18
- allowed_api_subdomains.include? request_subdomain
18
+ allowed_api_subdomains.include? request.subdomain
19
19
  end
20
20
 
21
21
  protected
@@ -23,12 +23,6 @@ class SubdomainMatcher
23
23
  attr_accessor :allowed_subdomains,
24
24
  :allowed_api_subdomains,
25
25
  :request
26
-
27
- private
28
-
29
- def request_subdomain
30
- @request_subdomain ||= request.fetch('HTTP_HOST', '')[/\A([a-z\-]+)/i, 1]
31
- end
32
26
  end
33
27
  end
34
28
  end
@@ -1,17 +1,15 @@
1
1
  require 'apill/configuration'
2
- require 'apill/matchers/generic_matcher'
2
+ require 'apill/matchers/generic'
3
3
 
4
4
  module Apill
5
5
  module Matchers
6
- class VersionMatcher
7
- include GenericMatcher
6
+ class Version
7
+ include Generic
8
8
 
9
9
  attr_accessor :version_constraint,
10
10
  :default_version
11
11
 
12
- def matches?(request)
13
- super
14
-
12
+ def matches?
15
13
  requested_version == version_constraint
16
14
  end
17
15
 
@@ -1,42 +1,43 @@
1
1
  require 'apill/configuration'
2
2
  require 'apill/parameters'
3
- require 'apill/matchers/subdomain_matcher'
4
- require 'apill/matchers/accept_header_matcher'
5
- require 'apill/responses/invalid_api_request_response'
6
- require 'apill/responses/invalid_subdomain_response'
3
+ require 'apill/matchers/subdomain'
4
+ require 'apill/matchers/accept_header'
5
+ require 'apill/requests/base'
6
+ require 'apill/responses/invalid_api_request'
7
+ require 'apill/responses/invalid_subdomain'
8
+ require 'apill/responses/invalid_token'
7
9
 
8
10
  module Apill
9
11
  module Middleware
10
12
  class ApiRequest
11
- JSON_API_MIME_TYPE_PATTERN = %r{application/vnd\.api\+json(?=\z|;)}
12
-
13
13
  def initialize(app)
14
14
  @app = app
15
15
  end
16
16
 
17
+ # rubocop:disable Metrics/LineLength
17
18
  def call(env)
18
19
  env['HTTP_X_APPLICATION_NAME'] = Apill.configuration.application_name
19
20
 
20
- subdomain_matcher = Matchers::SubdomainMatcher.new(request: env)
21
+ request = Requests::Base.resolve(env)
22
+ subdomain_matcher = Matchers::Subdomain.new(request: request)
23
+ accept_header_matcher = Matchers::AcceptHeader.new(request: request)
24
+ token = request.authorization_token
21
25
 
22
- if subdomain_matcher.matches?
23
- if !subdomain_matcher.matches_api_subdomain? ||
24
- Matchers::AcceptHeaderMatcher.new.matches?(env)
26
+ return Responses::InvalidSubdomain.call(env) unless subdomain_matcher.matches?
27
+ return Responses::InvalidApiRequest.call(env) unless !subdomain_matcher.matches_api_subdomain? ||
28
+ accept_header_matcher.matches?
29
+ return Responses::InvalidToken.call(env) unless token.valid?
25
30
 
26
- env['QUERY_STRING'] = Parameters.process(env['QUERY_STRING'])
27
- env['CONTENT_TYPE'] = env['CONTENT_TYPE'].
28
- to_s.
29
- gsub! JSON_API_MIME_TYPE_PATTERN,
30
- 'application/json'
31
+ env['HTTP_X_JSON_WEB_TOKEN'] = token.to_h
32
+ env['QUERY_STRING'] = Parameters.process(env['QUERY_STRING'])
31
33
 
32
- @app.call(env)
33
- else
34
- Responses::InvalidApiRequestResponse.call(env)
35
- end
36
- else
37
- Responses::InvalidSubdomainResponse.call(env)
34
+ if env['CONTENT_TYPE'] == 'application/vnd.api+json'
35
+ env['CONTENT_TYPE'] = 'application/json'
38
36
  end
37
+
38
+ @app.call(env)
39
39
  end
40
+ # rubocop:enable Metrics/LineLength
40
41
  end
41
42
  end
42
43
  end
@@ -1,7 +1,7 @@
1
1
  module Apill
2
2
  class Parameters
3
3
  class Index
4
- DEFAULT_QUERY = '*'
4
+ DEFAULT_QUERY = '*'.freeze
5
5
 
6
6
  attr_accessor :raw_parameters
7
7
 
@@ -1,7 +1,7 @@
1
1
  module Apill
2
2
  class Parameters
3
3
  class Page
4
- PAGING_PARAMETERS = %w{number size limit offset cursor}
4
+ PAGING_PARAMETERS = %w{number size limit offset cursor}.freeze
5
5
  DEFAULT_STARTING_PAGE = 1
6
6
  DEFAULT_PAGE_SIZE = 25
7
7
 
@@ -1,7 +1,7 @@
1
1
  module Apill
2
2
  class Parameters
3
3
  class Sort
4
- DESCENDING_PREFIX = '-'
4
+ DESCENDING_PREFIX = '-'.freeze
5
5
 
6
6
  attr_accessor :raw_parameters
7
7
 
@@ -1,12 +1,19 @@
1
+ require 'apill/tokens/invalid_request_authorization'
2
+ require 'apill/tokens/request_authorization'
3
+
1
4
  module Apill
2
5
  module Requests
3
6
  class Base
4
- def self.resolve(original_request)
5
- if original_request.respond_to? :headers
6
- rails_request_class.new(original_request)
7
- else
8
- rack_request_class.new(original_request)
9
- end
7
+ TOKEN_PATTERN = %r{\A(?:Token ([A-Za-z0-9_/\+\=\-\.]+))?\z}
8
+
9
+ attr_accessor :token_private_key,
10
+ :request
11
+
12
+ def initialize(token_private_key: Apill.configuration.token_private_key,
13
+ request:)
14
+
15
+ self.token_private_key = token_private_key
16
+ self.request = request
10
17
  end
11
18
 
12
19
  def accept_header
@@ -19,16 +26,85 @@ class Base
19
26
  end
20
27
  end
21
28
 
29
+ def authorization_token
30
+ if (
31
+ !authorization_token_from_header.blank? &&
32
+ authorization_token_from_header.valid?
33
+ ) ||
34
+ (
35
+ authorization_token_from_params.blank? ||
36
+ !authorization_token_from_params.valid?
37
+ )
38
+
39
+ authorization_token_from_header
40
+ else
41
+ authorization_token_from_params
42
+ end
43
+ end
44
+
45
+ def application_name
46
+ raw_request_application_name || Apill.configuration.application_name
47
+ end
48
+
49
+ def subdomain
50
+ @subdomain ||= raw_host[/\A([a-z\-]+)/i, 1]
51
+ end
52
+
53
+ def self.resolve(original_request)
54
+ if original_request.respond_to? :headers
55
+ rails_request_class.new(request: original_request)
56
+ else
57
+ rack_request_class.new(request: original_request)
58
+ end
59
+ end
60
+
22
61
  def self.rails_request_class
23
- require 'apill/requests/rails_request'
62
+ require 'apill/requests/rails'
24
63
 
25
- Object.const_get('Apill::Requests::RailsRequest')
64
+ Object.const_get('Apill::Requests::Rails')
26
65
  end
27
66
 
28
67
  def self.rack_request_class
29
- require 'apill/requests/rack_request'
68
+ require 'apill/requests/rack'
69
+
70
+ Object.const_get('Apill::Requests::Rack')
71
+ end
72
+
73
+ private
74
+
75
+ def accept_header_from_header
76
+ AcceptHeader.new(application: application_name,
77
+ header: raw_accept_header_from_header || '')
78
+ end
79
+
80
+ def accept_header_from_params
81
+ AcceptHeader.new(application: application_name,
82
+ header: raw_accept_header_from_params || '')
83
+ end
84
+
85
+ def authorization_token_from_header
86
+ return Tokens::InvalidRequestAuthorization.instance \
87
+ unless raw_authorization_header.match(TOKEN_PATTERN)
88
+
89
+ Tokens::RequestAuthorization.convert(
90
+ token_private_key: token_private_key,
91
+ raw_token: raw_authorization_token_from_header || '')
92
+ end
93
+
94
+ def authorization_token_from_params
95
+ Tokens::RequestAuthorization.convert(
96
+ token_private_key: token_private_key,
97
+ raw_token: raw_authorization_token_from_params || '')
98
+ end
99
+
100
+ private
101
+
102
+ def raw_host
103
+ request.fetch('HTTP_HOST', '')
104
+ end
30
105
 
31
- Object.const_get('Apill::Requests::RackRequest')
106
+ def raw_authorization_token_from_header
107
+ raw_authorization_header[TOKEN_PATTERN, 1] || ''
32
108
  end
33
109
  end
34
110
  end
@@ -0,0 +1,34 @@
1
+ require 'apill/configuration'
2
+ require 'apill/requests/base'
3
+ require 'apill/accept_header'
4
+
5
+ module Apill
6
+ module Requests
7
+ class Rack < Base
8
+ ACCEPT_PARAM_PATTERN = /(?:\A|&)accept=(.+?)(?=\z|&)/
9
+ AUTH_TOKEN_PARAM_PATTERN = /(?:\A|&)auth_token=(.+?)(?=\z|&)/
10
+
11
+ private
12
+
13
+ def raw_accept_header_from_header
14
+ request['HTTP_ACCEPT']
15
+ end
16
+
17
+ def raw_accept_header_from_params
18
+ URI.unescape(request['QUERY_STRING'][ACCEPT_PARAM_PATTERN, 1] || '')
19
+ end
20
+
21
+ def raw_authorization_header
22
+ request['HTTP_AUTHORIZATION'] || ''
23
+ end
24
+
25
+ def raw_authorization_token_from_params
26
+ URI.unescape(request['QUERY_STRING'][AUTH_TOKEN_PARAM_PATTERN, 1] || '')
27
+ end
28
+
29
+ def raw_request_application_name
30
+ request['HTTP_X_APPLICATION_NAME']
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,31 @@
1
+ require 'apill/configuration'
2
+ require 'apill/requests/base'
3
+ require 'apill/accept_header'
4
+
5
+ module Apill
6
+ module Requests
7
+ class Rails < Base
8
+ private
9
+
10
+ def raw_accept_header_from_header
11
+ request.headers['Accept']
12
+ end
13
+
14
+ def raw_accept_header_from_params
15
+ request.params['accept']
16
+ end
17
+
18
+ def raw_authorization_header
19
+ request.headers['HTTP_AUTHORIZATION'] || ''
20
+ end
21
+
22
+ def raw_authorization_token_from_params
23
+ request.params['auth_token'] || ''
24
+ end
25
+
26
+ def raw_request_application_name
27
+ request.headers['X-Application-Name']
28
+ end
29
+ end
30
+ end
31
+ end
@@ -6,7 +6,7 @@ require 'apill/resource/processors/indexing'
6
6
  module Apill
7
7
  module Resource
8
8
  class Model
9
- DEFAULT_PROCESSORS = %w{filtering sorting paging indexing}
9
+ DEFAULT_PROCESSORS = %w{filtering sorting paging indexing}.freeze
10
10
 
11
11
  attr_accessor :resource,
12
12
  :parameters,
@@ -7,10 +7,12 @@ class Filtering
7
7
  attr_accessor :resource,
8
8
  :parameters
9
9
 
10
+ # rubocop:disable Style/OptionHash
10
11
  def initialize(resource, parameters = {})
11
12
  self.resource = resource
12
13
  self.parameters = Parameters::Filter.new(parameters['filter'] || {})
13
14
  end
15
+ # rubocop:enable Style/OptionHash
14
16
 
15
17
  def self.processed(*attrs)
16
18
  new(*attrs).processed
@@ -7,10 +7,12 @@ class Indexing
7
7
  attr_accessor :resource,
8
8
  :parameters
9
9
 
10
+ # rubocop:disable Style/OptionHash
10
11
  def initialize(resource, parameters = {})
11
12
  self.resource = resource
12
13
  self.parameters = Parameters::Index.new(parameters['filter'] || {})
13
14
  end
15
+ # rubocop:enable Style/OptionHash
14
16
 
15
17
  def self.processed(*attrs)
16
18
  new(*attrs).processed
@@ -7,10 +7,12 @@ class Paging
7
7
  attr_accessor :resource,
8
8
  :parameters
9
9
 
10
+ # rubocop:disable Style/OptionHash
10
11
  def initialize(resource, parameters = {})
11
12
  self.resource = resource
12
13
  self.parameters = Parameters::Page.new(parameters['page'] || {})
13
14
  end
15
+ # rubocop:enable Style/OptionHash
14
16
 
15
17
  def self.processed(*attrs)
16
18
  new(*attrs).processed
@@ -7,10 +7,12 @@ class Sorting
7
7
  attr_accessor :resource,
8
8
  :parameters
9
9
 
10
+ # rubocop:disable Style/OptionHash
10
11
  def initialize(resource, parameters = {})
11
12
  self.resource = resource
12
13
  self.parameters = Parameters::Sort.new(parameters['sort'])
13
14
  end
15
+ # rubocop:enable Style/OptionHash
14
16
 
15
17
  def self.processed(*attrs)
16
18
  new(*attrs).processed
@@ -1,10 +1,10 @@
1
- require 'apill/errors/invalid_subdomain_error'
1
+ require 'apill/errors/invalid_api_request'
2
2
 
3
3
  module Apill
4
4
  module Responses
5
- class InvalidSubdomainResponse
5
+ class InvalidApiRequest
6
6
  def self.call(env)
7
- error = Apill::Errors::InvalidSubdomainError.new(http_host: env['HTTP_HOST'])
7
+ error = Apill::Errors::InvalidApiRequest.new(accept_header: env['HTTP_ACCEPT'])
8
8
 
9
9
  [
10
10
  error.http_status, # HTTP Status Code
@@ -1,10 +1,10 @@
1
- require 'apill/errors/invalid_api_request_error'
1
+ require 'apill/errors/invalid_subdomain'
2
2
 
3
3
  module Apill
4
4
  module Responses
5
- class InvalidApiRequestResponse
5
+ class InvalidSubdomain
6
6
  def self.call(env)
7
- error = Apill::Errors::InvalidApiRequestError.new(accept_header: env['HTTP_ACCEPT'])
7
+ error = Apill::Errors::InvalidSubdomain.new(http_host: env['HTTP_HOST'])
8
8
 
9
9
  [
10
10
  error.http_status, # HTTP Status Code
@@ -0,0 +1,17 @@
1
+ require 'apill/errors/invalid_token'
2
+
3
+ module Apill
4
+ module Responses
5
+ class InvalidToken
6
+ def self.call(_env)
7
+ error = Apill::Errors::InvalidToken.new
8
+
9
+ [
10
+ error.http_status, # HTTP Status Code
11
+ {}, # Response Headers
12
+ [error.to_json], # Message
13
+ ]
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ require 'singleton'
2
+
3
+ module Apill
4
+ module Tokens
5
+ class InvalidRequestAuthorization
6
+ include Singleton
7
+
8
+ def valid?
9
+ false
10
+ end
11
+
12
+ def blank?
13
+ false
14
+ end
15
+
16
+ def to_h
17
+ {}
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require 'singleton'
2
+
3
+ module Apill
4
+ module Tokens
5
+ class NullRequestAuthorization
6
+ include Singleton
7
+
8
+ def valid?
9
+ true
10
+ end
11
+
12
+ def blank?
13
+ true
14
+ end
15
+
16
+ def to_h
17
+ {}
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,62 @@
1
+ require 'jwt'
2
+ require 'json/jwt'
3
+ require 'apill/tokens/invalid_request_authorization'
4
+ require 'apill/tokens/null_request_authorization'
5
+
6
+ module Apill
7
+ module Tokens
8
+ class RequestAuthorization
9
+ attr_accessor :token
10
+
11
+ def initialize(token:)
12
+ self.token = token
13
+ end
14
+
15
+ def valid?
16
+ true
17
+ end
18
+
19
+ def blank?
20
+ false
21
+ end
22
+
23
+ def to_h
24
+ token
25
+ end
26
+
27
+ def self.convert(raw_token:, token_private_key: Apill.configuration.token_private_key)
28
+ return NullRequestAuthorization.instance if raw_token.to_s == ''
29
+
30
+ decrypted_token = JSON::JWT.decode(raw_token, token_private_key).plain_text
31
+ decoded_token = JWT.decode(decrypted_token,
32
+ token_private_key,
33
+ true,
34
+ algorithm: 'RS256',
35
+ verify_expiration: true,
36
+ verify_not_before: true,
37
+ verify_iat: true,
38
+ leeway: 5,
39
+ )
40
+
41
+ new(token: decoded_token)
42
+ rescue JSON::JWT::Exception,
43
+ JSON::JWT::InvalidFormat,
44
+ JSON::JWT::VerificationFailed,
45
+ JSON::JWT::UnexpectedAlgorithm,
46
+ JWT::DecodeError,
47
+ JWT::VerificationError,
48
+ JWT::ExpiredSignature,
49
+ JWT::IncorrectAlgorithm,
50
+ JWT::ImmatureSignature,
51
+ JWT::InvalidIssuerError,
52
+ JWT::InvalidIatError,
53
+ JWT::InvalidAudError,
54
+ JWT::InvalidSubError,
55
+ JWT::InvalidJtiError,
56
+ OpenSSL::PKey::RSAError
57
+
58
+ InvalidRequestAuthorization.instance
59
+ end
60
+ end
61
+ end
62
+ end
data/lib/apill/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Apill
2
- VERSION = '3.1.3'
2
+ VERSION = '4.0.0'.freeze
3
3
  end