active_record_api-request 0.2.1 → 0.3.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 +4 -4
- data/lib/active_record_api/request.rb +4 -1
- data/lib/active_record_api/request/auth_error.rb +9 -0
- data/lib/active_record_api/request/connection.rb +2 -1
- data/lib/active_record_api/request/credentials.rb +16 -5
- data/lib/active_record_api/request/faraday_auth_token_retry.rb +38 -0
- data/lib/active_record_api/request/token_cache.rb +65 -0
- data/lib/active_record_api/request/token_retriever.rb +19 -0
- data/lib/active_record_api/request/version.rb +1 -1
- metadata +6 -3
- data/lib/active_record_api/request/micro_services.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1bb4855eb0cc1e05c36a6cbf9f854e5e9f5d7295273c8ffdb2b3a818c010b1b8
|
4
|
+
data.tar.gz: 262c7a98bcf70e50279c2c19e28710780259fd3518168e6b1169b1f8616e6e93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 :
|
13
|
+
autoload :AuthError
|
14
|
+
autoload :FaradayAuthTokenRetry
|
15
|
+
autoload :TokenRetriever
|
16
|
+
autoload :TokenCache
|
14
17
|
end
|
15
18
|
end
|
@@ -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)
|
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
|
-
|
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}"] ||
|
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:#
|
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
|
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-
|
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/
|
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
|