[fix #3269] bufferize login token email

This commit is contained in:
simon lehericey 2019-01-10 10:41:03 +01:00
parent 3e149e7c8e
commit 29fff9ee68
4 changed files with 77 additions and 18 deletions

View file

@ -30,8 +30,8 @@ class Users::SessionsController < Sessions::SessionsController
redirect_to after_sign_in_path_for(:user) redirect_to after_sign_in_path_for(:user)
else else
gestionnaire = current_gestionnaire gestionnaire = current_gestionnaire
login_token = gestionnaire.login_token!
GestionnaireMailer.send_login_token(gestionnaire, login_token).deliver_later send_login_token_or_bufferize(gestionnaire)
[:user, :gestionnaire, :administrateur].each { |role| sign_out(role) } [:user, :gestionnaire, :administrateur].each { |role| sign_out(role) }
@ -103,6 +103,13 @@ class Users::SessionsController < Sessions::SessionsController
private private
def send_login_token_or_bufferize(gestionnaire)
if !gestionnaire.young_login_token?
login_token = gestionnaire.login_token!
GestionnaireMailer.send_login_token(gestionnaire, login_token).deliver_later
end
end
def error_procedure def error_procedure
session["user_return_to"] = nil session["user_return_to"] = nil
flash.alert = t('errors.messages.procedure_not_found') flash.alert = t('errors.messages.procedure_not_found')

View file

@ -4,6 +4,7 @@ class Gestionnaire < ApplicationRecord
include ActiveRecord::SecureToken include ActiveRecord::SecureToken
LOGIN_TOKEN_VALIDITY = 30.minutes LOGIN_TOKEN_VALIDITY = 30.minutes
LOGIN_TOKEN_YOUTH = 15.minutes
devise :database_authenticatable, :registerable, :async, devise :database_authenticatable, :registerable, :async,
:recoverable, :rememberable, :trackable, :validatable :recoverable, :rememberable, :trackable, :validatable
@ -211,6 +212,11 @@ class Gestionnaire < ApplicationRecord
save save
end end
def young_login_token?
login_token_created_at.present? &&
LOGIN_TOKEN_YOUTH.ago < login_token_created_at
end
private private
def annotations_hash(demande, annotations_privees, avis, messagerie) def annotations_hash(demande, annotations_privees, avis, messagerie)

View file

@ -17,6 +17,10 @@ describe Users::SessionsController, type: :controller do
before do before do
allow(controller).to receive(:trusted_device?).and_return(trusted_device) allow(controller).to receive(:trusted_device?).and_return(trusted_device)
allow(GestionnaireMailer).to receive(:send_login_token).and_return(double(deliver_later: true))
end
subject do
post :create, params: { user: { email: email, password: send_password } } post :create, params: { user: { email: email, password: send_password } }
user.reload user.reload
end end
@ -25,28 +29,47 @@ describe Users::SessionsController, type: :controller do
let(:trusted_device) { false } let(:trusted_device) { false }
it 'redirects to the confirmation link path' do it 'redirects to the confirmation link path' do
expect(subject).to redirect_to link_sent_path(email: email) subject
expect(controller).to redirect_to link_sent_path(email: email)
# do not know why, should be test related # do not know why, should be test related
expect(subject.current_user).to eq(user) expect(controller.current_user).to eq(user)
expect(subject.current_gestionnaire).to be(nil) expect(controller.current_gestionnaire).to be(nil)
expect(subject.current_administrateur).to be(nil) expect(controller.current_administrateur).to be(nil)
expect(user.reload.loged_in_with_france_connect).to be(nil) expect(user.loged_in_with_france_connect).to be(nil)
expect(GestionnaireMailer).to have_received(:send_login_token)
end
context 'and the user try to connect multiple times in a short period' do
before do
allow_any_instance_of(Gestionnaire).to receive(:young_login_token?).and_return(true)
allow(GestionnaireMailer).to receive(:send_login_token)
end
it 'does not renew nor send a new login token' do
subject
expect(GestionnaireMailer).not_to have_received(:send_login_token)
end
end end
end end
context 'when the device is trusted' do context 'when the device is trusted' do
it 'signs in as user, gestionnaire and adminstrateur' do it 'signs in as user, gestionnaire and adminstrateur' do
expect(@response.redirect?).to be(true) subject
expect(subject).not_to redirect_to link_sent_path(email: email)
# TODO when signing in as non-administrateur, and not starting a demarche, log in to gestionnaire path
# expect(subject).to redirect_to gestionnaire_procedures_path
expect(subject.current_user).to eq(user) expect(response.redirect?).to be(true)
expect(subject.current_gestionnaire).to eq(gestionnaire) expect(controller).not_to redirect_to link_sent_path(email: email)
expect(subject.current_administrateur).to eq(administrateur) # TODO when signing in as non-administrateur, and not starting a demarche, log in to gestionnaire path
# expect(controller).to redirect_to gestionnaire_procedures_path
expect(controller.current_user).to eq(user)
expect(controller.current_gestionnaire).to eq(gestionnaire)
expect(controller.current_administrateur).to eq(administrateur)
expect(user.loged_in_with_france_connect).to be(nil) expect(user.loged_in_with_france_connect).to be(nil)
expect(GestionnaireMailer).not_to have_received(:send_login_token)
end end
end end
@ -54,10 +77,12 @@ describe Users::SessionsController, type: :controller do
let(:send_password) { 'wrong_password' } let(:send_password) { 'wrong_password' }
it 'fails to sign in with bad credentials' do it 'fails to sign in with bad credentials' do
expect(@response.unauthorized?).to be(true) subject
expect(subject.current_user).to be(nil)
expect(subject.current_gestionnaire).to be(nil) expect(response.unauthorized?).to be(true)
expect(subject.current_administrateur).to be(nil) expect(controller.current_user).to be(nil)
expect(controller.current_gestionnaire).to be(nil)
expect(controller.current_administrateur).to be(nil)
end end
end end
end end

View file

@ -412,6 +412,27 @@ describe Gestionnaire, type: :model do
end end
end end
describe '#young_login_token?' do
let!(:gestionnaire) { create(:gestionnaire) }
context 'when there is a token' do
let!(:good_token) { gestionnaire.login_token! }
context 'when the token has just been created' do
it { expect(gestionnaire.young_login_token?).to be true }
end
context 'when the token is a bit old' do
before { gestionnaire.update(login_token_created_at: (Gestionnaire::LOGIN_TOKEN_YOUTH + 1.minute).ago) }
it { expect(gestionnaire.young_login_token?).to be false }
end
end
context 'when there are no token' do
it { expect(gestionnaire.young_login_token?).to be false }
end
end
private private
def assign(procedure_to_assign) def assign(procedure_to_assign)