ChampsPolicy: allow instructeurs to access private annotations (#4396)

Instructeur : corrige l'utilisation des cartes dans les annotations privées (#4388)
This commit is contained in:
Pierre de La Morinerie 2019-10-08 15:13:15 +02:00 committed by GitHub
commit fed723cc77
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 84 additions and 21 deletions

View file

@ -34,7 +34,7 @@ class ApplicationPolicy
false
end
class Scope
class ApplicationScope
attr_reader :user, :instructeur, :administrateur, :scope
def initialize(account, scope)

View file

@ -1,13 +1,25 @@
class ChampPolicy < ApplicationPolicy
class Scope < Scope
class Scope < ApplicationScope
def resolve
if user.present?
scope
.joins(:dossier)
.where({ dossiers: { user_id: user.id } })
else
scope.none
if user.blank?
return scope.none
end
# Users can access public champs on their own dossiers.
resolved_scope = scope
.left_outer_joins(dossier: { groupe_instructeur: [:instructeurs] })
.where('dossiers.user_id': user.id, private: false)
if instructeur.present?
# Additionnaly, instructeurs can access private champs
# on dossiers they are allowed to instruct.
instructeur_clause = scope
.left_outer_joins(dossier: { groupe_instructeur: [:instructeurs] })
.where('instructeurs.id': instructeur.id, private: true)
resolved_scope = resolved_scope.or(instructeur_clause)
end
resolved_scope
end
end
end

View file

@ -1,5 +1,5 @@
class TypeDeChampPolicy < ApplicationPolicy
class Scope < Scope
class Scope < ApplicationScope
def resolve
if administrateur.present?
scope

View file

@ -1,25 +1,76 @@
require 'spec_helper'
describe ChampPolicy do
let(:user) { create(:user) }
let(:dossier) { create(:dossier, user: user) }
let!(:champ) { create(:champ_text, dossier: dossier) }
let(:champ) { create(:champ_text, private: private, dossier: dossier) }
let(:dossier) { create(:dossier, user: dossier_owner) }
let(:dossier_owner) { create(:user) }
let(:account) { { user: user } }
let(:signed_in_user) { create(:user) }
let(:account) { { user: signed_in_user } }
subject { Pundit.policy_scope(account, Champ) }
context 'when the user has only user rights' do
context 'cannot access champs for other dossiers' do
let(:account) { { user: create(:user) } }
shared_examples_for 'they can access a public champ' do
let(:private) { false }
it { expect(subject.find_by(id: champ.id)).to eq(champ) }
end
it { expect(subject.find_by(id: champ.id)).to eq(nil) }
shared_examples_for 'they cant access a public champ' do
let(:private) { false }
it { expect(subject.find_by(id: champ.id)).to eq(nil) }
end
shared_examples_for 'they can access a private champ' do
let(:private) { true }
it { expect(subject.find_by(id: champ.id)).to eq(champ) }
end
shared_examples_for 'they cant access a private champ' do
let(:private) { true }
it { expect(subject.find_by(id: champ.id)).to eq(nil) }
end
context 'when an user only has user rights' do
context 'as the dossier owner' do
let(:signed_in_user) { dossier_owner }
it_behaves_like 'they can access a public champ'
it_behaves_like 'they cant access a private champ'
end
context 'can access champs for its own dossiers' do
it {
expect(subject.find(champ.id)).to eq(champ)
}
context 'as another user' do
let(:signed_in_user) { create(:user) }
it_behaves_like 'they cant access a public champ'
it_behaves_like 'they cant access a private champ'
end
end
context 'when the user also has instruction rights' do
let(:instructeur) { create(:instructeur, email: signed_in_user.email, password: signed_in_user.password) }
let(:account) { { user: signed_in_user, instructeur: instructeur } }
context 'as the dossier instructeur and owner' do
let(:signed_in_user) { dossier_owner }
before { instructeur.assign_to_procedure(dossier.procedure) }
it_behaves_like 'they can access a public champ'
it_behaves_like 'they can access a private champ'
end
context 'as the dossier instructeur (but not owner)' do
let(:signed_in_user) { create(:user) }
before { instructeur.assign_to_procedure(dossier.procedure) }
it_behaves_like 'they cant access a public champ'
it_behaves_like 'they can access a private champ'
end
context 'as an instructeur not assigned to the procedure' do
let(:signed_in_user) { create(:user) }
it_behaves_like 'they cant access a public champ'
it_behaves_like 'they cant access a private champ'
end
end
end