Merge pull request #4168 from betagouv/issue/3928_check_complexity_when_admin_edit_pwd
Check complexity when editing admin password
This commit is contained in:
commit
a181210651
40 changed files with 284 additions and 112 deletions
|
@ -312,8 +312,8 @@
|
|||
}
|
||||
|
||||
.explication {
|
||||
margin-bottom: 2 * $default-padding;
|
||||
padding: $default-padding;
|
||||
margin-bottom: $default-padding;
|
||||
padding: $default-padding / 2;
|
||||
background-color: $light-grey;
|
||||
|
||||
p:not(:last-child) {
|
||||
|
|
|
@ -2,33 +2,39 @@
|
|||
@import "constants";
|
||||
|
||||
$strength-bg: #EEEEEE;
|
||||
$weak-strength-color: $lighter-red;
|
||||
$medium-strength-color: $orange;
|
||||
$strong-strength-color: $green;
|
||||
$strength-color-0: $lighter-red;
|
||||
$strength-color-1: #FF5000;
|
||||
$strength-color-2: $orange;
|
||||
$strength-color-3: #FFD000;
|
||||
$strength-color-4: $green;
|
||||
|
||||
.password-strength {
|
||||
margin-top: -24px;
|
||||
width: 100%;
|
||||
min-height: 22px;
|
||||
height: 12px;
|
||||
background: $strength-bg;
|
||||
display: block;
|
||||
margin-bottom: $default-spacer;
|
||||
text-align: center;
|
||||
border-radius: 8px;
|
||||
|
||||
&.strength-0 {
|
||||
background: linear-gradient(to right, $strength-color-0 00%, $strength-bg 20%);
|
||||
}
|
||||
|
||||
&.strength-1 {
|
||||
background: linear-gradient(to right, $weak-strength-color 0%, $weak-strength-color 25%, $strength-bg 25%, $strength-bg 100%);
|
||||
background: linear-gradient(to right, $strength-color-1 20%, $strength-bg 40%);
|
||||
}
|
||||
|
||||
&.strength-2 {
|
||||
background: linear-gradient(to right, $medium-strength-color 0%, $medium-strength-color 50%, $strength-bg 50%, $strength-bg 100%);
|
||||
background: linear-gradient(to right, $strength-color-2 40%, $strength-bg 60%);
|
||||
}
|
||||
|
||||
&.strength-3 {
|
||||
background: linear-gradient(to right, $medium-strength-color 0%, $medium-strength-color 75%, $strength-bg 75%, $strength-bg 100%);
|
||||
background: linear-gradient(to right, $strength-color-3 60%, $strength-bg 80%);
|
||||
}
|
||||
|
||||
&.strength-4 {
|
||||
background: $strong-strength-color;
|
||||
color: #FFFFFF;
|
||||
background: $strength-color-4;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
require 'zxcvbn'
|
||||
|
||||
class Administrateurs::ActivateController < ApplicationController
|
||||
include TrustedDeviceConcern
|
||||
|
||||
|
@ -34,10 +32,6 @@ class Administrateurs::ActivateController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def test_password_strength
|
||||
@score = Zxcvbn.test(params[:administrateur][:password], [], ZXCVBN_DICTIONNARIES).score
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_administrateur_params
|
||||
|
|
69
app/controllers/administrateurs/passwords_controller.rb
Normal file
69
app/controllers/administrateurs/passwords_controller.rb
Normal file
|
@ -0,0 +1,69 @@
|
|||
class Administrateurs::PasswordsController < Devise::PasswordsController
|
||||
after_action :try_to_authenticate_user, only: [:update]
|
||||
after_action :try_to_authenticate_gestionnaire, only: [:update]
|
||||
|
||||
# GET /resource/password/new
|
||||
# def new
|
||||
# super
|
||||
# end
|
||||
|
||||
# POST /resource/password
|
||||
# def create
|
||||
# super
|
||||
# end
|
||||
|
||||
# GET /resource/password/edit?reset_password_token=abcdef
|
||||
# def edit
|
||||
# super
|
||||
# end
|
||||
|
||||
# PUT /resource/password
|
||||
# def update
|
||||
# # params[:user][:password_confirmation] = params[:user][:password]
|
||||
# super
|
||||
# end
|
||||
|
||||
# protected
|
||||
|
||||
# def after_resetting_password_path_for(resource)
|
||||
# super(resource)
|
||||
# end
|
||||
|
||||
# The path used after sending reset password instructions
|
||||
# def after_sending_reset_password_instructions_path_for(resource_name)
|
||||
# super(resource_name)
|
||||
# end
|
||||
|
||||
def try_to_authenticate_user
|
||||
if administrateur_signed_in?
|
||||
user = User.find_by(email: current_administrateur.email)
|
||||
|
||||
if user
|
||||
sign_in user
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def try_to_authenticate_gestionnaire
|
||||
if administrateur_signed_in?
|
||||
gestionnaire = Gestionnaire.find_by(email: current_administrateur.email)
|
||||
|
||||
if gestionnaire
|
||||
sign_in gestionnaire
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_strength
|
||||
@score, @words, @length = ZxcvbnService.new(password_params[:password]).complexity
|
||||
@min_length = PASSWORD_MIN_LENGTH
|
||||
@min_complexity = PASSWORD_COMPLEXITY_FOR_ADMIN
|
||||
render 'shared/password/test_strength'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def password_params
|
||||
params.require(:administrateur).permit(:reset_password_token, :password)
|
||||
end
|
||||
end
|
|
@ -8,9 +8,19 @@ class Users::PasswordsController < Devise::PasswordsController
|
|||
# end
|
||||
|
||||
# POST /resource/password
|
||||
# def create
|
||||
# super
|
||||
# end
|
||||
def create
|
||||
# Check the credentials associated to the mail to generate a correct reset link
|
||||
email = params[:user][:email]
|
||||
if Administrateur.find_by(email: email)
|
||||
@devise_mapping = Devise.mappings[:administrateur]
|
||||
params[:administrateur] = params[:user]
|
||||
# uncomment to check password complexity for Gestionnaire
|
||||
# elsif Gestionnaire.find_by(email: email)
|
||||
# @devise_mapping = Devise.mappings[:gestionnaire]
|
||||
# params[:gestionnaire] = params[:user]
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
# GET /resource/password/edit?reset_password_token=abcdef
|
||||
# def edit
|
||||
|
@ -19,6 +29,7 @@ class Users::PasswordsController < Devise::PasswordsController
|
|||
|
||||
# PUT /resource/password
|
||||
# def update
|
||||
# # params[:user][:password_confirmation] = params[:user][:password]
|
||||
# super
|
||||
# end
|
||||
|
||||
|
@ -52,4 +63,15 @@ class Users::PasswordsController < Devise::PasswordsController
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_strength
|
||||
@score, @words, @length = ZxcvbnService.new(password_params[:password]).complexity
|
||||
@min_length = PASSWORD_MIN_LENGTH
|
||||
@min_complexity = PASSWORD_COMPLEXITY_FOR_USER
|
||||
render 'shared/password/test_strength'
|
||||
end
|
||||
|
||||
def password_params
|
||||
params.require(:user).permit(:reset_password_token, :password)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,11 +20,8 @@ class Administrateur < ApplicationRecord
|
|||
validate :password_complexity, if: Proc.new { |a| Devise.password_length.include?(a.password.try(:size)) }
|
||||
|
||||
def password_complexity
|
||||
if password.present?
|
||||
score = Zxcvbn.test(password, [], ZXCVBN_DICTIONNARIES).score
|
||||
if score < 4
|
||||
errors.add(:password, :not_strength)
|
||||
end
|
||||
if password.present? && ZxcvbnService.new(password).score < PASSWORD_COMPLEXITY_FOR_ADMIN
|
||||
errors.add(:password, :not_strong)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
23
app/services/zxcvbn_service.rb
Normal file
23
app/services/zxcvbn_service.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
class ZxcvbnService
|
||||
def initialize(password)
|
||||
@password = password
|
||||
end
|
||||
|
||||
def complexity
|
||||
wxcvbn = compute_zxcvbn
|
||||
score = wxcvbn.score
|
||||
length = @password.blank? ? 0 : @password.length
|
||||
vulnerabilities = wxcvbn.match_sequence.map { |m| m.matched_word.nil? ? m.token : m.matched_word }.select { |s| s.length > 2 }.join(', ')
|
||||
[score, vulnerabilities, length]
|
||||
end
|
||||
|
||||
def score
|
||||
compute_zxcvbn.score
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def compute_zxcvbn
|
||||
Zxcvbn.test(@password, [], ZXCVBN_DICTIONNARIES)
|
||||
end
|
||||
end
|
|
@ -1,5 +0,0 @@
|
|||
#strength-bar.password-strength{ class: "strength-#{score}" }
|
||||
- if score < 4
|
||||
Mot de passe pas assez complexe
|
||||
- else
|
||||
Mot de passe suffisamment complexe
|
|
@ -3,27 +3,4 @@
|
|||
- content_for :footer do
|
||||
= render partial: "root/footer"
|
||||
|
||||
.container.devise-container
|
||||
.one-column-centered
|
||||
= form_for @administrateur, url: { controller: 'administrateurs/activate', action: :create }, html: { class: "form" } do |f|
|
||||
%br
|
||||
%h1
|
||||
Choix du mot de passe
|
||||
|
||||
= f.label :email, "Email"
|
||||
= f.text_field :email, disabled: true
|
||||
|
||||
= f.label :password do
|
||||
Mot de passe
|
||||
|
||||
= f.password_field :password, placeholder: 'Mot de passe', data: { remote: true, url: admin_activate_test_password_strength_path }
|
||||
|
||||
#strength-bar.password-strength
|
||||
|
||||
|
||||
.explication
|
||||
%strong Aide :
|
||||
Une courte phrase peut être un mot de passe très sécurisé.
|
||||
|
||||
= f.hidden_field :reset_password_token, value: params[:token]
|
||||
= f.submit 'Continuer', class: 'button large primary expand', id: "submit-password", data: { disable_with: "Envoi..." }
|
||||
= render 'shared/password/new', object: @administrateur, controller: 'administrateurs/activate', test_password_strength: administrateurs_password_test_strength_path
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
<%= render_to_element('#strength-bar', partial: 'password_strength', outer: true, locals: { score: @score }) %>
|
6
app/views/administrateurs/passwords/edit.html.haml
Normal file
6
app/views/administrateurs/passwords/edit.html.haml
Normal file
|
@ -0,0 +1,6 @@
|
|||
- content_for(:title, 'Changement de mot de passe')
|
||||
|
||||
- content_for :footer do
|
||||
= render partial: 'root/footer'
|
||||
|
||||
= render 'shared/password/edit', test_password_strength: administrateurs_password_test_strength_path
|
21
app/views/shared/password/_edit.html.haml
Normal file
21
app/views/shared/password/_edit.html.haml
Normal file
|
@ -0,0 +1,21 @@
|
|||
- content_for(:title, 'Changement de mot de passe')
|
||||
|
||||
- content_for :footer do
|
||||
= render partial: 'root/footer'
|
||||
|
||||
.container.devise-container
|
||||
.one-column-centered
|
||||
= devise_error_messages!
|
||||
|
||||
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :patch, class: 'form' }) do |f|
|
||||
|
||||
%h1 Changement de mot de passe
|
||||
|
||||
= f.hidden_field :reset_password_token, value: params[:token]
|
||||
|
||||
= f.label 'Nouveau mot de passe'
|
||||
|
||||
= render partial 'shared/password/edit_password', locals: { form: f, controller: controller }
|
||||
|
||||
= f.submit 'Changer le mot de passe', class: 'button large primary expand', id: "submit-password", data: { disable_with: "Envoi..." }
|
||||
|
10
app/views/shared/password/_edit_password.html.haml
Normal file
10
app/views/shared/password/_edit_password.html.haml
Normal file
|
@ -0,0 +1,10 @@
|
|||
= form.password_field :password, autofocus: true, autocomplete: 'off', placeholder: 'Mot de passe', data: { remote: true, url: url_for(controller: controller, action: 'test_strength') }
|
||||
|
||||
#strength-bar.password-strength
|
||||
|
||||
|
||||
.explication
|
||||
#strength-label{ style: 'font-weight: bold' }
|
||||
Inscrivez un mot de passe.
|
||||
Une courte phrase avec ponctuation peut être un mot de passe très sécurisé.
|
||||
|
18
app/views/shared/password/_new.html.haml
Normal file
18
app/views/shared/password/_new.html.haml
Normal file
|
@ -0,0 +1,18 @@
|
|||
.container.devise-container
|
||||
.one-column-centered
|
||||
- controller_action = defined?(action) ? action : :create
|
||||
= form_for object, url: { controller: controller, action: controller_action }, html: { class: "form" } do |f|
|
||||
%br
|
||||
%h1
|
||||
Choix du mot de passe
|
||||
|
||||
= f.hidden_field :reset_password_token, value: object.reset_password_token
|
||||
= f.label :email, "Email"
|
||||
= f.text_field :email, disabled: true
|
||||
|
||||
= f.label :password do
|
||||
Mot de passe
|
||||
|
||||
= render partial: 'shared/password/edit_password', locals: { form: f, controller: controller }
|
||||
|
||||
= f.submit 'Continuer', class: 'button large primary expand', id: "submit-password", data: { disable_with: "Envoi..." }
|
1
app/views/shared/password/_password_strength.html.haml
Normal file
1
app/views/shared/password/_password_strength.html.haml
Normal file
|
@ -0,0 +1 @@
|
|||
#strength-bar.password-strength{ class: "strength-#{@length < @min_length ? @score/2 : @score}" }
|
16
app/views/shared/password/_password_strength_label.html.haml
Normal file
16
app/views/shared/password/_password_strength_label.html.haml
Normal file
|
@ -0,0 +1,16 @@
|
|||
#strength-label{ style: 'font-weight: bold' }
|
||||
- if @length > 0
|
||||
- if @length < @min_length
|
||||
Le mot de passe doit faire au moins #{@min_length} caractères.
|
||||
- else
|
||||
- case @score
|
||||
- when 0..1
|
||||
Mot de passe très vulnérable.
|
||||
- when 2...@min_complexity
|
||||
Mot de passe vulnérable.
|
||||
- when @min_complexity...4
|
||||
Mot de passe acceptable. Vous pouvez valider...<br> ou améliorer votre mot de passe.
|
||||
- else
|
||||
Félicitations ! Mot de passe suffisamment fort et sécurisé.
|
||||
- else
|
||||
Inscrivez un mot de passe.
|
3
app/views/shared/password/test_strength.js.erb
Normal file
3
app/views/shared/password/test_strength.js.erb
Normal file
|
@ -0,0 +1,3 @@
|
|||
<%= render_to_element('#strength-label', partial: 'shared/password/password_strength_label', outer: true) %>
|
||||
<%= render_to_element('#strength-bar', partial: 'shared/password/password_strength', outer: true) %>
|
||||
<%= raw("document.querySelector('#submit-password').disabled = #{@score < @min_complexity || @length < @min_length};") %>
|
|
@ -80,6 +80,6 @@
|
|||
"note": "`column` and `order` come from the model, which is validated to prevent injection attacks. Furthermore, the sql injection attack on `column` would need to survive the `to_i`"
|
||||
}
|
||||
],
|
||||
"updated": "2019-07-17 16:03:11 +0200",
|
||||
"updated": "2019-07-02 11:23:21 -1000",
|
||||
"brakeman_version": "4.3.1"
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require_relative "contacts"
|
||||
require_relative 'contacts'
|
||||
require_relative 'passwords'
|
||||
|
||||
# Use this hook to configure devise mailer, warden hooks and so forth.
|
||||
# Many of these configuration options can be set straight in your model.
|
||||
|
@ -142,7 +143,7 @@ Devise.setup do |config|
|
|||
|
||||
# ==> Configuration for :validatable
|
||||
# Range for password length.
|
||||
config.password_length = 8..128
|
||||
config.password_length = PASSWORD_MIN_LENGTH..128
|
||||
|
||||
# Email regex used to validate email formats. It simply asserts that
|
||||
# one (and only one) @ exists in the given string. This is mainly
|
||||
|
|
9
config/initializers/passwords.rb
Normal file
9
config/initializers/passwords.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
# complexity of the required password for the three kinds of users (user, gestionnaire, admnistrateur)
|
||||
# valid values are from 0 to 4, 0 means very simple, 4 means high level of complexity.
|
||||
if !defined?(PASSWORD_MIN_LENGTH)
|
||||
# PASSWORD_COMPLEXITY_FOR_USER = ENV.fetch('PASSWORD_COMPLEXITY_FOR_USER', '2').to_i
|
||||
# PASSWORD_COMPLEXITY_FOR_GESTIONNAIRE = ENV.fetch('PASSWORD_COMPLEXITY_FOR_GESTIONNAIRE', '3').to_i
|
||||
PASSWORD_COMPLEXITY_FOR_ADMIN = ENV.fetch('PASSWORD_COMPLEXITY_FOR_ADMIN', '4').to_i
|
||||
# password minimum length
|
||||
PASSWORD_MIN_LENGTH = ENV.fetch('PASSWORD_MIN_LENGTH', '8').to_i
|
||||
end
|
|
@ -12,4 +12,4 @@ fr:
|
|||
password:
|
||||
too_short: 'est trop court'
|
||||
blank: 'doit être rempli'
|
||||
not_strength: "n'est pas assez complexe"
|
||||
not_strong: "n'est pas assez complexe"
|
||||
|
|
|
@ -78,8 +78,9 @@ Rails.application.routes.draw do
|
|||
}
|
||||
|
||||
devise_for :administrateurs, controllers: {
|
||||
sessions: 'administrateurs/sessions'
|
||||
}, skip: [:password, :registrations]
|
||||
sessions: 'administrateurs/sessions',
|
||||
passwords: 'administrateurs/passwords'
|
||||
}, skip: [:registrations]
|
||||
|
||||
devise_for :gestionnaires, controllers: {
|
||||
sessions: 'gestionnaires/sessions',
|
||||
|
@ -108,6 +109,7 @@ Rails.application.routes.draw do
|
|||
|
||||
devise_scope :administrateur do
|
||||
get '/administrateurs/sign_in/demo' => redirect("/users/sign_in")
|
||||
get '/administrateurs/password/test_strength' => 'administrateurs/passwords#test_strength'
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -176,7 +178,6 @@ Rails.application.routes.draw do
|
|||
namespace :admin do
|
||||
get 'activate' => '/administrateurs/activate#new'
|
||||
patch 'activate' => '/administrateurs/activate#create'
|
||||
get 'activate/test_password_strength' => '/administrateurs/activate#test_password_strength'
|
||||
get 'sign_in' => '/administrateurs/sessions#new'
|
||||
get 'procedures/archived' => 'procedures#archived'
|
||||
get 'procedures/draft' => 'procedures#draft'
|
||||
|
|
|
@ -254,7 +254,7 @@ describe Gestionnaires::AvisController, type: :controller do
|
|||
let(:dossier) { create(:dossier) }
|
||||
let!(:avis) { create(:avis, email: invited_email, dossier: dossier) }
|
||||
let(:avis_id) { avis.id }
|
||||
let(:password) { '12345678' }
|
||||
let(:password) { 'démarches-simplifiées-pwd' }
|
||||
let(:created_gestionnaire) { Gestionnaire.find_by(email: invited_email) }
|
||||
let(:invitations_email) { true }
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ describe Gestionnaires::PasswordsController, type: :controller do
|
|||
|
||||
describe "update" do
|
||||
context "unified login" do
|
||||
let(:user) { create(:user, email: 'unique@plop.com', password: 'un super mot de passe') }
|
||||
let(:administrateur) { create(:administrateur, email: 'unique@plop.com', password: 'un super mot de passe') }
|
||||
let(:user) { create(:user, email: 'unique@plop.com', password: 'démarches-simplifiées-pwd') }
|
||||
let(:administrateur) { create(:administrateur, email: 'unique@plop.com', password: 'démarches-simplifiées-pwd') }
|
||||
let(:gestionnaire) { administrateur.gestionnaire }
|
||||
|
||||
before do
|
||||
|
@ -21,8 +21,8 @@ describe Gestionnaires::PasswordsController, type: :controller do
|
|||
put :update, params: {
|
||||
gestionnaire: {
|
||||
reset_password_token: @token,
|
||||
password: "supersecret",
|
||||
password_confirmation: "supersecret"
|
||||
password: "démarches-simplifiées-pwd",
|
||||
password_confirmation: "démarches-simplifiées-pwd"
|
||||
}
|
||||
}
|
||||
expect(subject.current_gestionnaire).to eq(gestionnaire)
|
||||
|
@ -33,8 +33,8 @@ describe Gestionnaires::PasswordsController, type: :controller do
|
|||
put :update, params: {
|
||||
gestionnaire: {
|
||||
reset_password_token: @token,
|
||||
password: "supersecret",
|
||||
password_confirmation: "supersecret"
|
||||
password: "démarches-simplifiées-pwd",
|
||||
password_confirmation: "démarches-simplifiées-pwd"
|
||||
}
|
||||
}
|
||||
expect(subject.current_administrateur).to eq(administrateur)
|
||||
|
|
|
@ -3,7 +3,7 @@ describe Manager::AdministrateursController, type: :controller do
|
|||
|
||||
describe 'POST #create' do
|
||||
let(:email) { 'plop@plop.com' }
|
||||
let(:password) { 'password' }
|
||||
let(:password) { 'démarches-simplifiées-pwd' }
|
||||
|
||||
before do
|
||||
sign_in administration
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
describe Users::RegistrationsController, type: :controller do
|
||||
let(:email) { 'test@octo.com' }
|
||||
let(:password) { 'password' }
|
||||
let(:password) { 'démarches-simplifiées-pwd' }
|
||||
|
||||
let(:user) { { email: email, password: password } }
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
describe Users::SessionsController, type: :controller do
|
||||
let(:email) { 'unique@plop.com' }
|
||||
let(:password) { 'un super mot de passe' }
|
||||
let(:password) { 'démarches-simplifiées-pwd' }
|
||||
let(:loged_in_with_france_connect) { User.loged_in_with_france_connects.fetch(:particulier) }
|
||||
let!(:user) { create(:user, email: email, password: password, loged_in_with_france_connect: loged_in_with_france_connect) }
|
||||
|
||||
|
@ -104,8 +104,8 @@ describe Users::SessionsController, type: :controller do
|
|||
end
|
||||
|
||||
context "when associated gestionnaire" do
|
||||
let(:user) { create(:user, email: 'unique@plop.com', password: 'password') }
|
||||
let(:gestionnaire) { create(:gestionnaire, email: 'unique@plop.com', password: 'password') }
|
||||
let(:user) { create(:user, email: 'unique@plop.com', password: 'démarches-simplifiées-pwd') }
|
||||
let(:gestionnaire) { create(:gestionnaire, email: 'unique@plop.com', password: 'démarches-simplifiées-pwd') }
|
||||
|
||||
it 'signs user out' do
|
||||
sign_in user
|
||||
|
|
|
@ -2,6 +2,6 @@ FactoryBot.define do
|
|||
sequence(:administration_email) { |n| "plop#{n}@plop.com" }
|
||||
factory :administration do
|
||||
email { generate(:administration_email) }
|
||||
password { 'password' }
|
||||
password { 'démarches-simplifiées-pwd' }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,6 @@ FactoryBot.define do
|
|||
sequence(:gestionnaire_email) { |n| "gest#{n}@gest.com" }
|
||||
factory :gestionnaire do
|
||||
email { generate(:gestionnaire_email) }
|
||||
password { 'password' }
|
||||
password { 'démarches-simplifiées-pwd' }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ FactoryBot.define do
|
|||
sequence(:user_email) { |n| "user#{n}@user.com" }
|
||||
factory :user do
|
||||
email { generate(:user_email) }
|
||||
password { 'password' }
|
||||
password { 'démarches-simplifiées-pwd' }
|
||||
confirmed_at { Time.zone.now }
|
||||
|
||||
trait :unconfirmed do
|
||||
|
|
|
@ -3,7 +3,7 @@ require 'spec_helper'
|
|||
feature 'The gestionnaire part' do
|
||||
include ActiveJob::TestHelper
|
||||
|
||||
let(:password) { 'secret_password' }
|
||||
let(:password) { 'démarches-simplifiées-pwd' }
|
||||
let!(:gestionnaire) { create(:gestionnaire, password: password) }
|
||||
|
||||
let!(:procedure) { create(:procedure, :published, gestionnaires: [gestionnaire]) }
|
||||
|
@ -237,7 +237,7 @@ feature 'The gestionnaire part' do
|
|||
|
||||
def avis_sign_up(avis, email)
|
||||
visit sign_up_gestionnaire_avis_path(avis, email)
|
||||
fill_in 'gestionnaire_password', with: 'a good password'
|
||||
fill_in 'gestionnaire_password', with: 'démarches-simplifiées-pwd'
|
||||
click_on 'Créer un compte'
|
||||
expect(page).to have_current_path(gestionnaire_avis_index_path)
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ require 'spec_helper'
|
|||
|
||||
feature 'Signin in:' do
|
||||
let!(:user) { create(:user, password: password) }
|
||||
let(:password) { 'testpassword' }
|
||||
let(:password) { 'démarches-simplifiées-pwd' }
|
||||
|
||||
scenario 'an existing user can sign-in' do
|
||||
visit root_path
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'rails_helper'
|
||||
|
||||
feature 'The user' do
|
||||
let(:password) { 'secret_password' }
|
||||
let(:password) { 'démarches-simplifiées-pwd' }
|
||||
let!(:user) { create(:user, password: password) }
|
||||
|
||||
let!(:procedure) { create(:procedure, :published, :for_individual, :with_all_champs_mandatory) }
|
||||
|
|
|
@ -27,7 +27,7 @@ feature 'Invitations' do
|
|||
|
||||
context 'when inviting someone without an existing account' do
|
||||
let(:invite) { create(:invite, dossier: dossier, user: nil) }
|
||||
let(:user_password) { 'l33tus3r' }
|
||||
let(:user_password) { 'démarches-simplifiées-pwd' }
|
||||
|
||||
scenario 'an invited user can register using the registration link sent in the invitation email' do
|
||||
# Click the invitation link
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
feature 'linked dropdown lists' do
|
||||
let(:password) { 'secret_password' }
|
||||
let(:password) { 'démarches-simplifiées-pwd' }
|
||||
let!(:user) { create(:user, password: password) }
|
||||
|
||||
let(:list_items) do
|
||||
|
|
|
@ -2,7 +2,7 @@ require 'spec_helper'
|
|||
|
||||
feature 'Signing up:' do
|
||||
let(:user_email) { generate :user_email }
|
||||
let(:user_password) { 'testpassword' }
|
||||
let(:user_password) { 'démarches-simplifiées-pwd' }
|
||||
|
||||
scenario 'a new user can sign-up' do
|
||||
visit root_path
|
||||
|
|
|
@ -72,29 +72,33 @@ describe Administrateur, type: :model do
|
|||
it { expect(administrateur.feature_enabled?(:test_a)).to be_truthy }
|
||||
end
|
||||
|
||||
describe "#password_complexity" do
|
||||
let(:administrateur) { build(:administrateur, password: password) }
|
||||
describe '#password_complexity' do
|
||||
let(:email) { 'mail@beta.gouv.fr' }
|
||||
let(:passwords) { ['pass', '12pass23', 'démarches ', 'démarches-simple', 'démarches-simplifiées-pwd'] }
|
||||
let(:administrateur) { build(:administrateur, email: email, password: password) }
|
||||
let(:min_complexity) { PASSWORD_COMPLEXITY_FOR_ADMIN }
|
||||
|
||||
subject do
|
||||
administrateur.save
|
||||
administrateur.errors[:password]
|
||||
administrateur.errors.full_messages
|
||||
end
|
||||
|
||||
context "with a strong password" do
|
||||
let(:password) { "la démat c'est simple" }
|
||||
context 'when password is too short' do
|
||||
let(:password) { 's' * (PASSWORD_MIN_LENGTH - 1) }
|
||||
|
||||
it { expect(subject).to eq(["Le mot de passe est trop court"]) }
|
||||
end
|
||||
|
||||
context 'when password is too simple' do
|
||||
let(:password) { passwords[min_complexity - 1] }
|
||||
|
||||
it { expect(subject).to eq(["Le mot de passe n'est pas assez complexe"]) }
|
||||
end
|
||||
|
||||
context 'when password is acceptable' do
|
||||
let(:password) { passwords[min_complexity] }
|
||||
|
||||
it { expect(subject).to eq([]) }
|
||||
end
|
||||
|
||||
context "with a weak password" do
|
||||
let(:password) { "12345678" }
|
||||
it { expect(subject).to include "n'est pas assez complexe" }
|
||||
it { expect(subject).not_to include "est trop court" }
|
||||
end
|
||||
|
||||
context "with a short password" do
|
||||
let(:password) { "1" }
|
||||
it { expect(subject).to include "est trop court" }
|
||||
it { expect(subject).not_to include "n'est pas assez complexe" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -146,21 +146,21 @@ describe Gestionnaire, type: :model do
|
|||
gestionnaire = create(:gestionnaire)
|
||||
user = create(:user, email: gestionnaire.email)
|
||||
|
||||
gestionnaire.update(email: 'whoami@plop.com', password: 'super secret')
|
||||
gestionnaire.update(email: 'whoami@plop.com', password: 'démarches-simplifiées-pwd')
|
||||
|
||||
user.reload
|
||||
expect(user.email).to eq('whoami@plop.com')
|
||||
expect(user.valid_password?('super secret')).to be(true)
|
||||
expect(user.valid_password?('démarches-simplifiées-pwd')).to be(true)
|
||||
end
|
||||
|
||||
it 'syncs credentials to associated administrateur' do
|
||||
admin = create(:administrateur)
|
||||
gestionnaire = admin.gestionnaire
|
||||
|
||||
gestionnaire.update(password: 'super secret')
|
||||
gestionnaire.update(password: 'démarches-simplifiées-pwd')
|
||||
|
||||
admin.reload
|
||||
expect(admin.valid_password?('super secret')).to be(true)
|
||||
expect(admin.valid_password?('démarches-simplifiées-pwd')).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ describe User, type: :model do
|
|||
let(:user) do
|
||||
create(:user,
|
||||
email: email,
|
||||
password: 'a good password',
|
||||
password: 'démarches-simplifiées-pwd',
|
||||
confirmation_token: '123',
|
||||
confirmed_at: nil)
|
||||
end
|
||||
|
@ -106,24 +106,24 @@ describe User, type: :model do
|
|||
user = create(:user)
|
||||
gestionnaire = create(:gestionnaire, email: user.email)
|
||||
|
||||
user.update(email: 'whoami@plop.com', password: 'super secret')
|
||||
user.update(email: 'whoami@plop.com', password: 'démarches-simplifiées2')
|
||||
user.confirm
|
||||
|
||||
gestionnaire.reload
|
||||
expect(gestionnaire.email).to eq('whoami@plop.com')
|
||||
expect(gestionnaire.valid_password?('super secret')).to be(true)
|
||||
expect(gestionnaire.valid_password?('démarches-simplifiées2')).to be(true)
|
||||
end
|
||||
|
||||
it 'syncs credentials to associated administrateur' do
|
||||
user = create(:user)
|
||||
admin = create(:administrateur, email: user.email)
|
||||
|
||||
user.update(email: 'whoami@plop.com', password: 'super secret')
|
||||
user.update(email: 'whoami@plop.com', password: 'démarches-simplifiées2')
|
||||
user.confirm
|
||||
|
||||
admin.reload
|
||||
expect(admin.email).to eq('whoami@plop.com')
|
||||
expect(admin.valid_password?('super secret')).to be(true)
|
||||
expect(admin.valid_password?('démarches-simplifiées2')).to be(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,7 +35,7 @@ module FeatureHelpers
|
|||
end
|
||||
end
|
||||
|
||||
def sign_up_with(email, password = 'testpassword')
|
||||
def sign_up_with(email, password = 'démarches-simplifiées-pwd')
|
||||
fill_in :user_email, with: email
|
||||
fill_in :user_password, with: password
|
||||
|
||||
|
|
Loading…
Reference in a new issue