From: Jean-Philippe Lang Date: Sun, 5 Jun 2016 11:50:09 +0000 (+0000) Subject: Adds issue visibility by role/tracker (#285). X-Git-Tag: 3.4.0~939 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=a23450fe08f367a1d4a03e937c3f8e90f83383fe;p=redmine.git Adds issue visibility by role/tracker (#285). git-svn-id: http://svn.redmine.org/redmine/trunk@15465 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- diff --git a/app/models/issue.rb b/app/models/issue.rb index 2baaea3f8..91ea73a6f 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -120,10 +120,10 @@ class Issue < ActiveRecord::Base # Returns a SQL conditions string used to find all issues visible by the specified user def self.visible_condition(user, options={}) Project.allowed_to_condition(user, :view_issues, options) do |role, user| - if user.id && user.logged? + sql = if user.id && user.logged? case role.issues_visibility when 'all' - nil + '1=1' when 'default' user_ids = [user.id] + user.groups.map(&:id).compact "(#{table_name}.is_private = #{connection.quoted_false} OR #{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id IN (#{user_ids.join(',')}))" @@ -136,13 +136,22 @@ class Issue < ActiveRecord::Base else "(#{table_name}.is_private = #{connection.quoted_false})" end + unless role.permissions_all_trackers?(:view_issues) + tracker_ids = role.permissions_tracker_ids(:view_issues) + if tracker_ids.any? + sql = "(#{sql} AND #{table_name}.tracker_id IN (#{tracker_ids.join(',')}))" + else + sql = '1=0' + end + end + sql end end # Returns true if usr or current user is allowed to view the issue def visible?(usr=nil) (usr || User.current).allowed_to?(:view_issues, self.project) do |role, user| - if user.logged? + visible = if user.logged? case role.issues_visibility when 'all' true @@ -156,6 +165,10 @@ class Issue < ActiveRecord::Base else !self.is_private? end + unless role.permissions_all_trackers?(:view_issues) + visible &&= role.permissions_tracker_ids?(:view_issues, tracker_id) + end + visible end end diff --git a/app/views/roles/_form.html.erb b/app/views/roles/_form.html.erb index 524c273d0..c8a3a61cc 100644 --- a/app/views/roles/_form.html.erb +++ b/app/views/roles/_form.html.erb @@ -64,7 +64,7 @@

<%= l(:label_issue_tracking) %>

-<% permissions = %w(add_issues) %> +<% permissions = %w(view_issues add_issues) %> diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb index f7f7003d2..3b7391a3c 100644 --- a/test/unit/issue_test.rb +++ b/test/unit/issue_test.rb @@ -342,6 +342,69 @@ class IssueTest < ActiveSupport::TestCase assert_include issue, issues end + def test_visible_scope_for_member_with_limited_tracker_ids + role = Role.find(1) + role.set_permission_trackers :view_issues, [2] + role.save! + user = User.find(2) + + issues = Issue.where(:project_id => 1).visible(user).to_a + assert issues.any? + assert_equal [2], issues.map(&:tracker_id).uniq + + assert Issue.where(:project_id => 1).all? {|issue| issue.visible?(user) ^ issue.tracker_id != 2} + end + + def test_visible_scope_should_consider_tracker_ids_on_each_project + user = User.generate! + + project1 = Project.generate! + role1 = Role.generate! + role1.add_permission! :view_issues + role1.set_permission_trackers :view_issues, :all + role1.save! + User.add_to_project(user, project1, role1) + + project2 = Project.generate! + role2 = Role.generate! + role2.add_permission! :view_issues + role2.set_permission_trackers :view_issues, [2] + role2.save! + User.add_to_project(user, project2, role2) + + visible_issues = [ + Issue.generate!(:project => project1, :tracker_id => 1), + Issue.generate!(:project => project1, :tracker_id => 2), + Issue.generate!(:project => project2, :tracker_id => 2) + ] + hidden_issue = Issue.generate!(:project => project2, :tracker_id => 1) + + issues = Issue.where(:project_id => [project1.id, project2.id]).visible(user) + assert_equal visible_issues.map(&:id), issues.ids.sort + + assert visible_issues.all? {|issue| issue.visible?(user)} + assert !hidden_issue.visible?(user) + end + + def test_visible_scope_should_not_consider_roles_without_view_issues_permission + user = User.generate! + role1 = Role.generate! + role1.remove_permission! :view_issues + role1.set_permission_trackers :view_issues, :all + role1.save! + role2 = Role.generate! + role2.add_permission! :view_issues + role2.set_permission_trackers :view_issues, [2] + role2.save! + User.add_to_project(user, Project.find(1), [role1, role2]) + + issues = Issue.where(:project_id => 1).visible(user).to_a + assert issues.any? + assert_equal [2], issues.map(&:tracker_id).uniq + + assert Issue.where(:project_id => 1).all? {|issue| issue.visible?(user) ^ issue.tracker_id != 2} + end + def test_visible_scope_for_admin user = User.find(1) user.members.each(&:destroy)