From 97fe88f8d96cae92be67b7c85d00e21264f11ce1 Mon Sep 17 00:00:00 2001 From: Eric Davis Date: Tue, 14 Dec 2010 09:11:48 -0800 Subject: [PATCH] [#805] Add the Watchers sidebar to Wiki Pages --- app/controllers/watchers_controller.rb | 27 +++++- app/views/watchers/_watchers.rhtml | 4 +- app/views/wiki/show.rhtml | 8 ++ lib/redmine.rb | 3 + test/fixtures/roles.yml | 3 + test/functional/watchers_controller_test.rb | 96 ++++++++++++++++++++- 6 files changed, 137 insertions(+), 4 deletions(-) diff --git a/app/controllers/watchers_controller.rb b/app/controllers/watchers_controller.rb index 2325634a..2f596caf 100644 --- a/app/controllers/watchers_controller.rb +++ b/app/controllers/watchers_controller.rb @@ -16,7 +16,8 @@ class WatchersController < ApplicationController before_filter :find_project before_filter :require_login, :check_project_privacy, :only => [:watch, :unwatch] before_filter :authorize, :only => [:new, :destroy] - + before_filter :authorize_access_to_object, :only => [:new, :destroy] + verify :method => :post, :only => [ :watch, :unwatch ], :render => { :nothing => true, :status => :method_not_allowed } @@ -97,4 +98,28 @@ private rescue ::ActionController::RedirectBackError render :text => (watching ? 'Watcher added.' : 'Watcher removed.'), :layout => true end + + def authorize_access_to_object + allowed = false + + case @watched.class.to_s + when "Issue" + if params[:action] == 'new' + allowed = true if User.current.allowed_to?(:add_issue_watchers, @project) + end + if params[:action] == 'destroy' + allowed = true if User.current.allowed_to?(:delete_issue_watchers, @project) + end + when "WikiPage" + if params[:action] == 'new' + allowed = true if User.current.allowed_to?(:add_wiki_page_watchers, @project) + end + if params[:action] == 'destroy' + allowed = true if User.current.allowed_to?(:delete_wiki_page_watchers, @project) + end + end + + deny_access unless allowed + end + end diff --git a/app/views/watchers/_watchers.rhtml b/app/views/watchers/_watchers.rhtml index 00b4954c..838b49f1 100644 --- a/app/views/watchers/_watchers.rhtml +++ b/app/views/watchers/_watchers.rhtml @@ -1,10 +1,10 @@
-<%= link_to_function(l(:button_add), "$('new-watcher-form').toggle();") if User.current.allowed_to?(:add_issue_watchers, @project) %> +<%= link_to_function(l(:button_add), "$('new-watcher-form').toggle();") if User.current.allowed_to?("add_#{watched.class.name.underscore}_watchers".to_sym, @project) %>

<%= l(:label_issue_watchers) %> (<%= watched.watcher_users.size %>)

-<% if User.current.allowed_to?(:add_issue_watchers, @project) %> +<% if User.current.allowed_to?("add_#{watched.class.name.underscore}_watchers".to_sym, @project) %> <% remote_form_for(:watcher, @watcher, :url => {:controller => 'watchers', :action => 'new', diff --git a/app/views/wiki/show.rhtml b/app/views/wiki/show.rhtml index c144fb1d..b2d7e2d2 100644 --- a/app/views/wiki/show.rhtml +++ b/app/views/wiki/show.rhtml @@ -59,6 +59,14 @@ <% content_for :sidebar do %> <%= render :partial => 'wiki/sidebar' %> + + <% if User.current.allowed_to?(:add_wiki_page_watchers, @project) || + (@page.watchers.present? && User.current.allowed_to?(:view_wiki_page_watchers, @project)) %> +
+ <%= render :partial => 'watchers/watchers', :locals => {:watched => @page} %> +
+ <% end %> + <% end %> <% html_title h(@page.pretty_title) %> diff --git a/lib/redmine.rb b/lib/redmine.rb index ec5a2618..7ed95c9e 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -136,6 +136,9 @@ Redmine::AccessControl.map do |map| map.permission :edit_wiki_pages, :wiki => [:edit, :update, :preview, :add_attachment] map.permission :delete_wiki_pages_attachments, {} map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member + map.permission :view_wiki_page_watchers, {} + map.permission :add_wiki_page_watchers, {:watchers => :new} + map.permission :delete_wiki_page_watchers, {:watchers => :destroy} end map.project_module :repository do |map| diff --git a/test/fixtures/roles.yml b/test/fixtures/roles.yml index 2f287e1b..5fc52b67 100644 --- a/test/fixtures/roles.yml +++ b/test/fixtures/roles.yml @@ -45,6 +45,9 @@ roles_001: - :protect_wiki_pages - :delete_wiki_pages - :rename_wiki_pages + - :view_wiki_page_watchers + - :add_wiki_page_watchers + - :delete_wiki_page_watchers - :add_messages - :edit_messages - :delete_messages diff --git a/test/functional/watchers_controller_test.rb b/test/functional/watchers_controller_test.rb index ad839bac..3e4f63cf 100644 --- a/test/functional/watchers_controller_test.rb +++ b/test/functional/watchers_controller_test.rb @@ -19,7 +19,8 @@ class WatchersController; def rescue_action(e) raise e end; end class WatchersControllerTest < ActionController::TestCase fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, - :issues, :trackers, :projects_trackers, :issue_statuses, :enumerations, :watchers + :issues, :trackers, :projects_trackers, :issue_statuses, :enumerations, :watchers, + :wikis, :wiki_pages def setup @controller = WatchersController.new @@ -145,9 +146,58 @@ class WatchersControllerTest < ActionController::TestCase end assert Issue.find(2).watched_by?(@group) end + + end + + def test_new_multiple_users_watching_wiki_page + Role.find(1).add_permission! :add_wiki_page_watchers + + @request.session[:user_id] = 2 + @page = WikiPage.find(1) + assert !@page.watched_by?(User.find(2)) + assert !@page.watched_by?(User.find(4)) + assert !@page.watched_by?(User.find(7)) + + assert_difference('Watcher.count', 3) do + xhr :post, :new, :object_type => 'wiki_page', :object_id => '1', :user_ids => ['2','4','7'] + assert_response :success + assert_select_rjs :replace_html, 'watchers' + end + @page.reload + assert @page.watched_by?(User.find(2)) + assert @page.watched_by?(User.find(4)) + assert @page.watched_by?(User.find(7)) + end + + def test_new_issue_watcher_without_permission + Role.find(1).remove_permission! :add_issue_watchers + + @request.session[:user_id] = 2 + assert_difference('Watcher.count',0) do + xhr :post, :new, :object_type => 'issue', :object_id => '2', :user_ids => ['4'] + assert_response :forbidden + end + assert !Issue.find(2).watched_by?(User.find(4)) + + end + + def test_remove_wiki_page_watcher_without_permission + Role.find(1).remove_permission! :delete_wiki_page_watchers + + @request.session[:user_id] = 2 + @page = WikiPage.find(1) + + assert_difference('Watcher.count',0) do + xhr :post, :new, :object_type => 'wiki_page', :object_id => '1', :user_ids => ['2'] + assert_response :forbidden + end + assert !WikiPage.find(1).watched_by?(User.find(2)) + end def test_remove_watcher + Role.find(1).add_permission! :delete_issue_watchers + @request.session[:user_id] = 2 assert_difference('Watcher.count', -1) do xhr :post, :destroy, :object_type => 'issue', :object_id => '2', :user_id => '3' @@ -175,4 +225,48 @@ class WatchersControllerTest < ActionController::TestCase end + def test_remove_wiki_page_watcher + Role.find(1).add_permission! :delete_wiki_page_watchers + + @request.session[:user_id] = 2 + @page = WikiPage.find(1) + Watcher.create!(:user_id => 2, :watchable => @page) + assert @page.watched_by?(User.find(2)) + + assert_difference('Watcher.count', -1) do + xhr :post, :destroy, :object_type => 'wiki_page', :object_id => '1', :user_id => '2' + assert_response :success + assert_select_rjs :replace_html, 'watchers' + end + assert !WikiPage.find(1).watched_by?(User.find(2)) + end + + def test_remove_issue_watcher_without_permission + Role.find(1).remove_permission! :delete_issue_watchers + + @request.session[:user_id] = 2 + assert_difference('Watcher.count',0) do + xhr :post, :destroy, :object_type => 'issue', :object_id => '2', :user_id => '3' + assert_response :forbidden + end + assert Issue.find(2).watched_by?(User.find(3)) + + end + + def test_remove_wiki_page_watcher_without_permission + Role.find(1).remove_permission! :delete_wiki_page_watchers + + @request.session[:user_id] = 2 + @page = WikiPage.find(1) + Watcher.create!(:user_id => 2, :watchable => @page) + assert @page.watched_by?(User.find(2)) + + assert_difference('Watcher.count',0) do + xhr :post, :destroy, :object_type => 'wiki_page', :object_id => '1', :user_id => '2' + assert_response :forbidden + end + assert WikiPage.find(1).watched_by?(User.find(2)) + + end + end