From 7c6757c81a04a4351063ffd764a1afd53209d09d Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Mon, 11 Jul 2016 18:08:55 +0000 Subject: [PATCH] Pull up query visibility methods. git-svn-id: http://svn.redmine.org/redmine/trunk@15636 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/models/issue_query.rb | 52 +--------------------------- app/models/query.rb | 63 ++++++++++++++++++++++++++++++++++ app/models/time_entry_query.rb | 1 + 3 files changed, 65 insertions(+), 51 deletions(-) diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index 807c5cf0e..e13c46a2f 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -18,6 +18,7 @@ class IssueQuery < Query self.queried_class = Issue + self.view_permission = :view_issues self.available_columns = [ QueryColumn.new(:id, :sortable => "#{Issue.table_name}.id", :default_order => 'desc', :caption => '#', :frozen => true), @@ -46,62 +47,11 @@ class IssueQuery < Query QueryColumn.new(:description, :inline => false) ] - scope :visible, lambda {|*args| - user = args.shift || User.current - base = Project.allowed_to_condition(user, :view_issues, *args) - scope = joins("LEFT OUTER JOIN #{Project.table_name} ON #{table_name}.project_id = #{Project.table_name}.id"). - where("#{table_name}.project_id IS NULL OR (#{base})") - - if user.admin? - scope.where("#{table_name}.visibility <> ? OR #{table_name}.user_id = ?", VISIBILITY_PRIVATE, user.id) - elsif user.memberships.any? - scope.where("#{table_name}.visibility = ?" + - " OR (#{table_name}.visibility = ? AND #{table_name}.id IN (" + - "SELECT DISTINCT q.id FROM #{table_name} q" + - " INNER JOIN #{table_name_prefix}queries_roles#{table_name_suffix} qr on qr.query_id = q.id" + - " INNER JOIN #{MemberRole.table_name} mr ON mr.role_id = qr.role_id" + - " INNER JOIN #{Member.table_name} m ON m.id = mr.member_id AND m.user_id = ?" + - " WHERE q.project_id IS NULL OR q.project_id = m.project_id))" + - " OR #{table_name}.user_id = ?", - VISIBILITY_PUBLIC, VISIBILITY_ROLES, user.id, user.id) - elsif user.logged? - scope.where("#{table_name}.visibility = ? OR #{table_name}.user_id = ?", VISIBILITY_PUBLIC, user.id) - else - scope.where("#{table_name}.visibility = ?", VISIBILITY_PUBLIC) - end - } - def initialize(attributes=nil, *args) super attributes self.filters ||= { 'status_id' => {:operator => "o", :values => [""]} } end - # Returns true if the query is visible to +user+ or the current user. - def visible?(user=User.current) - return true if user.admin? - return false unless project.nil? || user.allowed_to?(:view_issues, project) - case visibility - when VISIBILITY_PUBLIC - true - when VISIBILITY_ROLES - if project - (user.roles_for_project(project) & roles).any? - else - Member.where(:user_id => user.id).joins(:roles).where(:member_roles => {:role_id => roles.map(&:id)}).any? - end - else - user == self.user - end - end - - def is_private? - visibility == VISIBILITY_PRIVATE - end - - def is_public? - !is_private? - end - def draw_relations r = options[:draw_relations] r.nil? || r == '1' diff --git a/app/models/query.rb b/app/models/query.rb index 33962e319..0a7546cf2 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -231,6 +231,69 @@ class Query < ActiveRecord::Base class_attribute :queried_class + # Permission required to view the queries, set on subclasses. + class_attribute :view_permission + + # Scope of visible queries, can be used from subclasses only. + # Unlike other visible scopes, a class methods is used as it + # let handle inheritance more nicely than scope DSL. + def self.visible(*args) + if self == ::Query + # Visibility depends on permissions for each subclass, + # raise an error if the scope is called from Query (eg. Query.visible) + raise Exception.new("Cannot call .visible scope from the base Query class, but from subclasses only.") + end + + user = args.shift || User.current + base = Project.allowed_to_condition(user, view_permission, *args) + scope = joins("LEFT OUTER JOIN #{Project.table_name} ON #{table_name}.project_id = #{Project.table_name}.id"). + where("#{table_name}.project_id IS NULL OR (#{base})") + + if user.admin? + scope.where("#{table_name}.visibility <> ? OR #{table_name}.user_id = ?", VISIBILITY_PRIVATE, user.id) + elsif user.memberships.any? + scope.where("#{table_name}.visibility = ?" + + " OR (#{table_name}.visibility = ? AND #{table_name}.id IN (" + + "SELECT DISTINCT q.id FROM #{table_name} q" + + " INNER JOIN #{table_name_prefix}queries_roles#{table_name_suffix} qr on qr.query_id = q.id" + + " INNER JOIN #{MemberRole.table_name} mr ON mr.role_id = qr.role_id" + + " INNER JOIN #{Member.table_name} m ON m.id = mr.member_id AND m.user_id = ?" + + " WHERE q.project_id IS NULL OR q.project_id = m.project_id))" + + " OR #{table_name}.user_id = ?", + VISIBILITY_PUBLIC, VISIBILITY_ROLES, user.id, user.id) + elsif user.logged? + scope.where("#{table_name}.visibility = ? OR #{table_name}.user_id = ?", VISIBILITY_PUBLIC, user.id) + else + scope.where("#{table_name}.visibility = ?", VISIBILITY_PUBLIC) + end + end + + # Returns true if the query is visible to +user+ or the current user. + def visible?(user=User.current) + return true if user.admin? + return false unless project.nil? || user.allowed_to?(self.class.view_permission, project) + case visibility + when VISIBILITY_PUBLIC + true + when VISIBILITY_ROLES + if project + (user.roles_for_project(project) & roles).any? + else + Member.where(:user_id => user.id).joins(:roles).where(:member_roles => {:role_id => roles.map(&:id)}).any? + end + else + user == self.user + end + end + + def is_private? + visibility == VISIBILITY_PRIVATE + end + + def is_public? + !is_private? + end + def queried_table_name @queried_table_name ||= self.class.queried_class.table_name end diff --git a/app/models/time_entry_query.rb b/app/models/time_entry_query.rb index a921f6d93..99a52885e 100644 --- a/app/models/time_entry_query.rb +++ b/app/models/time_entry_query.rb @@ -18,6 +18,7 @@ class TimeEntryQuery < Query self.queried_class = TimeEntry + self.view_permission = :view_time_entries self.available_columns = [ QueryColumn.new(:project, :sortable => "#{Project.table_name}.name", :groupable => true), -- 2.39.5