This repository has been archived by the owner on Jun 5, 2019. It is now read-only.
/
watcher_filter.rb
133 lines (116 loc) · 3.95 KB
/
watcher_filter.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#-- encoding: UTF-8
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2017 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See doc/COPYRIGHT.rdoc for more details.
#++
class Queries::WorkPackages::Filter::WatcherFilter <
Queries::WorkPackages::Filter::PrincipalBaseFilter
def allowed_values
@allowed_values ||= begin
# populate the watcher list with the same user list as other user filters
# if the user has the :view_work_package_watchers permission
# in at least one project
# TODO: this could be differentiated
# more, e.g. all users could watch issues in public projects,
# but won't necessarily be shown here
values = me_value
if User.current.allowed_to?(:view_work_package_watchers, project, global: project.nil?)
values += principal_loader.user_values
end
values
end
end
def type
:list
end
def order
15
end
def self.key
:watcher_id
end
def where
if User.current.admin?
# Admins can always see all watchers
where_any_watcher
else
where_allowed_watchers
end
end
private
def where_any_watcher
db_table = Watcher.table_name
db_field = 'user_id'
<<-SQL
#{WorkPackage.table_name}.id #{operator == '=' ? 'IN' : 'NOT IN'}
(SELECT #{db_table}.watchable_id
FROM #{db_table}
WHERE #{db_table}.watchable_type='WorkPackage'
AND #{::Queries::Operators::Equals.sql_for_field values_replaced, db_table, db_field})
SQL
end
def where_allowed_watchers
sql_parts = []
if User.current.logged? && user_id = values_replaced.delete(User.current.id.to_s)
# a user can always see his own watched issues
sql_parts << where_self_watcher(user_id)
end
# filter watchers only in projects the user has the permission to view watchers in
sql_parts << where_watcher_in_view_watchers_allowed
sql_parts.join(' OR ')
end
def where_self_watcher(user_id)
<<-SQL
#{WorkPackage.table_name}.id #{operator == '=' ? 'IN' : 'NOT IN'}
(SELECT #{db_table}.watchable_id
FROM #{db_table}
WHERE #{db_table}.watchable_type='WorkPackage'
AND #{::Queries::Operators::Equals.sql_for_field [user_id], db_table, db_field})
SQL
end
def where_watcher_in_view_watchers_allowed
<<-SQL
#{WorkPackage.table_name}.id #{operator == '=' ? 'IN' : 'NOT IN'}
(SELECT #{db_table}.watchable_id
FROM #{db_table}
WHERE #{db_table}.watchable_type='WorkPackage'
AND #{::Queries::Operators::Equals.sql_for_field values_replaced, db_table, db_field})
AND #{Project.table_name}.id IN
(#{view_watcher_allowed_scoped.to_sql})
SQL
end
def db_table
Watcher.table_name
end
def db_field
'user_id'
end
def view_watcher_allowed_scoped
Project
.allowed_to(User.current, :view_work_package_watchers)
.select("#{Project.table_name}.id")
end
end