sync_attr_with_auth0 0.1.7 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cbd1d27afcb626e027d6b5d610d048e52611480e
4
- data.tar.gz: 1c0ba300b82dc2a2cb1a8da61ed0b16805967d96
2
+ SHA256:
3
+ metadata.gz: 0e0afb86d465d9c136f38d604c69f198a86a969b77301f6abf60da12aa98cf54
4
+ data.tar.gz: 237034211a5eaf258332933e8c10c3e2744b3033dd83f8f859dd578b42d06b63
5
5
  SHA512:
6
- metadata.gz: 2f8a355e4b26d652563dc2812108c13019ea5a18f1def848efdc749149e39877c3d0722780f11ae8449b2233629e130bf0fe9810943fc7a6f3c26e576e161f9c
7
- data.tar.gz: 0250be3d225041f815f7960f5fb59f25834799750b405168297bdecaea174611d8115ee5352c65d68eb58432f8a5c228585a83d3638d00c3d955259f03828b81
6
+ metadata.gz: 978bc082c1c60d5d13ba2a20a5f1d8faf5da73596e852c75d2d53aa6893a46fcfc1104029788ccc8b7320161597a3e352f365958b816b0f118bbde50e92e71d7
7
+ data.tar.gz: f87f7c4145859950ea7336adde22913c4ec1390893c57a097b77cf7147f2e18e068bf4fa3d3b4cd60f6d4e41feeae4183e3881fb471360fafce32aedab1d17ed
@@ -13,6 +13,7 @@ module SyncAttrWithAuth0
13
13
 
14
14
  module ClassMethods
15
15
 
16
+ # TODO: We should accept two arrays of fields: user_metadata (for user-managed settings) and app_metadata (for app-managed settings)
16
17
  def sync_attr_with_auth0(*fields)
17
18
  options = fields.extract_options!
18
19
 
@@ -33,9 +34,9 @@ module SyncAttrWithAuth0
33
34
 
34
35
  # Setup callbacks
35
36
  after_validation :validate_email_with_auth0
36
- after_create :save_to_auth0_on_create
37
- after_update :save_to_auth0_on_update
38
- after_commit :update_uid_from_auth0
37
+ after_create :save_to_auth0_after_create
38
+ after_update :save_to_auth0_after_update
39
+ after_commit :update_uid_and_picture_from_auth0
39
40
  end # sync_attr_with_auth0
40
41
 
41
42
  end # ClassMethods
@@ -52,18 +53,27 @@ module SyncAttrWithAuth0
52
53
  end # auth0_user_email
53
54
 
54
55
 
55
- def auth0_user_email_changed?
56
+ def auth0_user_saved_change_to_email?
56
57
  return false unless self.respond_to?(auth0_sync_configuration.email_attribute)
57
58
  # return false unless sync_email_with_auth0? # We don't care if it changed if we aren't syncing it.
58
59
 
59
- return self.send("#{auth0_sync_configuration.email_attribute}_changed?")
60
- end # auth0_email_changed?
60
+ if respond_to? :"saved_change_to_#{auth0_sync_configuration.email_attribute}?"
61
+ # Modern method
62
+ public_send :"saved_change_to_#{auth0_sync_configuration.email_attribute}?"
63
+ else
64
+ # Legacy method. Drop when no longer supporting <= Rails 5.1
65
+ public_send :"#{auth0_sync_configuration.email_attribute}_changed?"
66
+ end
67
+ end # auth0_user_saved_change_to_email?
61
68
 
62
69
 
63
70
  def auth0_user_uid
64
71
  self.send(auth0_sync_configuration.auth0_uid_attribute) if self.respond_to?(auth0_sync_configuration.auth0_uid_attribute)
65
72
  end # auth0_user_uid
66
73
 
74
+ def auth0_picture
75
+ public_send auth0_sync_configuration.picture_attribute if respond_to? auth0_sync_configuration.picture_attribute
76
+ end
67
77
 
68
78
  def auth0_user_name
69
79
  self.send(auth0_sync_configuration.name_attribute) if self.respond_to?(auth0_sync_configuration.name_attribute)
@@ -85,18 +95,21 @@ module SyncAttrWithAuth0
85
95
  end # auth0_user_password
86
96
 
87
97
 
