cognito_rails 1.1.0 → 1.3.0

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: 1b69f6c8db91a764df6878e0de53feb9879f7509e79bf0d406e6fe9522f96e61
4
- data.tar.gz: f44a4f4dfce641e54493730c9f183c9bd2f6a2e73fe4cd0c7a60d084b6d0d09a
3
+ metadata.gz: bf2686f37e8a52be09eb2a043f21055fca0823015460b964e448ccc27e7a5637
4
+ data.tar.gz: d5d983d923769b5ff58325e05d5a5f942b69efe80b9e0adbcc9ca384fe3b8960
5
5
  SHA512:
6
- metadata.gz: 17551dd1de906fd5813214f4fdd98bd49f7d4503138cfa5cd9beedc235707dc00b000d356e090a154b7de0c08e692553154b273d50236b31f455903044c97594
7
- data.tar.gz: ee07b9c1b821bc601ac2c62d4268392783e5f687da1d9b810d6160f64c5b7f3546ffd7e5998f05a5a03fc2326bd162e338e0be2ceda461d2cae1152072e44ec8
6
+ metadata.gz: bf8e6743abb4d4a7968598b84c08a92c04b1838fdab5754e75d6157626b7f1b8106397a917799872693e0da51e0f310b3e353759b36e2c77bc6fbb0d85d321c0
7
+ data.tar.gz: bc2b2a108801f6d108d13db71b1ac7c86ab3c9bf16fbf0cb93d0bd1e59f488b16eb7009df04088eaec9ac6c68706dfb651a30db7b856e36f8a2b7ef03835bdbb
@@ -12,6 +12,7 @@ module CognitoRails
12
12
  class_attribute :_cognito_verify_phone
13
13
  class_attribute :_cognito_custom_attributes
14
14
  class_attribute :_cognito_attribute_name
15
+ class_attribute :_cognito_password_policy
15
16
  self._cognito_custom_attributes = []
16
17
 
17
18
  before_create do
@@ -28,10 +29,13 @@ module CognitoRails
28
29
  # @return [Array<ActiveRecord::Base>] all users
29
30
  # @raise [CognitoRails::Error] if failed to fetch users
30
31
  # @raise [ActiveRecord::RecordInvalid] if failed to save user
32
+ # @yield [user, user_data] yields user and user_data just before saving
31
33
  def sync_from_cognito!
32
34
  response = User.all
33
35
  response.users.map do |user_data|
34
- sync_user!(user_data)
36
+ sync_user!(user_data) do |user|
37
+ yield user, user_data if block_given?
38
+ end
35
39
  end
36
40
  end
37
41
 
@@ -56,6 +60,8 @@ module CognitoRails
56
60
  user.phone = User.extract_cognito_attribute(user_data.attributes, :phone_number) if user.respond_to?(:phone)
57
61
  _cognito_resolve_custom_attribute(user, user_data)
58
62
 
63
+ yield user if block_given?
64
+
59
65
  user.save!
60
66
  user
61
67
  end
@@ -137,6 +143,10 @@ module CognitoRails
137
143
  self._cognito_verify_phone = true
138
144
  end
139
145
 
146
+ def cognito_password_policy(type)
147
+ self._cognito_password_policy = type
148
+ end
149
+
140
150
  # @param name [String] attribute name
141
151
  # @param value [String] attribute name
142
152
  def define_cognito_attribute(name, value)
@@ -171,6 +171,11 @@ module CognitoRails
171
171
  user_class._cognito_verify_phone
172
172
  end
173
173
 
174
+ # @return [Symbol] :temporary | :user_provided
175
+ def cognito_password_policy
176
+ user_class._cognito_password_policy || :temporary
177
+ end
178
+
174
179
  # @return [Array<Hash>]
175
180
  def general_user_attributes
176
181
  [
@@ -188,18 +193,41 @@ module CognitoRails
188
193
  ]
189
194
  end
190
195
 
196
+ # @return [Array<Hash>]
197
+ def password_attributes
198
+ if cognito_password_policy == :user_provided
199
+ { message_action: 'SUPPRESS' }
200
+ else
201
+ { temporary_password: password }
202
+ end
203
+ end
204
+
205
+ def set_user_provided_password
206
+ cognito_client.admin_set_user_password(
207
+ {
208
+ user_pool_id: CognitoRails::Config.aws_user_pool_id,
209
+ username: email,
210
+ password: password,
211
+ permanent: true
212
+ }
213
+ )
214
+ end
215
+
191
216
  def save_for_create
