sync_attr_with_auth0 0.0.2 → 0.0.3

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
2
  SHA1:
3
- metadata.gz: b8fd4fe0d8262793df4e430fb322eeabab071710
4
- data.tar.gz: 849ec5ec07920f5dcca3d340011493109e1f3f2b
3
+ metadata.gz: 28d6cfca51b11a00ab317f9073a6c468ce766c91
4
+ data.tar.gz: 53566a7a330101e2ee36d5007e757393334dfc2d
5
5
  SHA512:
6
- metadata.gz: cb61a603b3c9c88dbe7fb6a4ed63e2735d786a0a9f7a0a478853e1be5de78325c8cd407a71468c88c100a30c951a76f73fd9097bb7a641374be762b127adb0d0
7
- data.tar.gz: cc27922b2519fb9444d4582aa2a854879a30451ca949eae6183d2b247140fa6aa7fd02e6d167dd0d180228c921dd24971a9e33b9180079ed9513cedc51f6f3f6
6
+ metadata.gz: 9a703f54e191345eb816b6310b2700653f563e80946fcccaaa8d48a4da26583cdbbf6b61944a716261cd962a3c4627be9c3a9a0ff182716127267f15c8586e35
7
+ data.tar.gz: 8f2cb379658f3f687016dd0f6ecbceb31372d52ba2ac00b533fa015e1866a2b88ba916d15f83127acdfcd90ad9c636706fea16746d9bf5035db6287c264d2978
@@ -3,44 +3,185 @@ module SyncAttrWithAuth0
3
3
  extend ::ActiveSupport::Concern
4
4
 
5
5
  module ClassMethods
6
- def sync_attr_with_auth0(*args)
7
- class_attribute :auth0_uid_att
8
- class_attribute :auth0_sync_atts
9
6
 
10
- self.auth0_uid_att = args.shift
7
+ def sync_attr_with_auth0(options = {})
8
+ class_attribute :uid_att
9
+ class_attribute :email_att
10
+ class_attribute :password_att
11
+ class_attribute :email_verified_att
12
+ class_attribute :connection_name
13
+ class_attribute :sync_atts
11
14
 
12
- self.auth0_sync_atts ||= []
13
- self.auth0_sync_atts += args.shift.collect(&:to_s)
15
+ _options = merge_default_options(options)
14
16
 
15
- after_save :sync_attr_with_auth0
17
+ self.uid_att = _options[:uid_att]
18
+ self.email_att = _options[:email_att]
19
+ self.password_att = _options[:password_att]
20
+ self.email_verified_att = _options[:email_verified_att]
21
+ self.connection_name = _options[:connection_name]
22
+ self.sync_atts = _options[:sync_atts].collect(&:to_s)
23
+
24
+ after_validation :validate_email_with_auth0
25
+ after_create :create_user_in_auth0
26
+ after_update :sync_attr_with_auth0
27
+ end
28
+
29
+ private
30
+
31
+ def merge_default_options(options)
32
+ _options = {
33
+ uid_att: :uid,
34
+ email_att: :email,
35
+ password_att: :password,
36
+ email_verified_att: :email_verified,
37
+ connection_name: 'Username-Password-Authentication',
38
+ sync_atts: []
39
+ }
40
+
41
+ _options.merge!(options)
42
+
43
+ return _options
16
44
  end
45
+
17
46
  end
18
47
 
19
- def sync_attr_with_auth0
20
- # Look for matches between what's changing
21
- # and what needs to be transmitted to Auth0
22
- matches = ( (self.class.auth0_sync_atts || []) & (self.changes.keys || []) )
48
+ def validate_email_with_auth0
49
+ # If the email is being modified, verify the new email does not already
50
+ # exist in auth0.
51
+
52
+ ok_to_validate = (self.respond_to?(:validate_with_auth0) ? self.validate_with_auth0 : true)
53
+
54
+ if ok_to_validate and self.email_changed?
55
+ # Get an access token
56
+ access_token = SyncAttrWithAuth0::Auth0.get_access_token
57
+
58
+ response = SyncAttrWithAuth0::Auth0.make_request(
59
+ access_token,
60
+ 'get',
61
+ "/api/users?search=email:#{self.email}")
62
+
63
+ return JSON.parse(response).empty?
64
+ end
65
+
66
+ return true
67
+ end
23
68
 
24
- # If we find matches
25
- unless matches.empty?
69
+ def create_user_in_auth0
70
+ # When creating a new user, create the user in auth0.
26
71
 
