devise-rownd 1.0.2 → 1.0.3

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: ce95c890c9eaefb6188d86384d0b895d12263a54b50869202fd1913fd0137741
4
- data.tar.gz: 8cd89c98656cdeff0dd3845e69d9b8441147fe334ccaeee06ab6ed49b05f93ce
3
+ metadata.gz: d54df50c4a7815d8fe0ee291891134f7e1fbb9f9afebb935b48e6f34ec649467
4
+ data.tar.gz: 24410b4335a8e44ed8d1bb62215ce43ec8215e5d3ef949565c022ce533188f6b
5
5
  SHA512:
6
- metadata.gz: 51753f3cc575a7683641c42ccf7d6e2a019bb9dbc2e1791ff8a07149e4c84e282d7d00f0c1b8e45a310f45afaaba99a58b64a0ea48330c745323ebd010e8b8c9
7
- data.tar.gz: 35c90e573f0143dfe8ca6d3119d0b27a33b0f080c2a2e82449ba13f116d6a9b01bd4d4a67b763b8c0d3402ed5fe27825317387fdc6749502510604dca824aec9
6
+ metadata.gz: 4323c21cdf8ba62dc8d11c4c95016064987ca2d256cef7e525cc635286ad57d2fd40fc2d52708677d5d6a970ad335800cd728326befdfbc34dc9e9d8dbd535d9
7
+ data.tar.gz: c835bc2862a1338fb379c0578a4dc9493a372ff0aadf1ec4f1aebb011a383a595b401b5e1868ea53a0584cf8118c5ff3d543525216ff9d20f1148d958205780a
@@ -20,9 +20,11 @@ module Devise::Rownd
20
20
  warden.authenticate!(scope: :user)
21
21
  end
22
22
 
23
+ warden.authenticate!(scope: :user)
24
+
23
25
  render json: {
24
26
  message: 'Successfully authenticated user',
25
- should_refresh_page: new_access_token || session[:rownd_stale_data] == true,
27
+ should_refresh_page: new_access_token || session[:rownd_stale_data] == true
26
28
  }, status: :ok
27
29
  end
28
30
 
@@ -1,19 +1,25 @@
1
1
  require 'devise/rownd/api'
2
+ require 'devise/rownd/caching'
2
3
 
3
4
  module Devise
4
5
  module Rownd
5
6
  include API
6
7
 
7
8
  def app_config
8
- fetch_app_config
9
+ config = Devise::Rownd::Caching.fetch('rownd_app_config', 15.minutes) { fetch_app_config }
10
+
11
+ raise 'Failed to fetch app config' unless config
12
+
13
+ config
9
14
  end
10
15
 
11
16
  def self.fetch_app_config
12
- Rails.cache.fetch("rownd_app_config", expires_in: 15.minutes) do
13
- response = API.make_api_call('/hub/app-config', { method: 'GET',
14
- headers: { 'x-rownd-app-key' => app_key } })
15
- response.body['app'] if response.success?
16
- end
17
+ response = API.make_api_call('/hub/app-config', { method: 'GET',
18
+ headers: { 'x-rownd-app-key' => app_key } })
19
+ return response.body['app'] if response.success?
20
+
21
+ Rails.logger.error("Failed to fetch app config from Rownd: #{response.body['message']}")
22
+ nil
17
23
  end
18
24
 
19
25
  module_function :app_config
@@ -0,0 +1,30 @@
1
+ require 'async'
2
+
3
+ module Devise::Rownd
4
+ module Caching
5
+ def fetch(cache_key, ttl)
6
+ cache_val = Rails.cache.read(cache_key)
7
+
8
+ # If there's nothing in the cache, yield the value and write it to cache
9
+ if cache_val.nil?
10
+ return_value = yield
11
+ Rails.cache.write(cache_key, [return_value, Time.now]) if return_value
12
+ else
13
+ return_value = cache_val[0]
14
+ last_fetch_time = cache_val[1]
15
+
16
+ # Start a new thread to update the cached value if the TTL is exceeded
17
+ Async do
18
+ if Time.now - last_fetch_time > ttl
19
+ new_value = yield
20
+ Rails.cache.write(cache_key, [new_value, Time.now]) if new_value
21
+ end
22
+ end
23
+ end
24
+
25
+ return_value
26
+ end
27
+
28
+ module_function :fetch
29
+ end
30
+ end
@@ -2,6 +2,7 @@ require 'devise'
2
2
  require 'devise/strategies/authenticatable'
3
3
  require 'devise/rownd/user'
4
4
  require 'devise/rownd/api'
5
+ require 'devise/rownd/caching'
5
6
  require 'jose'
6
7
 
7
8
  require_relative '../../../../config/initializers/app_creds'
@@ -20,18 +21,26 @@ module Devise
20
21
  @access_token = session[:rownd_user_access_token]
21
22
  return fail!('No Access Token') unless @access_token
22
23
 
