diff --git a/app/controllers/watchers_controller.rb b/app/controllers/watchers_controller.rb index b4efa10e9..a446d6410 100644 --- a/app/controllers/watchers_controller.rb +++ b/app/controllers/watchers_controller.rb @@ -41,6 +41,8 @@ class WatchersController < ApplicationController end def create + return unless authorize_for_watchable_type(:add) + user_ids = [] if params[:watcher] user_ids << (params[:watcher][:user_ids] || params[:watcher][:user_id]) @@ -76,6 +78,8 @@ class WatchersController < ApplicationController end def destroy + return unless authorize_for_watchable_type(:delete) + user = Principal.find(params[:user_id]) @watchables.each do |watchable| watchable.set_watcher(user, false) @@ -228,4 +232,14 @@ class WatchersController < ApplicationController objects end + + # Check permission for the watchable type for each watchable involved + def authorize_for_watchable_type(action) + if @watchables.any?{|watchable| !User.current.allowed_to?(:"#{action}_#{watchable.class.name.underscore}_watchers", watchable.project)} + render_403 + return false + else + return true + end + end end diff --git a/test/functional/watchers_controller_test.rb b/test/functional/watchers_controller_test.rb index 65aad4e1f..ed3c25770 100644 --- a/test/functional/watchers_controller_test.rb +++ b/test/functional/watchers_controller_test.rb @@ -578,6 +578,41 @@ class WatchersControllerTest < Redmine::ControllerTest assert !wiki_page.watched_by?(user) end + def test_destroy_without_permission + @request.session[:user_id] = 2 + wiki_page = WikiPage.find(1) + user = User.find(1) + Role.find(1).remove_permission! :delete_wiki_page_watchers + + assert wiki_page.watched_by?(user) + assert_no_difference('Watcher.count') do + delete :destroy, :params => { + :object_type => 'wiki_page', :object_id => '1', :user_id => '1' + }, :xhr => true + assert_response 403 + end + wiki_page.reload + assert wiki_page.watched_by?(user) + end + + def test_create_without_permission + @request.session[:user_id] = 2 + wiki_page = WikiPage.find(1) + user = User.find(1) + Role.find(1).remove_permission! :add_wiki_page_watchers + Watcher.delete_all + + assert_not wiki_page.watched_by?(user) + assert_no_difference('Watcher.count') do + post :create, :params => { + :object_type => 'wiki_page', :object_id => '1', :user_id => '1' + }, :xhr => true + assert_response 403 + end + wiki_page.reload + assert_not wiki_page.watched_by?(user) + end + def test_destroy_locked_user user = User.find(3) user.lock!