Patch #14318 » allow_watchers_and_contributers_access_to_issues_4.1.0.patch
app/models/issue.rb | ||
---|---|---|
128 | 128 |
when 'default' |
129 | 129 |
user_ids = [user.id] + user.groups.pluck(:id).compact |
130 | 130 |
"(#{table_name}.is_private = #{connection.quoted_false} OR #{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id IN (#{user_ids.join(',')}))" |
131 |
when 'own_watch' |
|
132 |
user_ids = [user.id] + user.groups.pluck(:id) |
|
133 |
"(#{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id IN (#{user_ids.join(',')}) OR #{table_name}.id IN (SELECT watchable_id FROM watchers WHERE user_id=#{user.id} AND watchable_type = 'Issue'))" |
|
134 |
when 'own_watch_contributed' |
|
135 |
user_ids = [user.id] + user.groups.pluck(:id) |
|
136 |
"(#{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id IN (#{user_ids.join(',')}) OR #{table_name}.id IN (SELECT watchable_id FROM watchers WHERE user_id=#{user.id} AND watchable_type = 'Issue') OR #{table_name}.id IN (SELECT journalized_id FROM journals where journalized_type = 'Issue' AND user_id=#{user.id} GROUP BY journalized_id))" |
|
131 | 137 |
when 'own' |
132 | 138 |
user_ids = [user.id] + user.groups.pluck(:id).compact |
133 | 139 |
"(#{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id IN (#{user_ids.join(',')}))" |
... | ... | |
161 | 167 |
!self.is_private? || (self.author == user || user.is_or_belongs_to?(assigned_to)) |
162 | 168 |
when 'own' |
163 | 169 |
self.author == user || user.is_or_belongs_to?(assigned_to) |
170 |
when 'own_watch' |
|
171 |
self.author == user || user.is_or_belongs_to?(assigned_to) || self.watched_by?(user) |
|
172 |
when 'own_watch_contributed' |
|
173 |
self.author == user || user.is_or_belongs_to?(assigned_to) || self.watched_by?(user) || self.journals.where('journalized_id = ?', self.id).where('user_id = ?', user).count > 0 |
|
164 | 174 |
else |
165 | 175 |
false |
166 | 176 |
end |
app/models/role.rb | ||
---|---|---|
40 | 40 |
ISSUES_VISIBILITY_OPTIONS = [ |
41 | 41 |
['all', :label_issues_visibility_all], |
42 | 42 |
['default', :label_issues_visibility_public], |
43 |
['own', :label_issues_visibility_own] |
|
43 |
['own', :label_issues_visibility_own], |
|
44 |
['own_watch', :label_issues_visibility_own_watch], |
|
45 |
['own_watch_contributed', :label_issues_visibility_own_watch_contributed] |
|
44 | 46 |
] |
45 | 47 | |
46 | 48 |
TIME_ENTRIES_VISIBILITY_OPTIONS = [ |
config/locales/en.yml | ||
---|---|---|
479 | 479 |
setting_new_item_menu_tab: Project menu tab for creating new objects |
480 | 480 |
setting_commit_logs_formatting: Apply text formatting to commit messages |
481 | 481 |
setting_timelog_required_fields: Required fields for time logs |
482 |
setting_enable_watcher_issue_visibility: Enable watcher issue visibility |
|
482 | 483 |
setting_close_duplicate_issues: Close duplicate issues automatically |
483 | 484 |
setting_time_entry_list_defaults: Timelog list defaults |
484 | 485 |
setting_timelog_accept_0_hours: Accept time logs with 0 hours |
... | ... | |
1080 | 1081 |
label_display_type_list: List |
1081 | 1082 |
label_display_type_board: Board |
1082 | 1083 |
label_my_bookmarks: My bookmarks |
1083 | ||
1084 |
label_issues_visibility_own_watch: Issues created by, assigned to, or watched by the user |
|
1085 |
label_issues_visibility_own_watch_contributed: Issues created by, assigned to, watched by, or contributed to by the user |
|
1086 |
|
|
1084 | 1087 |
button_login: Login |
1085 | 1088 |
button_submit: Submit |
1086 | 1089 |
button_save: Save |
test/unit/issue_test.rb | ||
---|---|---|
281 | 281 |
assert_visibility_match user, issues |
282 | 282 |
end |
283 | 283 | |
284 |
def test_visible_scope_for_non_member_with_own_watch_issues_visibility |
|
285 |
#Role.non_member.add_permission! :view_issues |
|
286 |
Role.non_member.update! :issues_visibility, 'own_watch' |
|
287 |
user = User.find(9) |
|
288 |
assert user.projects.empty? |
|
289 |
own_issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => user.id, :subject => 'Issue by non member') |
|
290 |
watching_issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'Issue watched by non member') |
|
291 |
watching_issue.add_watcher(user) |
|
292 | ||
293 |
#assert_equal true, own_issue.visible?(user) |
|
294 |
#assert_equal true, watching_issue.visible?(user) |
|
295 |
assert_visibility_match user, [own_issue, watching_issue] |
|
296 |
end |
|
297 | ||
298 |
def test_visible_scope_for_non_member_with_own_watch_contributed_issues_visibility |
|
299 |
#Role.non_member.add_permission! :view_issues |
|
300 |
Role.non_member.update! :issues_visibility, 'own_watch_contributed' |
|
301 |
user = User.find(9) |
|
302 |
assert user.projects.empty? |
|
303 |
own_issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => user.id, :subject => 'Issue by non member') |
|
304 |
watching_issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'Issue watched by non member') |
|
305 |
watching_issue.add_watcher(user) |
|
306 |
watching_issue.reload |
|
307 |
contributed_issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'Issue contributed by non member') |
|
308 |
journal = contributed_issue.init_journal(user) |
|
309 |
journal.notes = 'journal notes' |
|
310 |
journal.save! |
|
311 | ||
312 |
#assert_equal true, own_issue.visible?(user) |
|
313 |
#assert_equal true, watching_issue.visible?(user) |
|
314 |
#assert_equal true, contributed_issue.visible?(user) |
|
315 |
assert_visibility_match user, [own_issue, watching_issue, contributed_issue] |
|
316 |
end |
|
284 | 317 |
def test_visible_scope_for_non_member_without_view_issues_permissions |
285 | 318 |
# Non member user should not see issues without permission |
286 | 319 |
Role.non_member.remove_permission!(:view_issues) |
... | ... | |
359 | 392 |
:assigned_to => group, |
360 | 393 |
:is_private => true) |
361 | 394 | |
362 |
Role.find(2).update! :issues_visibility => 'default' |
|
363 |
issues = Issue.visible(User.find(8)).to_a |
|
364 |
assert issues.any? |
|
365 |
assert issues.include?(issue) |
|
395 |
['default', 'own', 'own_watch', 'own_watch_contributed'].each do |issue_visibility| |
|
396 |
Role.find(2).update! :issues_visibility => issue_visibility |
|
397 |
issues = Issue.visible(User.find(8)).to_a |
|
398 |
assert issues.any? |
|
399 |
assert issues.include?(issue) |
|
400 |
end |
|
401 |
end |
|
402 |
end |
|
366 | 403 | |
367 |
Role.find(2).update! :issues_visibility => 'own' |
|
368 |
issues = Issue.visible(User.find(8)).to_a |
|
404 |
def test_visible_scope_for_non_member_and_watcher_should_return_watching_issues |
|
405 |
user = User.find(9) |
|
406 |
assert user.projects.empty? |
|
407 |
Role.non_member.add_permission!(:view_issues) |
|
408 | ||
409 |
issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'Issue visible to watcher', :is_private => true) |
|
410 |
issue.add_watcher(user) |
|
411 | ||
412 |
['own_watch', 'own_watch_contributed'].each do |issue_visibility| |
|
413 |
Role.non_member.update! :issues_visibility => issue_visibility |
|
414 |
issues = Issue.visible(user).to_a |
|
369 | 415 |
assert issues.any? |
370 |
assert_include issue, issues
|
|
416 |
assert issues.include?(issue)
|
|
371 | 417 |
end |
372 | 418 |
end |
373 | 419 | |
420 |
def test_visible_scope_for_non_member_and_contributer_should_return_contributing_issues |
|
421 |
user = User.find(9) |
|
422 |
assert user.projects.empty? |
|
423 |
Role.non_member.add_permission!(:view_issues) |
|
424 | ||
425 |
issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'Issue visible to watcher', :is_private => true) |
|
426 |
journal = issue.init_journal(user) |
|
427 |
journal.notes = 'journal notes' |
|
428 |
journal.save! |
|
429 | ||
430 |
Role.non_member.update! :issues_visibility, 'own_watch_contributed' |
|
431 |
issues = Issue.visible(user).to_a |
|
432 |
end |
|
433 | ||
374 | 434 |
def test_visible_scope_for_member_with_limited_tracker_ids |
375 | 435 |
role = Role.find(1) |
376 | 436 |
role.set_permission_trackers :view_issues, [2] |