]> source.dussan.org Git - redmine.git/commitdiff
Adds issue visibility by role/tracker (#285).
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 5 Jun 2016 11:50:09 +0000 (11:50 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 5 Jun 2016 11:50:09 +0000 (11:50 +0000)
git-svn-id: http://svn.redmine.org/redmine/trunk@15465 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/models/issue.rb
app/views/roles/_form.html.erb
test/unit/issue_test.rb

index 2baaea3f83256bd335bbecba7708e6124caf2ace..91ea73a6fc9c857eddb05396c051e2be4462a840 100644 (file)
@@ -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
 
index 524c273d08d47601aa292ba3b902d0b17c711336..c8a3a61cc487fa628bbc4c8ff6a7aa0f950da0d7 100644 (file)
@@ -64,7 +64,7 @@
 
 <div id="role-permissions-trackers">
 <h3><%= l(:label_issue_tracking) %></h3>
-<% permissions = %w(add_issues) %>
+<% permissions = %w(view_issues add_issues) %>
 <table class="list">
   <thead>
     <tr>
index f7f7003d209dc06a958d458c284b71ae01460fc1..3b7391a3c5a31e8cab5974dadc7853219a2d32cf 100644 (file)
@@ -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)