cognito_rails 1.0.0 → 1.1.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: f8bbd85c82670198044b07ac6bd693920201e3911166f1432365bd834e54fafd
4
- data.tar.gz: 1c435514395d116f142fb22121bb0bdb7cdb91b46897b48566453e3748ae184d
3
+ metadata.gz: 1b69f6c8db91a764df6878e0de53feb9879f7509e79bf0d406e6fe9522f96e61
4
+ data.tar.gz: f44a4f4dfce641e54493730c9f183c9bd2f6a2e73fe4cd0c7a60d084b6d0d09a
5
5
  SHA512:
6
- metadata.gz: 11bea4faacf98021ee61a6ae2280e4da743fd1e62e68c4dc88681c98f735973ccabc5806261df3e1d22243da42eef7fb3ddc2fc02f5c06677e6291f1e3d9f780
7
- data.tar.gz: 26ba725b881ab2333e8ea5823ac199fc4fd430426b85f1f50832d2e9b1985db692615d2543ef7cea6d6a21aa8cddfdc9358194bf0ce30655acb35b0a971a1d90
6
+ metadata.gz: 17551dd1de906fd5813214f4fdd98bd49f7d4503138cfa5cd9beedc235707dc00b000d356e090a154b7de0c08e692553154b273d50236b31f455903044c97594
7
+ data.tar.gz: ee07b9c1b821bc601ac2c62d4268392783e5f687da1d9b810d6160f64c5b7f3546ffd7e5998f05a5a03fc2326bd162e338e0be2ceda461d2cae1152072e44ec8
@@ -19,7 +19,7 @@ module CognitoRails
19
19
  # @!attribute default_user_class [w]
20
20
  # @return [String,nil]
21
21
  attr_writer :aws_client_credentials, :skip_model_hooks, :aws_region,
22
- :aws_user_pool_id, :default_user_class
22
+ :aws_user_pool_id, :default_user_class, :password_generator
23
23
 
24
24
  # @return [Boolean] skip model hooks
25
25
  def skip_model_hooks
@@ -49,6 +49,10 @@ module CognitoRails
49
49
  def default_user_class
50
50
  @default_user_class || (raise 'Missing config default_user_class')
51
51
  end
52
+
53
+ def password_generator
54
+ @password_generator || CognitoRails::PasswordGenerator.method(:generate)
55
+ end
52
56
  end
53
57
  end
54
58
  end
@@ -92,12 +92,17 @@ module CognitoRails
92
92
  def init_cognito_user
93
93
  return if cognito_external_id.present?
94
94
 
95
+ cognito_user = User.new(init_attributes)
96
+ cognito_user.save!
97
+ self.cognito_external_id = cognito_user.id
98
+ end
99
+
100
+ def init_attributes
95
101
  attrs = { email: email, user_class: self.class }
96
102
  attrs[:phone] = phone if respond_to?(:phone)
103
+ attrs[:password] = password if respond_to?(:password)
97
104
  attrs[:custom_attributes] = instance_custom_attributes
98
- cognito_user = User.new(attrs)
99
- cognito_user.save!
100
- self.cognito_external_id = cognito_user.id
105
+ attrs
101
106
  end
102
107
 
103
108
  # @return [Array<Hash>]
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CognitoRails
4
+ class PasswordGenerator
5
+ NUMERIC = (0..9).to_a.freeze
6
+ LOWER_CASE = ('a'..'z').to_a.freeze
7
+ UPPER_CASE = ('A'..'Z').to_a.freeze
8
+ SPECIAL = [
9
+ '^', '$', '*', '.', '[', ']', '{', '}',
10
+ '(', ')', '?', '"', '!', '@', '#', '%',
11
+ '&', '/', '\\', ',', '>', '<', "'", ':',
12
+ ';', '|', '_', '~', '`', '=', '+', '-'
13
+ ].freeze
14
+
15
+ # Generates a random password given a length range
16
+ #
17
+ # @param range [Range]
18
+ # @return [String]
19
+ def self.generate(range = 8..16)
20
+ password_length = rand(range)
21
+ numeric_count = rand(1..(password_length-3))
22
+
23
+ lower_case_count = rand(1..(password_length-(numeric_count+2)))
24
+ upper_case_count = rand(1..(password_length-(numeric_count + lower_case_count + 1)))
25
+ special_count = password_length-(numeric_count + lower_case_count + upper_case_count)
26
+
27
+ numeric_characters = numeric_count.times.map { NUMERIC.sample }
28
+ lower_case_characters = lower_case_count.times.map { LOWER_CASE.sample }
29
+ upper_case_characters = upper_case_count.times.map { UPPER_CASE.sample }
30
+ special_characters = special_count.times.map { SPECIAL.sample }
31
+
32
+ (numeric_characters + lower_case_characters + upper_case_characters + special_characters).shuffle.join
33
+ end
34
+ end
35
+ end
@@ -39,7 +39,7 @@ module CognitoRails
39
39
  def initialize(attributes = {})
40
40
  attributes = attributes.with_indifferent_access
41
41
  self.email = attributes[:email]
42
- self.password = SecureRandom.urlsafe_base64 || attributes[:password]
42
+ self.password = attributes[:password] || Config.password_generator.call
43
43
  self.phone = attributes[:phone]
44
44
  self.user_class = attributes[:user_class] || Config.default_user_class.constantize
