cognito_rails 0.1.0 → 1.0.0
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/cognito_rails/config.rb +6 -17
- data/lib/cognito_rails/model.rb +49 -0
- data/lib/cognito_rails/user.rb +18 -14
- data/lib/cognito_rails/version.rb +1 -1
- data/spec/cognito_rails/user_spec.rb +36 -0
- data/spec/spec_helper.rb +5 -4
- data/spec/support/cognito_helpers.rb +20 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8bbd85c82670198044b07ac6bd693920201e3911166f1432365bd834e54fafd
|
4
|
+
data.tar.gz: 1c435514395d116f142fb22121bb0bdb7cdb91b46897b48566453e3748ae184d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11bea4faacf98021ee61a6ae2280e4da743fd1e62e68c4dc88681c98f735973ccabc5806261df3e1d22243da42eef7fb3ddc2fc02f5c06677e6291f1e3d9f780
|
7
|
+
data.tar.gz: 26ba725b881ab2333e8ea5823ac199fc4fd430426b85f1f50832d2e9b1985db692615d2543ef7cea6d6a21aa8cddfdc9358194bf0ce30655acb35b0a971a1d90
|
data/lib/cognito_rails/config.rb
CHANGED
@@ -5,26 +5,21 @@ require 'logger'
|
|
5
5
|
module CognitoRails
|
6
6
|
class Config
|
7
7
|
class << self
|
8
|
-
# @raise [RuntimeError] if not set
|
9
8
|
# @return [String] AWS access key id
|
10
|
-
def
|
11
|
-
|
12
|
-
@aws_access_key_id || (raise 'Missing config aws_access_key_id')
|
9
|
+
def aws_client_credentials
|
10
|
+
@aws_client_credentials || {}
|
13
11
|
end
|
14
12
|
|
15
|
-
# @!attribute
|
16
|
-
# @return [
|
13
|
+
# @!attribute aws_client_credentials [w]
|
14
|
+
# @return [Hash]
|
17
15
|
# @!attribute aws_region [w]
|
18
16
|
# @return [String]
|
19
|
-
# @!attribute aws_secret_access_key [w]
|
20
|
-
# @return [String]
|
21
17
|
# @!attribute aws_user_pool_id [w]
|
22
18
|
# @return [String]
|
23
19
|
# @!attribute default_user_class [w]
|
24
20
|
# @return [String,nil]
|
25
|
-
attr_writer :
|
26
|
-
:
|
27
|
-
:default_user_class
|
21
|
+
attr_writer :aws_client_credentials, :skip_model_hooks, :aws_region,
|
22
|
+
:aws_user_pool_id, :default_user_class
|
28
23
|
|
29
24
|
# @return [Boolean] skip model hooks
|
30
25
|
def skip_model_hooks
|
@@ -43,12 +38,6 @@ module CognitoRails
|
|
43
38
|
@aws_region || (raise 'Missing config aws_region')
|
44
39
|
end
|
45
40
|
|
46
|
-
# @return [String] AWS secret access key
|
47
|
-
# @raise [RuntimeError] if not set
|
48
|
-
def aws_secret_access_key
|
49
|
-
@aws_secret_access_key || (raise 'Missing config aws_secret_access_key')
|
50
|
-
end
|
51
|
-
|
52
41
|
# @return [String] AWS user pool id
|
53
42
|
# @raise [RuntimeError] if not set
|
54
43
|
def aws_user_pool_id
|
data/lib/cognito_rails/model.rb
CHANGED
@@ -23,6 +23,55 @@ module CognitoRails
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
# rubocop:disable Metrics/BlockLength
|
27
|
+
class_methods do
|
28
|
+
# @return [Array<ActiveRecord::Base>] all users
|
29
|
+
# @raise [CognitoRails::Error] if failed to fetch users
|
30
|
+
# @raise [ActiveRecord::RecordInvalid] if failed to save user
|
31
|
+
def sync_from_cognito!
|
32
|
+
response = User.all
|
33
|
+
response.users.map do |user_data|
|
34
|
+
sync_user!(user_data)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [Array<ActiveRecord::Base>] all users
|
39
|
+
# @raise [CognitoRails::Error] if failed to fetch users
|
40
|
+
# @raise [ActiveRecord::RecordInvalid] if failed to save user
|
41
|
+
def sync_to_cognito!
|
42
|
+
find_each.map do |user|
|
43
|
+
user.init_cognito_user
|
44
|
+
user.save!
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def sync_user!(user_data)
|
51
|
+
external_id = user_data.username
|
52
|
+
return if external_id.blank?
|
53
|
+
|
54
|
+
user = find_or_initialize_by(_cognito_attribute_name => external_id)
|
55
|
+
user.email = User.extract_cognito_attribute(user_data.attributes, :email)
|
56
|
+
user.phone = User.extract_cognito_attribute(user_data.attributes, :phone_number) if user.respond_to?(:phone)
|
57
|
+
_cognito_resolve_custom_attribute(user, user_data)
|
58
|
+
|
59
|
+
user.save!
|
60
|
+
user
|
61
|
+
end
|
62
|
+
|
63
|
+
def _cognito_resolve_custom_attribute(user, user_data)
|
64
|
+
_cognito_custom_attributes.each do |attribute|
|
65
|
+
next if attribute[:value].is_a?(String)
|
66
|
+
|
67
|
+
value = User.extract_cognito_attribute(user_data.attributes, attribute[:name])
|
68
|
+
next unless value
|
69
|
+
|
70
|
+
user[attribute[:name].gsub('custom:', '')] = value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
26
75
|
# @return [String]
|
27
76
|
def cognito_external_id
|
28
77
|
self[self.class._cognito_attribute_name]
|
data/lib/cognito_rails/user.rb
CHANGED
@@ -57,11 +57,15 @@ module CognitoRails
|
|
57
57
|
)
|
58
58
|
user = new(user_class: user_class)
|
59
59
|
user.id = result.username
|
60
|
-
user.email = result.user_attributes
|
61
|
-
user.phone = result.user_attributes
|
60
|
+
user.email = extract_cognito_attribute(result.user_attributes, :email)
|
61
|
+
user.phone = extract_cognito_attribute(result.user_attributes, :phone_number)
|
62
62
|
user
|
63
63
|
end
|
64
64
|
|
65
|
+
def self.all
|
66
|
+
cognito_client.list_users(user_pool_id: CognitoRails::Config.aws_user_pool_id)
|
67
|
+
end
|
68
|
+
|
65
69
|
# @param attributes [Hash]
|
66
70
|
# @option attributes [String] :email
|
67
71
|
# @option attributes [String] :password
|
@@ -138,6 +142,18 @@ module CognitoRails
|
|
138
142
|
destroy || (raise ActiveRecord::RecordInvalid, self)
|
139
143
|
end
|
140
144
|
|
145
|
+
# @return [Aws::CognitoIdentityProvider::Client]
|
146
|
+
# @raise [RuntimeError]
|
147
|
+
def self.cognito_client
|
148
|
+
@cognito_client ||= Aws::CognitoIdentityProvider::Client.new(
|
149
|
+
{ region: CognitoRails::Config.aws_region }.merge(CognitoRails::Config.aws_client_credentials)
|
150
|
+
)
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.extract_cognito_attribute(attributes, column)
|
154
|
+
attributes.find { |attribute| attribute[:name] == column.to_s }&.dig(:value)
|
155
|
+
end
|
156
|
+
|
141
157
|
private
|
142
158
|
|
143
159
|
# @return [Aws::CognitoIdentityProvider::Client]
|
@@ -155,18 +171,6 @@ module CognitoRails
|
|
155
171
|
user_class._cognito_verify_phone
|
156
172
|
end
|
157
173
|
|
158
|
-
# @return [Aws::CognitoIdentityProvider::Client]
|
159
|
-
# @raise [RuntimeError]
|
160
|
-
def self.cognito_client
|
161
|
-
raise 'Can\'t create user in test mode' if Rails.env.test?
|
162
|
-
|
163
|
-
@cognito_client ||= Aws::CognitoIdentityProvider::Client.new(
|
164
|
-
access_key_id: CognitoRails::Config.aws_access_key_id,
|
165
|
-
secret_access_key: CognitoRails::Config.aws_secret_access_key,
|
166
|
-
region: CognitoRails::Config.aws_region
|
167
|
-
)
|
168
|
-
end
|
169
|
-
|
170
174
|
# @return [Array<Hash>]
|
171
175
|
def general_user_attributes
|
172
176
|
[
|
@@ -111,6 +111,42 @@ RSpec.describe CognitoRails::User, type: :model do
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
+
context 'class methods' do
|
115
|
+
before do
|
116
|
+
expect(CognitoRails::User).to receive(:cognito_client).at_least(:once).and_return(fake_cognito_client)
|
117
|
+
end
|
118
|
+
|
119
|
+
it '#sync_from_cognito!' do
|
120
|
+
expect(fake_cognito_client).to receive(:list_users).and_return(
|
121
|
+
OpenStruct.new(
|
122
|
+
users: [
|
123
|
+
build_cognito_user_data('some@example.com'),
|
124
|
+
build_cognito_user_data('some2@example.com')
|
125
|
+
],
|
126
|
+
pagination_token: nil
|
127
|
+
)
|
128
|
+
)
|
129
|
+
|
130
|
+
expect do
|
131
|
+
users = User.sync_from_cognito!
|
132
|
+
|
133
|
+
expect(users).to be_a(Array)
|
134
|
+
expect(users.size).to eq(2)
|
135
|
+
expect(users.first).to be_a(User)
|
136
|
+
end.to change { User.count }.by(2)
|
137
|
+
|
138
|
+
expect(User.pluck(:email)).to match_array(['some@example.com', 'some2@example.com'])
|
139
|
+
expect(User.pluck(:name)).to match_array(['Giovanni', 'Giovanni'])
|
140
|
+
end
|
141
|
+
|
142
|
+
it '#sync_to_cognito!' do
|
143
|
+
User.create!(email: sample_cognito_email)
|
144
|
+
|
145
|
+
expect_any_instance_of(User).to receive(:init_cognito_user).exactly(1).times
|
146
|
+
User.sync_to_cognito!
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
114
150
|
context 'admin' do
|
115
151
|
before do
|
116
152
|
expect(CognitoRails::User).to receive(:cognito_client).at_least(:once).and_return(fake_cognito_client)
|
data/spec/spec_helper.rb
CHANGED
@@ -11,16 +11,17 @@ require 'factories/user'
|
|
11
11
|
I18n.enforce_available_locales = false
|
12
12
|
RSpec::Expectations.configuration.warn_about_potential_false_positives = false
|
13
13
|
|
14
|
-
Dir[File.expand_path('../support/*.rb', __FILE__)].each { |f| require f }
|
14
|
+
Dir[File.expand_path('../support/*.rb', __FILE__)].sort.each { |f| require f }
|
15
15
|
|
16
|
-
CognitoRails::Config.
|
16
|
+
CognitoRails::Config.aws_client_credentials = {
|
17
|
+
access_key_id: 'access_key_id',
|
18
|
+
secret_access_key: 'secret_access_key'
|
19
|
+
}
|
17
20
|
CognitoRails::Config.aws_region = 'region'
|
18
|
-
CognitoRails::Config.aws_secret_access_key = 'secret_access_key'
|
19
21
|
CognitoRails::Config.aws_user_pool_id = 'user_pool_id'
|
20
22
|
CognitoRails::Config.default_user_class = 'User'
|
21
23
|
|
22
24
|
RSpec.configure do |config|
|
23
|
-
|
24
25
|
config.include FactoryBot::Syntax::Methods
|
25
26
|
|
26
27
|
config.before(:suite) do
|
@@ -40,4 +40,24 @@ module CognitoRails::Helpers
|
|
40
40
|
client
|
41
41
|
end
|
42
42
|
end
|
43
|
+
|
44
|
+
def build_cognito_user_data(email)
|
45
|
+
OpenStruct.new(
|
46
|
+
username: SecureRandom.uuid,
|
47
|
+
user_status: 'CONFIRMED',
|
48
|
+
enabled: true,
|
49
|
+
user_last_modified_date: Time.now,
|
50
|
+
attributes: [
|
51
|
+
OpenStruct.new(
|
52
|
+
name: 'email',
|
53
|
+
value: email
|
54
|
+
),
|
55
|
+
OpenStruct.new(
|
56
|
+
name: 'custom:name',
|
57
|
+
value: 'Giovanni'
|
58
|
+
)
|
59
|
+
],
|
60
|
+
mfa_options: []
|
61
|
+
)
|
62
|
+
end
|
43
63
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cognito_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mònade
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-03-
|
11
|
+
date: 2023-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|