active_record_api-request 0.2.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50362697da6b9fa6cb9f864ccf8445d699751c3ac6186ac51b397a1a7c8d96b5
4
- data.tar.gz: c329f7ea4c3501dd6696c3bf35a6727dd417da3841904f47e655b3be6e9e7836
3
+ metadata.gz: 1bb4855eb0cc1e05c36a6cbf9f854e5e9f5d7295273c8ffdb2b3a818c010b1b8
4
+ data.tar.gz: 262c7a98bcf70e50279c2c19e28710780259fd3518168e6b1169b1f8616e6e93
5
5
  SHA512:
6
- metadata.gz: a64b9a39dc79bf9aec4d44d3c1f702648840e1ce4af75e4b3d69388b4a0f6524e12fd107dc88cbb60d46b7c121bcce4e7aa79f33d76e47a6438828930ff14098
7
- data.tar.gz: 62c66f196fed51c485e665ed89c155316dd6fefbbdb8fa7997c381a3e33f86d2bb2289ffe1bcc90540440327e379458cdce0136bd00fd44b4aa8ca32bdfdaf00
6
+ metadata.gz: 4863d724c7155740e6873cae1d1f0d1e51b8947810cbb31d57c99effd0c18c5fcefec930628402deaed14be4ea157d88eb7064ee89b55a87c998217b930242a6
7
+ data.tar.gz: bb3949e1090164cd04be0f4e06f9e26e0b01f88c065196e0fedfa7ef32cf941b0533349fd376ed9330c3c165de8033dd7eea412bf05fe332ba345099638c6554
@@ -10,6 +10,9 @@ module ActiveRecordApi
10
10
  autoload :Connection
11
11
  autoload :FaradayFollowNextLinks
12
12
  autoload :FaradayCacheServiceDown
13
- autoload :MicroServices
13
+ autoload :AuthError
14
+ autoload :FaradayAuthTokenRetry
15
+ autoload :TokenRetriever
16
+ autoload :TokenCache
14
17
  end
15
18
  end
@@ -0,0 +1,9 @@
1
+ require 'faraday_middleware'
2
+ #:nocov:#
3
+ module ActiveRecordApi
4
+ module Request
5
+ class AuthError < Faraday::ClientError
6
+ end
7
+ end
8
+ end
9
+ #:nocov:#
@@ -19,11 +19,12 @@ module ActiveRecordApi
19
19
  builder.options[:timeout] = 5
20
20
  builder.request :json
21
21
  builder.request :url_encoded
22
- builder.request :retry, max: 5, interval: 0.05, interval_randomness: 0.5, backoff_factor: 2
22
+ builder.request :retry, max: 5, interval: 0.05, interval_randomness: 0.5, backoff_factor: 2, exceptions: [ActiveRecordApi::Request::AuthError]
23
23
  builder.use FaradayCacheServiceDown, cache_store
24
24
  builder.use :http_cache, http_cache_options
25
25
  builder.use FaradayFollowNextLinks, 5
26
26
  builder.use FaradayMiddleware::FollowRedirects, standards_compliant: true
27
+ builder.use FaradayAuthTokenRetry, credentials: credentials, host: host, token_path: token_path, debug: debug
27
28
  builder.response :json, content_type: /\bjson$/
28
29
  builder.response :raise_error
29
30
  builder.response :logger if debug
@@ -1,4 +1,5 @@
1
1
  require 'active_attr'
2
+ #:nocov:#
2
3
 
3
4
  module ActiveRecordApi
4
5
  module Request
@@ -7,7 +8,7 @@ module ActiveRecordApi
7
8
  attr_writer :host, :token_path, :token, :email, :password, :headers
8
9
 
9
10
  def token
10
- @token ||= config(:token) || connection.post("#{host}/#{token_path}", credentials).body['token']
11
+ @token ||= config(:token)
11
12
  end
12
13
 
13
14
  def host
@@ -27,9 +28,13 @@ module ActiveRecordApi
27
28
  end
28
29
 
29
30
  def headers
30
- @headers ||= {
31
- 'Authorization' => "Bearer #{token}"
32
- }
31
+ @headers ||= {}.tap do |headers|
32
+ if token.present?
33
+ headers['Authorization'] = "Bearer #{token}"
34
+ else
35
+ headers['InjectToken'] = 'true'
36
+ end
37
+ end
33
38
  end
34
39
 
35
40
  def credentials
@@ -41,8 +46,14 @@ module ActiveRecordApi
41
46
  end
42
47
 
43
48
  def config(name)
44
- ENV["ACTIVE_RECORD_API_REQUEST_#{name.upcase}"] || Rails.application.credentials.try(:active_record_api_request).try(:[], name)
49
+ ENV["ACTIVE_RECORD_API_REQUEST_#{name.upcase}"] || credentials_config(name)
50
+ end
51
+
52
+ def credentials_config(name)
53
+ return unless defined? Rails
54
+ Rails.application.try(:credentials).try(:active_record_api_request).try(:[], name)
45
55
  end
46
56
  end
47
57
  end
48
58
  end
