]> source.dussan.org Git - redmine.git/commitdiff
Assignable users should not include users that cannot view the tracker (#23172).
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Tue, 28 Jun 2016 20:31:08 +0000 (20:31 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Tue, 28 Jun 2016 20:31:08 +0000 (20:31 +0000)
git-svn-id: http://svn.redmine.org/redmine/trunk@15586 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/controllers/context_menus_controller.rb
app/models/issue.rb
app/models/project.rb
app/models/role.rb
test/unit/issue_test.rb

index 66ec35085179b67b1e6987420ce192ba401bf251..dc8e726093bc2bfa5a17c94c4a7bdd83f952960d 100644 (file)
@@ -35,16 +35,8 @@ class ContextMenusController < ApplicationController
             :add_watchers => User.current.allowed_to?(:add_issue_watchers, @projects),
             :delete => @issues.all?(&:deletable?)
             }
-    if @project
-      if @issue
-        @assignables = @issue.assignable_users
-      else
-        @assignables = @project.assignable_users
-      end
-    else
-      #when multiple projects, we only keep the intersection of each set
-      @assignables = @projects.map(&:assignable_users).reduce(:&)
-    end
+
+    @assignables = @issues.map(&:assignable_users).reduce(:&)
     @trackers = @projects.map {|p| Issue.allowed_target_trackers(p) }.reduce(:&)
     @versions = @projects.map {|p| p.shared_versions.open}.reduce(:&)
 
index 9cf29532a514dcd4b6dd627dd80e99b33ca93e81..5b6ae304185228efa7d8618953bc142ab1ae99e6 100644 (file)
@@ -854,7 +854,7 @@ class Issue < ActiveRecord::Base
 
   # Users the issue can be assigned to
   def assignable_users
-    users = project.assignable_users.to_a
+    users = project.assignable_users(tracker).to_a
     users << author if author && author.active?
     users << assigned_to if assigned_to
     users.uniq.sort
index b6bc13dde19d0ad14c59773795dab02d696456ed..c48c54855595152be4eb313951899468ea080144 100644 (file)
@@ -512,16 +512,27 @@ class Project < ActiveRecord::Base
   end
 
   # Return a Principal scope of users/groups issues can be assigned to
-  def assignable_users
+  def assignable_users(tracker=nil)
+    return @assignable_users[tracker] if @assignable_users && @assignable_users[tracker]
+
     types = ['User']
     types << 'Group' if Setting.issue_group_assignment?
 
-    @assignable_users ||= Principal.
+    scope = Principal.
       active.
       joins(:members => :roles).
       where(:type => types, :members => {:project_id => id}, :roles => {:assignable => true}).
       uniq.
       sorted
+
+    if tracker
+      # Rejects users that cannot the view the tracker
+      roles = Role.where(:assignable => true).select {|role| role.permissions_tracker?(:view_issues, tracker)}
+      scope = scope.where(:roles => {:id => roles.map(&:id)})
+    end
+
+    @assignable_users ||= {}
+    @assignable_users[tracker] = scope
   end
 
   # Returns the mail addresses of users that should be always notified on project events
index 89538aa4d8f79690d13e2f6debdea7d387ae2829..86fe73070dad63eb1629a1720dbb856de728f5cd 100644 (file)
@@ -222,6 +222,13 @@ class Role < ActiveRecord::Base
     permissions_all_trackers[permission.to_s].to_s != '0'
   end
 
+  # Returns true if permission is given for the tracker
+  # (explicitly or for all trackers)
+  def permissions_tracker?(permission, tracker)
+    permissions_all_trackers?(permission) ||
+      permissions_tracker_ids?(permission, tracker.try(:id))
+  end
+
   # Sets the trackers that are allowed for a permission.
   # tracker_ids can be an array of tracker ids or :all for
   # no restrictions.
index 3b7391a3c5a31e8cab5974dadc7853219a2d32cf..f27fd1d1eb701c872c4522656b11877a1820c008 100644 (file)
@@ -2292,6 +2292,19 @@ class IssueTest < ActiveSupport::TestCase
     end
   end
 
+  def test_assignable_users_should_not_include_users_that_cannot_view_the_tracker
+    user = User.find(3)
+    role = Role.find(2)
+    role.set_permission_trackers :view_issues, [1, 3]
+    role.save!
+
+    issue1 = Issue.new(:project_id => 1, :tracker_id => 1)
+    issue2 = Issue.new(:project_id => 1, :tracker_id => 2)
+
+    assert_include user, issue1.assignable_users
+    assert_not_include user, issue2.assignable_users
+  end
+
   def test_create_should_send_email_notification
     ActionMailer::Base.deliveries.clear
     issue = Issue.new(:project_id => 1, :tracker_id => 1,