45
45
  self.custom_attributes = attributes[:custom_attributes]
@@ -2,5 +2,5 @@
2
2
 
3
3
  module CognitoRails
4
4
  # @return [String] gem version
5
- VERSION = '1.0.0'
5
+ VERSION = '1.1.0'
6
6
  end
data/lib/cognito_rails.rb CHANGED
@@ -15,6 +15,7 @@ module CognitoRails
15
15
  autoload :Model
16
16
  autoload :User
17
17
  autoload :JWT
18
+ autoload :PasswordGenerator
18
19
 
19
20
  # @private
20
21
  module ModelInitializer
@@ -1,8 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- # rubocop:disable Metrics/BlockLength
4
3
  RSpec.describe CognitoRails::Controller, type: :model do
5
- # rubocop:enable Metrics/BlockLength
6
4
  include CognitoRails::Helpers
7
5
 
8
6
  context 'with an API controller' do
@@ -2,9 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- # rubocop:disable Metrics/BlockLength
6
5
  RSpec.describe CognitoRails::JWT, type: :model do
7
- # rubocop:enable Metrics/BlockLength
8
6
  before do
9
7
  allow(URI).to receive(:open).and_return(double(read: jwks))
10
8
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe CognitoRails::PasswordGenerator do
6
+ it 'generates a password' do
7
+ expect(described_class.generate).to be_a(String)
8
+ end
9
+
10
+ it 'generates a password with the correct length' do
11
+ 1000.times do
12
+ expect(described_class.generate(8..8).length).to eq(8)
13
+ end
14
+ end
15
+
16
+ it 'contains at least one letter, one number, one upper case letter, one symbol' do
17
+ 1000.times do
18
+ password = described_class.generate
19
+ expect(password).to match(/[a-z]/)
20
+ expect(password).to match(/[A-Z]/)
21
+ expect(password).to match(/[0-9]/)
22
+ include_symbol = CognitoRails::PasswordGenerator::SPECIAL.any? do |symbol|
23
+ password.include?(symbol)
24
+ end
25
+ expect(include_symbol).to be_truthy
26
+ end
27
+ end
28
+ end
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- # rubocop:disable Metrics/BlockLength
6
5
  RSpec.describe CognitoRails::User, type: :model do
7
6
  include CognitoRails::Helpers
8
7
 
@@ -83,6 +82,34 @@ RSpec.describe CognitoRails::User, type: :model do
83
82
  user.destroy!
84
83
  end
85
84
 
85
+ it 'uses the password generator defined in config' do
86
+ CognitoRails::Config.password_generator = -> { 'ciao' }
87
+ expect(CognitoRails::User).to receive(:cognito_client).at_least(:once).and_return(fake_cognito_client)
88
+
89
+ expect(fake_cognito_client).to receive(:admin_create_user).with(
90
+ hash_including(
91
+ temporary_password: 'ciao'
92
+ )
93
+ )
94
+ user = User.new(email: sample_cognito_email)
95
+ user.save!
96
+ ensure
97
+ CognitoRails::Config.password_generator = nil
98
+ end
99
+
100
+ it 'uses the custom password passed as parameter' do
101
+ expect(CognitoRails::User).to receive(:cognito_client).at_least(:once).and_return(fake_cognito_client)
102
+
103
+ expect(fake_cognito_client).to receive(:admin_create_user).with(
104
+ hash_including(
105
+ temporary_password: '12345678'
106
+ )
107
+ )
108
+ user = User.new(email: sample_cognito_email)
109
+ user.password = '12345678'
110
+ user.save!
111
+ end
112
+
86
113
  it 'saves custom attributes in cognito' do
87
114
  expect(CognitoRails::User).to receive(:cognito_client).at_least(:once).and_return(fake_cognito_client)
88
115
 
@@ -13,6 +13,8 @@ class User < ActiveRecord::Base
13
13
  cognito_verify_email
14
14
  define_cognito_attribute 'role', 'user'
15
15
  define_cognito_attribute 'name', :name
16
+
17
+ attr_accessor :password
16
18
  end
17
19
 
18
20
  class Admin < ActiveRecord::Base
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.0.0
4
+ version: 1.1.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-30 00:00:00.000000000 Z
11
+ date: 2023-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -97,10 +97,12 @@ files:
97
97
  - lib/cognito_rails/controller.rb
98
98
  - lib/cognito_rails/jwt.rb
99
99
  - lib/cognito_rails/model.rb
100
+ - lib/cognito_rails/password_generator.rb
100
101
  - lib/cognito_rails/user.rb
101
102
  - lib/cognito_rails/version.rb
102
103
  - spec/cognito_rails/controller_spec.rb
103
104
  - spec/cognito_rails/jwt_spec.rb
105
+ - spec/cognito_rails/password_generator_spec.rb
104
106
  - spec/cognito_rails/user_spec.rb
105
107
  - spec/factories/user.rb
106
108
  - spec/spec_helper.rb
@@ -133,6 +135,7 @@ summary: Add Cognito authentication to your Rails API
133
135
  test_files:
134
136
  - spec/cognito_rails/controller_spec.rb
135
137
  - spec/cognito_rails/jwt_spec.rb
138
+ - spec/cognito_rails/password_generator_spec.rb
136
139
  - spec/cognito_rails/user_spec.rb
137
140
  - spec/factories/user.rb
138
141
  - spec/spec_helper.rb