]> source.dussan.org Git - redmine.git/commitdiff
Pull up query visibility methods.
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Mon, 11 Jul 2016 18:08:55 +0000 (18:08 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Mon, 11 Jul 2016 18:08:55 +0000 (18:08 +0000)
git-svn-id: http://svn.redmine.org/redmine/trunk@15636 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/models/issue_query.rb
app/models/query.rb
app/models/time_entry_query.rb

index 807c5cf0e1efc563fd915837bb077c2dcca24dba..e13c46a2fc67c0dc1deb5249950c83e9934eceee 100644 (file)
@@ -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'
index 33962e31981a8deb69765a3f9ba4ec2ac74e17b8..0a7546cf2297b84754a531a7d1dc0ff2d76f9258 100644 (file)
@@ -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
index a921f6d9399ceb5b17fa2f60b437de2194284d1f..99a52885e6cce603e1f0528dbe1b697d3347be74 100644 (file)
@@ -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),