From bdb6c040c9ce70f0da4bad1e7c808cfba9338d5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Charignon?= Date: Mon, 23 Sep 2024 17:53:15 +0200 Subject: [PATCH] =?UTF-8?q?g=C3=A8re=20aussi=20la=20migration=20pole-emplo?= =?UTF-8?q?i.fr=20vers=20francetravail.fr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/pro_connect_helper.rb | 37 +-- .../pro_connect_recupere_compte_helper.rb | 52 ++++ spec/helpers/pro_connect_helper_spec.rb | 191 --------------- ...pro_connect_recupere_compte_helper_spec.rb | 222 ++++++++++++++++++ 4 files changed, 275 insertions(+), 227 deletions(-) create mode 100644 app/helpers/pro_connect_recupere_compte_helper.rb create mode 100644 spec/helpers/pro_connect_recupere_compte_helper_spec.rb diff --git a/app/helpers/pro_connect_helper.rb b/app/helpers/pro_connect_helper.rb index 067e2b13d..cc3d0091e 100644 --- a/app/helpers/pro_connect_helper.rb +++ b/app/helpers/pro_connect_helper.rb @@ -55,7 +55,7 @@ def compte(access_token) user_info = get_user_info(access_token) return false if user_info.blank? - cree_ou_recupere_compte(user_info) + ProConnectRecupereCompteHelper.cree_ou_recupere_compte(user_info) end def recupere_tokens(code, callback_url) @@ -81,40 +81,5 @@ def get_user_info(token) decode_jwt(res.body) { |user_info| user_info } end - - def cree_ou_recupere_compte(user_info) - email = user_info['email'].strip.downcase - compte = Compte.find_by(id_pro_connect: user_info['sub']) - if compte.present? && compte.email != email - compte = actualise_email_compte_existant(compte, email) - end - compte ||= Compte.find_or_create_by(email: email) - actualise_autres_champs(compte, user_info) - compte.save! - compte - end - - private - - def actualise_email_compte_existant(compte, email) - compte_existant = Compte.find_by(email: email) - if compte_existant.present? - compte.update!(id_pro_connect: nil) - compte = compte_existant - else - compte.email = email - compte.skip_reconfirmation! - compte.confirmed_at = Time.zone.now - end - compte - end - - def actualise_autres_champs(compte, user_info) - compte.id_pro_connect = user_info['sub'] - compte.prenom = user_info['given_name'] - compte.nom = user_info['usual_name'] - compte.password = SecureRandom.uuid if compte.encrypted_password.blank? - compte.confirmed_at ||= Time.zone.now - end end end diff --git a/app/helpers/pro_connect_recupere_compte_helper.rb b/app/helpers/pro_connect_recupere_compte_helper.rb new file mode 100644 index 000000000..a3b6c39a2 --- /dev/null +++ b/app/helpers/pro_connect_recupere_compte_helper.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module ProConnectRecupereCompteHelper + class << self + def cree_ou_recupere_compte(user_info) + email = user_info['email'].strip.downcase + compte = Compte.find_by(id_pro_connect: user_info['sub']) + if compte.present? && compte.email != email + compte = actualise_email_compte_existant(compte, email) + end + if compte.blank? && email.end_with?('francetravail.fr') + compte = cherche_compte_pole_emploi(email) + end + compte ||= Compte.find_or_create_by(email: email) + actualise_autres_champs_et_sauve(compte, user_info) + end + + private + + def actualise_email_compte_existant(compte, email) + compte_existant = Compte.find_by(email: email) + if compte_existant.present? + compte.update!(id_pro_connect: nil) + compte = compte_existant + else + compte.email = email + compte.skip_reconfirmation! + compte.confirmed_at = Time.zone.now + end + compte + end + + def cherche_compte_pole_emploi(email) + email_pe = email.gsub('francetravail.fr', 'pole-emploi.fr') + compte = Compte.find_by(email: email_pe) + compte&.email = email + compte&.skip_reconfirmation! + compte&.confirmed_at = Time.zone.now + compte + end + + def actualise_autres_champs_et_sauve(compte, user_info) + compte.id_pro_connect = user_info['sub'] + compte.prenom = user_info['given_name'] + compte.nom = user_info['usual_name'] + compte.password = SecureRandom.uuid if compte.encrypted_password.blank? + compte.confirmed_at ||= Time.zone.now + compte.save! + compte + end + end +end diff --git a/spec/helpers/pro_connect_helper_spec.rb b/spec/helpers/pro_connect_helper_spec.rb index 506d9a874..228a65d3c 100644 --- a/spec/helpers/pro_connect_helper_spec.rb +++ b/spec/helpers/pro_connect_helper_spec.rb @@ -20,195 +20,4 @@ expect(session[:pc_logout_token]).to be_nil end end - - describe '#cree_ou_recupere_compte' do - let(:id_ic) { 'identifiant_ic' } - - context "le compte n'existe pas" do - it do - Timecop.freeze(aujourdhui) do - compte = described_class.cree_ou_recupere_compte({ - 'sub' => id_ic, - 'email' => email, - 'given_name' => 'prénom', - 'usual_name' => 'nom' - }) - expect(compte).not_to be_nil - expect(compte.email).to eq(email) - expect(compte.prenom).to eq('prénom') - expect(compte.nom).to eq('nom') - expect(compte.confirmed_at).to eq(aujourdhui) - expect(compte.password).not_to be_nil - expect(compte.id_pro_connect).to eq(id_ic) - end - end - end - - context 'le compte existe déjà en base sans id inclusion connect' do - before do - create :compte_admin, email: email - end - - it do - Timecop.freeze(aujourdhui) do - compte = described_class.cree_ou_recupere_compte({ - 'sub' => id_ic, - 'email' => email, - 'given_name' => 'prénom', - 'usual_name' => 'nom' - }) - expect(compte).not_to be_nil - expect(compte.email).to eq(email) - expect(compte.prenom).to eq('prénom') - expect(compte.nom).to eq('nom') - expect(compte.confirmed_at).to eq(aujourdhui) - expect(compte.password).to be_nil - expect(compte.id_pro_connect).to eq(id_ic) - end - end - end - - context 'le compte existe déjà en base sans id inclusion connect, email avec majuscule' do - before do - create :compte_admin, email: email - end - - it do - Timecop.freeze(aujourdhui) do - compte = described_class.cree_ou_recupere_compte({ - 'sub' => id_ic, - 'email' => 'toto@eva.beta.gouv.FR', - 'given_name' => 'prénom', - 'usual_name' => 'nom' - }) - expect(compte).not_to be_nil - expect(compte.email).to eq(email) - expect(compte.prenom).to eq('prénom') - expect(compte.nom).to eq('nom') - expect(compte.confirmed_at).to eq(aujourdhui) - expect(compte.password).to be_nil - expect(compte.id_pro_connect).to eq(id_ic) - end - end - end - - context 'le compte existe déjà en base même email, mais effacé' do - before do - create :compte_admin, email: email, confirmed_at: hier, deleted_at: hier - end - - it do - Timecop.freeze(aujourdhui) do - compte = described_class.cree_ou_recupere_compte({ - 'sub' => id_ic, - 'email' => email, - 'given_name' => 'prénom', - 'usual_name' => 'nom' - }) - expect(compte).not_to be_nil - expect(compte.prenom).to eq('prénom') - expect(compte.nom).to eq('nom') - expect(compte.email).to eq(email) - expect(compte.confirmed_at).to eq(aujourdhui) - expect(compte.password).not_to be_nil - expect(compte.id_pro_connect).to eq(id_ic) - expect(compte.id).not_to eq(Compte.only_deleted.find_by(email: email).id) - end - end - end - - context 'le compte existe déjà en base avec id inclusion connect, même email' do - before do - create :compte_admin, email: email, confirmed_at: hier, id_pro_connect: id_ic - end - - it do - Timecop.freeze(aujourdhui) do - compte = described_class.cree_ou_recupere_compte({ - 'sub' => id_ic, - 'email' => email, - 'given_name' => 'prénom', - 'usual_name' => 'nom' - }) - expect(compte).not_to be_nil - expect(compte.prenom).to eq('prénom') - expect(compte.nom).to eq('nom') - expect(compte.email).to eq(email) - expect(compte.confirmed_at).to eq(hier) - expect(compte.password).to be_nil - expect(compte.id_pro_connect).to eq(id_ic) - end - end - end - - context 'le compte existe déjà en base avec id inclusion connect, email différent' do - before do - create :compte_admin, email: ancien_email, confirmed_at: hier, id_pro_connect: id_ic - end - - it do - Timecop.freeze(aujourdhui) do - compte = described_class.cree_ou_recupere_compte({ - 'sub' => id_ic, - 'email' => email, - 'given_name' => 'prénom', - 'usual_name' => 'nom' - }) - expect(compte).not_to be_nil - expect(compte.prenom).to eq('prénom') - expect(compte.nom).to eq('nom') - expect(compte.email).to eq(email) - expect(compte.confirmed_at).to eq(aujourdhui) - expect(compte.password).to be_nil - expect(compte.id_pro_connect).to eq(id_ic) - end - end - end - - context "Il existe deux comptes en base dans le cas d'une mise à jourd d'email" do - before do - create :compte_admin, email: email, confirmed_at: hier - create :compte_admin, email: ancien_email, confirmed_at: hier, id_pro_connect: id_ic - end - - it do - Timecop.freeze(aujourdhui) do - compte = described_class.cree_ou_recupere_compte({ - 'sub' => id_ic, - 'email' => email, - 'given_name' => 'prénom', - 'usual_name' => 'nom' - }) - expect(compte).not_to be_nil - expect(compte.prenom).to eq('prénom') - expect(compte.nom).to eq('nom') - expect(compte.email).to eq(email) - expect(compte.confirmed_at).to eq(hier) - expect(compte.password).to be_nil - expect(compte.id_pro_connect).to eq(id_ic) - ancien_compte = Compte.find_by(email: ancien_email) - expect(ancien_compte).not_to be_nil - expect(ancien_compte.id_pro_connect).to be_nil - end - end - end - - context 'le compte existe déjà en base et avec un email déjà confirmé' do - before do - create :compte_admin, email: email, confirmed_at: hier - end - - it do - Timecop.freeze(aujourdhui) do - compte = described_class.cree_ou_recupere_compte({ - 'sub' => id_ic, - 'email' => email, - 'given_name' => 'prénom', - 'usual_name' => 'nom' - }) - expect(compte.confirmed_at).to eq(hier) - end - end - end - end end diff --git a/spec/helpers/pro_connect_recupere_compte_helper_spec.rb b/spec/helpers/pro_connect_recupere_compte_helper_spec.rb new file mode 100644 index 000000000..f7d5075e5 --- /dev/null +++ b/spec/helpers/pro_connect_recupere_compte_helper_spec.rb @@ -0,0 +1,222 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe ProConnectRecupereCompteHelper do + let(:email) { 'toto@eva.beta.gouv.fr' } + let(:ancien_email) { 'autre@eva.beta.gouv.fr' } + let(:aujourdhui) { Time.zone.local(2023, 1, 10, 12, 0, 0) } + let(:hier) { Time.zone.local(2023, 1, 9, 12, 0, 0) } + + describe '#cree_ou_recupere_compte' do + let(:id_ic) { 'identifiant_ic' } + + context "le compte n'existe pas" do + it do + Timecop.freeze(aujourdhui) do + compte = described_class.cree_ou_recupere_compte({ + 'sub' => id_ic, + 'email' => email, + 'given_name' => 'prénom', + 'usual_name' => 'nom' + }) + expect(compte).not_to be_nil + expect(compte.email).to eq(email) + expect(compte.prenom).to eq('prénom') + expect(compte.nom).to eq('nom') + expect(compte.confirmed_at).to eq(aujourdhui) + expect(compte.password).not_to be_nil + expect(compte.id_pro_connect).to eq(id_ic) + end + end + end + + context 'le compte existe déjà en base sans id inclusion connect' do + before do + create :compte_admin, email: email + end + + it do + Timecop.freeze(aujourdhui) do + compte = described_class.cree_ou_recupere_compte({ + 'sub' => id_ic, + 'email' => email, + 'given_name' => 'prénom', + 'usual_name' => 'nom' + }) + expect(compte).not_to be_nil + expect(compte.email).to eq(email) + expect(compte.prenom).to eq('prénom') + expect(compte.nom).to eq('nom') + expect(compte.confirmed_at).to eq(aujourdhui) + expect(compte.password).to be_nil + expect(compte.id_pro_connect).to eq(id_ic) + end + end + end + + context 'le compte existe déjà en base sans id inclusion connect, email avec majuscule' do + before do + create :compte_admin, email: email + end + + it do + Timecop.freeze(aujourdhui) do + compte = described_class.cree_ou_recupere_compte({ + 'sub' => id_ic, + 'email' => 'toto@eva.beta.gouv.FR', + 'given_name' => 'prénom', + 'usual_name' => 'nom' + }) + expect(compte).not_to be_nil + expect(compte.email).to eq(email) + expect(compte.prenom).to eq('prénom') + expect(compte.nom).to eq('nom') + expect(compte.confirmed_at).to eq(aujourdhui) + expect(compte.password).to be_nil + expect(compte.id_pro_connect).to eq(id_ic) + end + end + end + + context 'le compte existe déjà en base même email, mais effacé' do + before do + create :compte_admin, email: email, confirmed_at: hier, deleted_at: hier + end + + it do + Timecop.freeze(aujourdhui) do + compte = described_class.cree_ou_recupere_compte({ + 'sub' => id_ic, + 'email' => email, + 'given_name' => 'prénom', + 'usual_name' => 'nom' + }) + expect(compte).not_to be_nil + expect(compte.prenom).to eq('prénom') + expect(compte.nom).to eq('nom') + expect(compte.email).to eq(email) + expect(compte.confirmed_at).to eq(aujourdhui) + expect(compte.password).not_to be_nil + expect(compte.id_pro_connect).to eq(id_ic) + expect(compte.id).not_to eq(Compte.only_deleted.find_by(email: email).id) + end + end + end + + context 'le compte existe déjà en base avec id inclusion connect, même email' do + before do + create :compte_admin, email: email, confirmed_at: hier, id_pro_connect: id_ic + end + + it do + Timecop.freeze(aujourdhui) do + compte = described_class.cree_ou_recupere_compte({ + 'sub' => id_ic, + 'email' => email, + 'given_name' => 'prénom', + 'usual_name' => 'nom' + }) + expect(compte).not_to be_nil + expect(compte.prenom).to eq('prénom') + expect(compte.nom).to eq('nom') + expect(compte.email).to eq(email) + expect(compte.confirmed_at).to eq(hier) + expect(compte.password).to be_nil + expect(compte.id_pro_connect).to eq(id_ic) + end + end + end + + context 'le compte existe déjà en base avec id inclusion connect, email différent' do + before do + create :compte_admin, email: ancien_email, confirmed_at: hier, id_pro_connect: id_ic + end + + it do + Timecop.freeze(aujourdhui) do + compte = described_class.cree_ou_recupere_compte({ + 'sub' => id_ic, + 'email' => email, + 'given_name' => 'prénom', + 'usual_name' => 'nom' + }) + expect(compte).not_to be_nil + expect(compte.prenom).to eq('prénom') + expect(compte.nom).to eq('nom') + expect(compte.email).to eq(email) + expect(compte.confirmed_at).to eq(aujourdhui) + expect(compte.password).to be_nil + expect(compte.id_pro_connect).to eq(id_ic) + end + end + end + + context "Il existe deux comptes en base dans le cas d'une mise à jourd d'email" do + before do + create :compte_admin, email: email, confirmed_at: hier + create :compte_admin, email: ancien_email, confirmed_at: hier, id_pro_connect: id_ic + end + + it do + Timecop.freeze(aujourdhui) do + compte = described_class.cree_ou_recupere_compte({ + 'sub' => id_ic, + 'email' => email, + 'given_name' => 'prénom', + 'usual_name' => 'nom' + }) + expect(compte).not_to be_nil + expect(compte.prenom).to eq('prénom') + expect(compte.nom).to eq('nom') + expect(compte.email).to eq(email) + expect(compte.confirmed_at).to eq(hier) + expect(compte.password).to be_nil + expect(compte.id_pro_connect).to eq(id_ic) + ancien_compte = Compte.find_by(email: ancien_email) + expect(ancien_compte).not_to be_nil + expect(ancien_compte.id_pro_connect).to be_nil + end + end + end + + context 'le compte existe déjà en base et avec un email déjà confirmé' do + before do + create :compte_admin, email: email, confirmed_at: hier + end + + it do + Timecop.freeze(aujourdhui) do + compte = described_class.cree_ou_recupere_compte({ + 'sub' => id_ic, + 'email' => email, + 'given_name' => 'prénom', + 'usual_name' => 'nom' + }) + expect(compte.confirmed_at).to eq(hier) + end + end + end + + context 'Il existe un comptes avec un email pole-emploi.fr' do + let(:email_pe) { 'toto@pole-emploi.fr' } + let(:email_ft) { 'toto@francetravail.fr' } + let!(:compte_pe) { create :compte_admin, email: email_pe } + + it do + Timecop.freeze(aujourdhui) do + compte = described_class.cree_ou_recupere_compte({ + 'sub' => id_ic, + 'email' => email_ft, + 'given_name' => 'prénom', + 'usual_name' => 'nom' + }) + expect(compte).not_to be_nil + expect(compte.email).to eq(email_ft) + expect(compte.id_pro_connect).to eq(id_ic) + expect(compte.id).to eq(compte_pe.id) + end + end + end + end +end