Browse Source

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

git-svn-id: http://svn.redmine.org/redmine/trunk@15465 e93f8b46-1217-0410-a6f0-8f06a7374b81
tags/3.4.0
Jean-Philippe Lang 8 years ago
parent
commit
a23450fe08
3 changed files with 80 additions and 4 deletions
  1. 16
    3
      app/models/issue.rb
  2. 1
    1
      app/views/roles/_form.html.erb
  3. 63
    0
      test/unit/issue_test.rb

+ 16
- 3
app/models/issue.rb View 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


+ 1
- 1
app/views/roles/_form.html.erb View 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>

+ 63
- 0
test/unit/issue_test.rb View 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)

Loading…
Cancel
Save