88
- def auth0_user_password_changed?
98
+ def auth0_user_saved_change_to_password?
89
99
  return false unless self.respond_to?(auth0_sync_configuration.password_attribute)
90
- # return false unless sync_password_with_auth0? # We don't care if it changed if we aren't syncing it.
91
100
 
92
- if self.respond_to?(:"#{auth0_sync_configuration.password_attribute.to_s}_changed?")
93
- # We have a changed method, use it
94
- return self.send(:"#{auth0_sync_configuration.password_attribute.to_s}_changed?")
95
- else
96
- # We don't have a changed method, check if the attribute was set.
97
- return !self.send(auth0_sync_configuration.password_attribute).nil?
101
+ case
102
+ when respond_to?(:"saved_change_to_#{auth0_sync_configuration.password_attribute}?")
103
+ # Prefer modern method
104
+ public_send :"saved_change_to_#{auth0_sync_configuration.password_attribute}?"
105
+ when respond_to?(:"#{auth0_sync_configuration.password_attribute}_changed?")
106
+ # Legacy method. Drop when no longer supporting <= Rails 5.1
107
+ public_send :"#{auth0_sync_configuration.password_attribute}_changed?"
108
+ else
109
+ # Neither exists so must be in-memory accessor. Just check if set.
110
+ public_send(auth0_sync_configuration.password_attribute).present?
98
111
  end
99
- end # auth0_user_password_changed?
112
+ end # auth0_user_saved_change_to_password?
100
113
 
101
114
 
102
115
  def auth0_default_password
@@ -23,40 +23,50 @@ module SyncAttrWithAuth0
23
23
  end # sync_with_auth0_on_update?
24
24
 
25
25
 
26
- def save_to_auth0_on_create
26
+ def save_to_auth0_after_create
27
27
  return true unless sync_with_auth0_on_create?
28
28
 
29
29
  save_to_auth0
30
30
 
31
31
  true # don't abort the callback chain
32
- end # save_to_auth0_on_create
32
+ end # save_to_auth0_after_create
33
33
 
34
34
 
35
- def save_to_auth0_on_update
35
+ def save_to_auth0_after_update
36
36
  return true unless sync_with_auth0_on_update?
37
- return true unless auth0_dirty?
37
+ return true unless auth0_saved_change_dirty?
38
38
 
39
39
  save_to_auth0
40
40
 
41
41
  true # don't abort the callback chain
42
- end # save_to_auth0_on_update
42
+ end # save_to_auth0_after_update
43
43
 
44
44
 
45
- def auth0_dirty?
46
- is_dirty = !!(
47
- auth0_attributes_to_sync.inject(false) do |memo, attrib|
48
- memo || self.try("#{attrib}_changed?")
45
+ def auth0_saved_change_dirty?
46
+ is_dirty = auth0_attributes_to_sync.any? do |attrib|
47
+ if respond_to? :"saved_change_to_#{attrib}?"
48
+ # Prefer modern method
49
+ public_send :"saved_change_to_#{attrib}?"
50
+ elsif respond_to? :"#{attrib}_changed?"
51
+ # Legacy method. Drop when no longer supporting <= Rails 5.1
52
+ public_send :"#{attrib}_changed?"
53
+ else
54
+ # Specs currently verify attributes specified as needing synced
55
+ # that are not defined not cause an error. I'm not sure why we
56
+ # need this. Seems like a misconfiguration and we should blow
57
+ # up. But to limit scope of change keeping with defined behavior.
58
+ false
49
59
  end
50
- )
60
+ end
51
61
 
52
62
  # If the password was changed, force is_dirty to be true
53
- is_dirty = true if auth0_user_password_changed?
63
+ is_dirty = true if auth0_user_saved_change_to_password?
54
64
 
55
65
  # If the email was changed, force is_dirty to be true
56
- is_dirty = true if auth0_user_email_changed?
66
+ is_dirty = true if auth0_user_saved_change_to_email?
57
67
 
58
68
  return is_dirty
59
- end # auth0_dirty?
69
+ end # auth0_saved_change_dirty?
60
70
 
61
71
 
62
72
  def save_to_auth0
@@ -86,8 +96,9 @@ module SyncAttrWithAuth0
86
96
 