23
- @decoded_jwt = verify_token(@access_token)
24
- @app_id = @decoded_jwt['aud'].find(/^app:.+/).first.split(':').last
24
+ begin
25
+ @decoded_jwt = verify_token(@access_token)
25
26
 
26
- configured_app_id = Devise::Rownd.app_id
27
- ok = @app_id == configured_app_id
28
- return fail!('JWT not authorized for app') unless ok
27
+ @app_id = @decoded_jwt['aud'].find(/^app:.+/).first.split(':').last
29
28
 
30
- rownd_user = Devise::Rownd::User.new(fetch_user)
29
+ configured_app_id = Devise::Rownd.app_id
30
+ ok = @app_id == configured_app_id
31
+ return fail!('JWT not authorized for app') unless ok
31
32
 
32
- return fail!(:unable_to_authenticate) unless rownd_user
33
+ user_data = fetch_user
34
+ return fail!('Failed to fetch user') unless user_data
33
35
 
34
- success!(rownd_user)
36
+ rownd_user = Devise::Rownd::User.new(user_data)
37
+
38
+ return fail!('Failed to initialize user') unless rownd_user
39
+
40
+ success!(rownd_user)
41
+ rescue StandardError => e
42
+ fail!("Unable to authenticate: #{e.message}")
43
+ end
35
44
  end
36
45
 
37
46
  def return_to_after_sign_out
@@ -42,14 +51,14 @@ module Devise
42
51
  cache_key = "rownd_user_#{@decoded_jwt['jti']}"
43
52
  if session[:rownd_stale_data] == true
44
53
  data = fetch_user_from_api
54
+ return nil unless data
55
+
45
56
  Rails.cache.write(cache_key, data, expires_in: 1.minute)
46
57
  session.delete(:rownd_stale_data) if session[:rownd_stale_data]
47
58
  return data
48
59
  end
49
60
 
50
- Rails.cache.fetch(cache_key, expires_in: 1.minute) do
51
- fetch_user_from_api
52
- end
61
+ Devise::Rownd::Caching.fetch(cache_key, 1.minute) { fetch_user_from_api }
53
62
  end
54
63
 
55
64
  def fetch_user_from_api
@@ -62,31 +71,32 @@ module Devise
62
71
  )
63
72
  return response.body['data'] if response.success?
64
73
 
65
- raise StandardError, response.body['message']
74
+ Rails.logger.error("Failed to fetch user: #{response.body['message']}")
75
+ nil
66
76
  end
67
77
 
68
78
  def verify_token(access_token)
69
- for jwk in jwks
70
- begin
71
- response = JOSE::JWT.verify_strict(jwk, ['EdDSA'], access_token)
72
- return response[1].fields if response[0]
73
- rescue StandardError => e
74
- puts "Error: #{e}"
75
- next
76
- end
77
- raise StandardError
79
+ raise StandardError, 'No JWKs' unless jwks
80
+
81
+ jwks.each do |jwk|
82
+ response = JOSE::JWT.verify_strict(jwk, ['EdDSA'], access_token)
83
+ return response[1].fields if response[0]
84
+ rescue StandardError
85
+ next
78
86
  end
87
+ raise StandardError, 'Failed to verify JWT. No matching JWKs'
79
88
  end
80
89
 
81
90
  def jwks
82
- Rails.cache.fetch('rownd_jwks', expires_in: 15.minutes) do
83
- fetch_jwks
84
- end
91
+ Devise::Rownd::Caching.fetch('rownd_jwks', 15.minutes) { fetch_jwks_from_api }
85
92
  end
86
93
 
87
- def fetch_jwks
94
+ def fetch_jwks_from_api
88
95
  response = ::Devise::Rownd::API.make_api_call('/hub/auth/keys')
89
- response.body['keys']
96
+ return response.body['keys'] if response.success?
97
+
98
+ Rails.logger.error("Failed to fetch JWKs: #{response.body['message']}")
99
+ nil
90
100
  end
91
101
  end
92
102
  end
@@ -1,5 +1,5 @@
1
1
  module Devise
2
2
  module Rownd
3
- VERSION = '1.0.2'
3
+ VERSION = '1.0.3'
4
4
  end
5
5
  end
data/lib/devise/rownd.rb CHANGED
@@ -4,6 +4,7 @@ require 'devise/rownd/strategies'
4
4
  require 'devise/rownd/models'
5
5
  require 'devise/rownd/api'
6
6
  require 'devise/rownd/user'
7
+ require 'devise/rownd/caching'
7
8
 
8
9
  module Devise
9
10
  module Rownd
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise-rownd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bobby Radford
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-01 00:00:00.000000000 Z
11
+ date: 2022-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: async
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.30.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.30.2
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: devise
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -191,6 +205,7 @@ files:
191
205
  - config/routes.rb
192
206
  - lib/devise/rownd.rb
193
207
  - lib/devise/rownd/api.rb
208
+ - lib/devise/rownd/caching.rb
194
209
  - lib/devise/rownd/custom_failure.rb
195
210
  - lib/devise/rownd/engine.rb
196
211
  - lib/devise/rownd/models.rb