# frozen_string_literal: true module Decidim module ParticipatoryProcesses class Permissions < Decidim::DefaultPermissions def permissions user_can_enter_processes_space_area? user_can_enter_process_groups_space_area? return permission_action if process && !process.is_a?(Decidim::ParticipatoryProcess) if read_admin_dashboard_action? user_can_read_admin_dashboard? return permission_action end if permission_action.scope == :public public_list_processes_action? public_list_process_groups_action? public_read_process_group_action? public_read_process_action? public_embed_process_action? return permission_action end return permission_action unless user if !has_manageable_processes? && !user.admin? disallow! return permission_action end return permission_action unless permission_action.scope == :admin valid_process_group_action? user_can_read_process_list? user_can_read_current_process? user_can_create_process? # org admins and space admins can do everything in the admin section org_admin_action? participatory_process_type_action? return permission_action unless process moderator_action? collaborator_action? valuator_action? process_admin_action? permission_action end private # It's an admin user if it's an organization admin or is a space admin # for the current `process`. def admin_user? user.admin? || (process ? can_manage_process?(role: :admin) : has_manageable_processes?) end # Checks if it has any manageable process, with any possible role. def has_manageable_processes?(role: :any) return unless user participatory_processes_with_role_privileges(role).any? end # Whether the user can manage the given process or not. def can_manage_process?(role: :any) return unless user participatory_processes_with_role_privileges(role).include? process end # Returns a collection of Participatory processes where the given user has the # specific role privilege. def participatory_processes_with_role_privileges(role) Decidim::ParticipatoryProcessesWithUserRole.for(user, role) end def public_list_processes_action? return unless permission_action.action == :list && permission_action.subject == :process allow! end def public_list_process_groups_action? return unless permission_action.action == :list && permission_action.subject == :process_group allow! end def public_read_process_group_action? return unless permission_action.action == :read && permission_action.subject == :process_group && process_group allow! end def public_read_process_action? return unless permission_action.action == :read && [:process, :participatory_space].include?(permission_action.subject) && process return disallow! unless can_view_private_space? return allow! if user&.admin? return allow! if process.published? toggle_allow(can_manage_process?) end def public_embed_process_action? return unless permission_action.action == :embed && [:process, :participatory_space].include?(permission_action.subject) && process return disallow! unless process.published? return disallow! if process.private_space allow! end def can_view_private_space? return true unless process.private_space return false unless user user.admin || process.users.include?(user) end # Only organization admins can enter the process groups space area. def user_can_enter_process_groups_space_area? return unless permission_action.action == :enter && permission_action.scope == :admin && permission_action.subject == :space_area && context.fetch(:space_name, nil) == :process_groups toggle_allow(user.admin?) end # All users with a relation to a process and organization admins can enter # the processes space area. def user_can_enter_processes_space_area? return unless permission_action.action == :enter && permission_action.scope == :admin && permission_action.subject == :space_area && context.fetch(:space_name, nil) == :processes toggle_allow(user.admin? || has_manageable_processes?) end # Only organization admins can manage process groups. def valid_process_group_action? return unless permission_action.subject == :process_group toggle_allow(user.admin?) end # Checks if the permission_action is to read in the admin or not. def admin_read_permission_action? permission_action.action == :read end def read_admin_dashboard_action? permission_action.action == :read && permission_action.subject == :admin_dashboard end # Any user that can enter the space area can read the admin dashboard. def user_can_read_admin_dashboard? allow! if user.admin? || has_manageable_processes? end # Only organization admins can create a process def user_can_create_process? return unless permission_action.action == :create && permission_action.subject == :process toggle_allow(user.admin?) end # Everyone can read the process list def user_can_read_process_list? return unless read_process_list_permission_action? toggle_allow(user.admin? || has_manageable_processes?) end def user_can_read_current_process? return unless read_process_list_permission_action? return if permission_action.subject == :process_list toggle_allow(user.admin? || can_manage_process?) end # A moderator needs to be able to read the process they are assigned to, # and needs to perform all actions for the moderations of that process. def moderator_action? return unless can_manage_process?(role: :moderator) allow! if permission_action.subject == :moderation end # Collaborators can only preview their own processes. def collaborator_action? return unless can_manage_process?(role: :collaborator) allow! if permission_action.action == :preview end # Valuators can only read the components of a process. def valuator_action? return unless can_manage_process?(role: :valuator) allow! if permission_action.action == :read && permission_action.subject == :component allow! if permission_action.action == :export && permission_action.subject == :component_data end # Process admins can eprform everything *inside* that process. They cannot # create a process or perform actions on process groups or other # processes. def process_admin_action? return unless can_manage_process?(role: :admin) return if user.admin? return disallow! if permission_action.action == :create && permission_action.subject == :process is_allowed = [ :attachment, :attachment_collection, :category, :component, :component_data, :moderation, :process, :process_step, :process_user_role, :space_private_user, :export_space, :import ].include?(permission_action.subject) allow! if is_allowed end def org_admin_action? return unless user.admin? is_allowed = [ :attachment, :attachment_collection, :category, :component, :component_data, :moderation, :process, :process_step, :process_user_role, :space_private_user, :export_space, :import ].include?(permission_action.subject) allow! if is_allowed end def participatory_process_type_action? return unless permission_action.subject == :participatory_process_type return disallow! unless user.admin? participatory_process_type = context.fetch(:participatory_process_type, nil) case permission_action.action when :destroy toggle_allow(participatory_process_type&.processes&.none?) else allow! end end # Checks if the permission_action is to read the admin processes list or # not. def read_process_list_permission_action? permission_action.action == :read && [:process, :participatory_space, :process_list].include?(permission_action.subject) end def process @process ||= context.fetch(:current_participatory_space, nil) || context.fetch(:process, nil) end def process_group @process_group ||= context.fetch(:process_group, nil) end end end end