feat(Administrateurs::GroupeInstructeur): ensure admin from super admin can not add an instructeur
This commit is contained in:
parent
d1544bc4ae
commit
25c0e91d87
9 changed files with 116 additions and 39 deletions
|
@ -1,6 +1,9 @@
|
||||||
module Administrateurs
|
module Administrateurs
|
||||||
class GroupeInstructeursController < AdministrateurController
|
class GroupeInstructeursController < AdministrateurController
|
||||||
include ActiveSupport::NumberHelper
|
include ActiveSupport::NumberHelper
|
||||||
|
|
||||||
|
before_action :ensure_not_super_admin!, only: [:add_instructeur]
|
||||||
|
|
||||||
ITEMS_PER_PAGE = 25
|
ITEMS_PER_PAGE = 25
|
||||||
CSV_MAX_SIZE = 1.megabytes
|
CSV_MAX_SIZE = 1.megabytes
|
||||||
CSV_ACCEPTED_CONTENT_TYPES = [
|
CSV_ACCEPTED_CONTENT_TYPES = [
|
||||||
|
@ -10,6 +13,7 @@ module Administrateurs
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@procedure = procedure
|
@procedure = procedure
|
||||||
|
@disabled_as_super_admin = is_administrateur_through_procedure_administration_as_manager?
|
||||||
|
|
||||||
if procedure.routee?
|
if procedure.routee?
|
||||||
@groupes_instructeurs = paginated_groupe_instructeurs
|
@groupes_instructeurs = paginated_groupe_instructeurs
|
||||||
|
@ -27,6 +31,7 @@ module Administrateurs
|
||||||
@groupe_instructeur = groupe_instructeur
|
@groupe_instructeur = groupe_instructeur
|
||||||
@instructeurs = paginated_instructeurs
|
@instructeurs = paginated_instructeurs
|
||||||
@available_instructeur_emails = available_instructeur_emails
|
@available_instructeur_emails = available_instructeur_emails
|
||||||
|
@disabled_as_super_admin = is_administrateur_through_procedure_administration_as_manager?
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
|
|
@ -2,6 +2,7 @@ module Administrateurs
|
||||||
class ProcedureAdministrateursController < AdministrateurController
|
class ProcedureAdministrateursController < AdministrateurController
|
||||||
before_action :retrieve_procedure, except: [:new]
|
before_action :retrieve_procedure, except: [:new]
|
||||||
before_action :ensure_not_super_admin!, only: [:create]
|
before_action :ensure_not_super_admin!, only: [:create]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@disabled_as_super_admin = is_administrateur_through_procedure_administration_as_manager?
|
@disabled_as_super_admin = is_administrateur_through_procedure_administration_as_manager?
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,15 +5,20 @@
|
||||||
.instructeur-wrapper
|
.instructeur-wrapper
|
||||||
- if !procedure.routee?
|
- if !procedure.routee?
|
||||||
%p.notice Entrez les adresses email des instructeurs que vous souhaitez affecter à cette démarche
|
%p.notice Entrez les adresses email des instructeurs que vous souhaitez affecter à cette démarche
|
||||||
= hidden_field_tag :emails, nil
|
|
||||||
= react_component("ComboMultiple",
|
|
||||||
options: available_instructeur_emails, selected: [], disabled: [],
|
|
||||||
group: '.instructeur-wrapper',
|
|
||||||
name: 'emails',
|
|
||||||
label: 'Emails',
|
|
||||||
acceptNewValues: true)
|
|
||||||
|
|
||||||
= f.submit 'Affecter', class: 'button primary send'
|
- if disabled_as_super_admin
|
||||||
|
= f.select :emails, available_instructeur_emails, {}, disabled: disabled_as_super_admin, id: 'instructeur_emails'
|
||||||
|
- else
|
||||||
|
= hidden_field_tag :emails, nil
|
||||||
|
= react_component("ComboMultiple",
|
||||||
|
options: available_instructeur_emails, selected: [], disabled: [],
|
||||||
|
group: '.instructeur-wrapper',
|
||||||
|
id: 'instructeur_emails',
|
||||||
|
name: 'emails',
|
||||||
|
label: 'Emails',
|
||||||
|
acceptNewValues: true)
|
||||||
|
|
||||||
|
= f.submit 'Affecter', class: 'button primary send', disabled: disabled_as_super_admin
|
||||||
|
|
||||||
%table.table.mt-2
|
%table.table.mt-2
|
||||||
%thead
|
%thead
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.card
|
.card
|
||||||
.card-title
|
%h2.card-title= t('.title')
|
||||||
= t('.title')
|
|
||||||
- if !procedure.routee?
|
- if !procedure.routee?
|
||||||
%p.notice= t('.notice_html')
|
%p.notice= t('.notice_html')
|
||||||
|
|
||||||
|
@ -9,16 +9,16 @@
|
||||||
= link_to t('.button.routing_disable'), update_routing_enabled_admin_procedure_groupe_instructeurs_path(procedure, routing: :disable), class: 'button primary mt-1', method: 'patch'
|
= link_to t('.button.routing_disable'), update_routing_enabled_admin_procedure_groupe_instructeurs_path(procedure, routing: :disable), class: 'button primary mt-1', method: 'patch'
|
||||||
- else
|
- else
|
||||||
= link_to t('.button.routing_enable'), update_routing_enabled_admin_procedure_groupe_instructeurs_path(procedure, routing: :enable), class: 'button primary mt-1', method: 'patch'
|
= link_to t('.button.routing_enable'), update_routing_enabled_admin_procedure_groupe_instructeurs_path(procedure, routing: :enable), class: 'button primary mt-1', method: 'patch'
|
||||||
|
.card
|
||||||
|
%h2.card-title L‘autogestion des instructeurs
|
||||||
|
%p.notice= t('.self_managment_notice_html')
|
||||||
|
|
||||||
.card-title.mt-4 L‘autogestion des instructeurs
|
= form_for procedure,
|
||||||
%p.notice= t('.self_managment_notice_html')
|
method: :patch,
|
||||||
|
url: update_instructeurs_self_management_enabled_admin_procedure_groupe_instructeurs_path(procedure),
|
||||||
= form_for procedure,
|
html: { class: 'form procedure-form__column--form no-background' } do |f|
|
||||||
method: :patch,
|
%label.toggle-switch
|
||||||
url: update_instructeurs_self_management_enabled_admin_procedure_groupe_instructeurs_path(procedure),
|
= f.check_box :instructeurs_self_management_enabled, class: 'toggle-switch-checkbox', onchange: 'this.form.submit()'
|
||||||
html: { class: 'form procedure-form__column--form no-background' } do |f|
|
%span.toggle-switch-control.round
|
||||||
%label.toggle-switch
|
%span.toggle-switch-label.on
|
||||||
= f.check_box :instructeurs_self_management_enabled, class: 'toggle-switch-checkbox', onchange: 'this.form.submit()'
|
%span.toggle-switch-label.off
|
||||||
%span.toggle-switch-control.round
|
|
||||||
%span.toggle-switch-label.on
|
|
||||||
%span.toggle-switch-label.off
|
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
'Instructeurs'] }
|
'Instructeurs'] }
|
||||||
|
|
||||||
.container.groupe-instructeur
|
.container.groupe-instructeur
|
||||||
|
%h1 Gérer les instructeurs et les options d'instruction de « #{@procedure.libelle} »
|
||||||
|
|
||||||
= render partial: 'administrateurs/groupe_instructeurs/routing', locals: { procedure: @procedure }
|
= render partial: 'administrateurs/groupe_instructeurs/routing', locals: { procedure: @procedure }
|
||||||
|
|
||||||
- if @procedure.routee?
|
- if @procedure.routee?
|
||||||
|
@ -19,4 +21,5 @@
|
||||||
locals: { procedure: @procedure,
|
locals: { procedure: @procedure,
|
||||||
groupe_instructeur: @procedure.defaut_groupe_instructeur,
|
groupe_instructeur: @procedure.defaut_groupe_instructeur,
|
||||||
instructeurs: @instructeurs,
|
instructeurs: @instructeurs,
|
||||||
available_instructeur_emails: @available_instructeur_emails }
|
available_instructeur_emails: @available_instructeur_emails,
|
||||||
|
disabled_as_super_admin: @disabled_as_super_admin }
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
= render partial: 'administrateurs/breadcrumbs',
|
= render partial: 'administrateurs/breadcrumbs',
|
||||||
locals: { steps: [link_to('Démarches', admin_procedures_path),
|
locals: { steps: [link_to('Démarches', admin_procedures_path),
|
||||||
link_to(@procedure.libelle, admin_procedure_path(@procedure)),
|
link_to(@procedure.libelle, admin_procedure_path(@procedure)),
|
||||||
|
@ -11,4 +10,5 @@
|
||||||
locals: { procedure: @procedure,
|
locals: { procedure: @procedure,
|
||||||
groupe_instructeur: @groupe_instructeur,
|
groupe_instructeur: @groupe_instructeur,
|
||||||
instructeurs: @instructeurs,
|
instructeurs: @instructeurs,
|
||||||
available_instructeur_emails: @available_instructeur_emails }
|
available_instructeur_emails: @available_instructeur_emails,
|
||||||
|
disabled_as_super_admin: @disabled_as_super_admin }
|
||||||
|
|
|
@ -208,10 +208,11 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#add_instructeur_procedure_non_routee' do
|
describe '#add_instructeur_procedure_non_routee' do
|
||||||
let(:procedure) { create :procedure, administrateur: admin }
|
let(:procedure) { create :procedure }
|
||||||
|
let!(:groupe_instructeur) { create(:administrateurs_procedure, procedure: procedure, administrateur: admin, manager: manager) }
|
||||||
let(:emails) { ['instructeur_3@ministere_a.gouv.fr', 'instructeur_4@ministere_b.gouv.fr'].to_json }
|
let(:emails) { ['instructeur_3@ministere_a.gouv.fr', 'instructeur_4@ministere_b.gouv.fr'].to_json }
|
||||||
subject { post :add_instructeur, params: { emails: emails, procedure_id: procedure.id, id: gi_1_1.id } }
|
subject { post :add_instructeur, params: { emails: emails, procedure_id: procedure.id, id: gi_1_1.id } }
|
||||||
|
let(:manager) { false }
|
||||||
context 'when all emails are valid' do
|
context 'when all emails are valid' do
|
||||||
let(:emails) { ['test@b.gouv.fr', 'test2@b.gouv.fr'].to_json }
|
let(:emails) { ['test@b.gouv.fr', 'test2@b.gouv.fr'].to_json }
|
||||||
it { expect(response.status).to eq(200) }
|
it { expect(response.status).to eq(200) }
|
||||||
|
@ -233,18 +234,17 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
|
||||||
it { expect(subject.request.flash[:alert]).to be_present }
|
it { expect(subject.request.flash[:alert]).to be_present }
|
||||||
it { expect(subject).to redirect_to admin_procedure_groupe_instructeurs_path(procedure) }
|
it { expect(subject).to redirect_to admin_procedure_groupe_instructeurs_path(procedure) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when signed in admin comes from manager' do
|
||||||
|
let(:manager) { true }
|
||||||
|
it { is_expected.to have_http_status(:forbidden) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#add_instructeur' do
|
describe '#add_instructeur' do
|
||||||
let!(:instructeur) { create(:instructeur) }
|
let!(:instructeur) { create(:instructeur) }
|
||||||
let(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') }
|
let(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') }
|
||||||
|
let(:do_request) do
|
||||||
before do
|
|
||||||
gi_1_2.instructeurs << instructeur
|
|
||||||
|
|
||||||
allow(GroupeInstructeurMailer).to receive(:add_instructeurs)
|
|
||||||
.and_return(double(deliver_later: true))
|
|
||||||
|
|
||||||
post :add_instructeur,
|
post :add_instructeur,
|
||||||
params: {
|
params: {
|
||||||
procedure_id: procedure.id,
|
procedure_id: procedure.id,
|
||||||
|
@ -252,10 +252,16 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
|
||||||
emails: new_instructeur_emails.to_json
|
emails: new_instructeur_emails.to_json
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
before do
|
||||||
|
gi_1_2.instructeurs << instructeur
|
||||||
|
|
||||||
|
allow(GroupeInstructeurMailer).to receive(:add_instructeurs)
|
||||||
|
.and_return(double(deliver_later: true))
|
||||||
|
end
|
||||||
|
|
||||||
context 'of a news instructeurs' do
|
context 'of a news instructeurs' do
|
||||||
let(:new_instructeur_emails) { ['new_i1@mail.com', 'new_i2@mail.com'] }
|
let(:new_instructeur_emails) { ['new_i1@mail.com', 'new_i2@mail.com'] }
|
||||||
|
before { do_request }
|
||||||
it { expect(gi_1_2.instructeurs.pluck(:email)).to include(*new_instructeur_emails) }
|
it { expect(gi_1_2.instructeurs.pluck(:email)).to include(*new_instructeur_emails) }
|
||||||
it { expect(flash.notice).to be_present }
|
it { expect(flash.notice).to be_present }
|
||||||
it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_2)) }
|
it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_2)) }
|
||||||
|
@ -271,22 +277,32 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do
|
||||||
|
|
||||||
context 'of an instructeur already in the group' do
|
context 'of an instructeur already in the group' do
|
||||||
let(:new_instructeur_emails) { [instructeur.email] }
|
let(:new_instructeur_emails) { [instructeur.email] }
|
||||||
|
before { do_request }
|
||||||
it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_2)) }
|
it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_2)) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'of badly formed email' do
|
context 'of badly formed email' do
|
||||||
let(:new_instructeur_emails) { ['badly_formed_email'] }
|
let(:new_instructeur_emails) { ['badly_formed_email'] }
|
||||||
|
before { do_request }
|
||||||
it { expect(flash.alert).to be_present }
|
it { expect(flash.alert).to be_present }
|
||||||
it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_2)) }
|
it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_2)) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'of an empty string' do
|
context 'of an empty string' do
|
||||||
let(:new_instructeur_emails) { [''] }
|
let(:new_instructeur_emails) { [''] }
|
||||||
|
before { do_request }
|
||||||
it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_2)) }
|
it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_2)) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when connected as an administrateur from manager' do
|
||||||
|
let(:new_instructeur_emails) { [instructeur.email] }
|
||||||
|
before do
|
||||||
|
admin.administrateurs_procedures.update_all(manager: true)
|
||||||
|
do_request
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(response).to have_http_status(:forbidden) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#remove_instructeur' do
|
describe '#remove_instructeur' do
|
||||||
|
|
|
@ -14,7 +14,7 @@ describe 'Administrateurs can manage administrateurs', js: true do
|
||||||
scenario 'card is clickable' do
|
scenario 'card is clickable' do
|
||||||
visit admin_procedure_path(procedure)
|
visit admin_procedure_path(procedure)
|
||||||
find('#administrateurs').click
|
find('#administrateurs').click
|
||||||
expect(page).to have_css(:h1, text: "Administrateurs de « #{procedure.libelle} »")
|
expect(page).to have_css("h1", text: "Administrateurs de « #{procedure.libelle} »")
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'as admin not flagged from manager' do
|
context 'as admin not flagged from manager' do
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
require 'system/administrateurs/procedure_spec_helper'
|
||||||
|
|
||||||
|
describe 'Manage procedure instructeurs', js: true do
|
||||||
|
include ProcedureSpecHelper
|
||||||
|
|
||||||
|
let(:administrateur) { create(:administrateur) }
|
||||||
|
let!(:procedure) { create(:procedure) }
|
||||||
|
let!(:administrateurs_procedure) { create(:administrateurs_procedure, administrateur: administrateur, procedure: procedure, manager: manager) }
|
||||||
|
let(:manager) { false }
|
||||||
|
before do
|
||||||
|
login_as administrateur.user, scope: :user
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'is accessible via card' do
|
||||||
|
let(:manager) { false }
|
||||||
|
|
||||||
|
scenario 'it works' do
|
||||||
|
visit admin_procedure_path(procedure)
|
||||||
|
byebug
|
||||||
|
find('#groupe-instructeurs').click
|
||||||
|
expect(page).to have_css("h1", text: "Gérer les instructeurs et les options d'instruction de « #{procedure.libelle} »")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'as admin not from manager' do
|
||||||
|
let(:manager) { false }
|
||||||
|
|
||||||
|
scenario 'can add instructeur' do
|
||||||
|
visit admin_procedure_groupe_instructeurs_path(procedure)
|
||||||
|
|
||||||
|
expect {
|
||||||
|
fill_in "instructeur_emails", with: create(:instructeur).email
|
||||||
|
click_on "Affecter"
|
||||||
|
}.to change { procedure.instructeurs.count }.by(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'as admin from manager' do
|
||||||
|
let(:manager) { true }
|
||||||
|
|
||||||
|
scenario 'cannot add instructeur' do
|
||||||
|
visit admin_procedure_groupe_instructeurs_path(procedure)
|
||||||
|
|
||||||
|
expect(page).to have_css("#instructeur_emails[disabled=\"disabled\"]")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Add table
Reference in a new issue