demarches-normaliennes/app/policies/champ_policy.rb

46 lines
2 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
2019-06-27 16:26:07 +02:00
class ChampPolicy < ApplicationPolicy
# Scope for WRITING to a champ.
#
# (If the need for a scope to READ a champ emerges, we can implement another scope
# in this file, following this example: https://github.com/varvet/pundit/issues/368#issuecomment-196111115)
class Scope < ApplicationScope
2019-06-27 16:26:07 +02:00
def resolve
if user.blank?
return scope.none
2019-06-27 16:26:07 +02:00
end
2020-04-01 16:05:54 +02:00
# The join must be the same for all elements of the WHERE clause.
#
# NB: here we want to do `.left_outer_joins(dossier: [:invites, { :groupe_instructeur: :instructeurs }]))`,
# but for some reasons ActiveRecord <= 5.2 generates bogus SQL. Hence the manual version of it below.
2020-04-01 16:05:54 +02:00
joined_scope = scope
.joins('LEFT OUTER JOIN dossiers ON dossiers.id = champs.dossier_id')
.joins('LEFT OUTER JOIN invites ON invites.dossier_id = dossiers.id OR invites.dossier_id = dossiers.editing_fork_origin_id')
.joins('LEFT OUTER JOIN groupe_instructeurs ON groupe_instructeurs.id = dossiers.groupe_instructeur_id')
.joins('LEFT OUTER JOIN assign_tos ON assign_tos.groupe_instructeur_id = groupe_instructeurs.id')
.joins('LEFT OUTER JOIN instructeurs ON instructeurs.id = assign_tos.instructeur_id')
2020-04-01 16:05:54 +02:00
# Users can access public champs on their own dossiers.
resolved_scope = joined_scope
.where('dossiers.user_id': user.id, private: false)
# Invited users can access public champs on dossiers they are invited to
invite_clause = joined_scope
.where('invites.user_id': user.id, private: false)
resolved_scope = resolved_scope.or(invite_clause)
if instructeur.present?
# Additionnaly, instructeurs can access private champs
# on dossiers they are allowed to instruct.
2020-04-01 16:05:54 +02:00
instructeur_clause = joined_scope
.where('instructeurs.id': instructeur.id, private: true)
resolved_scope = resolved_scope.or(instructeur_clause)
end
resolved_scope.or(joined_scope.where('dossiers.for_procedure_preview': true))
2019-06-27 16:26:07 +02:00
end
end
end