#3928 administrator new & edit pwd pages

This commit is contained in:
maatinito 2019-06-19 12:36:50 -10:00 committed by Pierre de La Morinerie
parent 220b38ad2a
commit 8d3e3baabc
32 changed files with 187 additions and 77 deletions

View file

@ -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

View 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

View file

@ -14,10 +14,10 @@ class Users::PasswordsController < Devise::PasswordsController
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]
# 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

View file

@ -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

View file

@ -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
&nbsp;
.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

View file

@ -1 +0,0 @@
<%= render_to_element('#strength-bar', partial: 'password_strength', outer: true, locals: { score: @score }) %>

View 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

View 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..." }

View 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
&nbsp;
.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é.

View 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..." }

View file

@ -0,0 +1 @@
#strength-bar.password-strength{ class: "strength-#{@length < @min_length ? @score/2 : @score}" }

View 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.

View 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};") %>

View file

@ -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"
}

View file

@ -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'

View file

@ -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 }

View file

@ -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)

View file

@ -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

View file

@ -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 } }

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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) }

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -3,12 +3,12 @@ require 'spec_helper'
describe User, type: :model do
describe '#after_confirmation' do
let(:email) { 'mail@beta.gouv.fr' }
let!(:invite) { create(:invite, email: email) }
let!(:invite) { create(:invite, email: email) }
let!(:invite2) { create(:invite, email: email) }
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

View file

@ -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