From 6cd84af522bbc1904d937440a6ad2628cd75fce9 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Sat, 18 Jun 2016 06:42:25 +0000 Subject: [PATCH] Limits the tracker list in filters and issue counts (#285). git-svn-id: http://svn.redmine.org/redmine/trunk@15540 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/controllers/projects_controller.rb | 2 +- app/controllers/reports_controller.rb | 4 ++-- app/models/project.rb | 28 +++++++++++++++++--------- app/models/query.rb | 2 +- app/models/tracker.rb | 23 +++++++++++++++++++++ test/unit/tracker_test.rb | 14 ++++++++++++- 6 files changed, 58 insertions(+), 15 deletions(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 7e1798a06..8753badde 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -137,7 +137,7 @@ class ProjectsController < ApplicationController @users_by_role = @project.users_by_role @subprojects = @project.children.visible.to_a @news = @project.news.limit(5).includes(:author, :project).reorder("#{News.table_name}.created_on DESC").to_a - @trackers = @project.rolled_up_trackers + @trackers = @project.rolled_up_trackers.visible cond = @project.project_condition(Setting.display_subprojects_issues?) diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index b7bf920fd..20279871e 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -20,7 +20,7 @@ class ReportsController < ApplicationController before_filter :find_project, :authorize, :find_issue_statuses def issue_report - @trackers = @project.trackers + @trackers = @project.rolled_up_trackers(false).visible @versions = @project.shared_versions.sort @priorities = IssuePriority.all.reverse @categories = @project.issue_categories @@ -43,7 +43,7 @@ class ReportsController < ApplicationController case params[:detail] when "tracker" @field = "tracker_id" - @rows = @project.trackers + @rows = @project.rolled_up_trackers(false).visible @data = Issue.by_tracker(@project) @report_title = l(:field_tracker) when "version" diff --git a/app/models/project.rb b/app/models/project.rb index e9b2647d4..b6bc13dde 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -421,16 +421,24 @@ class Project < ActiveRecord::Base save end - # Returns an array of the trackers used by the project and its active sub projects - def rolled_up_trackers - @rolled_up_trackers ||= - Tracker. - joins(projects: :enabled_modules). - where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ? AND #{Project.table_name}.status <> ?", lft, rgt, STATUS_ARCHIVED). - where("#{EnabledModule.table_name}.name = ?", 'issue_tracking'). - uniq. - sorted. - to_a + # Returns a scope of the trackers used by the project and its active sub projects + def rolled_up_trackers(include_subprojects=true) + if include_subprojects + @rolled_up_trackers ||= rolled_up_trackers_base_scope. + where("#{Project.table_name}.lft >= ? AND #{Project.table_name}.rgt <= ?", lft, rgt) + else + rolled_up_trackers_base_scope. + where(:projects => {:id => id}) + end + end + + def rolled_up_trackers_base_scope + Tracker. + joins(projects: :enabled_modules). + where("#{Project.table_name}.status <> ?", STATUS_ARCHIVED). + where(:enabled_modules => {:name => 'issue_tracking'}). + uniq. + sorted end # Closes open and locked project versions that are completed diff --git a/app/models/query.rb b/app/models/query.rb index bb1807f6e..8fab46669 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -301,7 +301,7 @@ class Query < ActiveRecord::Base end def trackers - @trackers ||= project.nil? ? Tracker.sorted.to_a : project.rolled_up_trackers + @trackers ||= (project.nil? ? Tracker.all : project.rolled_up_trackers).visible.sorted end # Returns a hash of localized labels for all filter operators diff --git a/app/models/tracker.rb b/app/models/tracker.rb index 73cf569fc..5e4a24b51 100644 --- a/app/models/tracker.rb +++ b/app/models/tracker.rb @@ -46,6 +46,29 @@ class Tracker < ActiveRecord::Base scope :sorted, lambda { order(:position) } scope :named, lambda {|arg| where("LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip)} + # Returns the trackers that are visible by the user. + # + # Examples: + # project.trackers.visible(user) + # => returns the trackers that are visible by the user in project + # + # Tracker.visible(user) + # => returns the trackers that are visible by the user in at least on project + scope :visible, lambda {|*args| + user = args.shift || User.current + condition = Project.allowed_to_condition(user, :view_issues) do |role, user| + unless role.permissions_all_trackers?(:view_issues) + tracker_ids = role.permissions_tracker_ids(:view_issues) + if tracker_ids.any? + "#{Tracker.table_name}.id IN (#{tracker_ids.join(',')})" + else + '1=0' + end + end + end + joins(:projects).where(condition).uniq + } + def to_s; name end def <=>(tracker) diff --git a/test/unit/tracker_test.rb b/test/unit/tracker_test.rb index 658dbb7f6..d45291fd7 100644 --- a/test/unit/tracker_test.rb +++ b/test/unit/tracker_test.rb @@ -18,7 +18,7 @@ require File.expand_path('../../test_helper', __FILE__) class TrackerTest < ActiveSupport::TestCase - fixtures :trackers, :workflows, :issue_statuses, :roles, :issues + fixtures :trackers, :workflows, :issue_statuses, :roles, :issues, :projects, :projects_trackers def test_sorted_scope assert_equal Tracker.all.sort, Tracker.sorted.to_a @@ -28,6 +28,18 @@ class TrackerTest < ActiveSupport::TestCase assert_equal Tracker.find_by_name('Feature'), Tracker.named('feature').first end + def test_visible_scope_chained_with_project_rolled_up_trackers + project = Project.find(1) + role = Role.generate! + role.add_permission! :view_issues + role.set_permission_trackers :view_issues, [2] + role.save! + user = User.generate! + User.add_to_project user, project, role + + assert_equal [2], project.rolled_up_trackers(false).visible(user).map(&:id) + end + def test_copy_workflows source = Tracker.find(1) rules_count = source.workflow_rules.count -- 2.39.5