FC ParticulierController: implement auto reconciliation based on user email
This commit is contained in:
parent
ecfb0f4ec2
commit
02dd1e209c
8 changed files with 11 additions and 269 deletions
|
@ -12,51 +12,20 @@ class FranceConnect::ParticulierController < ApplicationController
|
||||||
.find_by(france_connect_particulier_id: fetched_fci[:france_connect_particulier_id]) ||
|
.find_by(france_connect_particulier_id: fetched_fci[:france_connect_particulier_id]) ||
|
||||||
fetched_fci.tap { |object| object.save }
|
fetched_fci.tap { |object| object.save }
|
||||||
|
|
||||||
salt = FranceConnectSaltService.new(fci).salt
|
|
||||||
|
|
||||||
if fci.user.nil?
|
if fci.user.nil?
|
||||||
redirect_to france_connect_particulier_new_path(fci_id: fci.id, salt: salt)
|
user = User.find_or_create_by(email: fci.email_france_connect) do |new_user|
|
||||||
else
|
new_user.password = Devise.friendly_token[0, 20]
|
||||||
connect_france_connect_particulier(fci.user)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
fci.update_attribute('user_id', user.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
connect_france_connect_particulier(fci.user)
|
||||||
rescue Rack::OAuth2::Client::Error => e
|
rescue Rack::OAuth2::Client::Error => e
|
||||||
Rails.logger.error e.message
|
Rails.logger.error e.message
|
||||||
redirect_france_connect_error_connection
|
redirect_france_connect_error_connection
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
|
||||||
return redirect_france_connect_error_connection if !valid_salt_and_fci_id_params?
|
|
||||||
|
|
||||||
france_connect_information = FranceConnectInformation.find(params[:fci_id])
|
|
||||||
@user = User.new(france_connect_information: france_connect_information).decorate
|
|
||||||
rescue ActiveRecord::RecordNotFound
|
|
||||||
redirect_france_connect_error_connection
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_email
|
|
||||||
return redirect_france_connect_error_connection if !valid_salt_and_fci_id_params?
|
|
||||||
|
|
||||||
user = User.find_by_email(params[:user][:email_france_connect])
|
|
||||||
|
|
||||||
return create if user.nil?
|
|
||||||
|
|
||||||
if params[:user][:password].present?
|
|
||||||
|
|
||||||
if user.valid_password?(params[:user][:password])
|
|
||||||
user.france_connect_information = FranceConnectInformation.find(params[:fci_id])
|
|
||||||
|
|
||||||
return connect_france_connect_particulier user
|
|
||||||
else
|
|
||||||
flash.now.alert = 'Mot de passe invalide'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
france_connect_information = FranceConnectInformation.find(params[:fci_id])
|
|
||||||
france_connect_information.update_attribute(:email_france_connect, params[:user][:email_france_connect])
|
|
||||||
|
|
||||||
@user = User.new(france_connect_information: france_connect_information).decorate
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def redirect_to_login_if_fc_aborted
|
def redirect_to_login_if_fc_aborted
|
||||||
|
@ -65,22 +34,6 @@ class FranceConnect::ParticulierController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
|
||||||
user = User.new email: params[:user][:email_france_connect]
|
|
||||||
user.password = Devise.friendly_token[0, 20]
|
|
||||||
|
|
||||||
if !user.valid?
|
|
||||||
flash.alert = 'Email non valide'
|
|
||||||
|
|
||||||
return redirect_to france_connect_particulier_new_path fci_id: params[:fci_id], salt: params[:salt], user: {email_france_connect: params[:user]['email_france_connect']}
|
|
||||||
end
|
|
||||||
|
|
||||||
user.save
|
|
||||||
FranceConnectInformation.find(params[:fci_id]).update_attribute(:user, user)
|
|
||||||
|
|
||||||
connect_france_connect_particulier user
|
|
||||||
end
|
|
||||||
|
|
||||||
def connect_france_connect_particulier user
|
def connect_france_connect_particulier user
|
||||||
sign_out :user if user_signed_in?
|
sign_out :user if user_signed_in?
|
||||||
sign_out :gestionnaire if gestionnaire_signed_in?
|
sign_out :gestionnaire if gestionnaire_signed_in?
|
||||||
|
@ -98,9 +51,4 @@ class FranceConnect::ParticulierController < ApplicationController
|
||||||
flash.alert = t('errors.messages.france_connect.connexion')
|
flash.alert = t('errors.messages.france_connect.connexion')
|
||||||
redirect_to(new_user_session_path)
|
redirect_to(new_user_session_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def valid_salt_and_fci_id_params?
|
|
||||||
france_connect_information = FranceConnectInformation.find(params[:fci_id])
|
|
||||||
FranceConnectSaltService.new(france_connect_information).valid? params[:salt]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
class FranceConnectSaltService
|
|
||||||
attr_reader :model
|
|
||||||
|
|
||||||
def initialize france_connect_information
|
|
||||||
raise 'Not a FranceConnectInformation class' if france_connect_information.class != FranceConnectInformation
|
|
||||||
@model = france_connect_information
|
|
||||||
end
|
|
||||||
|
|
||||||
def valid? test_salt
|
|
||||||
salt == test_salt
|
|
||||||
end
|
|
||||||
|
|
||||||
def salt
|
|
||||||
Digest::MD5.hexdigest(model.france_connect_particulier_id + model.given_name + model.family_name + FRANCE_CONNECT[:particulier][:secret] + DateTime.now.to_date.to_s)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,23 +0,0 @@
|
||||||
%h2.text-info
|
|
||||||
= image_tag('logo_FC_02_small.png', style: 'height: 55px;')
|
|
||||||
France Connect - Particulier
|
|
||||||
|
|
||||||
%h3 Nouvelle connexion
|
|
||||||
%h4.text-warning{ style: 'margin-left: 20px;' } Email déjà utilisé
|
|
||||||
|
|
||||||
%br
|
|
||||||
%p
|
|
||||||
%h4.center Nous avons trouvé un compte qui utilise déjà cette adresse email.
|
|
||||||
%p.center
|
|
||||||
Afin d'associer ce compte à votre identifiant France Connect, merci de saisir votre mot de passe TPS.
|
|
||||||
%br
|
|
||||||
.center
|
|
||||||
#france-connect-particulier-email
|
|
||||||
= form_for @user, url: { controller: 'france_connect/particulier', action: :check_email }, method: :post do |f|
|
|
||||||
.form-group.form-group-lg
|
|
||||||
= f.text_field :email_france_connect, class: "form-control", readonly: 'readonly'
|
|
||||||
%br
|
|
||||||
= f.password_field :password, class: "form-control", placeholder: "Entrez votre mot de passe"
|
|
||||||
= hidden_field_tag :fci_id, params[:fci_id]
|
|
||||||
= hidden_field_tag :salt, params[:salt]
|
|
||||||
= f.submit 'Terminer', class: %w(btn btn-lg btn-success), style: 'margin-top: 20px;', id: 'valid_new_fcp'
|
|
|
@ -1,32 +0,0 @@
|
||||||
%h2.text-info
|
|
||||||
= image_tag('logo_FC_02_small.png', style: 'height: 55px;')
|
|
||||||
France Connect - Particulier
|
|
||||||
|
|
||||||
%h3 Nouvelle connexion
|
|
||||||
|
|
||||||
%br
|
|
||||||
%p
|
|
||||||
Nous vous avons identifié comme étant
|
|
||||||
|
|
||||||
%h4.text-info.center
|
|
||||||
%strong
|
|
||||||
= @user.gender_fr
|
|
||||||
= @user.given_name
|
|
||||||
= @user.family_name
|
|
||||||
né le
|
|
||||||
%strong
|
|
||||||
= @user.birthdate_fr
|
|
||||||
|
|
||||||
%br
|
|
||||||
%h4
|
|
||||||
Afin de finaliser votre première connexion à TPS, merci de saisir un email valide :
|
|
||||||
%br
|
|
||||||
|
|
||||||
.center
|
|
||||||
#france-connect-particulier-email
|
|
||||||
= form_for @user, url: { controller: 'france_connect/particulier', action: :check_email }, method: :post do |f|
|
|
||||||
.form-group.form-group-lg
|
|
||||||
= f.text_field :email_france_connect, class: "form-control", placeholder: "Entrez votre email"
|
|
||||||
= hidden_field_tag :fci_id, params[:fci_id]
|
|
||||||
= hidden_field_tag :salt, params[:salt]
|
|
||||||
= f.submit 'Terminer', class: %w(btn btn-lg btn-success), style: 'margin-top: 20px;', id: 'valid_new_fcp'
|
|
|
@ -65,9 +65,6 @@ Rails.application.routes.draw do
|
||||||
namespace :france_connect do
|
namespace :france_connect do
|
||||||
get 'particulier' => 'particulier#login'
|
get 'particulier' => 'particulier#login'
|
||||||
get 'particulier/callback' => 'particulier#callback'
|
get 'particulier/callback' => 'particulier#callback'
|
||||||
|
|
||||||
get 'particulier/new' => 'particulier#new'
|
|
||||||
post 'particulier/check_email' => 'particulier#check_email'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
namespace :users do
|
namespace :users do
|
||||||
|
|
|
@ -9,7 +9,6 @@ describe FranceConnect::ParticulierController, type: :controller do
|
||||||
let(:birthplace) { '1234' }
|
let(:birthplace) { '1234' }
|
||||||
let(:france_connect_particulier_id) { 'blabla' }
|
let(:france_connect_particulier_id) { 'blabla' }
|
||||||
let(:email) { 'test@test.com' }
|
let(:email) { 'test@test.com' }
|
||||||
let(:password) { '' }
|
|
||||||
|
|
||||||
let(:user_info) { { france_connect_particulier_id: france_connect_particulier_id, given_name: given_name, family_name: family_name, birthdate: birthdate, birthplace: birthplace, gender: gender, email_france_connect: email } }
|
let(:user_info) { { france_connect_particulier_id: france_connect_particulier_id, given_name: given_name, family_name: family_name, birthdate: birthdate, birthplace: birthplace, gender: gender, email_france_connect: email } }
|
||||||
|
|
||||||
|
@ -70,21 +69,16 @@ describe FranceConnect::ParticulierController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when france_connect_particulier_id does not have an associate user' do
|
context 'when france_connect_particulier_id does not have an associate user' do
|
||||||
let(:salt) { FranceConnectSaltService.new(france_connect_information).salt }
|
|
||||||
|
|
||||||
before do
|
before do
|
||||||
get :callback, params: {code: code}
|
get :callback, params: {code: code}
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'redirects to check email FC page' do
|
it {expect(response).to redirect_to(root_path)}
|
||||||
expect(response).to redirect_to(france_connect_particulier_new_path(fci_id: france_connect_information.id, salt: salt))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when france_connect_particulier_id does not exist in database' do
|
context 'when france_connect_particulier_id does not exist in database' do
|
||||||
let(:last_france_connect_information) { FranceConnectInformation.last }
|
let(:last_france_connect_information) { FranceConnectInformation.last }
|
||||||
let(:salt) { FranceConnectSaltService.new(last_france_connect_information).salt }
|
|
||||||
subject { get :callback, params: {code: code} }
|
subject { get :callback, params: {code: code} }
|
||||||
|
|
||||||
it { expect { subject }.to change { FranceConnectInformation.count }.by(1) }
|
it { expect { subject }.to change { FranceConnectInformation.count }.by(1) }
|
||||||
|
@ -105,9 +99,7 @@ describe FranceConnect::ParticulierController, type: :controller do
|
||||||
it { expect(subject.france_connect_particulier_id).to eq france_connect_particulier_id }
|
it { expect(subject.france_connect_particulier_id).to eq france_connect_particulier_id }
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'redirects to check email FC page' do
|
it { expect(subject).to redirect_to(root_path) }
|
||||||
expect(subject).to redirect_to(france_connect_particulier_new_path(fci_id: last_france_connect_information.id, salt: salt))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -127,77 +119,4 @@ describe FranceConnect::ParticulierController, type: :controller do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'POST #check_email' do
|
|
||||||
let(:email) { 'plop@gmail.com' }
|
|
||||||
|
|
||||||
let!(:france_connect_information) { create(:france_connect_information) }
|
|
||||||
let(:france_connect_information_id) { france_connect_information.id }
|
|
||||||
let(:salt) { FranceConnectSaltService.new(france_connect_information).salt }
|
|
||||||
|
|
||||||
subject { post :check_email, params: {fci_id: france_connect_information_id, salt: salt, user: {email_france_connect: email}} }
|
|
||||||
|
|
||||||
context 'when salt and fci_id does not matches' do
|
|
||||||
let(:france_connect_information_fake) { create(:france_connect_information, france_connect_particulier_id: 'iugfjh') }
|
|
||||||
let(:france_connect_information_id) { france_connect_information_fake.id }
|
|
||||||
|
|
||||||
it { is_expected.to redirect_to new_user_session_path }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when salt and fci_id matches' do
|
|
||||||
context 'when email is not used' do
|
|
||||||
context 'when email is valid' do
|
|
||||||
it { expect { subject }.to change { User.count }.by(1) }
|
|
||||||
|
|
||||||
describe 'New user attributs' do
|
|
||||||
before do
|
|
||||||
subject
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:user) { User.last }
|
|
||||||
|
|
||||||
it { expect(user.email).to eq email }
|
|
||||||
it { expect(user.france_connect_information).to eq france_connect_information }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when email is not valid' do
|
|
||||||
let(:email) { 'kdjizjflk' }
|
|
||||||
|
|
||||||
it { expect { subject }.not_to change { User.count } }
|
|
||||||
it { is_expected.to redirect_to(france_connect_particulier_new_path fci_id: france_connect_information.id, salt: salt, user: {email_france_connect: email}) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when email is used' do
|
|
||||||
let!(:user) { create(:user, email: france_connect_information.email_france_connect) }
|
|
||||||
let(:email) { france_connect_information.email_france_connect }
|
|
||||||
let(:password) { user.password }
|
|
||||||
|
|
||||||
before do
|
|
||||||
subject
|
|
||||||
end
|
|
||||||
|
|
||||||
subject { post :check_email, params: {fci_id: france_connect_information_id, salt: salt, user: {email_france_connect: email, password: password}} }
|
|
||||||
|
|
||||||
context 'when email and password couple is valid' do
|
|
||||||
it { expect { subject }.not_to change { User.count } }
|
|
||||||
|
|
||||||
describe 'Update user attributs' do
|
|
||||||
before do
|
|
||||||
subject
|
|
||||||
end
|
|
||||||
|
|
||||||
it { expect(user.france_connect_information).to eq france_connect_information }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when email and password couple is not valid' do
|
|
||||||
let(:password) { 'fake' }
|
|
||||||
|
|
||||||
it { expect(flash.alert).to eq 'Mot de passe invalide' }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -55,21 +55,11 @@ feature 'France Connect Particulier Connexion' do
|
||||||
before do
|
before do
|
||||||
page.find('.login-with-fc').click
|
page.find('.login-with-fc').click
|
||||||
end
|
end
|
||||||
scenario 'he is redirected to france connect particulier page' do
|
|
||||||
expect(page).to have_content('Nouvelle connexion')
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when he fill an email and valid' do
|
|
||||||
before do
|
|
||||||
page.find_by_id('user_email_france_connect').set email
|
|
||||||
page.find_by_id('valid_new_fcp').click
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario 'he is redirected to user dossiers page' do
|
scenario 'he is redirected to user dossiers page' do
|
||||||
expect(page).to have_content('Dossiers')
|
expect(page).to have_content('Dossiers')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
context 'when is not the first connexion' do
|
context 'when is not the first connexion' do
|
||||||
before do
|
before do
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe FranceConnectSaltService do
|
|
||||||
describe '.initialize' do
|
|
||||||
context 'when args is not a FranceConnectInformation class' do
|
|
||||||
let(:args) { create(:dossier) }
|
|
||||||
|
|
||||||
subject { described_class.new args }
|
|
||||||
|
|
||||||
it { expect { subject }.to raise_error 'Not a FranceConnectInformation class' }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.valid?' do
|
|
||||||
let(:france_connect_information) { create(:france_connect_information) }
|
|
||||||
let(:salt_service) { FranceConnectSaltService.new(france_connect_information) }
|
|
||||||
let(:salt) { salt_service.salt }
|
|
||||||
|
|
||||||
context 'when france_connect_information_id is correct' do
|
|
||||||
let(:france_connect_information_id) { france_connect_information.id }
|
|
||||||
let(:france_connect_information_get_with_id) { FranceConnectInformation.find(france_connect_information_id) }
|
|
||||||
let(:salt_service_compare) { FranceConnectSaltService.new france_connect_information_get_with_id }
|
|
||||||
|
|
||||||
subject { salt_service_compare.valid? salt }
|
|
||||||
|
|
||||||
it { is_expected.to be_truthy }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when france_connect_information_id is not correct' do
|
|
||||||
let(:france_connect_information_fake) { create(:france_connect_information, france_connect_particulier_id: '87515272') }
|
|
||||||
|
|
||||||
let(:france_connect_information_id) { france_connect_information_fake.id }
|
|
||||||
let(:france_connect_information_get_with_id) { FranceConnectInformation.find(france_connect_information_id) }
|
|
||||||
let(:salt_service_compare) { FranceConnectSaltService.new france_connect_information_get_with_id }
|
|
||||||
|
|
||||||
subject { salt_service_compare.valid? salt }
|
|
||||||
|
|
||||||
it { is_expected.to be_falsey }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Reference in a new issue