2020-11-05 15:09:11 +01:00
|
|
|
|
describe SuperAdmin, type: :model do
|
2018-01-11 14:17:50 +01:00
|
|
|
|
describe '#invite_admin' do
|
2020-11-05 15:09:11 +01:00
|
|
|
|
let(:super_admin) { create :super_admin }
|
2018-01-11 14:17:50 +01:00
|
|
|
|
let(:valid_email) { 'paul@tps.fr' }
|
2019-08-09 11:41:36 +02:00
|
|
|
|
|
2020-11-05 15:09:11 +01:00
|
|
|
|
subject { super_admin.invite_admin(valid_email) }
|
2018-01-11 14:17:50 +01:00
|
|
|
|
|
|
|
|
|
it {
|
2019-08-09 11:41:36 +02:00
|
|
|
|
user = subject
|
|
|
|
|
expect(user.errors).to be_empty
|
|
|
|
|
expect(user).to be_persisted
|
2018-01-11 14:17:50 +01:00
|
|
|
|
}
|
2019-08-09 11:41:36 +02:00
|
|
|
|
|
2020-11-05 15:09:11 +01:00
|
|
|
|
it { expect(super_admin.invite_admin(nil).errors).not_to be_empty }
|
|
|
|
|
it { expect(super_admin.invite_admin('toto').errors).not_to be_empty }
|
2018-04-11 17:14:47 +02:00
|
|
|
|
|
|
|
|
|
it 'creates a corresponding user account for the email' do
|
|
|
|
|
subject
|
|
|
|
|
user = User.find_by(email: valid_email)
|
|
|
|
|
expect(user).to be_present
|
|
|
|
|
end
|
|
|
|
|
|
2019-08-06 11:02:54 +02:00
|
|
|
|
it 'creates a corresponding instructeur account for the email' do
|
2018-10-30 15:31:13 +01:00
|
|
|
|
subject
|
2019-10-15 17:44:59 +02:00
|
|
|
|
instructeur = Instructeur.by_email(valid_email)
|
2019-08-06 11:02:54 +02:00
|
|
|
|
expect(instructeur).to be_present
|
2018-10-30 15:31:13 +01:00
|
|
|
|
end
|
|
|
|
|
|
2018-04-11 17:14:47 +02:00
|
|
|
|
context 'when there already is a user account with the same email' do
|
|
|
|
|
before { create(:user, email: valid_email) }
|
|
|
|
|
it 'still creates an admin account' do
|
|
|
|
|
expect(subject.errors).to be_empty
|
|
|
|
|
expect(subject).to be_persisted
|
|
|
|
|
end
|
|
|
|
|
end
|
2018-01-11 14:17:50 +01:00
|
|
|
|
end
|
2020-11-04 16:35:15 +01:00
|
|
|
|
|
|
|
|
|
describe 'enable_otp!' do
|
2020-11-05 15:09:11 +01:00
|
|
|
|
let(:super_admin) { create(:super_admin, otp_required_for_login: false) }
|
|
|
|
|
let(:subject) { super_admin.enable_otp! }
|
2020-11-04 16:35:15 +01:00
|
|
|
|
|
|
|
|
|
it 'updates otp_required_for_login' do
|
2020-11-05 15:09:11 +01:00
|
|
|
|
expect { subject }.to change { super_admin.otp_required_for_login? }.from(false).to(true)
|
2020-11-04 16:35:15 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'updates otp_secret' do
|
2020-11-05 15:09:11 +01:00
|
|
|
|
expect { subject }.to change { super_admin.otp_secret }
|
2020-11-04 16:35:15 +01:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe 'disable_otp!' do
|
2020-11-05 15:09:11 +01:00
|
|
|
|
let(:super_admin) { create(:super_admin, otp_required_for_login: true) }
|
|
|
|
|
let(:subject) { super_admin.disable_otp! }
|
2020-11-04 16:35:15 +01:00
|
|
|
|
|
|
|
|
|
it 'updates otp_required_for_login' do
|
2020-11-05 15:09:11 +01:00
|
|
|
|
expect { subject }.to change { super_admin.otp_required_for_login? }.from(true).to(false)
|
2020-11-04 16:35:15 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'nullifies otp_secret' do
|
2020-11-05 15:09:11 +01:00
|
|
|
|
super_admin.enable_otp!
|
2023-05-03 11:37:28 +02:00
|
|
|
|
expect(super_admin.reload.otp_secret).not_to be_nil
|
|
|
|
|
|
2023-03-15 16:34:12 +01:00
|
|
|
|
super_admin.disable_otp!
|
2023-05-03 11:37:28 +02:00
|
|
|
|
expect(super_admin.reload.otp_secret).to be_nil
|
2020-11-04 16:35:15 +01:00
|
|
|
|
end
|
|
|
|
|
end
|
2020-11-17 17:11:04 +01:00
|
|
|
|
|
|
|
|
|
describe '#password_complexity' do
|
|
|
|
|
# This password list is sorted by password complexity, according to zxcvbn (used for complexity evaluation)
|
|
|
|
|
# 0 - too guessable: risky password. (guesses < 10^3)
|
|
|
|
|
# 1 - very guessable: protection from throttled online attacks. (guesses < 10^6)
|
|
|
|
|
# 2 - somewhat guessable: protection from unthrottled online attacks. (guesses < 10^8)
|
|
|
|
|
# 3 - safely unguessable: moderate protection from offline slow-hash scenario. (guesses < 10^10)
|
|
|
|
|
# 4 - very unguessable: strong protection from offline slow-hash scenario. (guesses >= 10^10)
|
2021-09-09 16:40:23 +02:00
|
|
|
|
passwords = ['password', '12pass23', 'démarches ', 'démarches-simple', '{My-$3cure-p4ssWord}']
|
2020-11-17 17:11:04 +01:00
|
|
|
|
min_complexity = PASSWORD_COMPLEXITY_FOR_ADMIN
|
|
|
|
|
|
|
|
|
|
let(:email) { 'mail@beta.gouv.fr' }
|
|
|
|
|
let(:super_admin) { build(:super_admin, email: email, password: password) }
|
|
|
|
|
|
|
|
|
|
subject do
|
2021-09-09 16:40:23 +02:00
|
|
|
|
super_admin.valid?
|
2020-11-17 17:11:04 +01:00
|
|
|
|
super_admin.errors.full_messages
|
|
|
|
|
end
|
|
|
|
|
|
2021-09-09 16:40:23 +02:00
|
|
|
|
context 'when the password is too short' do
|
2020-11-17 17:11:04 +01:00
|
|
|
|
let(:password) { 's' * (PASSWORD_MIN_LENGTH - 1) }
|
|
|
|
|
|
2021-09-09 16:40:23 +02:00
|
|
|
|
it 'reports an error about password length (but not about complexity)' do
|
2022-12-20 17:51:36 +01:00
|
|
|
|
expect(subject).to eq(["Le champ « Mot de passe » est trop court. Saisir un mot de passe avec au moins 8 caractères"])
|
2021-09-09 16:40:23 +02:00
|
|
|
|
end
|
2020-11-17 17:11:04 +01:00
|
|
|
|
end
|
|
|
|
|
|
2021-09-09 16:40:23 +02:00
|
|
|
|
passwords[0..(min_complexity - 1)].each do |simple_password|
|
|
|
|
|
context 'when the password is long enough, but too simple' do
|
|
|
|
|
let(:password) { simple_password }
|
2020-11-17 17:11:04 +01:00
|
|
|
|
|
2022-12-20 17:51:36 +01:00
|
|
|
|
it { expect(subject).to eq(["Le champ « Mot de passe » n’est pas assez complexe. Saisir un mot de passe plus complexe"]) }
|
2020-11-17 17:11:04 +01:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2021-09-09 16:40:23 +02:00
|
|
|
|
context 'when the password is long and complex' do
|
2020-11-17 17:11:04 +01:00
|
|
|
|
let(:password) { passwords[min_complexity] }
|
|
|
|
|
|
2021-09-09 16:40:23 +02:00
|
|
|
|
it { expect(subject).to be_empty }
|
2020-11-17 17:11:04 +01:00
|
|
|
|
end
|
|
|
|
|
end
|
2018-01-11 14:17:50 +01:00
|
|
|
|
end
|