59
+ #:nocov:#
@@ -0,0 +1,38 @@
1
+ require 'faraday_middleware'
2
+ #:nocov:#
3
+
4
+ module ActiveRecordApi
5
+ module Request
6
+ class FaradayAuthTokenRetry < Faraday::Middleware
7
+ AUTH_KEY = 'Authorization'.freeze
8
+
9
+ attr_reader :credentials, :host, :token_path, :debug
10
+
11
+ def initialize(app, credentials: nil, host: nil, token_path: nil, debug: false)
12
+ super(app)
13
+ @credentials = credentials
14
+ @host = host
15
+ @token_path = token_path
16
+ @debug = debug
17
+ end
18
+
19
+ def call(env)
20
+ if env.request_headers['InjectToken'].present? && env.request_headers['InjectToken'] == 'true'
21
+ env.request_headers[AUTH_KEY] = "Bearer #{retrieve_token}"
22
+ end
23
+ @app.call(env)
24
+ rescue Faraday::ClientError => error
25
+ if error.response.try(:[], 'code') == 401
26
+ raise AuthError, error.response
27
+ else
28
+ raise error
29
+ end
30
+ end
31
+
32
+ def retrieve_token
33
+ TokenCache.new(debug: debug).fetch_token Proc.new { TokenRetriever.new(credentials: credentials, host: host, token_path: token_path, debug: debug).fetch_token }
34
+ end
35
+ end
36
+ end
37
+ end
38
+ #:nocov:#
@@ -0,0 +1,65 @@
1
+ #:nocov:#
2
+ module ActiveRecordApi
3
+ module Request
4
+ class TokenCache
5
+ include ActiveAttr::Model
6
+ attr_accessor :debug
7
+
8
+ def fetch_token(token_proc)
9
+ retrieve_token_from_redis(token_proc)
10
+ end
11
+
12
+ def retrieve_token_from_redis(token_proc)
13
+ debug_log 'looking?'
14
+ return token_proc.call() unless defined? AUTH_REDIS_POOL
15
+ debug_log 'looking for token in cache'
16
+ AUTH_REDIS_POOL.with do |client|
17
+ @redis_client = client
18
+ @token = nil
19
+ @retry = 0
20
+ while @token.nil? && @retry < 5
21
+ @retry += 1
22
+ @token = @redis_client.get('auth_token')
23
+ debug_log "retry ##{@retry}"
24
+ debug_log "found token: #{@token}"
25
+ if @token.nil?
26
+ if acquire_lock
27
+ begin
28
+ debug_log "acquired lock"
29
+ @token = token_proc.call()
30
+ @redis_client.set 'auth_token', @token
31
+ ensure
32
+ debug_log 'releasing lock'
33
+ release_lock
34
+ end
35
+ else
36
+ debug_log 'waiting for token to be cached'
37
+ sleep 3
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ def debug_log(message)
45
+ Rails.logger.info message if debug
46
+ end
47
+
48
+ def acquire_lock
49
+ @redis_client.set 'auth_token_lock', unique_key, nx: true, ex: 60
50
+ current_lock_value = @redis_client.get 'auth_token_lock'
51
+ Rails.logger.info "#{current_lock_value} == #{unique_key}" if debug
52
+ current_lock_value == unique_key
53
+ end
54
+
55
+ def release_lock
56
+ @redis_client.del 'auth_token_lock'
57
+ end
58
+
59
+ def unique_key
60
+ @unique_key ||= rand.to_s
61
+ end
62
+ end
63
+ end
64
+ end
65
+ #:nocov:#
@@ -0,0 +1,19 @@
1
+ #:nocov:#
2
+ module ActiveRecordApi
3
+ module Request
4
+ class TokenRetriever < Methods
5
+ attr_accessor :credentials, :host, :token_path
6
+
7
+ alias_method :path, :token_path
8
+
9
+ def fetch_token
10
+ post(payload: credentials)
11
+ end
12
+
13
+ def headers
14
+ @headers ||= {}
15
+ end
16
+ end
17
+ end
18
+ end
19
+ #:nocov:#
@@ -1,5 +1,5 @@
1
1
  module ActiveRecordApi
2
2
  module Request
3
- VERSION = '0.2.1'.freeze
3
+ VERSION = '0.3.2'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_api-request
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Full Measure Education
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-19 00:00:00.000000000 Z
11
+ date: 2019-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_attr
@@ -176,12 +176,15 @@ files:
176
176
  - README.md
177
177
  - Rakefile
178
178
  - lib/active_record_api/request.rb
179
+ - lib/active_record_api/request/auth_error.rb
179
180
  - lib/active_record_api/request/connection.rb
180
181
  - lib/active_record_api/request/credentials.rb
182
+ - lib/active_record_api/request/faraday_auth_token_retry.rb
181
183
  - lib/active_record_api/request/faraday_cache_service_down.rb
182
184
  - lib/active_record_api/request/faraday_follow_next_links.rb
183
185
  - lib/active_record_api/request/methods.rb
184
- - lib/active_record_api/request/micro_services.rb
186
+ - lib/active_record_api/request/token_cache.rb
187
+ - lib/active_record_api/request/token_retriever.rb
185
188
  - lib/active_record_api/request/version.rb
186
189
  homepage: https://gitlab.com/fullmeasure/public/gems/active_record_api-request
187
190
  licenses:
@@ -1,15 +0,0 @@
1
- module ActiveRecordApi
2
- module Request
3
- module MicroServices
4
- MICRO_SERVICE_PATHS.each do |path_hash|
5
- klass = Class.new(Methods) do
6
- define_method :path do
7
- "#{path_hash[:service_path]}/#{path_hash[:model_path]}"
8
- end
9
- end
10
- klass_name = klass.new.path.tr('/', '_').gsub(/[^a-z_]/i, '').camelcase
11
- const_set klass_name, klass
12
- end
13
- end
14
- end
15
- end