- Add FranceConnectInformation table to make safe FranceConnect pivot identity.

- Adapt source code with the new table
This commit is contained in:
Xavier J 2016-01-21 17:06:09 +01:00
parent d6e795df02
commit 4d812220fd
18 changed files with 454 additions and 163 deletions

View file

@ -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

View file

@ -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

View 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

View file

@ -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)

View 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

View file

@ -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'

View file

@ -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'

View file

@ -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

View file

@ -0,0 +1,5 @@
class AddEmailToFranceConnectInformation < ActiveRecord::Migration
def change
add_column :france_connect_informations, :email_france_connect, :string
end
end

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View 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

View file

@ -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')

View 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

View file

@ -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

View 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