Patch #14318 » allow_watchers_and_contributers_access_to_issues_4.2.2.patch
| app/models/issue.rb | ||
|---|---|---|
| 135 | 135 |             "(#{table_name}.is_private = #{connection.quoted_false} " \ | 
| 136 | 136 |               "OR #{table_name}.author_id = #{user.id} " \ | 
| 137 | 137 |               "OR #{table_name}.assigned_to_id IN (#{user_ids.join(',')}))" | 
| 138 | when 'own_watch' | |
| 139 | user_ids = [user.id] + user.groups.pluck(:id) | |
| 140 |             "(#{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'))" | |
| 141 | when 'own_watch_contributed' | |
| 142 | user_ids = [user.id] + user.groups.pluck(:id) | |
| 143 |           "(#{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))" | |
| 138 | 144 | when 'own' | 
| 139 | 145 | user_ids = [user.id] + user.groups.pluck(:id).compact | 
| 140 | 146 |             "(#{table_name}.author_id = #{user.id} OR " \ | 
| ... | ... | |
| 169 | 175 | !self.is_private? || (self.author == user || user.is_or_belongs_to?(assigned_to)) | 
| 170 | 176 | when 'own' | 
| 171 | 177 | self.author == user || user.is_or_belongs_to?(assigned_to) | 
| 178 | when 'own_watch' | |
| 179 | self.author == user || user.is_or_belongs_to?(assigned_to) || self.watched_by?(user) | |
| 180 | when 'own_watch_contributed' | |
| 181 |             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 | |
| 172 | 182 | else | 
| 173 | 183 | false | 
| 174 | 184 | 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 | ||
|---|---|---|
| 501 | 501 | setting_new_item_menu_tab: Project menu tab for creating new objects | 
| 502 | 502 | setting_commit_logs_formatting: Apply text formatting to commit messages | 
| 503 | 503 | setting_timelog_required_fields: Required fields for time logs | 
| 504 | setting_enable_watcher_issue_visibility: Enable watcher issue visibility | |
| 504 | 505 | setting_close_duplicate_issues: Close duplicate issues automatically | 
| 505 | 506 | setting_time_entry_list_defaults: Timelog list defaults | 
| 506 | 507 | setting_timelog_accept_0_hours: Accept time logs with 0 hours | 
| ... | ... | |
| 1121 | 1122 | label_display_type_board: Board | 
| 1122 | 1123 | label_my_bookmarks: My bookmarks | 
| 1123 | 1124 | label_assign_to_me: Assign to me | 
| 1124 | ||
| 1125 | label_issues_visibility_own_watch: Issues created by, assigned to, or watched by the user | |
| 1126 | label_issues_visibility_own_watch_contributed: Issues created by, assigned to, watched by, or contributed to by the user | |
| 1125 | 1127 | button_login: Login | 
| 1126 | 1128 | button_submit: Submit | 
| 1127 | 1129 | button_save: Save | 
| test/unit/issue_test.rb | ||
|---|---|---|
| 292 | 292 | assert_visibility_match user, issues | 
| 293 | 293 | end | 
| 294 | 294 | |
| 295 | def test_visible_scope_for_non_member_with_own_watch_issues_visibility | |
| 296 | #Role.non_member.add_permission! :view_issues | |
| 297 | Role.non_member.update! :issues_visibility, 'own_watch' | |
| 298 | user = User.find(9) | |
| 299 | assert user.projects.empty? | |
| 300 | own_issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => user.id, :subject => 'Issue by non member') | |
| 301 | watching_issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'Issue watched by non member') | |
| 302 | watching_issue.add_watcher(user) | |
| 303 | ||
| 304 | #assert_equal true, own_issue.visible?(user) | |
| 305 | #assert_equal true, watching_issue.visible?(user) | |
| 306 | assert_visibility_match user, [own_issue, watching_issue] | |
| 307 | end | |
| 308 | ||
| 309 | def test_visible_scope_for_non_member_with_own_watch_contributed_issues_visibility | |
| 310 | #Role.non_member.add_permission! :view_issues | |
| 311 | Role.non_member.update! :issues_visibility, 'own_watch_contributed' | |
| 312 | user = User.find(9) | |
| 313 | assert user.projects.empty? | |
| 314 | own_issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => user.id, :subject => 'Issue by non member') | |
| 315 | watching_issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'Issue watched by non member') | |
| 316 | watching_issue.add_watcher(user) | |
| 317 | watching_issue.reload | |
| 318 | contributed_issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'Issue contributed by non member') | |
| 319 | journal = contributed_issue.init_journal(user) | |
| 320 | journal.notes = 'journal notes' | |
| 321 | journal.save! | |
| 322 | ||
| 323 | #assert_equal true, own_issue.visible?(user) | |
| 324 | #assert_equal true, watching_issue.visible?(user) | |
| 325 | #assert_equal true, contributed_issue.visible?(user) | |
| 326 | assert_visibility_match user, [own_issue, watching_issue, contributed_issue] | |
| 327 | end | |
| 295 | 328 | def test_visible_scope_for_non_member_without_view_issues_permissions | 
| 296 | 329 | # Non member user should not see issues without permission | 
| 297 | 330 | Role.non_member.remove_permission!(:view_issues) | 
| ... | ... | |
| 370 | 403 | :assigned_to => group, | 
| 371 | 404 | :is_private => true) | 
| 372 | 405 | |
| 373 | Role.find(2).update! :issues_visibility => 'default' | |
| 374 | issues = Issue.visible(User.find(8)).to_a | |
| 375 | assert issues.any? | |
| 376 | assert issues.include?(issue) | |
| 406 | ['default', 'own', 'own_watch', 'own_watch_contributed'].each do |issue_visibility| | |
| 407 | Role.find(2).update! :issues_visibility => issue_visibility | |
| 408 | issues = Issue.visible(User.find(8)).to_a | |
| 409 | assert issues.any? | |
| 410 | assert issues.include?(issue) | |
| 411 | end | |
| 412 | end | |
| 413 | end | |
| 377 | 414 | |
| 378 | Role.find(2).update! :issues_visibility => 'own' | |
| 379 | issues = Issue.visible(User.find(8)).to_a | |
| 415 | def test_visible_scope_for_non_member_and_watcher_should_return_watching_issues | |
| 416 | user = User.find(9) | |
| 417 | assert user.projects.empty? | |
| 418 | Role.non_member.add_permission!(:view_issues) | |
| 419 | ||
| 420 | issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'Issue visible to watcher', :is_private => true) | |
| 421 | issue.add_watcher(user) | |
| 422 | ||
| 423 | ['own_watch', 'own_watch_contributed'].each do |issue_visibility| | |
| 424 | Role.non_member.update! :issues_visibility => issue_visibility | |
| 425 | issues = Issue.visible(user).to_a | |
| 380 | 426 | assert issues.any? | 
| 381 |       assert_include issue, issues | |
| 427 |       assert issues.include?(issue) | |
| 382 | 428 | end | 
| 383 | 429 | end | 
| 384 | 430 | |
| 431 | def test_visible_scope_for_non_member_and_contributer_should_return_contributing_issues | |
| 432 | user = User.find(9) | |
| 433 | assert user.projects.empty? | |
| 434 | Role.non_member.add_permission!(:view_issues) | |
| 435 | ||
| 436 | issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'Issue visible to watcher', :is_private => true) | |
| 437 | journal = issue.init_journal(user) | |
| 438 | journal.notes = 'journal notes' | |
| 439 | journal.save! | |
| 440 | ||
| 441 | Role.non_member.update! :issues_visibility, 'own_watch_contributed' | |
| 442 | issues = Issue.visible(user).to_a | |
| 443 | end | |
| 444 | ||
| 385 | 445 | def test_visible_scope_for_member_with_limited_tracker_ids | 
| 386 | 446 | role = Role.find(1) | 
| 387 | 447 | role.set_permission_trackers :view_issues, [2] |