- Add FranceConnectInformation table to make safe FranceConnect pivot identity.
- Adapt source code with the new table
This commit is contained in:
parent
d6e795df02
commit
4d812220fd
18 changed files with 454 additions and 163 deletions
|
@ -13,74 +13,86 @@ class FranceConnect::ParticulierController < ApplicationController
|
||||||
redirect_to authorization_uri
|
redirect_to authorization_uri
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
|
||||||
return redirect_to root_path if france_connect_particulier_id_blank?
|
|
||||||
|
|
||||||
@user = (User.new create_user_params).decorate
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
user = User.new create_user_params
|
|
||||||
user.password = Devise.friendly_token[0, 20]
|
|
||||||
|
|
||||||
unless user.valid?
|
|
||||||
flash.alert = 'Email non valide'
|
|
||||||
return redirect_to france_connect_particulier_new_path user: params[:user]
|
|
||||||
end
|
|
||||||
|
|
||||||
user.save
|
|
||||||
connect_france_connect_particulier user
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_email
|
|
||||||
user = User.find_by_email(params[:user][:email])
|
|
||||||
|
|
||||||
return create if user.nil?
|
|
||||||
return redirect_to root_path if france_connect_particulier_id_blank?
|
|
||||||
|
|
||||||
unless params[:user][:password].nil?
|
|
||||||
|
|
||||||
if user.valid_password?(params[:user][:password])
|
|
||||||
user.update_attributes create_user_params
|
|
||||||
return connect_france_connect_particulier user
|
|
||||||
else
|
|
||||||
flash.now.alert = 'Mot de passe invalide'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@user = (User.new create_user_params).decorate
|
|
||||||
end
|
|
||||||
|
|
||||||
def callback
|
def callback
|
||||||
return redirect_to new_user_session_path unless params.has_key?(:code)
|
return redirect_to new_user_session_path unless params.has_key?(:code)
|
||||||
|
|
||||||
user_infos = FranceConnectService.retrieve_user_informations_particulier(params[:code])
|
user_infos = FranceConnectService.retrieve_user_informations_particulier(params[:code])
|
||||||
|
|
||||||
unless user_infos.nil?
|
unless user_infos.nil?
|
||||||
user = User.find_for_france_connect_particulier user_infos
|
france_connect_information = FranceConnectInformation.find_by_france_connect_particulier user_infos
|
||||||
|
|
||||||
if user.nil?
|
france_connect_information = FranceConnectInformation.create(
|
||||||
return redirect_to france_connect_particulier_new_path(user: user_infos)
|
{gender: user_infos[:gender],
|
||||||
end
|
given_name: user_infos[:given_name],
|
||||||
|
family_name: user_infos[:family_name],
|
||||||
|
email_france_connect: user_infos[:email],
|
||||||
|
birthdate: user_infos[:birthdate],
|
||||||
|
birthplace: user_infos[:birthplace],
|
||||||
|
france_connect_particulier_id: user_infos[:france_connect_particulier_id]}
|
||||||
|
) if france_connect_information.nil?
|
||||||
|
|
||||||
|
user = france_connect_information.user
|
||||||
|
salt = FranceConnectSaltService.new(france_connect_information).salt
|
||||||
|
|
||||||
|
return redirect_to france_connect_particulier_new_path(fci_id: france_connect_information.id, salt: salt) if user.nil?
|
||||||
|
|
||||||
connect_france_connect_particulier user
|
connect_france_connect_particulier user
|
||||||
end
|
end
|
||||||
rescue Rack::OAuth2::Client::Error => e
|
rescue Rack::OAuth2::Client::Error => e
|
||||||
Rails.logger.error e.message
|
Rails.logger.error e.message
|
||||||
flash.alert = t('errors.messages.france_connect.connexion')
|
redirect_france_connect_error_connection
|
||||||
redirect_to(new_user_session_path)
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
return redirect_france_connect_error_connection unless 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 unless valid_salt_and_fci_id_params?
|
||||||
|
|
||||||
|
user = User.find_by_email(params[:user][:email_france_connect])
|
||||||
|
|
||||||
|
return create if user.nil?
|
||||||
|
|
||||||
|
unless params[:user][:password].nil?
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
def create
|
||||||
|
user = User.new email: params[:user][:email_france_connect]
|
||||||
|
user.password = Devise.friendly_token[0, 20]
|
||||||
|
|
||||||
|
unless user.valid?
|
||||||
|
flash.alert = 'Email non valide'
|
||||||
|
return redirect_to france_connect_particulier_new_path fci_id: params[:fci_id], salt: params[:salt], user: params[:user]
|
||||||
|
end
|
||||||
|
|
||||||
|
user.save
|
||||||
|
FranceConnectInformation.find(params[:fci_id]).update_attribute(:user, user)
|
||||||
|
|
||||||
|
connect_france_connect_particulier user
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def create_user_params
|
|
||||||
params.require(:user).permit(:france_connect_particulier_id, :gender, :given_name, :family_name, :birthdate, :birthplace, :email)
|
|
||||||
end
|
|
||||||
|
|
||||||
def france_connect_particulier_id_blank?
|
|
||||||
redirect_to root_path if params[:user][:france_connect_particulier_id].blank?
|
|
||||||
end
|
|
||||||
|
|
||||||
def connect_france_connect_particulier user
|
def connect_france_connect_particulier user
|
||||||
sign_in user
|
sign_in user
|
||||||
|
|
||||||
|
@ -89,4 +101,14 @@ class FranceConnect::ParticulierController < ApplicationController
|
||||||
|
|
||||||
redirect_to stored_location_for(current_user) || signed_in_root_path(current_user)
|
redirect_to stored_location_for(current_user) || signed_in_root_path(current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def redirect_france_connect_error_connection
|
||||||
|
flash.alert = t('errors.messages.france_connect.connexion')
|
||||||
|
redirect_to(new_user_session_path)
|
||||||
|
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
|
|
@ -157,12 +157,13 @@ class Users::DossiersController < UsersController
|
||||||
end
|
end
|
||||||
|
|
||||||
def mandataire_social? mandataires_list
|
def mandataire_social? mandataires_list
|
||||||
|
unless current_user.france_connect_information.nil?
|
||||||
mandataires_list.each do |mandataire|
|
mandataires_list.each do |mandataire|
|
||||||
return true if !current_user.france_connect_particulier_id.nil? &&
|
return true if mandataire[:nom].upcase == current_user.family_name.upcase &&
|
||||||
mandataire[:nom].upcase == current_user.family_name.upcase &&
|
|
||||||
mandataire[:prenom].upcase == current_user.given_name.upcase &&
|
mandataire[:prenom].upcase == current_user.given_name.upcase &&
|
||||||
mandataire[:date_naissance_timestamp] == current_user.birthdate.to_time.to_i
|
mandataire[:date_naissance_timestamp] == current_user.birthdate.to_time.to_i
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
9
app/models/france_connect_information.rb
Normal file
9
app/models/france_connect_information.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
class FranceConnectInformation < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
|
||||||
|
validates :france_connect_particulier_id, presence: true, allow_blank: false, allow_nil: false
|
||||||
|
|
||||||
|
def self.find_by_france_connect_particulier user_info
|
||||||
|
FranceConnectInformation.find_by(france_connect_particulier_id: user_info[:france_connect_particulier_id])
|
||||||
|
end
|
||||||
|
end
|
|
@ -8,11 +8,10 @@ class User < ActiveRecord::Base
|
||||||
:recoverable, :rememberable, :trackable, :validatable
|
:recoverable, :rememberable, :trackable, :validatable
|
||||||
|
|
||||||
has_many :dossiers, dependent: :destroy
|
has_many :dossiers, dependent: :destroy
|
||||||
|
has_one :france_connect_information, dependent: :destroy
|
||||||
|
|
||||||
def self.find_for_france_connect_particulier user_info
|
delegate :given_name, :family_name, :email_france_connect, :gender, :birthdate, :birthplace, :france_connect_particulier_id, to: :france_connect_information
|
||||||
|
accepts_nested_attributes_for :france_connect_information
|
||||||
User.find_by(france_connect_particulier_id: user_info[:france_connect_particulier_id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.find_for_france_connect email, siret
|
def self.find_for_france_connect email, siret
|
||||||
user = User.find_by_email(email)
|
user = User.find_by_email(email)
|
||||||
|
|
17
app/services/france_connect_salt_service.rb
Normal file
17
app/services/france_connect_salt_service.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
class FranceConnectSaltService
|
||||||
|
|
||||||
|
attr_reader :model
|
||||||
|
|
||||||
|
def initialize france_connect_information
|
||||||
|
raise 'Not a FranceConnectInformation class' unless 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
|
|
@ -15,14 +15,9 @@
|
||||||
#france_connect_particulier_email
|
#france_connect_particulier_email
|
||||||
= form_for @user, url: {controller: 'france_connect/particulier', action: :check_email}, method: :post do |f|
|
= form_for @user, url: {controller: 'france_connect/particulier', action: :check_email}, method: :post do |f|
|
||||||
.form-group.form-group-lg
|
.form-group.form-group-lg
|
||||||
= f.text_field :email, class: "form-control", readonly: 'readonly'
|
= f.text_field :email_france_connect, class: "form-control", readonly: 'readonly'
|
||||||
%br
|
%br
|
||||||
= f.password_field :password, class: "form-control", placeholder: "Entrez votre mot de passe"
|
= f.password_field :password, class: "form-control", placeholder: "Entrez votre mot de passe"
|
||||||
= f.hidden_field :email
|
= hidden_field_tag :fci_id, params[:fci_id]
|
||||||
= f.hidden_field :gender
|
= hidden_field_tag :salt, params[:salt]
|
||||||
= f.hidden_field :given_name
|
|
||||||
= f.hidden_field :family_name
|
|
||||||
= f.hidden_field :birthdate
|
|
||||||
= f.hidden_field :birthplace
|
|
||||||
= f.hidden_field :france_connect_particulier_id
|
|
||||||
= f.submit 'Terminer', class: %w(btn btn-lg btn-success), style: 'margin-top:20px;', id: 'valid_new_fcp'
|
= f.submit 'Terminer', class: %w(btn btn-lg btn-success), style: 'margin-top:20px;', id: 'valid_new_fcp'
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
%br
|
%br
|
||||||
%p
|
%p
|
||||||
Nous vous avons correctement identifié comme étant
|
Nous vous avons identifié comme étant
|
||||||
|
|
||||||
%h4.text-info.center
|
%h4.text-info.center
|
||||||
%strong
|
%strong
|
||||||
|
@ -26,11 +26,7 @@
|
||||||
#france_connect_particulier_email
|
#france_connect_particulier_email
|
||||||
= form_for @user, url: {controller: 'france_connect/particulier', action: :check_email}, method: :post do |f|
|
= form_for @user, url: {controller: 'france_connect/particulier', action: :check_email}, method: :post do |f|
|
||||||
.form-group.form-group-lg
|
.form-group.form-group-lg
|
||||||
= f.text_field :email, class: "form-control", placeholder: "Entrez votre email"
|
= f.text_field :email_france_connect, class: "form-control", placeholder: "Entrez votre email"
|
||||||
= f.hidden_field :gender
|
= hidden_field_tag :fci_id, params[:fci_id]
|
||||||
= f.hidden_field :given_name
|
= hidden_field_tag :salt, params[:salt]
|
||||||
= f.hidden_field :family_name
|
|
||||||
= f.hidden_field :birthdate
|
|
||||||
= f.hidden_field :birthplace
|
|
||||||
= f.hidden_field :france_connect_particulier_id
|
|
||||||
= f.submit 'Terminer', class: %w(btn btn-lg btn-success), style: 'margin-top:20px;', id: 'valid_new_fcp'
|
= f.submit 'Terminer', class: %w(btn btn-lg btn-success), style: 'margin-top:20px;', id: 'valid_new_fcp'
|
|
@ -0,0 +1,61 @@
|
||||||
|
class CreateFranceConnectInformation < ActiveRecord::Migration
|
||||||
|
|
||||||
|
class User < ActiveRecord::Base
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
class FranceConnectInformation < ActiveRecord::Base
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def up
|
||||||
|
create_table :france_connect_informations do |t|
|
||||||
|
t.string :gender
|
||||||
|
t.string :given_name
|
||||||
|
t.string :family_name
|
||||||
|
t.date :birthdate
|
||||||
|
t.string :birthplace
|
||||||
|
t.string :france_connect_particulier_id
|
||||||
|
end
|
||||||
|
|
||||||
|
add_reference :france_connect_informations, :user, references: :users
|
||||||
|
|
||||||
|
User.all.each do |user|
|
||||||
|
FranceConnectInformation.create({gender: user.gender,
|
||||||
|
given_name: user.given_name,
|
||||||
|
family_name: user.family_name,
|
||||||
|
birthdate: user.birthdate,
|
||||||
|
birthplace: user.birthplace,
|
||||||
|
france_connect_particulier_id: user.france_connect_particulier_id,
|
||||||
|
user_id: user.id}) unless user.france_connect_particulier_id.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
remove_column :users, :gender
|
||||||
|
remove_column :users, :given_name
|
||||||
|
remove_column :users, :family_name
|
||||||
|
remove_column :users, :birthdate
|
||||||
|
remove_column :users, :birthplace
|
||||||
|
remove_column :users, :france_connect_particulier_id
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def down
|
||||||
|
add_column :users, :gender, :string
|
||||||
|
add_column :users, :given_name, :string
|
||||||
|
add_column :users, :family_name, :string
|
||||||
|
add_column :users, :birthdate, :date
|
||||||
|
add_column :users, :birthplace, :string
|
||||||
|
add_column :users, :france_connect_particulier_id, :string
|
||||||
|
|
||||||
|
FranceConnectInformation.all.each do |fci|
|
||||||
|
User.find(fci.user_id).update_attributes({gender: fci.gender,
|
||||||
|
given_name: fci.given_name,
|
||||||
|
family_name: fci.family_name,
|
||||||
|
birthdate: fci.birthdate,
|
||||||
|
birthplace: fci.birthplace,
|
||||||
|
france_connect_particulier_id: fci.france_connect_particulier_id})
|
||||||
|
end
|
||||||
|
|
||||||
|
drop_table :france_connect_informations
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddEmailToFranceConnectInformation < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :france_connect_informations, :email_france_connect, :string
|
||||||
|
end
|
||||||
|
end
|
21
db/schema.rb
21
db/schema.rb
|
@ -11,9 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
|
ActiveRecord::Schema.define(version: 20160121110603) do
|
||||||
ActiveRecord::Schema.define(version: 20160115135025) do
|
|
||||||
|
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -131,6 +129,17 @@ ActiveRecord::Schema.define(version: 20160115135025) do
|
||||||
t.integer "etablissement_id"
|
t.integer "etablissement_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "france_connect_informations", force: :cascade do |t|
|
||||||
|
t.string "gender"
|
||||||
|
t.string "given_name"
|
||||||
|
t.string "family_name"
|
||||||
|
t.date "birthdate"
|
||||||
|
t.string "birthplace"
|
||||||
|
t.string "france_connect_particulier_id"
|
||||||
|
t.integer "user_id"
|
||||||
|
t.string "email_france_connect"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "gestionnaires", force: :cascade do |t|
|
create_table "gestionnaires", force: :cascade do |t|
|
||||||
t.string "email", default: "", null: false
|
t.string "email", default: "", null: false
|
||||||
t.string "encrypted_password", default: "", null: false
|
t.string "encrypted_password", default: "", null: false
|
||||||
|
@ -232,12 +241,6 @@ ActiveRecord::Schema.define(version: 20160115135025) do
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
t.string "siret"
|
t.string "siret"
|
||||||
t.string "loged_in_with_france_connect", default: "false"
|
t.string "loged_in_with_france_connect", default: "false"
|
||||||
t.string "gender"
|
|
||||||
t.string "given_name"
|
|
||||||
t.string "family_name"
|
|
||||||
t.date "birthdate"
|
|
||||||
t.string "birthplace"
|
|
||||||
t.string "france_connect_particulier_id"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
|
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
|
||||||
|
|
|
@ -24,7 +24,7 @@ describe API::V1::DossiersController do
|
||||||
context 'when procedure is found and belongs to admin' do
|
context 'when procedure is found and belongs to admin' do
|
||||||
let(:procedure_id) { procedure.id }
|
let(:procedure_id) { procedure.id }
|
||||||
let(:date_creation) { Time.local(2008, 9, 1, 10, 5, 0) }
|
let(:date_creation) { Time.local(2008, 9, 1, 10, 5, 0) }
|
||||||
let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, :with_user, procedure: procedure) } }
|
let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, procedure: procedure) } }
|
||||||
let(:body) { JSON.parse(response.body, symbolize_names: true) }
|
let(:body) { JSON.parse(response.body, symbolize_names: true) }
|
||||||
it { expect(response.code).to eq('200') }
|
it { expect(response.code).to eq('200') }
|
||||||
it { expect(body).to have_key :pagination }
|
it { expect(body).to have_key :pagination }
|
||||||
|
@ -54,8 +54,8 @@ describe API::V1::DossiersController do
|
||||||
|
|
||||||
context 'when there are multiple pages' do
|
context 'when there are multiple pages' do
|
||||||
let(:response) { get :index, token: admin.api_token, procedure_id: procedure_id, page: 2 }
|
let(:response) { get :index, token: admin.api_token, procedure_id: procedure_id, page: 2 }
|
||||||
let!(:dossier1) { create(:dossier, :with_entreprise, :with_user, procedure: procedure) }
|
let!(:dossier1) { create(:dossier, :with_entreprise, procedure: procedure) }
|
||||||
let!(:dossier2) { create(:dossier, :with_entreprise, :with_user, procedure: procedure) }
|
let!(:dossier2) { create(:dossier, :with_entreprise, procedure: procedure) }
|
||||||
before do
|
before do
|
||||||
allow(Dossier).to receive(:per_page).and_return(1)
|
allow(Dossier).to receive(:per_page).and_return(1)
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,7 +8,7 @@ describe FranceConnect::ParticulierController, type: :controller do
|
||||||
let(:gender) { 'M' }
|
let(:gender) { 'M' }
|
||||||
let(:birthplace) { '1234' }
|
let(:birthplace) { '1234' }
|
||||||
let(:france_connect_particulier_id) { 'blabla' }
|
let(:france_connect_particulier_id) { 'blabla' }
|
||||||
let(:email) { '' }
|
let(:email) { 'test@test.com' }
|
||||||
let(:password) { '' }
|
let(:password) { '' }
|
||||||
|
|
||||||
let(:user_info) { Hashie::Mash.new(france_connect_particulier_id: france_connect_particulier_id, given_name: given_name, family_name: family_name, birthdate: birthdate, birthplace: birthplace, gender: gender, email: email, password: password) }
|
let(:user_info) { Hashie::Mash.new(france_connect_particulier_id: france_connect_particulier_id, given_name: given_name, family_name: family_name, birthdate: birthdate, birthplace: birthplace, gender: gender, email: email, password: password) }
|
||||||
|
@ -32,12 +32,23 @@ describe FranceConnect::ParticulierController, type: :controller do
|
||||||
context 'when code is correct' do
|
context 'when code is correct' do
|
||||||
before do
|
before do
|
||||||
allow(FranceConnectService).to receive(:retrieve_user_informations_particulier).and_return(user_info)
|
allow(FranceConnectService).to receive(:retrieve_user_informations_particulier).and_return(user_info)
|
||||||
get :callback, code: code
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when france_connect_particulier_id exist in database' do
|
context 'when france_connect_particulier_id exist in database' do
|
||||||
|
let!(:france_connect_information) { create(:france_connect_information, france_connect_particulier_id: france_connect_particulier_id, given_name: given_name, family_name: family_name, birthdate: birthdate, gender: gender, birthplace: birthplace) }
|
||||||
|
|
||||||
|
context {
|
||||||
|
subject { get :callback, code: code }
|
||||||
|
|
||||||
|
it 'does not create a new france_connect_information in database' do
|
||||||
|
expect { subject }.not_to change { FranceConnectInformation.count }
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
context 'when france_connect_particulier_id have an associate user' do
|
||||||
before do
|
before do
|
||||||
create(:user, france_connect_particulier_id: france_connect_particulier_id, email: email, given_name: given_name, family_name: family_name, birthdate: birthdate, gender: gender, birthplace: birthplace)
|
create(:user, email: email, france_connect_information: france_connect_information)
|
||||||
|
|
||||||
get :callback, code: code
|
get :callback, code: code
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -51,14 +62,50 @@ describe FranceConnect::ParticulierController, type: :controller do
|
||||||
|
|
||||||
it 'redirect to stored location' do
|
it 'redirect to stored location' do
|
||||||
subject.store_location_for(:user, stored_location)
|
subject.store_location_for(:user, stored_location)
|
||||||
|
|
||||||
get :callback, code: code
|
get :callback, code: code
|
||||||
expect(response).to redirect_to(stored_location)
|
expect(response).to redirect_to(stored_location)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when france_connect_particulier_id does not exist in database' do
|
context 'when france_connect_particulier_id does not have an associate user' do
|
||||||
|
let(:salt) { FranceConnectSaltService.new(france_connect_information).salt }
|
||||||
|
|
||||||
|
before do
|
||||||
|
get :callback, code: code
|
||||||
|
end
|
||||||
|
|
||||||
it 'redirects to check email FC page' do
|
it 'redirects to check email FC page' do
|
||||||
expect(response).to redirect_to(france_connect_particulier_new_path(user: user_info))
|
expect(response).to redirect_to(france_connect_particulier_new_path(fci_id: france_connect_information.id, salt: salt))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when france_connect_particulier_id does not exist in database' do
|
||||||
|
let(:last_france_connect_information) { FranceConnectInformation.last }
|
||||||
|
let(:salt) { FranceConnectSaltService.new(last_france_connect_information).salt }
|
||||||
|
subject { get :callback, code: code }
|
||||||
|
|
||||||
|
it { expect { subject }.to change { FranceConnectInformation.count }.by(1) }
|
||||||
|
|
||||||
|
describe 'FranceConnectInformation attributs' do
|
||||||
|
before do
|
||||||
|
get :callback, code: code
|
||||||
|
end
|
||||||
|
|
||||||
|
subject { last_france_connect_information }
|
||||||
|
|
||||||
|
it { expect(subject.gender).to eq gender }
|
||||||
|
it { expect(subject.given_name).to eq given_name }
|
||||||
|
it { expect(subject.family_name).to eq family_name }
|
||||||
|
it { expect(subject.email_france_connect).to eq email }
|
||||||
|
it { expect(subject.birthdate.to_time.to_i).to eq birthdate.to_time.to_i }
|
||||||
|
it { expect(subject.birthplace).to eq birthplace }
|
||||||
|
it { expect(subject.france_connect_particulier_id).to eq france_connect_particulier_id }
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'redirects to check email FC page' do
|
||||||
|
expect(subject).to redirect_to(france_connect_particulier_new_path(fci_id: last_france_connect_information.id, salt: salt))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -80,8 +127,85 @@ describe FranceConnect::ParticulierController, type: :controller do
|
||||||
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, 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, 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
|
||||||
|
|
||||||
describe 'POST #create' do
|
describe 'POST #create' do
|
||||||
subject { post :create, user: user_info }
|
let!(:france_connect_information) { create(:france_connect_information, email_france_connect: email) }
|
||||||
|
let(:france_connect_information_id) { france_connect_information.id }
|
||||||
|
let(:salt) { FranceConnectSaltService.new(france_connect_information).salt }
|
||||||
|
|
||||||
|
subject { post :create, fci_id: france_connect_information_id, salt: salt, user:{email_france_connect: france_connect_information.email_france_connect} }
|
||||||
|
|
||||||
context 'when email is filled' do
|
context 'when email is filled' do
|
||||||
let(:email) { 'plop@gmail.com' }
|
let(:email) { 'plop@gmail.com' }
|
||||||
|
@ -93,38 +217,8 @@ describe FranceConnect::ParticulierController, type: :controller do
|
||||||
context 'when email is incorrect' do
|
context 'when email is incorrect' do
|
||||||
let(:email) { '' }
|
let(:email) { '' }
|
||||||
|
|
||||||
it { expect { subject }.to change { User.count }.by(0) }
|
it { expect { subject }.not_to change { User.count } }
|
||||||
it { expect(subject).to redirect_to(france_connect_particulier_new_path(user: user_info)) }
|
it { expect(subject).to redirect_to(france_connect_particulier_new_path(fci_id: france_connect_information_id, salt: salt, user:{email_france_connect: france_connect_information.email_france_connect})) }
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'POST #check_email' do
|
|
||||||
let(:email) { 'plop@gmail.com' }
|
|
||||||
let(:password) { 'blabla141415' }
|
|
||||||
|
|
||||||
subject { post :check_email, user: user_info }
|
|
||||||
|
|
||||||
context 'when email is linked at an existant user' do
|
|
||||||
context 'when email and password couple is valid' do
|
|
||||||
let!(:user) { create(:user, email: email, password: password) }
|
|
||||||
|
|
||||||
it { expect { subject }.to change { user.reload.france_connect_particulier_id } }
|
|
||||||
it { is_expected.to redirect_to root_path }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when email and password couple is not valid' do
|
|
||||||
let!(:user) { create(:user, email: email, password: 'plop12345678') }
|
|
||||||
|
|
||||||
before do
|
|
||||||
subject
|
|
||||||
end
|
|
||||||
|
|
||||||
it { expect(flash[:alert]).to be_present }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when email is not used' do
|
|
||||||
it { expect { subject }.to change { User.count }.by(1) }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -152,7 +152,8 @@ describe Users::DossiersController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'Mandataires Sociaux' do
|
describe 'Mandataires Sociaux' do
|
||||||
let(:user) { create(:user, given_name: given_name, family_name: family_name, birthdate: birthdate, france_connect_particulier_id: '1234567') }
|
let(:france_connect_information) { create(:france_connect_information, given_name: given_name, family_name: family_name, birthdate: birthdate, france_connect_particulier_id: '1234567') }
|
||||||
|
let(:user) { create(:user, france_connect_information: france_connect_information) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
subject
|
subject
|
||||||
|
|
9
spec/factories/france_connect_information.rb
Normal file
9
spec/factories/france_connect_information.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
FactoryGirl.define do
|
||||||
|
factory :france_connect_information do
|
||||||
|
given_name 'plop'
|
||||||
|
family_name 'plip'
|
||||||
|
birthdate '1976-02-24'
|
||||||
|
france_connect_particulier_id '1234567'
|
||||||
|
email_france_connect 'plip@octo.com'
|
||||||
|
end
|
||||||
|
end
|
|
@ -9,8 +9,7 @@ feature 'France Connect Particulier Connexion' do
|
||||||
let(:gender) { 'M' }
|
let(:gender) { 'M' }
|
||||||
let(:birthplace) { '1234' }
|
let(:birthplace) { '1234' }
|
||||||
let(:email) { 'plop@plop.com' }
|
let(:email) { 'plop@plop.com' }
|
||||||
let(:know_france_connect_particulier_id) { 'blabla' }
|
let(:france_connect_particulier_id) { 'blabla' }
|
||||||
let(:unknow_france_connect_particulier_id) { 'titi' }
|
|
||||||
|
|
||||||
let(:user_info) { Hashie::Mash.new(france_connect_particulier_id: france_connect_particulier_id,
|
let(:user_info) { Hashie::Mash.new(france_connect_particulier_id: france_connect_particulier_id,
|
||||||
given_name: given_name,
|
given_name: given_name,
|
||||||
|
@ -34,30 +33,31 @@ feature 'France Connect Particulier Connexion' do
|
||||||
let(:code) { 'plop' }
|
let(:code) { 'plop' }
|
||||||
|
|
||||||
context 'when authentification is ok' do
|
context 'when authentification is ok' do
|
||||||
let!(:user) { create(:user,
|
let(:france_connect_information) { create(:france_connect_information,
|
||||||
france_connect_particulier_id: know_france_connect_particulier_id,
|
france_connect_particulier_id: france_connect_particulier_id,
|
||||||
given_name: given_name,
|
given_name: given_name,
|
||||||
family_name: family_name,
|
family_name: family_name,
|
||||||
birthdate: birthdate,
|
birthdate: birthdate,
|
||||||
birthplace: birthplace,
|
birthplace: birthplace,
|
||||||
gender: gender) }
|
gender: gender,
|
||||||
|
email_france_connect: email) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
allow_any_instance_of(FranceConnectParticulierClient).to receive(:authorization_uri).and_return(france_connect_particulier_callback_path(code: code))
|
allow_any_instance_of(FranceConnectParticulierClient).to receive(:authorization_uri).and_return(france_connect_particulier_callback_path(code: code))
|
||||||
allow(FranceConnectService).to receive(:retrieve_user_informations_particulier).and_return(user_info)
|
allow(FranceConnectService).to receive(:retrieve_user_informations_particulier).and_return(user_info)
|
||||||
page.find_by_id('btn_fcp').click
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when is the first connexion' do
|
context 'when is the first connexion' do
|
||||||
let(:france_connect_particulier_id) { unknow_france_connect_particulier_id }
|
before do
|
||||||
|
page.find_by_id('btn_fcp').click
|
||||||
|
end
|
||||||
scenario 'he is redirected to france connect particulier page' do
|
scenario 'he is redirected to france connect particulier page' do
|
||||||
expect(page).to have_content('Nouvelle connexion')
|
expect(page).to have_content('Nouvelle connexion')
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when he fill an email and valid' do
|
context 'when he fill an email and valid' do
|
||||||
before do
|
before do
|
||||||
page.find_by_id('user_email').set email
|
page.find_by_id('user_email_france_connect').set email
|
||||||
page.find_by_id('valid_new_fcp').click
|
page.find_by_id('valid_new_fcp').click
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -68,7 +68,10 @@ feature 'France Connect Particulier Connexion' do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when is not the first connexion' do
|
context 'when is not the first connexion' do
|
||||||
let(:france_connect_particulier_id) { know_france_connect_particulier_id }
|
before do
|
||||||
|
create(:user, france_connect_information: france_connect_information)
|
||||||
|
page.find_by_id('btn_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('Mes dossiers')
|
expect(page).to have_content('Mes dossiers')
|
||||||
|
|
41
spec/models/france_connect_information_spec.rb
Normal file
41
spec/models/france_connect_information_spec.rb
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe FranceConnectInformation, type: :model do
|
||||||
|
describe 'database columns' do
|
||||||
|
it { is_expected.to have_db_column(:given_name) }
|
||||||
|
it { is_expected.to have_db_column(:family_name) }
|
||||||
|
it { is_expected.to have_db_column(:email_france_connect) }
|
||||||
|
it { is_expected.to have_db_column(:birthdate) }
|
||||||
|
it { is_expected.to have_db_column(:gender) }
|
||||||
|
it { is_expected.to have_db_column(:birthplace) }
|
||||||
|
it { is_expected.to have_db_column(:france_connect_particulier_id) }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'associations' do
|
||||||
|
it { is_expected.to belong_to(:user) }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'validation' do
|
||||||
|
context 'france_connect_particulier_id' do
|
||||||
|
it { is_expected.not_to allow_value(nil).for(:france_connect_particulier_id) }
|
||||||
|
it { is_expected.not_to allow_value('').for(:france_connect_particulier_id) }
|
||||||
|
it { is_expected.to allow_value('mon super projet').for(:france_connect_particulier_id) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.find_by_france_connect_particulier' do
|
||||||
|
let(:user_info) { {france_connect_particulier_id: '123456'} }
|
||||||
|
|
||||||
|
subject { described_class.find_by_france_connect_particulier user_info }
|
||||||
|
|
||||||
|
context 'when france_connect_particulier_id is prensent in database' do
|
||||||
|
let!(:france_connect_information) { create(:france_connect_information, france_connect_particulier_id: '123456') }
|
||||||
|
|
||||||
|
it { is_expected.to eq france_connect_information }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when france_connect_particulier_id is prensent in database' do
|
||||||
|
it { is_expected.to eq nil }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -16,12 +16,6 @@ describe User, type: :model do
|
||||||
it { is_expected.to have_db_column(:updated_at) }
|
it { is_expected.to have_db_column(:updated_at) }
|
||||||
it { is_expected.to have_db_column(:siret) }
|
it { is_expected.to have_db_column(:siret) }
|
||||||
it { is_expected.to have_db_column(:loged_in_with_france_connect) }
|
it { is_expected.to have_db_column(:loged_in_with_france_connect) }
|
||||||
it { is_expected.to have_db_column(:given_name) }
|
|
||||||
it { is_expected.to have_db_column(:family_name) }
|
|
||||||
it { is_expected.to have_db_column(:birthdate) }
|
|
||||||
it { is_expected.to have_db_column(:gender) }
|
|
||||||
it { is_expected.to have_db_column(:birthplace) }
|
|
||||||
it { is_expected.to have_db_column(:france_connect_particulier_id) }
|
|
||||||
|
|
||||||
end
|
end
|
||||||
describe 'associations' do
|
describe 'associations' do
|
||||||
|
|
41
spec/services/france_connect_salt_service_spec.rb
Normal file
41
spec/services/france_connect_salt_service_spec.rb
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
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