diff --git a/app/controllers/france_connect/particulier_controller.rb b/app/controllers/france_connect/particulier_controller.rb index 8a2a7139f..3efe18e97 100644 --- a/app/controllers/france_connect/particulier_controller.rb +++ b/app/controllers/france_connect/particulier_controller.rb @@ -13,16 +13,23 @@ class FranceConnect::ParticulierController < ApplicationController fci = FranceConnectService.find_or_retrieve_france_connect_information(params[:code]) if fci.user.nil? - fci.associate_user!(fci.email_france_connect) - end + preexisting_unlinked_user = User.find_by(email: fci.email_france_connect.downcase) - user = fci.user - - if user.can_france_connect? - connect_france_connect_particulier(user) + if preexisting_unlinked_user.nil? + fci.associate_user!(fci.email_france_connect) + connect_france_connect_particulier(fci.user) + else + redirect_to france_connect_particulier_merge_path(fci.create_merge_token!) + end else - fci.destroy - redirect_to new_user_session_path, alert: t('errors.messages.france_connect.forbidden_html', reset_link: new_user_password_path) + user = fci.user + + if user.can_france_connect? + connect_france_connect_particulier(user) + else + fci.destroy + redirect_to new_user_session_path, alert: t('errors.messages.france_connect.forbidden_html', reset_link: new_user_password_path) + end end rescue Rack::OAuth2::Client::Error => e @@ -30,6 +37,9 @@ class FranceConnect::ParticulierController < ApplicationController redirect_france_connect_error_connection end + def merge + end + private def redirect_to_login_if_fc_aborted diff --git a/app/views/france_connect/particulier/merge.html.haml b/app/views/france_connect/particulier/merge.html.haml new file mode 100644 index 000000000..ad4a0489c --- /dev/null +++ b/app/views/france_connect/particulier/merge.html.haml @@ -0,0 +1,5 @@ += content_for :title, "Fusion des comptes FC et #{APPLICATION_NAME}" + +.container + %h1.page-title Fusion des comptes FranceConnect et #{APPLICATION_NAME} + diff --git a/config/routes.rb b/config/routes.rb index 3e8b1168b..3560cc97a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -124,6 +124,7 @@ Rails.application.routes.draw do namespace :france_connect do get 'particulier' => 'particulier#login' get 'particulier/callback' => 'particulier#callback' + get 'particulier/merge/:merge_token' => 'particulier#merge', as: :particulier_merge end namespace :champs do diff --git a/spec/controllers/france_connect/particulier_controller_spec.rb b/spec/controllers/france_connect/particulier_controller_spec.rb index 569d444e3..3a416491d 100644 --- a/spec/controllers/france_connect/particulier_controller_spec.rb +++ b/spec/controllers/france_connect/particulier_controller_spec.rb @@ -1,6 +1,6 @@ describe FranceConnect::ParticulierController, type: :controller do let(:birthdate) { '20150821' } - let(:email) { 'email_from_fc@test.com' } + let(:email) { 'EMAIL_from_fc@test.com' } let(:user_info) do { @@ -50,7 +50,7 @@ describe FranceConnect::ParticulierController, type: :controller do end context 'when france_connect_particulier_id exists in database' do - let!(:fci) { FranceConnectInformation.create!(user_info.merge(user_id: fc_user.id)) } + let!(:fci) { FranceConnectInformation.create!(user_info.merge(user_id: fc_user&.id)) } context 'and is linked to an user' do let(:fc_user) { create(:user, email: 'associated_user@a.com') } @@ -81,6 +81,32 @@ describe FranceConnect::ParticulierController, type: :controller do expect(flash[:alert]).to be_present end end + + context 'and is not linked to an user' do + let(:fc_user) { nil } + + context 'and no user with the same email exists' do + it 'creates an user with the same email and log in' do + expect { subject }.to change { User.count }.by(1) + + user = User.last + + expect(user.email).to eq(email.downcase) + expect(controller.current_user).to eq(user) + expect(response).to redirect_to(root_path) + end + end + + context 'and an user with the same email exists' do + let!(:preexisting_user) { create(:user, email: email) } + + it 'redirects to the merge process' do + expect { subject }.not_to change { User.count } + + expect(response).to redirect_to(france_connect_particulier_merge_path(fci.reload.merge_token)) + end + end + end end context 'when france_connect_particulier_id does not exist in database' do