2024-04-29 00:17:15 +02:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2015-12-24 10:12:23 +01:00
|
|
|
class FranceConnect::ParticulierController < ApplicationController
|
2018-01-15 21:18:02 +01:00
|
|
|
before_action :redirect_to_login_if_fc_aborted, only: [:callback]
|
2024-07-31 17:50:14 +02:00
|
|
|
before_action :securely_retrieve_fci, only: [:merge_using_fc_email, :merge_using_password, :send_email_merge_request]
|
|
|
|
before_action :securely_retrieve_fci_from_email_merge_token, only: [:merge_using_email_link]
|
2024-07-25 13:24:43 +02:00
|
|
|
before_action :set_user_by_confirmation_token, only: [:confirm_email]
|
2018-01-15 21:18:02 +01:00
|
|
|
|
2015-12-24 10:12:23 +01:00
|
|
|
def login
|
2020-08-01 10:33:38 +02:00
|
|
|
if FranceConnectService.enabled?
|
2023-04-27 13:21:20 +02:00
|
|
|
redirect_to FranceConnectService.authorization_uri, allow_other_host: true
|
2020-08-01 10:33:38 +02:00
|
|
|
else
|
|
|
|
redirect_to new_user_session_path
|
|
|
|
end
|
2015-12-24 10:12:23 +01:00
|
|
|
end
|
|
|
|
|
2016-01-21 17:06:09 +01:00
|
|
|
def callback
|
2024-07-31 17:50:14 +02:00
|
|
|
@fci = FranceConnectService.find_or_retrieve_france_connect_information(params[:code])
|
2021-10-11 11:39:14 +02:00
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
if @fci.user.nil?
|
|
|
|
preexisting_unlinked_user = User.find_by(email: sanitize(@fci.email_france_connect))
|
2021-10-11 11:30:45 +02:00
|
|
|
|
2021-10-13 00:45:20 +02:00
|
|
|
if preexisting_unlinked_user.nil?
|
2024-07-31 17:50:14 +02:00
|
|
|
@fci.create_merge_token!
|
|
|
|
render :choose_email
|
|
|
|
elsif preexisting_unlinked_user.can_france_connect?
|
|
|
|
@fci.create_merge_token!
|
|
|
|
render :merge
|
2021-10-13 00:45:20 +02:00
|
|
|
else
|
2024-07-31 17:50:14 +02:00
|
|
|
destroy_fci_and_redirect_to_login(@fci)
|
2021-10-13 00:45:20 +02:00
|
|
|
end
|
2021-10-11 11:30:45 +02:00
|
|
|
else
|
2024-07-31 17:50:14 +02:00
|
|
|
if @fci.user.can_france_connect?
|
|
|
|
@fci.update(updated_at: Time.zone.now)
|
|
|
|
connect_france_connect_particulier(@fci.user)
|
2024-07-01 16:37:33 +02:00
|
|
|
else
|
2024-07-31 17:50:14 +02:00
|
|
|
destroy_fci_and_redirect_to_login(@fci)
|
2021-10-13 00:45:20 +02:00
|
|
|
end
|
2015-12-24 10:12:23 +01:00
|
|
|
end
|
2018-01-16 12:08:50 +01:00
|
|
|
|
2016-01-21 17:06:09 +01:00
|
|
|
rescue Rack::OAuth2::Client::Error => e
|
|
|
|
Rails.logger.error e.message
|
2024-07-31 17:50:14 +02:00
|
|
|
redirect_to(new_user_session_path, alert: t('errors.messages.france_connect.connexion'))
|
2016-01-21 17:06:09 +01:00
|
|
|
end
|
2015-12-24 10:12:23 +01:00
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
def send_email_merge_request
|
|
|
|
@fci.update(requested_email: sanitized_email_params)
|
2024-07-01 16:37:33 +02:00
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
@fci.create_email_merge_token!
|
|
|
|
UserMailer.france_connect_merge_confirmation(
|
|
|
|
sanitized_email_params,
|
|
|
|
@fci.email_merge_token,
|
|
|
|
@fci.email_merge_token_created_at
|
|
|
|
)
|
|
|
|
.deliver_later
|
2024-07-01 16:37:33 +02:00
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
redirect_to root_path, notice: t('france_connect.particulier.flash.confirmation_mail_sent')
|
2024-07-01 16:37:33 +02:00
|
|
|
end
|
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
def merge_using_fc_email
|
|
|
|
@fci.safely_associate_user!(@fci.email_france_connect)
|
2021-10-13 00:45:20 +02:00
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
sign_in(@fci.user)
|
2021-10-13 09:23:40 +02:00
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
@fci.send_custom_confirmation_instructions
|
2021-10-13 09:23:40 +02:00
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
render :confirmation_sent, locals: { email: @fci.email_france_connect, destination_path: destination_path(@fci.user) }
|
|
|
|
end
|
2021-10-13 09:23:40 +02:00
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
def merge_using_password
|
|
|
|
user = User.find_by(email: sanitize(@fci.email_france_connect))
|
|
|
|
|
|
|
|
if user.present? && !user.can_france_connect?
|
|
|
|
return destroy_fci_and_redirect_to_login(@fci)
|
2021-10-13 09:23:40 +02:00
|
|
|
end
|
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
if user.present? && user.valid_for_authentication? { user.valid_password?(params[:password]) }
|
|
|
|
@fci.safely_update_user(user:)
|
|
|
|
|
2024-03-20 11:34:54 +01:00
|
|
|
flash.notice = t('france_connect.particulier.flash.connection_done', application_name: Current.application_name)
|
2021-11-17 16:21:55 +01:00
|
|
|
connect_france_connect_particulier(user)
|
2024-07-31 17:50:14 +02:00
|
|
|
else
|
|
|
|
flash.alert = t('france_connect.particulier.flash.invalid_password')
|
2021-11-17 16:21:55 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
def merge_using_email_link
|
|
|
|
user = User.find_by(email: @fci.requested_email)
|
|
|
|
|
|
|
|
if user.present? && !user.can_france_connect?
|
|
|
|
return destroy_fci_and_redirect_to_login(@fci)
|
|
|
|
end
|
2021-10-13 09:26:54 +02:00
|
|
|
|
|
|
|
if user.nil?
|
2024-07-31 17:50:14 +02:00
|
|
|
@fci.safely_associate_user!(@fci.requested_email)
|
2021-10-13 09:26:54 +02:00
|
|
|
else
|
2024-07-31 17:50:14 +02:00
|
|
|
@fci.safely_update_user(user:)
|
2021-10-13 09:26:54 +02:00
|
|
|
end
|
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
@fci.user.update(email_verified_at: Time.zone.now)
|
2024-01-11 10:44:19 +01:00
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
flash.notice = t('france_connect.particulier.flash.connection_done', application_name: Current.application_name)
|
|
|
|
connect_france_connect_particulier(@fci.user)
|
2021-11-17 16:21:55 +01:00
|
|
|
end
|
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
# TODO mutualiser avec le controller Users::ActivateController
|
|
|
|
# pour toute la partie de confirmation de compte
|
2024-07-01 16:37:33 +02:00
|
|
|
def confirm_email
|
2024-07-31 17:50:14 +02:00
|
|
|
if @user.confirmation_sent_at && 2.days.ago < @user.confirmation_sent_at
|
2024-07-01 16:37:33 +02:00
|
|
|
@user.update(email_verified_at: Time.zone.now, confirmation_token: nil)
|
|
|
|
@user.after_confirmation
|
2024-07-25 13:24:43 +02:00
|
|
|
redirect_to destination_path(@user), notice: I18n.t('france_connect.particulier.flash.email_confirmed')
|
|
|
|
return
|
2024-07-01 16:37:33 +02:00
|
|
|
end
|
|
|
|
|
2024-07-25 13:24:43 +02:00
|
|
|
fci = FranceConnectInformation.find_by(user: @user)
|
2024-07-01 16:37:33 +02:00
|
|
|
|
2024-07-25 13:24:43 +02:00
|
|
|
if fci
|
2024-07-31 17:50:14 +02:00
|
|
|
fci.send_custom_confirmation_instructions
|
2024-07-25 13:24:43 +02:00
|
|
|
redirect_to root_path, notice: I18n.t('france_connect.particulier.flash.confirmation_mail_resent')
|
2024-07-01 16:37:33 +02:00
|
|
|
else
|
2024-07-25 13:24:43 +02:00
|
|
|
redirect_to root_path, alert: I18n.t('france_connect.particulier.flash.confirmation_mail_resent_error')
|
2024-07-01 16:37:33 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-01-15 14:37:28 +01:00
|
|
|
private
|
|
|
|
|
2024-07-01 16:37:33 +02:00
|
|
|
def set_user_by_confirmation_token
|
|
|
|
@user = User.find_by(confirmation_token: params[:token])
|
|
|
|
|
|
|
|
if @user.nil?
|
2024-07-31 17:50:14 +02:00
|
|
|
return redirect_to root_path, alert: I18n.t('france_connect.particulier.flash.user_not_found')
|
2024-07-01 16:37:33 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
if user_signed_in? && current_user != @user
|
2024-07-31 17:50:14 +02:00
|
|
|
sign_out :user
|
2024-07-25 13:24:43 +02:00
|
|
|
redirect_to new_user_session_path, alert: I18n.t('france_connect.particulier.flash.redirect_new_user_session')
|
2024-07-01 16:37:33 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def destination_path(user) = stored_location_for(user) || root_path(user)
|
|
|
|
|
2024-01-11 10:44:19 +01:00
|
|
|
def securely_retrieve_fci_from_email_merge_token
|
2024-07-31 17:50:14 +02:00
|
|
|
@fci = FranceConnectInformation.find_by(email_merge_token: params[:email_merge_token])
|
2024-01-11 10:44:19 +01:00
|
|
|
|
|
|
|
if @fci.nil? || !@fci.valid_for_email_merge?
|
2024-07-25 13:24:43 +02:00
|
|
|
flash.alert = I18n.t('france_connect.particulier.flash.merger_token_expired', application_name: Current.application_name)
|
2024-01-11 10:44:19 +01:00
|
|
|
|
|
|
|
redirect_to root_path
|
|
|
|
else
|
|
|
|
@fci.delete_email_merge_token!
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-10-13 09:23:14 +02:00
|
|
|
def securely_retrieve_fci
|
2024-07-31 17:50:14 +02:00
|
|
|
@fci = FranceConnectInformation.find_by(merge_token: params[:merge_token])
|
2021-10-13 09:23:14 +02:00
|
|
|
|
|
|
|
if @fci.nil? || !@fci.valid_for_merge?
|
2024-07-25 13:24:43 +02:00
|
|
|
flash.alert = I18n.t('france_connect.particulier.flash.merger_token_expired', application_name: Current.application_name)
|
2021-10-13 09:23:14 +02:00
|
|
|
|
2022-07-13 14:03:41 +02:00
|
|
|
redirect_to root_path
|
2021-10-13 09:23:14 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-01-15 21:18:02 +01:00
|
|
|
def redirect_to_login_if_fc_aborted
|
2019-05-09 13:54:50 +02:00
|
|
|
if params[:code].blank?
|
2018-01-15 21:18:02 +01:00
|
|
|
redirect_to new_user_session_path
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
def destroy_fci_and_redirect_to_login(fci)
|
|
|
|
fci.destroy
|
|
|
|
redirect_to new_user_session_path, alert: t('errors.messages.france_connect.forbidden_html', reset_link: new_user_password_path)
|
|
|
|
end
|
2018-10-01 13:24:37 +02:00
|
|
|
|
2024-07-31 17:50:14 +02:00
|
|
|
def connect_france_connect_particulier(user)
|
|
|
|
sign_out :user if user_signed_in?
|
2015-12-24 10:12:23 +01:00
|
|
|
sign_in user
|
|
|
|
|
2018-08-28 11:41:37 +02:00
|
|
|
user.update_attribute('loged_in_with_france_connect', User.loged_in_with_france_connects.fetch(:particulier))
|
2015-12-24 10:12:23 +01:00
|
|
|
|
2024-07-25 13:24:43 +02:00
|
|
|
redirect_to destination_path(current_user)
|
2015-12-24 10:12:23 +01:00
|
|
|
end
|
2016-01-21 17:06:09 +01:00
|
|
|
|
2021-10-13 09:23:40 +02:00
|
|
|
def sanitized_email_params
|
2024-01-10 21:09:40 +01:00
|
|
|
sanitize(params[:email])
|
|
|
|
end
|
|
|
|
|
|
|
|
def sanitize(string)
|
|
|
|
string&.gsub(/[[:space:]]/, ' ')&.strip&.downcase
|
2021-10-13 09:23:40 +02:00
|
|
|
end
|
2017-04-04 15:27:04 +02:00
|
|
|
end
|