87
97
  response = SyncAttrWithAuth0::Auth0.create_user(auth0_user_name, params, config: auth0_sync_configuration)
88
98
 
89
- # Update the record with the uid after_commit
99
+ # Update the record with the uid and picture after_commit
90
100
  @auth0_uid = response['user_id']
101
+ @auth0_picture = response['picture']
91
102
  end # create_in_auth0
92
103
 
93
104
 
@@ -97,10 +108,11 @@ module SyncAttrWithAuth0
97
108
  params = auth0_update_params
98
109
 
99
110
  begin
100
- SyncAttrWithAuth0::Auth0.patch_user(user_uid, params, config: auth0_sync_configuration)
111
+ response = SyncAttrWithAuth0::Auth0.patch_user(user_uid, params, config: auth0_sync_configuration)
101
112
 
102
113
  # Update the record with the uid after_commit (in case it doesn't match what's on file).
103
114
  @auth0_uid = user_uid
115
+ @auth0_picture = response['picture']
104
116
  rescue ::Auth0::NotFound => e
105
117
  # For whatever reason, the passed in uid was invalid,
106
118
  # determine how to proceed.
@@ -113,10 +125,11 @@ module SyncAttrWithAuth0
113
125
  else
114
126
  # The uid was incorrect, so re-attempt with the new uid
115
127
  # and update the one on file.
116
- SyncAttrWithAuth0::Auth0.patch_user(found_user['user_id'], params, config: auth0_sync_configuration)
128
+ response = SyncAttrWithAuth0::Auth0.patch_user(found_user['user_id'], params, config: auth0_sync_configuration)
117
129
 
118
130
  # Update the record with the uid after_commit
119
131
  @auth0_uid = found_user['user_id']
132
+ @auth0_picture = response['picture']
120
133
  end
121
134
 
122
135
  rescue Exception => e
@@ -146,6 +159,10 @@ module SyncAttrWithAuth0
146
159
  'password' => password,
147
160
  'connection' => auth0_sync_configuration.connection_name,
148
161
  'email_verified' => email_verified,
162
+ 'name' => auth0_user_name,
163
+ 'nickname' => auth0_user_name,
164
+ 'given_name' => auth0_user_given_name,
165
+ 'family_name' => auth0_user_family_name,
149
166
  'user_metadata' => user_metadata,
150
167
  'app_metadata' => app_metadata
151
168
  }
@@ -159,40 +176,50 @@ module SyncAttrWithAuth0
159
176
  app_metadata = auth0_app_metadata
160
177
 
161
178
  params = {
179
+ 'name' => auth0_user_name,
180
+ 'nickname' => auth0_user_name,
181
+ 'given_name' => auth0_user_given_name,
182
+ 'family_name' => auth0_user_family_name,
162
183
  'app_metadata' => app_metadata,
163
184
  'user_metadata' => user_metadata
164
185
  }
165
186
 
166
- if auth0_user_password_changed?
187
+ if auth0_user_saved_change_to_password?
167
188
  # The password needs to be updated.
168
189
  params['password'] = auth0_user_password
169
190
  params['verify_password'] = auth0_verify_password?
170
191
  end
171
192
 
172
- if auth0_user_email_changed?
193
+ if auth0_user_saved_change_to_email?
173
194
  # The email needs to be updated.
174
195
  params['email'] = auth0_user_email
175
- params['verify_email'] = auth0_email_verified?
196
+ params['verify_email'] = !auth0_email_verified?
176
197
  end
177
198
 
178
199
  return params
179
200
  end # auth0_update_params
180
201
 
181
202
 
182
- def update_uid_from_auth0
183
- if @auth0_uid
184
- self.sync_with_auth0_on_update = false if self.respond_to?(:sync_with_auth0_on_update=)
185
- self.send("#{auth0_sync_configuration.auth0_uid_attribute}=", @auth0_uid)
203
+ def update_uid_and_picture_from_auth0
204
+ data = {}
186
205
 
187
- # Nil the instance variable to prevent an infinite loop
188
- @auth0_uid = nil
206
+ if @auth0_uid
207
+ attr = auth0_sync_configuration.auth0_uid_attribute
208
+ data[attr] = @auth0_uid if respond_to?(attr) && @auth0_uid != public_send(attr)
209
+ end
189
210
 
