From 390facab54ff62dc3954c1b5bc986493f5ad5723 Mon Sep 17 00:00:00 2001 From: Holger Just Date: Thu, 12 May 2022 18:42:07 +0200 Subject: [PATCH] Respect group memberships when checking if an object is watched #37065 --- .../lib/acts_as_watchable.rb | 22 ++++++++++++++----- test/unit/watcher_test.rb | 15 ++++++++++++- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb b/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb index bb71a2884b..907535ec7a 100644 --- a/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb +++ b/lib/plugins/acts_as_watchable/lib/acts_as_watchable.rb @@ -15,9 +15,13 @@ def acts_as_watchable(options = {}) has_many :watchers, :as => :watchable, :dependent => :delete_all has_many :watcher_users, :through => :watchers, :source => :user, :validate => false - scope :watched_by, lambda { |user_id| + scope :watched_by, lambda { |principal| + user_ids = Array(principal.id) + user_ids |= principal.group_ids if principal.is_a?(User) + user_ids.compact! + joins(:watchers). - where("#{Watcher.table_name}.user_id = ?", user_id) + where("#{Watcher.table_name}.user_id IN (?)", user_ids) } end send :include, Redmine::Acts::Watchable::InstanceMethods @@ -66,9 +70,17 @@ def watcher_user_ids=(user_ids) super user_ids end - # Returns true if object is watched by +user+ - def watched_by?(user) - !!(user && self.watcher_user_ids.detect {|uid| uid == user.id }) + # Returns true if object is watched by +principal+, that is + # either by a given group, + # or by a given user or any of their groups + def watched_by?(principal) + return false unless principal + + user_ids = Array(principal.id) + user_ids |= principal.group_ids if principal.is_a?(User) + user_ids.compact! + + (self.watcher_user_ids & user_ids).any? end def notified_watchers diff --git a/test/unit/watcher_test.rb b/test/unit/watcher_test.rb index 1638f4fcbb..a2de4c1920 100644 --- a/test/unit/watcher_test.rb +++ b/test/unit/watcher_test.rb @@ -20,7 +20,7 @@ require File.expand_path('../../test_helper', __FILE__) class WatcherTest < ActiveSupport::TestCase - fixtures :projects, :users, :email_addresses, :members, :member_roles, :roles, :enabled_modules, + fixtures :projects, :groups_users, :users, :email_addresses, :members, :member_roles, :roles, :enabled_modules, :issues, :issue_statuses, :enumerations, :trackers, :projects_trackers, :boards, :messages, :wikis, :wiki_pages, @@ -60,6 +60,19 @@ def test_watched_by assert Issue.watched_by(@user).include?(@issue) end + def test_watched_by_group + group = Group.find(10) + user = User.find(8) + assert @issue.add_watcher(group) + @issue.reload + + assert @issue.watched_by?(group) + assert Issue.watched_by(group).include?(@issue) + + assert @issue.watched_by?(user) + assert Issue.watched_by(user).include?(@issue) + end + def test_watcher_users watcher_users = Issue.find(2).watcher_users assert_kind_of Array, watcher_users.collect{|w| w} -- 2.34.0