Fix instructeur invitation

This commit is contained in:
simon lehericey 2019-08-07 15:52:38 +02:00
parent efd793f266
commit 5fdac38cb2
12 changed files with 86 additions and 113 deletions

View file

@ -37,26 +37,24 @@ class Admin::InstructeursController < AdminController
private private
def invite_instructeur(email) def invite_instructeur(email)
password = SecureRandom.hex user = User.find_by(email: email)
@instructeur = Instructeur.create( if user.nil?
user = User.create(
email: email, email: email,
password: password, password: SecureRandom.hex,
password_confirmation: password, confirmed_at: Time.zone.now
administrateurs: [current_administrateur]
) )
if @instructeur.errors.messages.empty?
@instructeur.invite!
if User.exists?(email: @instructeur.email)
InstructeurMailer.user_to_instructeur(@instructeur.email).deliver_later
else
User.create(email: email, password: password, confirmed_at: Time.zone.now)
end end
if user.errors.empty?
@instructeur = Instructeur.create(email: email, administrateurs: [current_administrateur])
user.update!(instructeur: @instructeur)
user.invite!
flash.notice = 'Instructeur ajouté' flash.notice = 'Instructeur ajouté'
else else
flash.alert = @instructeur.errors.full_messages flash.alert = user.errors.full_messages
end end
end end

View file

@ -1,50 +0,0 @@
class Instructeurs::ActivateController < ApplicationController
include TrustedDeviceConcern
def new
@instructeur = Instructeur.with_reset_password_token(params[:token])
if @instructeur
# the instructeur activates its account from an email
trust_device(Time.zone.now)
else
flash.alert = "Le lien de validation du compte instructeur a expiré, #{helpers.contact_link('contactez-nous', tags: 'lien expiré')} pour obtenir un nouveau lien."
redirect_to root_path
end
end
def create
password = create_instructeur_params[:password]
instructeur = Instructeur.reset_password_by_token({
password: password,
password_confirmation: password,
reset_password_token: create_instructeur_params[:reset_password_token]
})
if instructeur && instructeur.errors.empty?
sign_in(instructeur, scope: :instructeur)
try_to_authenticate(User, instructeur.email, password)
try_to_authenticate(Administrateur, instructeur.email, password)
flash.notice = "Mot de passe enregistré"
redirect_to instructeur_procedures_path
else
flash.alert = instructeur.errors.full_messages
redirect_to instructeur_activate_path(token: create_instructeur_params[:reset_password_token])
end
end
private
def create_instructeur_params
params.require(:instructeur).permit(:reset_password_token, :password)
end
def try_to_authenticate(klass, email, password)
resource = klass.find_for_database_authentication(email: email)
if resource&.valid_password?(password)
sign_in resource
resource.force_sync_credentials
end
end
end

View file

@ -0,0 +1,49 @@
class Users::ActivateController < ApplicationController
include TrustedDeviceConcern
def new
@user = User.with_reset_password_token(params[:token])
if @user
# the user activates its account from an email
trust_device(Time.zone.now)
else
flash.alert = "Le lien de validation du compte instructeur a expiré, #{helpers.contact_link('contactez-nous', tags: 'lien expiré')} pour obtenir un nouveau lien."
redirect_to root_path
end
end
def create
password = create_user_params[:password]
user = User.reset_password_by_token({
password: password,
password_confirmation: password,
reset_password_token: create_user_params[:reset_password_token]
})
if user && user.errors.empty?
sign_in(user, scope: :user)
try_to_authenticate(Administrateur, user.email, password)
flash.notice = "Mot de passe enregistré"
redirect_to instructeur_procedures_path
else
flash.alert = user.errors.full_messages
redirect_to users_activate_path(token: create_user_params[:reset_password_token])
end
end
private
def create_user_params
params.require(:user).permit(:reset_password_token, :password)
end
def try_to_authenticate(klass, email, password)
resource = klass.find_for_database_authentication(email: email)
if resource&.valid_password?(password)
sign_in resource
resource.force_sync_credentials
end
end
end

View file

@ -2,16 +2,6 @@
class InstructeurMailer < ApplicationMailer class InstructeurMailer < ApplicationMailer
layout 'mailers/layout' layout 'mailers/layout'
def invite_instructeur(instructeur, reset_password_token)
@reset_password_token = reset_password_token
@instructeur = instructeur
subject = "Activez votre compte instructeur"
mail(to: instructeur.email,
subject: subject,
reply_to: CONTACT_EMAIL)
end
def user_to_instructeur(email) def user_to_instructeur(email)
@email = email @email = email
subject = "Vous avez été nommé instructeur" subject = "Vous avez été nommé instructeur"

View file

@ -16,4 +16,14 @@ class UserMailer < ApplicationMailer
mail(to: requested_email, subject: @subject) mail(to: requested_email, subject: @subject)
end end
def invite_instructeur(user, reset_password_token)
@reset_password_token = reset_password_token
@user = user
subject = "Activez votre compte instructeur"
mail(to: user.email,
subject: subject,
reply_to: CONTACT_EMAIL)
end
end end

View file

@ -177,12 +177,6 @@ class Instructeur < ApplicationRecord
Follow.where(instructeur: self, dossier: dossier).update_all(attributes) Follow.where(instructeur: self, dossier: dossier).update_all(attributes)
end end
def invite!
reset_password_token = set_reset_password_token
InstructeurMailer.invite_instructeur(self, reset_password_token).deliver_later
end
def feature_enabled?(feature) def feature_enabled?(feature)
Flipflop.feature_set.feature(feature) Flipflop.feature_set.feature(feature)
features[feature.to_s] features[feature.to_s]

View file

@ -40,6 +40,10 @@ class User < ApplicationRecord
owns?(dossier) || invite?(dossier.id) owns?(dossier) || invite?(dossier.id)
end end
def invite!
UserMailer.invite_instructeur(self, set_reset_password_token).deliver_later
end
private private
def link_invites! def link_invites!

View file

@ -7,8 +7,8 @@
Vous venez d'être nommé instructeur sur demarches-simplifiees.fr. Vous venez d'être nommé instructeur sur demarches-simplifiees.fr.
%p %p
Votre compte a été créé pour l'adresse email #{@instructeur.email}. Pour lactiver, je vous invite à cliquer sur le lien suivant :  Votre compte a été créé pour l'adresse email #{@user.email}. Pour lactiver, je vous invite à cliquer sur le lien suivant : 
= link_to(instructeur_activate_url(token: @reset_password_token), instructeur_activate_url(token: @reset_password_token)) = link_to(users_activate_url(token: @reset_password_token), users_activate_url(token: @reset_password_token))
%p %p
Par ailleurs, nous vous invitons à prendre quelques minutes pour consulter notre tutoriel à destination des nouveaux instructeurs : Par ailleurs, nous vous invitons à prendre quelques minutes pour consulter notre tutoriel à destination des nouveaux instructeurs :

View file

@ -1,7 +1,7 @@
.container .container
= form_for @instructeur, url: { controller: 'instructeurs/activate', action: :create }, html: { class: "form" } do |f| = form_for @user, url: { controller: 'users/activate', action: :create }, html: { class: "form" } do |f|
%br %br
%h1= @instructeur.email %h1= @user.email
= f.password_field :password, placeholder: 'Mot de passe' = f.password_field :password, placeholder: 'Mot de passe'
= f.hidden_field :reset_password_token, value: params[:token] = f.hidden_field :reset_password_token, value: params[:token]
= f.submit 'Définir le mot de passe', class: 'button large primary expand' = f.submit 'Définir le mot de passe', class: 'button large primary expand'

View file

@ -152,11 +152,9 @@ Rails.application.routes.draw do
get 'dossiers', to: redirect('/dossiers') get 'dossiers', to: redirect('/dossiers')
get 'dossiers/:id/recapitulatif', to: redirect('/dossiers/%{id}') get 'dossiers/:id/recapitulatif', to: redirect('/dossiers/%{id}')
get 'dossiers/invites/:id', to: redirect(path: '/invites/%{id}') get 'dossiers/invites/:id', to: redirect(path: '/invites/%{id}')
end
namespace :instructeur do get 'activate' => '/users/activate#new'
get 'activate' => '/instructeurs/activate#new' patch 'activate' => '/users/activate#create'
patch 'activate' => '/instructeurs/activate#create'
end end
namespace :admin do namespace :admin do

View file

@ -149,30 +149,10 @@ describe Admin::InstructeursController, type: :controller do
context 'Email notification' do context 'Email notification' do
it 'Notification email is sent when instructeur is create' do it 'Notification email is sent when instructeur is create' do
expect_any_instance_of(Instructeur).to receive(:invite!) expect_any_instance_of(User).to receive(:invite!)
subject subject
end end
end end
context 'unified login' do
before do
subject
end
it "creates associated user with same credentials" do
instructeur = controller.instance_variable_get(:@instructeur)
user = User.find_by(email: instructeur.email)
expect(user.valid_password?(instructeur.password)).to be(true)
end
context 'invalid email' do
let(:email) { 'fail' }
it "won't create associated user" do
expect(User.where(email: email).exists?).to be(false)
end
end
end
end end
describe 'DELETE #destroy' do describe 'DELETE #destroy' do

View file

@ -1,7 +1,7 @@
describe Instructeurs::ActivateController, type: :controller do describe Users::ActivateController, type: :controller do
describe '#new' do describe '#new' do
let(:instructeur) { create(:instructeur) } let(:user) { create(:user) }
let(:token) { instructeur.send(:set_reset_password_token) } let(:token) { user.send(:set_reset_password_token) }
before { allow(controller).to receive(:trust_device) } before { allow(controller).to receive(:trust_device) }