mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-30 19:52:20 +01:00
improvement: add complexity check of the user password
This commit is contained in:
parent
acbd327f6d
commit
1d6a59dd67
@ -142,7 +142,7 @@
|
||||
class="form-control"
|
||||
id="user_password"
|
||||
placeholder="{{ 'app.shared.user.new_password' | translate }}"
|
||||
ng-minlength="8"
|
||||
ng-minlength="12"
|
||||
required/>
|
||||
</div>
|
||||
<span class="help-block" ng-show="userForm['user[password]'].$dirty && userForm['user[password]'].$error.required" translate>{{ 'app.shared.user.password_is_required' }}</span>
|
||||
@ -158,7 +158,7 @@
|
||||
class="form-control"
|
||||
id="user_password_confirmation"
|
||||
placeholder="{{ 'app.shared.user.confirmation_of_new_password' | translate }}"
|
||||
ng-minlength="8"
|
||||
ng-minlength="12"
|
||||
required
|
||||
match="user.password"/>
|
||||
</div>
|
||||
|
@ -18,7 +18,7 @@
|
||||
class="form-control"
|
||||
placeholder="{{ 'app.public.common.your_new_password' | translate }}"
|
||||
required
|
||||
ng-minlength="8">
|
||||
ng-minlength="12">
|
||||
</div>
|
||||
<span class="help-block" ng-show="passwordEditForm.password.$dirty && passwordEditForm.password.$error.required" translate>{{ 'app.public.common.password_is_required' }}</span>
|
||||
<span class="help-block" ng-show="passwordEditForm.password.$dirty && passwordEditForm.password.$error.minlength" translate>{{ 'app.public.common.password_is_too_short' }}</span>
|
||||
@ -35,7 +35,7 @@
|
||||
class="form-control"
|
||||
placeholder="{{ 'app.public.common.type_your_password_again' | translate }}"
|
||||
required
|
||||
ng-minlength="8"
|
||||
ng-minlength="12"
|
||||
match="user.password">
|
||||
</div>
|
||||
<span class="help-block" ng-show="passwordEditForm.password_confirmation.$dirty && passwordEditForm.password_confirmation.$error.required" translate>{{ 'app.public.common.password_confirmation_is_required' }}</span>
|
||||
|
@ -96,7 +96,7 @@
|
||||
class="form-control"
|
||||
placeholder="{{ 'app.public.common.your_password' | translate }}"
|
||||
required
|
||||
ng-minlength="8">
|
||||
ng-minlength="12">
|
||||
</div>
|
||||
<span class="exponent"><i class="fa fa-asterisk" aria-hidden="true"></i></span>
|
||||
<span class="help-block" ng-show="signupForm.password.$dirty && signupForm.password.$error.required" translate>{{ 'app.public.common.password_is_required' }}</span>
|
||||
|
@ -161,7 +161,7 @@ module SingleSignOnConcern
|
||||
user.set_data_from_sso_mapping(key, value)
|
||||
end
|
||||
logger.debug 'generating a new password'
|
||||
user.password = Devise.friendly_token[0, 20]
|
||||
user.password = SecurePassword.generate
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -78,6 +78,7 @@ class User < ApplicationRecord
|
||||
validate :cgu_must_accept, if: :new_record?
|
||||
|
||||
validates :username, presence: true, uniqueness: true, length: { maximum: 30 }
|
||||
validate :password_complexity
|
||||
|
||||
scope :active, -> { where(is_active: true) }
|
||||
scope :without_subscription, -> { includes(statistic_profile: [:subscriptions]).where(subscriptions: { statistic_profile_id: nil }) }
|
||||
@ -347,4 +348,10 @@ class User < ApplicationRecord
|
||||
last_name: last_name
|
||||
)
|
||||
end
|
||||
|
||||
def password_complexity
|
||||
return if password.blank? || SecurePassword.is_secured?(password)
|
||||
|
||||
errors.add I18n.t("app.public.common.password_is_too_weak"), I18n.t("app.public.common.password_is_too_weak_explanations")
|
||||
end
|
||||
end
|
||||
|
@ -128,7 +128,7 @@ class Members::MembersService
|
||||
|
||||
def password(params)
|
||||
if !params[:password] && !params[:password_confirmation]
|
||||
Devise.friendly_token.first(8)
|
||||
SecurePassword.generate
|
||||
else
|
||||
params[:password]
|
||||
end
|
||||
|
18
app/services/secure_password.rb
Normal file
18
app/services/secure_password.rb
Normal file
@ -0,0 +1,18 @@
|
||||
class SecurePassword
|
||||
LOWER_LETTERS = ('a'..'z').to_a
|
||||
UPPER_LETTERS = ('A'..'Z').to_a
|
||||
DIGITS = ('0'..'9').to_a
|
||||
SPECIAL_CHARS = ["!", "#", "$", "%", "&", "(", ")", "*", "+", ",", "-", ".", "/", ":", ";", "<", "=", ">", "?", "@", "[", "]", "^", "_", "{", "|", "}", "~", "'", "`", '"']
|
||||
|
||||
def self.generate
|
||||
(LOWER_LETTERS.shuffle.first(4) + UPPER_LETTERS.shuffle.first(4) + DIGITS.shuffle.first(4) + SPECIAL_CHARS.shuffle.first(4)).shuffle.join
|
||||
end
|
||||
|
||||
def self.is_secured?(password)
|
||||
password_as_array = password.split("")
|
||||
password_as_array.any? {|c| c.in? LOWER_LETTERS } &&
|
||||
password_as_array.any? {|c| c.in? UPPER_LETTERS } &&
|
||||
password_as_array.any? {|c| c.in? DIGITS } &&
|
||||
password_as_array.any? {|c| c.in? SPECIAL_CHARS }
|
||||
end
|
||||
end
|
@ -3,7 +3,7 @@
|
||||
# helpers for managing users with special roles
|
||||
class UserService
|
||||
def self.create_partner(params)
|
||||
generated_password = Devise.friendly_token.first(8)
|
||||
generated_password = SecurePassword.generate
|
||||
group_id = Group.first.id
|
||||
user = User.new(
|
||||
email: params[:email],
|
||||
@ -31,7 +31,7 @@ class UserService
|
||||
end
|
||||
|
||||
def self.create_admin(params)
|
||||
generated_password = Devise.friendly_token.first(8)
|
||||
generated_password = SecurePassword.generate
|
||||
admin = User.new(params.merge(password: generated_password))
|
||||
admin.send :set_slug
|
||||
|
||||
@ -52,7 +52,7 @@ class UserService
|
||||
end
|
||||
|
||||
def self.create_manager(params)
|
||||
generated_password = Devise.friendly_token.first(8)
|
||||
generated_password = SecurePassword.generate
|
||||
manager = User.new(params.merge(password: generated_password))
|
||||
manager.send :set_slug
|
||||
|
||||
|
@ -134,7 +134,7 @@ Devise.setup do |config|
|
||||
|
||||
# ==> Configuration for :validatable
|
||||
# Range for password length.
|
||||
config.password_length = 8..128
|
||||
config.password_length = 12..128
|
||||
|
||||
# Email regex used to validate email formats. It simply asserts that
|
||||
# one (and only one) @ exists in the given string. This is mainly
|
||||
|
@ -71,7 +71,9 @@ en:
|
||||
email_is_required: "E-mail address is required."
|
||||
your_password: "Your password"
|
||||
password_is_required: "Password is required."
|
||||
password_is_too_short: "Password is too short (minimum 8 characters)"
|
||||
password_is_too_short: "Password is too short (minimum 12 characters)"
|
||||
password_is_too_weak: "Password is too weak:"
|
||||
password_is_too_weak_explanations: "minimum 12 characters, at least one uppercase letter, one lowercase letter, one number and one special character"
|
||||
type_your_password_again: "Type your password again"
|
||||
password_confirmation_is_required: "Password confirmation is required."
|
||||
password_does_not_match_with_confirmation: "Password does not match with confirmation."
|
||||
|
@ -4,7 +4,7 @@ require 'test_helper'
|
||||
|
||||
class UserTest < ActiveSupport::TestCase
|
||||
test 'must create wallet and profiles after create user' do
|
||||
u = User.create(username: 'user', email: 'userwallet@fabmanager.com', password: 'testpassword', password_confirmation: 'testpassword',
|
||||
u = User.create(username: 'user', email: 'userwallet@fabmanager.com', password: 'Testpassword1$', password_confirmation: 'Testpassword1$',
|
||||
profile_attributes: { first_name: 'user', last_name: 'wallet', phone: '0123456789' },
|
||||
statistic_profile_attributes: { gender: true, birthday: 18.years.ago })
|
||||
assert u.wallet.present?
|
||||
|
Loading…
x
Reference in New Issue
Block a user