change password complexity library and setup

This commit is contained in:
Lisa Durand 2024-09-09 15:40:54 +02:00
parent 0b0e47b7cd
commit 22e06bc5eb
No known key found for this signature in database
GPG key ID: 0DF91F2CA1E8B816
8 changed files with 11 additions and 5026 deletions

View file

@ -111,7 +111,7 @@ gem 'webrick', require: false
gem 'yabeda-prometheus' gem 'yabeda-prometheus'
gem 'yabeda-sidekiq' gem 'yabeda-sidekiq'
gem 'zipline' gem 'zipline'
gem 'zxcvbn-ruby', require: 'zxcvbn' gem 'zxcvbn'
group :test do group :test do
gem 'axe-core-rspec' # accessibility rspec matchers gem 'axe-core-rspec' # accessibility rspec matchers

View file

@ -880,7 +880,7 @@ GEM
actionpack (>= 6.0, < 8.0) actionpack (>= 6.0, < 8.0)
content_disposition (~> 1.0) content_disposition (~> 1.0)
zip_tricks (>= 4.2.1, < 6.0) zip_tricks (>= 4.2.1, < 6.0)
zxcvbn-ruby (1.2.0) zxcvbn (0.1.11)
PLATFORMS PLATFORMS
ruby ruby
@ -1034,7 +1034,7 @@ DEPENDENCIES
yabeda-prometheus yabeda-prometheus
yabeda-sidekiq yabeda-sidekiq
zipline zipline
zxcvbn-ruby zxcvbn
BUNDLED WITH BUNDLED WITH
2.5.9 2.5.9

View file

@ -7,4 +7,4 @@ fr:
strong: Félicitations ! Mot de passe suffisamment fort et sécurisé. strong: Félicitations ! Mot de passe suffisamment fort et sécurisé.
weak: Mot de passe vulnérable. weak: Mot de passe vulnérable.
weakest: Mot de passe très vulnérable. weakest: Mot de passe très vulnérable.
hint: Une courte phrase avec ponctuation peut être un mot de passe très sécurisé. hint: Pour un mot de passe sécurisé, éviter d'utiliser des suites ou des répétitions de même caractère. Vous pouvez par exemple choisir une phrase (avec des espaces) que vous retiendrez facilement.

View file

@ -2,7 +2,7 @@
class PasswordComplexityController < ApplicationController class PasswordComplexityController < ApplicationController
def show def show
@score, @words, @length = ZxcvbnService.new(password_param).complexity @score, @length = ZxcvbnService.new(password_param).complexity
@min_length = PASSWORD_MIN_LENGTH @min_length = PASSWORD_MIN_LENGTH
@min_complexity = PASSWORD_COMPLEXITY_FOR_ADMIN @min_complexity = PASSWORD_COMPLEXITY_FOR_ADMIN
end end

View file

@ -11,22 +11,9 @@ class ZxcvbnService
# to cache it between threads. # to cache it between threads.
def tester def tester
@tester_mutex.synchronize do @tester_mutex.synchronize do
@tester ||= build_tester @tester ||= Zxcvbn::Tester.new
end end
end end
private
# Returns a fully initializer tester from the on-disk dictionary.
#
# This is slow: loading and parsing the dictionary may take around 1s.
def build_tester
dictionaries = YAML.safe_load(Rails.root.join("config", "initializers", "zxcvbn_dictionnaries.yaml").read)
tester = Zxcvbn::Tester.new
tester.add_word_lists(dictionaries)
tester
end
end end
def initialize(password) def initialize(password)
@ -37,8 +24,7 @@ class ZxcvbnService
wxcvbn = compute_zxcvbn wxcvbn = compute_zxcvbn
score = wxcvbn.score score = wxcvbn.score
length = @password.blank? ? 0 : @password.length length = @password.blank? ? 0 : @password.length
vulnerabilities = wxcvbn.match_sequence.map { |m| m.matched_word.nil? ? m.token : m.matched_word }.filter { |s| s.length > 2 }.join(', ') [score, length]
[score, vulnerabilities, length]
end end
def score def score

View file

@ -7,5 +7,5 @@ if !defined?(PASSWORD_MIN_LENGTH)
# PASSWORD_COMPLEXITY_FOR_INSTRUCTEUR = ENV.fetch('PASSWORD_COMPLEXITY_FOR_INSTRUCTEUR', '3').to_i # PASSWORD_COMPLEXITY_FOR_INSTRUCTEUR = ENV.fetch('PASSWORD_COMPLEXITY_FOR_INSTRUCTEUR', '3').to_i
PASSWORD_COMPLEXITY_FOR_ADMIN = ENV.fetch('PASSWORD_COMPLEXITY_FOR_ADMIN', '4').to_i PASSWORD_COMPLEXITY_FOR_ADMIN = ENV.fetch('PASSWORD_COMPLEXITY_FOR_ADMIN', '4').to_i
# password minimum length # password minimum length
PASSWORD_MIN_LENGTH = ENV.fetch('PASSWORD_MIN_LENGTH', '8').to_i PASSWORD_MIN_LENGTH = ENV.fetch('PASSWORD_MIN_LENGTH', '12').to_i
end end

File diff suppressed because it is too large Load diff

View file

@ -6,13 +6,13 @@ describe ZxcvbnService do
describe '#score' do describe '#score' do
it 'returns the password complexity score' do it 'returns the password complexity score' do
expect(service.score).to eq 3 expect(service.score).to eq 4
end end
end end
describe '#complexity' do describe '#complexity' do
it 'returns the password score, vulnerability and length' do it 'returns the password score, vulnerability and length' do
expect(service.complexity).to eq [3, 'medium, strength, password', 24] expect(service.complexity).to eq [4, 24]
end end
end end
@ -42,7 +42,7 @@ describe ZxcvbnService do
end.map(&:join) end.map(&:join)
scores = threads.map(&:value) scores = threads.map(&:value)
expect(scores).to eq([3, 3, 3, 3]) expect(scores).to eq([4, 4, 4, 4])
expect(Zxcvbn::Tester).to have_received(:new).at_most(:once) expect(Zxcvbn::Tester).to have_received(:new).at_most(:once)
end end
end end