190
- # Save!
191
- self.save
211
+ if @auth0_picture
212
+ attr = auth0_sync_configuration.picture_attribute
213
+ data[attr] = @auth0_picture if respond_to?(attr) && @auth0_picture != public_send(attr)
192
214
  end
193
215
 
216
+ update_columns data unless data.empty?
217
+
218
+ remove_instance_variable :@auth0_uid if defined? @auth0_uid
219
+ remove_instance_variable :@auth0_picture if defined? @auth0_picture
220
+
194
221
  true # don't abort the callback chain
195
- end # update_uid_from_auth0
222
+ end # update_uid_and_picture_from_auth0
196
223
 
197
224
  end
198
225
  end
@@ -14,7 +14,7 @@ module SyncAttrWithAuth0
14
14
  }
15
15
  },
16
16
  'iat' => Time.now.to_i,
17
- 'jti' => UUIDTools::UUID.timestamp_create.to_s
17
+ 'jti' => UUIDTools::UUID.random_create.to_s
18
18
  }
19
19
 
20
20
  jwt = JWT.encode(payload, JWT.base64url_decode(global_client_secret))
@@ -68,7 +68,15 @@ module SyncAttrWithAuth0
68
68
  auth0 = SyncAttrWithAuth0::Auth0.create_auth0_client(config: config)
69
69
 
70
70
  # Use the Lucene search because Find by Email is case sensitive
71
- results = auth0.get('/api/v2/users', q: "email:#{email}")
71
+ query = "email:#{email}"
72
+ unless config.search_connections.empty?
73
+ conn_query = config.search_connections
74
+ .collect { |conn| %Q{identities.connection:"#{conn}"} }
75
+ .join ' OR '
76
+ query = "#{query} AND (#{conn_query})"
77
+ end
78
+
79
+ results = auth0.get('/api/v2/users', q: query, search_engine: 'v3')
72
80
 
73
81
  if exclude_user_id
74
82
  results = results.reject { |r| r['user_id'] == exclude_user_id }
@@ -31,8 +31,8 @@ module SyncAttrWithAuth0
31
31
  :auth0_client_id, :auth0_client_secret, :auth0_namespace,
32
32
  :auth0_uid_attribute, :name_attribute, :given_name_attribute,
33
33
  :family_name_attribute, :email_attribute, :password_attribute,
34
- :email_verified_attribute, :verify_password_attribute,
35
- :connection_name
34
+ :email_verified_attribute, :verify_password_attribute, :picture_attribute,
35
+ :connection_name, :search_connections
36
36
 
37
37
 
38
38
  def initialize
@@ -50,7 +50,9 @@ module SyncAttrWithAuth0
50
50
  @password_attribute = :password
51
51
  @email_verified_attribute = :email_verified
52
52
  @verify_password_attribute = :verify_password
53
+ @picture_attribute = :picture
53
54
  @connection_name = 'Username-Password-Authentication'
55
+ @search_connections = []
54
56
  end
55
57
  end
56
58
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sync_attr_with_auth0
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick McGraw
@@ -29,16 +29,16 @@ dependencies:
29
29
  name: json
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - "~>"
32
+ - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: 1.8.1
34
+ version: '0'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - "~>"
39
+ - - ">="
40
40
  - !ruby/object:Gem::Version
41
- version: 1.8.1
41
+ version: '0'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: activerecord
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -99,14 +99,14 @@ dependencies:
99
99
  name: jwt
100
100
  requirement: !ruby/object:Gem::Requirement
101
101
  requirements:
102
- - - '='
102
+ - - "~>"
103
103
  - !ruby/object:Gem::Version
104
104
  version: 1.5.0
105
105
  type: :runtime
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - '='
109
+ - - "~>"
110
110
  - !ruby/object:Gem::Version
111
111
  version: 1.5.0
112
112
  - !ruby/object:Gem::Dependency
@@ -169,8 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
169
169
  - !ruby/object:Gem::Version
170
170
  version: '0'
171
171
  requirements: []
172
- rubyforge_project:
173
- rubygems_version: 2.6.13
172
+ rubygems_version: 3.1.2
174
173
  signing_key:
175
174
  specification_version: 4
176
175
  summary: Synchronize attributes on a local ActiveRecord user model with the user metadata