72
+ ok_to_sync = (self.respond_to?(:sync_with_auth0_on_create) ? self.sync_with_auth0_on_create : true)
73
+
74
+ if ok_to_sync
27
75
  # Get an access token
28
76
  access_token = SyncAttrWithAuth0::Auth0.get_access_token
29
77
 
78
+ # Look for matches between what's changing
79
+ # and what needs to be transmitted to Auth0
80
+ matches = ( (self.class.sync_atts || []) & (self.changes.keys || []) )
81
+
30
82
  # Figure out what needs to be sent to Auth0
31
83
  changes = {}
32
84
  matches.each do |m|
33
85
  changes[m] = self.send(m)
34
86
  end
35
87
 
36
- # If we actually have changes
37
- unless changes.empty?
38
- response = SyncAttrWithAuth0::Auth0.make_request(
39
- access_token,
40
- 'patch',
41
- "/api/users/#{::URI.escape( self.send(auth0_uid_att) )}/metadata",
42
- changes)
88
+ unless changes['email'].nil?
89
+ # Email is already being sent
90
+ changes.delete('email')
43
91
  end
92
+
93
+ unless changes['password'].nil?
94
+ # Password is already being sent
95
+ changes.delete('password')
96
+ end
97
+
98
+ response = SyncAttrWithAuth0::Auth0.make_request(
99
+ access_token,
100
+ 'post',
101
+ "/api/users",
102
+ {
103
+ 'email' => self.send(email_att),
104
+ 'password' => self.send(password_att),
105
+ 'connection' => connection_name,
106
+ 'email_verified' => self.send(email_verified_att)
107
+ }.merge(changes))
108
+
109
+ response = JSON.parse(response)
110
+
111
+ # Update the record with the uid
112
+ self.send("#{uid_att}=", response['user_id'])
113
+ self.save
114
+ end
115
+
116
+ true # don't abort the callback chain
117
+ end
118
+
119
+ def sync_attr_with_auth0
120
+ ok_to_sync = (self.respond_to?(:sync_with_auth0_on_update) ? self.sync_with_auth0_on_update : true)
121
+
122
+ if ok_to_sync
123
+ # Look for matches between what's changing
124
+ # and what needs to be transmitted to Auth0
125
+ matches = ( (self.class.sync_atts || []) & (self.changes.keys || []) )
126
+
127
+ # If we find matches
128
+ unless matches.empty?
129
+
130
+ # Get an access token
131
+ access_token = SyncAttrWithAuth0::Auth0.get_access_token
132
+
133
+ # Figure out what needs to be sent to Auth0
134
+ changes = {}
135
+ matches.each do |m|
136
+ changes[m] = self.send(m)
137
+ end
138
+
139
+ # If we actually have changes
140
+ unless changes.empty?
141
+ # Get the auth0 uid
142
+ uid = self.send(uid_att)
143
+
144
+ # Don't try to update auth0 if the user doesn't have a uid
145
+ unless uid.nil?
146
+ # Determine if the email was changed
147
+ unless changes['email'].nil?
148
+ email = changes.delete('email')
149
+
150
+ response = SyncAttrWithAuth0::Auth0.make_request(
151
+ access_token,
152
+ 'put',
153
+ "/api/users/#{::URI.escape(uid)}/email",
154
+ {
155
+ 'email' => email,
156
+ 'verify' => false # If the user were to fail to verify it would create a discrepency between auth0 and the local database
157
+ })
158
+ end
159
+
160
+ # Determine if the password was changed
161
+ unless changes['password'].nil?
162
+ password = changes.delete('password')
163
+
164
+ response = SyncAttrWithAuth0::Auth0.make_request(
165
+ access_token,
166
+ 'put',
167
+ "/api/users/#{::URI.escape(uid)}/password",
168
+ {
169
+ 'password' => password,
170
+ 'verify' => true
171
+ })
172
+ end
173
+
174
+ # Patch the changes
175
+ response = SyncAttrWithAuth0::Auth0.make_request(
176
+ access_token,
177
+ 'patch',
178
+ "/api/users/#{::URI.escape(uid)}/metadata",
179
+ changes)
180
+ end
181
+
182
+ end
183
+ end
184
+
44
185
  end
45
186
 
46
187
  true # don't abort the callback chain
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.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick McGraw
@@ -124,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
124
  version: '0'
125
125
  requirements: []
126
126
  rubyforge_project:
127
- rubygems_version: 2.4.5
127
+ rubygems_version: 2.4.6
128
128
  signing_key:
129
129
  specification_version: 4
130
130
  summary: Synchronize attributes on a local ActiveRecord user model with the user metadata