Start using pundit

This commit is contained in:
Paul Chavard 2019-06-27 16:26:07 +02:00
parent 25f49acbd2
commit fc75580a3c
11 changed files with 187 additions and 16 deletions

View file

@ -47,6 +47,7 @@ gem 'prawn' # PDF Generation
gem 'prawn_rails'
gem 'premailer-rails'
gem 'puma' # Use Puma as the app server
gem 'pundit'
gem 'rack-mini-profiler'
gem 'rails'
gem 'rails-i18n' # Locales par défaut

View file

@ -431,6 +431,8 @@ GEM
pry (~> 0.10)
public_suffix (3.0.3)
puma (3.12.0)
pundit (2.0.1)
activesupport (>= 3.0.0)
rack (2.0.6)
rack-mini-profiler (1.0.1)
rack (>= 1.2.0)
@ -749,6 +751,7 @@ DEPENDENCIES
premailer-rails
pry-byebug
puma
pundit
rack-mini-profiler
rails
rails-controller-testing

View file

@ -1,5 +1,6 @@
class ApplicationController < ActionController::Base
include TrustedDeviceConcern
include Pundit
MAINTENANCE_MESSAGE = 'Le site est actuellement en maintenance. Il sera à nouveau disponible dans un court instant.'
@ -41,12 +42,18 @@ class ApplicationController < ActionController::Base
logged_user.present?
end
def logged_user_ids
logged_users.map(&:id)
end
helper_method :logged_in?
def pundit_user
if administrateur_signed_in?
current_administrateur
elsif gestionnaire_signed_in?
current_gestionnaire
else
current_user
end
end
protected
def authenticate_logged_user!

View file

@ -14,15 +14,9 @@ class Champs::CarteController < ApplicationController
end
@champ = if params[:champ_id].present?
Champ
.joins(:dossier)
.where(dossiers: { user_id: logged_user_ids })
.find(params[:champ_id])
policy_scope(Champ).find(params[:champ_id])
else
TypeDeChamp
.joins(:procedure)
.where(procedures: { administrateur_id: logged_user_ids })
.find(params[:type_de_champ_id]).champ.build
policy_scope(TypeDeChamp).find(params[:type_de_champ_id]).champ.build
end
geo_areas = []

View file

@ -2,10 +2,7 @@ class Champs::RepetitionController < ApplicationController
before_action :authenticate_logged_user!
def show
@champ = Champ
.joins(:dossier)
.where(dossiers: { user_id: logged_user_ids })
.find(params[:champ_id])
@champ = policy_scope(Champ).find(params[:champ_id])
@position = params[:position]
row = (@champ.champs.empty? ? 0 : @champ.champs.last.row) + 1

View file

@ -225,6 +225,10 @@ class Gestionnaire < ApplicationRecord
end
end
def user
User.find_by(email: email)
end
private
def annotations_hash(demande, annotations_privees, avis, messagerie)

View file

@ -0,0 +1,49 @@
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
@user = user
@record = record
end
def index?
false
end
def show?
false
end
def create?
false
end
def new?
create?
end
def update?
false
end
def edit?
update?
end
def destroy?
false
end
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
scope.all
end
end
end

View file

@ -0,0 +1,24 @@
class ChampPolicy < ApplicationPolicy
class Scope < Scope
def resolve
if user.is_a?(User)
scope
.joins(:dossier)
.where({ dossiers: { user_id: user.id } })
elsif user.is_a?(Gestionnaire)
scope_with_join = scope.joins(dossier: :follows)
scope_with_left_join = scope.left_joins(dossier: :follows)
if user.user
scope_with_left_join
.where({ dossiers: { user_id: user.user.id } })
.or(scope_with_left_join.where(dossiers: { follows: { gestionnaire_id: user.id } }))
else
scope_with_join.where(dossiers: { follows: { gestionnaire_id: user.id } })
end
else
scope.none
end
end
end
end

View file

@ -0,0 +1,13 @@
class TypeDeChampPolicy < ApplicationPolicy
class Scope < Scope
def resolve
if user.is_a?(Administrateur)
scope
.joins(procedure: [:administrateurs])
.where({ administrateurs: { id: user.id } })
else
scope.none
end
end
end
end

View file

@ -0,0 +1,56 @@
require 'spec_helper'
describe ChampPolicy do
let(:user) { create(:user) }
let(:dossier) { create(:dossier, user: user) }
let!(:champ) { create(:champ_text, dossier: dossier) }
let(:pundit_user) { user }
subject { Pundit.policy_scope(pundit_user, Champ) }
context 'when the user has only user rights' do
context 'cannot access champs for other dossiers' do
let(:pundit_user) { create(:user) }
it { expect(subject.find_by(id: champ.id)).to eq(nil) }
end
context 'can access champs for its own dossiers' do
it {
expect(subject.find(champ.id)).to eq(champ)
}
end
end
context 'when the user has only gestionnaire rights' do
context 'can access champs for dossiers it follows' do
let(:dossier) { create(:dossier, :followed) }
let(:pundit_user) { dossier.followers_gestionnaires.first }
it { expect(subject.find(champ.id)).to eq(champ) }
end
end
context 'when the user has user and gestionnaire rights' do
let(:pundit_user) { dossier.followers_gestionnaires.first }
let(:dossier) { create(:dossier, :followed) }
let(:user) { create(:user, email: pundit_user.email) }
let(:dossier2) { create(:dossier, user: user) }
let!(:champ_2) { create(:champ_text, dossier: dossier2) }
context 'can access champs for dossiers it follows' do
it do
expect(pundit_user.user).to eq(user)
expect(subject.find(champ.id)).to eq(champ)
end
end
context 'can access champs for its own dossiers' do
it do
expect(pundit_user.user).to eq(user)
expect(subject.find(champ_2.id)).to eq(champ_2)
end
end
end
end

View file

@ -0,0 +1,23 @@
require 'spec_helper'
describe TypeDeChampPolicy do
let(:procedure) { create(:procedure) }
let!(:type_de_champ) { create(:type_de_champ_text, procedure: procedure) }
let(:pundit_user) { create(:user) }
subject { Pundit.policy_scope(pundit_user, TypeDeChamp) }
context 'when the user has only user rights' do
it 'can not access' do
expect(subject.find_by(id: type_de_champ.id)).to eq(nil)
end
end
context 'when the user has administrateur rights' do
let(:pundit_user) { procedure.administrateurs.first }
it 'can access' do
expect(subject.find(type_de_champ.id)).to eq(type_de_champ)
end
end
end