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-01 16:37:33 +02:00
before_action :securely_retrieve_fci , only : [ :merge , :merge_with_existing_account , :merge_with_new_account , :resend_and_renew_merge_confirmation , :associate_user ]
2024-01-11 10:44:19 +01:00
before_action :securely_retrieve_fci_from_email_merge_token , only : [ :mail_merge_with_existing_account ]
2024-07-01 16:37:33 +02:00
before_action :set_user_by_confirmation_token , only : [ :resend_confirmation , :post_resend_confirmation , :confirm_email , :connect_france_connect_particulier_redirect ]
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
2021-02-01 14:28:04 +01:00
fci = FranceConnectService . find_or_retrieve_france_connect_information ( params [ :code ] )
2021-10-11 11:39:14 +02:00
if fci . user . nil?
2024-01-10 21:09:40 +01:00
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-01 16:37:33 +02:00
merge_token = fci . create_merge_token!
render :choose_email , locals : { france_connect_email : fci . email_france_connect , merge_token : }
2021-11-23 10:44:38 +01:00
elsif ! preexisting_unlinked_user . can_france_connect?
fci . destroy
redirect_to new_user_session_path , alert : t ( 'errors.messages.france_connect.forbidden_html' , reset_link : new_user_password_path )
2021-10-13 00:45:20 +02:00
else
2021-11-17 16:21:55 +01:00
merge_token = fci . create_merge_token!
redirect_to france_connect_particulier_merge_path ( merge_token )
2021-10-13 00:45:20 +02:00
end
2021-10-11 11:30:45 +02:00
else
2021-10-13 00:45:20 +02:00
user = fci . user
if user . can_france_connect?
2021-10-13 15:45:57 +02:00
fci . update ( updated_at : Time . zone . now )
2021-10-13 00:45:20 +02:00
connect_france_connect_particulier ( user )
2024-07-01 16:37:33 +02:00
else
2021-10-13 00:45:20 +02:00
fci . destroy
redirect_to new_user_session_path , alert : t ( 'errors.messages.france_connect.forbidden_html' , reset_link : new_user_password_path )
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
redirect_france_connect_error_connection
end
2015-12-24 10:12:23 +01:00
2024-07-01 16:37:33 +02:00
def associate_user
email = use_fc_email? ? @fci . email_france_connect : params [ :alternative_email ]
@fci . associate_user! ( email )
user = @fci . user
@fci . delete_merge_token!
sign_only ( user )
destination_path = destination_path ( user )
render :confirmation_sent , locals : { email : , destination_path : }
2024-07-24 16:36:16 +02:00
rescue ActiveRecord :: RecordInvalid = > e
if e . record . errors . where ( :email , :taken )
redirect_to new_user_session_path , alert : t ( 'errors.messages.france_connect.email_taken' , reset_link : new_user_password_path )
else
redirect_to new_user_session_path , alert : t ( 'errors.messages.france_connect.unknown_error' )
end
2024-07-01 16:37:33 +02:00
end
2021-10-13 00:45:20 +02:00
def merge
end
2021-10-13 09:23:40 +02:00
def merge_with_existing_account
user = User . find_by ( email : sanitized_email_params )
2021-10-19 11:21:24 +02:00
if user . present? && user . valid_for_authentication? { user . valid_password? ( password_params ) }
2021-10-13 09:23:40 +02:00
if ! user . can_france_connect?
2021-11-23 13:30:07 +01:00
flash . alert = t ( 'errors.messages.france_connect.forbidden_html' , reset_link : new_user_password_path )
2021-10-13 09:23:40 +02:00
2022-07-13 14:03:41 +02:00
redirect_to root_path
2021-10-13 09:23:40 +02:00
else
@fci . update ( user : user )
@fci . delete_merge_token!
2024-01-11 11:21:09 +01:00
@fci . delete_email_merge_token!
2021-10-13 09:23:40 +02:00
2024-03-20 11:34:54 +01:00
flash . notice = t ( 'france_connect.particulier.flash.connection_done' , application_name : Current . application_name )
2021-10-13 09:23:40 +02:00
connect_france_connect_particulier ( user )
end
else
2021-11-23 13:30:07 +01:00
flash . alert = t ( 'france_connect.particulier.flash.invalid_password' )
2021-10-13 09:23:40 +02:00
end
end
2021-11-17 16:21:55 +01:00
def mail_merge_with_existing_account
2024-01-10 21:09:40 +01:00
user = User . find_by ( email : sanitize ( @fci . email_france_connect . downcase ) )
2021-11-17 16:21:55 +01:00
if user . can_france_connect?
@fci . update ( user : user )
@fci . delete_merge_token!
2024-07-01 16:37:33 +02:00
user . update ( email_verified_at : Time . zone . now )
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 )
else # same behaviour as redirect nicely with message when instructeur/administrateur
@fci . destroy
redirect_to new_user_session_path , alert : t ( 'errors.messages.france_connect.forbidden_html' , reset_link : new_user_password_path )
end
end
2021-10-13 09:26:54 +02:00
def merge_with_new_account
user = User . find_by ( email : sanitized_email_params )
if user . nil?
@fci . associate_user! ( sanitized_email_params )
@fci . delete_merge_token!
2024-07-01 16:37:33 +02:00
@fci . send_custom_confirmation_instructions ( @fci . user )
flash . notice = t ( 'france_connect.particulier.flash.connection_done_verify_email' , application_name : Current . application_name )
2021-10-13 09:26:54 +02:00
connect_france_connect_particulier ( @fci . user )
else
2021-10-13 01:08:57 +02:00
@email = sanitized_email_params
@merge_token = merge_token_params
2021-10-13 09:26:54 +02:00
end
end
2021-11-17 16:21:55 +01:00
def resend_and_renew_merge_confirmation
2024-01-11 10:44:19 +01:00
@fci . create_email_merge_token!
UserMailer . france_connect_merge_confirmation (
@fci . email_france_connect ,
@fci . email_merge_token ,
@fci . email_merge_token_created_at
)
. deliver_later
2021-11-17 16:21:55 +01:00
merge_token = @fci . create_merge_token!
redirect_to france_connect_particulier_merge_path ( merge_token ) ,
2021-11-23 13:30:07 +01:00
notice : t ( 'france_connect.particulier.flash.confirmation_mail_sent' )
2021-11-17 16:21:55 +01:00
end
2024-07-01 16:37:33 +02:00
def confirm_email
if @user . confirmation_sent_at && 2 . days . ago < @user . confirmation_sent_at
@user . update ( email_verified_at : Time . zone . now , confirmation_token : nil )
@user . after_confirmation
redirect_to stored_location_for ( @user ) || root_path ( @user ) , notice : 'Votre email est bien vérifié'
else
redirect_to france_connect_resend_confirmation_path ( token : @user . confirmation_token ) , alert : " Lien de confirmation expiré. Un nouveau lien de confirmation a été envoyé. "
end
end
def resend_confirmation
if @user . email_verified_at
redirect_to root_path , alert : 'Email déjà confirmé.'
end
end
def post_resend_confirmation
if ! @user . email_verified_at
fci = FranceConnectInformation . find_by ( user : @user )
fci . send_custom_confirmation_instructions ( @user )
redirect_to root_path ( @user ) , notice : " Un nouveau lien de confirmation vous a été envoyé par mail. "
else
redirect_to root_path ( @user ) , alert : " Adresse email non trouvée ou déjà confirmée. "
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?
redirect_to root_path , alert : 'Utilisateur non trouvé' and return
end
if user_signed_in? && current_user != @user
sign_out current_user
redirect_to new_user_session_path , alert : " Veuillez vous connecter avec le compte associé à ce lien de confirmation. "
end
end
def use_fc_email? = cast_bool ( params [ :use_france_connect_email ] )
def sign_only ( user )
sign_out ( user ) if user_signed_in?
sign_in ( user )
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
@fci = FranceConnectInformation . find_by ( email_merge_token : email_merge_token_params )
if @fci . nil? || ! @fci . valid_for_email_merge?
2024-03-20 11:34:54 +01:00
flash . alert = 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
@fci = FranceConnectInformation . find_by ( merge_token : merge_token_params )
if @fci . nil? || ! @fci . valid_for_merge?
2024-03-20 11:34:54 +01:00
flash . alert = 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
2018-03-20 17:47:37 +01:00
def connect_france_connect_particulier ( user )
2018-10-01 13:24:37 +02:00
if user_signed_in?
sign_out :user
end
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
2022-07-13 14:03:41 +02:00
redirect_to stored_location_for ( current_user ) || root_path ( current_user )
2015-12-24 10:12:23 +01:00
end
2016-01-21 17:06:09 +01:00
def redirect_france_connect_error_connection
flash . alert = t ( 'errors.messages.france_connect.connexion' )
redirect_to ( new_user_session_path )
end
2021-10-13 09:23:14 +02:00
def merge_token_params
params [ :merge_token ]
end
2021-10-13 09:23:40 +02:00
2024-01-11 10:40:44 +01:00
def email_merge_token_params
params [ :email_merge_token ]
end
2021-10-13 09:23:40 +02:00
def password_params
params [ :password ]
end
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