Commit 9f9f560f authored by jplang's avatar jplang

Adds issue visibility by role/tracker (#285).

git-svn-id: https://svn.redmine.org/redmine/trunk@15465 e93f8b46-1217-0410-a6f0-8f06a7374b81
parent 7dfe28cc
......@@ -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
......
......@@ -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>
......
......@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment