diff options
-rw-r--r-- | app/models/issue_query.rb | 22 | ||||
-rw-r--r-- | test/unit/query_test.rb | 32 |
2 files changed, 52 insertions, 2 deletions
diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index 417b98b2a..7539f427a 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -417,8 +417,26 @@ class IssueQuery < Query def sql_for_watcher_id_field(field, operator, value) db_table = Watcher.table_name - "#{Issue.table_name}.id #{ operator == '=' ? 'IN' : 'NOT IN' } (SELECT #{db_table}.watchable_id FROM #{db_table} WHERE #{db_table}.watchable_type='Issue' AND " + - sql_for_field(field, '=', value, db_table, 'user_id') + ')' + + me, others = value.partition { |id| ['0', User.current.id.to_s].include?(id) } + sql = if others.any? + "SELECT #{Issue.table_name}.id FROM #{Issue.table_name} " + + "INNER JOIN #{db_table} ON #{Issue.table_name}.id = #{db_table}.watchable_id AND #{db_table}.watchable_type = 'Issue' " + + "LEFT OUTER JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Issue.table_name}.project_id " + + "WHERE (" + + sql_for_field(field, '=', me, db_table, 'user_id') + + ') OR (' + + Project.allowed_to_condition(User.current, :view_issue_watchers) + + ' AND ' + + sql_for_field(field, '=', others, db_table, 'user_id') + + ')' + else + "SELECT #{db_table}.watchable_id FROM #{db_table} " + + "WHERE #{db_table}.watchable_type='Issue' AND " + + sql_for_field(field, '=', me, db_table, 'user_id') + end + + "#{Issue.table_name}.id #{ operator == '=' ? 'IN' : 'NOT IN' } (#{sql})" end def sql_for_member_of_group_field(field, operator, value) diff --git a/test/unit/query_test.rb b/test/unit/query_test.rb index 9e4c76417..54b96ea40 100644 --- a/test/unit/query_test.rb +++ b/test/unit/query_test.rb @@ -746,6 +746,38 @@ class QueryTest < ActiveSupport::TestCase User.current = nil end + def test_filter_on_watched_issues_with_view_issue_watchers_permission + User.current = User.find(1) + User.current.admin = true + assert User.current.allowed_to?(:view_issue_watchers, Project.find(1)) + + Issue.find(1).add_watcher User.current + Issue.find(3).add_watcher User.find(3) + query = IssueQuery.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me', '3']}}) + result = find_issues_with_query(query) + assert_includes result, Issue.find(1) + assert_includes result, Issue.find(3) + ensure + User.current.reload + User.current = nil + end + + def test_filter_on_watched_issues_without_view_issue_watchers_permission + User.current = User.find(1) + User.current.admin = false + assert !User.current.allowed_to?(:view_issue_watchers, Project.find(1)) + + Issue.find(1).add_watcher User.current + Issue.find(3).add_watcher User.find(3) + query = IssueQuery.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me', '3']}}) + result = find_issues_with_query(query) + assert_includes result, Issue.find(1) + assert_not_includes result, Issue.find(3) + ensure + User.current.reload + User.current = nil + end + def test_filter_on_custom_field_should_ignore_projects_with_field_disabled field = IssueCustomField.generate!(:trackers => Tracker.all, :project_ids => [1, 3, 4], :is_for_all => false, :is_filter => true) Issue.generate!(:project_id => 3, :tracker_id => 2, :custom_field_values => {field.id.to_s => 'Foo'}) |