192
217
  resp = cognito_client.admin_create_user(
193
218
  {
194
219
  user_pool_id: CognitoRails::Config.aws_user_pool_id,
195
220
  username: email,
196
- temporary_password: password,
197
221
  user_attributes: [
198
222
  *general_user_attributes,
199
223
  *verify_user_attributes
200
- ]
224
+ ],
225
+ **password_attributes
201
226
  }
202
227
  )
228
+
229
+ set_user_provided_password if cognito_password_policy == :user_provided
230
+
203
231
  self.id = resp.user.attributes.find { |a| a[:name] == 'sub' }[:value]
204
232
  end
205
233
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  module CognitoRails
4
4
  # @return [String] gem version
5
- VERSION = '1.1.0'
5
+ VERSION = '1.3.0'
6
6
  end
@@ -7,6 +7,7 @@ RSpec.describe CognitoRails::User, type: :model do
7
7
 
8
8
  let(:sample_cognito_email) { 'some@mail.com' }
9
9
  let(:sample_cognito_phone) { '123456789' }
10
+ let(:sample_cognito_password) { '123qweASD!@#' }
10
11
 
11
12
  it 'validates email presence' do
12
13
  expect(subject).to have(1).error_on(:email)
@@ -136,6 +137,14 @@ RSpec.describe CognitoRails::User, type: :model do
136
137
 
137
138
  User.create!(email: sample_cognito_email, name: 'TestName')
138
139
  end
140
+
141
+ it 'creates a cognito user with user_provided' do
142
+ expect(fake_cognito_client).to receive(:admin_set_user_password).exactly(1).time.and_return(OpenStruct.new)
143
+
144
+ allow_any_instance_of(CognitoRails::User).to receive(:cognito_client).and_return(fake_cognito_client)
145
+ PasswordProvidedUser.create!(email: sample_cognito_email, password: sample_cognito_password)
146
+ User.create!(email: sample_cognito_email)
147
+ end
139
148
  end
140
149
 
141
150
  context 'class methods' do
@@ -143,27 +152,50 @@ RSpec.describe CognitoRails::User, type: :model do
143
152
  expect(CognitoRails::User).to receive(:cognito_client).at_least(:once).and_return(fake_cognito_client)
144
153
  end
145
154
 
146
- it '#sync_from_cognito!' do
147
- expect(fake_cognito_client).to receive(:list_users).and_return(
148
- OpenStruct.new(
149
- users: [
150
- build_cognito_user_data('some@example.com'),
151
- build_cognito_user_data('some2@example.com')
152
- ],
153
- pagination_token: nil
155
+ context '#sync_from_cognito!' do
156
+ before do
157
+ expect(fake_cognito_client).to receive(:list_users).and_return(
158
+ OpenStruct.new(
159
+ users: [
160
+ build_cognito_user_data('some@example.com'),
161
+ build_cognito_user_data('some2@example.com')
162
+ ],
163
+ pagination_token: nil
164
+ )
154
165
  )
155
- )
156
-
157
- expect do
158
- users = User.sync_from_cognito!
159
-
160
- expect(users).to be_a(Array)
161
- expect(users.size).to eq(2)
162
- expect(users.first).to be_a(User)
163
- end.to change { User.count }.by(2)
164
-
165
- expect(User.pluck(:email)).to match_array(['some@example.com', 'some2@example.com'])
166
- expect(User.pluck(:name)).to match_array(['Giovanni', 'Giovanni'])
166
+ end
167
+ it 'imports all users correctly' do
168
+ expect do
169
+ users = User.sync_from_cognito!
170
+
171
+ expect(users).to be_a(Array)
172
+ expect(users.size).to eq(2)
173
+ expect(users.first).to be_a(User)
174
+ end.to change { User.count }.by(2)
175
+
176
+ expect(User.pluck(:email)).to match_array(['some@example.com', 'some2@example.com'])
177
+ expect(User.pluck(:name)).to match_array(['John Doe', 'John Doe'])
178
+ end
179
+
180
+ it 'allows to specify a block with extra changes applied pre-save' do
181
+ expect do
182
+ i = 0
183
+ users = EnrichedUser.sync_from_cognito! do |user, cognito_user|
184
+ i += 1
185
+ name = cognito_user.attributes.find { |a| a.name == 'custom:name' }
186
+ user.first_name = name.value.split(' ').first + i.to_s
187
+ user.last_name = name.value.split(' ').last
188
+ end
189
+
190
+ expect(users).to be_a(Array)
191
+ expect(users.size).to eq(2)
192
+ expect(users.first).to be_a(EnrichedUser)
193
+ end.to change { EnrichedUser.count }.by(2)
194
+
195
+ expect(EnrichedUser.pluck(:email)).to match_array(['some@example.com', 'some2@example.com'])
196
+ expect(EnrichedUser.order(:id).pluck(:first_name)).to match_array(%w[John1 John2])
197
+ expect(EnrichedUser.order(:id).pluck(:last_name)).to match_array(%w[Doe Doe])
198
+ end
167
199
  end
168
200
 
169
201
  it '#sync_to_cognito!' do
@@ -11,8 +11,7 @@ module CognitoRails::Helpers
11
11
  expect(params).to match_structure(
12
12
  user_pool_id: one_of(String, nil),
13
13
  username: String,
14
- temporary_password: String,
15
- user_attributes: a_list_of(name: String, value: one_of(String, nil))
14
+ user_attributes: a_list_of(name: String, value: one_of(String, nil)),
16
15
  )
17
16
  OpenStruct.new(user: OpenStruct.new(attributes: [{ name: 'sub', value: sample_cognito_id }]))
18
17
  end
@@ -54,7 +53,7 @@ module CognitoRails::Helpers
54
53
  ),
55
54
  OpenStruct.new(
56
55
  name: 'custom:name',
57
- value: 'Giovanni'
56
+ value: 'John Doe'
58
57
  )
59
58
  ],
60
59
  mfa_options: []
@@ -17,6 +17,19 @@ class User < ActiveRecord::Base
17
17
  attr_accessor :password
18
18
  end
19
19
 
20
+ class EnrichedUser < ActiveRecord::Base
21
+ validates :email, presence: true
22
+ validates :email, uniqueness: true
23
+ validates :first_name, :last_name, presence: true
24
+
25
+ as_cognito_user
26
+ cognito_verify_email
27
+ define_cognito_attribute 'role', 'user'
28
+
29
+ attr_accessor :password
30
+ end
31
+
32
+
20
33
  class Admin < ActiveRecord::Base
21
34
  validates :email, presence: true
22
35
  validates :email, uniqueness: true
@@ -29,6 +42,20 @@ class Admin < ActiveRecord::Base
29
42
  define_cognito_attribute 'role', 'admin'
30
43
  end
31
44
 
45
+
46
+ class PasswordProvidedUser < ActiveRecord::Base
47
+ validates :email, presence: true
48
+ validates :email, uniqueness: true
49
+
50
+ as_cognito_user
51
+ cognito_verify_email
52
+ cognito_password_policy :user_provided
53
+ define_cognito_attribute 'role', 'user'
54
+ define_cognito_attribute 'name', :name
55
+
56
+ attr_accessor :password
57
+ end
58
+
32
59
  module Schema
33
60
  def self.create
34
61
  ActiveRecord::Migration.verbose = false
@@ -41,12 +68,27 @@ module Schema
41
68
  t.timestamps null: false
42
69
  end
43
70
 
71
+ create_table :enriched_users, force: true do |t|
72
+ t.string "email", null: false
73
+ t.string "first_name", null: false
74
+ t.string "last_name", null: false
75
+ t.string "external_id", null: false
76
+ t.timestamps null: false
77
+ end
78
+
44
79
  create_table :admins, force: true do |t|
45
80
  t.string "email", null: false
46
81
  t.string "phone", null: false
47
82
  t.string "cognito_id", null: false
48
83
  t.timestamps null: false
49
84
  end
85
+
86
+ create_table :password_provided_users, force: true do |t|
87
+ t.string "email", null: false
88
+ t.string "name"
89
+ t.string "external_id", null: false
90
+ t.timestamps null: false
91
+ end
50
92
  end
51
93
 
52
94
  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: 1.1.0
4
+ version: 1.3.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-04-27 00:00:00.000000000 Z
11
+ date: 2023-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport