From 23692e2962b37e07da84c91b1b6ee9a39031604d Mon Sep 17 00:00:00 2001 From: Kevin Fischer Date: Mon, 15 Feb 2021 11:46:51 +0900 Subject: [PATCH 1/6] Show links to delete redirect (no function) --- app/controllers/wiki_controller.rb | 1 + app/views/wiki/show.html.erb | 3 +++ test/functional/wiki_controller_test.rb | 22 ++++++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index 2669c60e6..4b634fd0b 100644 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -118,6 +118,7 @@ def show @content.current_version? && Redmine::WikiFormatting.supports_section_edit? + @redirects_to_self = WikiRedirect.where(:redirects_to => @page.title, :redirects_to_wiki_id => @page.wiki_id) respond_to do |format| format.html format.api diff --git a/app/views/wiki/show.html.erb b/app/views/wiki/show.html.erb index 6a0245809..64075b2ec 100644 --- a/app/views/wiki/show.html.erb +++ b/app/views/wiki/show.html.erb @@ -15,6 +15,9 @@ <%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :id => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? %> <%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %> <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') %> + <% @redirects_to_self.map { |redirect| %> + <%= link_to("Delete redirect from #{WikiPage.pretty_title(redirect.title)}", '', :class => 'icon icon-link-break') %> + <% } %> <%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del') %> <% else %> <%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :id => @page.title, :version => @content.version }, :class => 'icon icon-cancel') %> diff --git a/test/functional/wiki_controller_test.rb b/test/functional/wiki_controller_test.rb index 3765ac867..043b6ff51 100644 --- a/test/functional/wiki_controller_test.rb +++ b/test/functional/wiki_controller_test.rb @@ -233,6 +233,28 @@ def test_show_protected_page_shoud_show_locked_badge end end + def test_show_delete_redirect_links + @request.session[:user_id] = 2 + + wiki_page = WikiPage.find_by(title: 'CookBook_documentation') + second_title = 'Old_Cookbook' + wiki_page.title = second_title + wiki_page.save + + new_title = 'New_Cookbook' + wiki_page.title = new_title + wiki_page.save + + get :show, :params => {:project_id => 'ecookbook', :id => new_title} + + assert_select '.drdn-items' do + assert_select 'a.icon-link-break', + text: 'Delete redirect from CookBook documentation' + assert_select 'a.icon-link-break', + text: 'Delete redirect from Old Cookbook' + end + end + def test_get_new @request.session[:user_id] = 2 From 9f9dd8f05979e227fb50f205d9e4948ac6b7c503 Mon Sep 17 00:00:00 2001 From: Kevin Fischer Date: Mon, 15 Feb 2021 12:09:48 +0900 Subject: [PATCH 2/6] Add WikiRedirectsController with destroy action --- app/controllers/wiki_redirects_controller.rb | 37 +++++++++ config/routes.rb | 1 + lib/redmine/preparation.rb | 2 +- .../wiki_redirects_controller_test.rb | 80 +++++++++++++++++++ 4 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 app/controllers/wiki_redirects_controller.rb create mode 100644 test/functional/wiki_redirects_controller_test.rb diff --git a/app/controllers/wiki_redirects_controller.rb b/app/controllers/wiki_redirects_controller.rb new file mode 100644 index 000000000..0496af509 --- /dev/null +++ b/app/controllers/wiki_redirects_controller.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +# Redmine - project management software +# Copyright (C) 2006-2020 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +class WikiRedirectsController < ApplicationController + before_action :find_wiki_redirect, :authorize + + def destroy + @wiki_redirect.destroy + end + + private + + def find_wiki_redirect + @project = Project.find(params[:project_id]) + page = Wiki.find_page(params[:wiki_page_id], project: @project) + @wiki_redirect= WikiRedirect.where(redirects_to: page.title).find(params[:id]) + render_404 unless @wiki_redirect + rescue ActiveRecord::RecordNotFound + render_404 + end +end diff --git a/config/routes.rb b/config/routes.rb index 00eadf679..0fa40a74c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -191,6 +191,7 @@ match 'wiki/index', :controller => 'wiki', :action => 'index', :via => :get resources :wiki, :except => [:index, :create], :as => 'wiki_page' do + resources :redirects, controller: 'wiki_redirects', only: :destroy member do get 'rename' post 'rename' diff --git a/lib/redmine/preparation.rb b/lib/redmine/preparation.rb index c51ecfdb9..962c688db 100644 --- a/lib/redmine/preparation.rb +++ b/lib/redmine/preparation.rb @@ -121,7 +121,7 @@ def self.prepare map.permission :view_wiki_edits, {:wiki => [:history, :diff, :annotate]}, :read => true map.permission :export_wiki_pages, {:wiki => [:export]}, :read => true map.permission :edit_wiki_pages, :wiki => [:new, :edit, :update, :preview, :add_attachment], :attachments => :upload - map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member + map.permission :rename_wiki_pages, {:wiki => :rename, :wiki_redirects => :destroy}, :require => :member map.permission :delete_wiki_pages, {:wiki => [:destroy, :destroy_version]}, :require => :member map.permission :delete_wiki_pages_attachments, {} map.permission :view_wiki_page_watchers, {}, :read => true diff --git a/test/functional/wiki_redirects_controller_test.rb b/test/functional/wiki_redirects_controller_test.rb new file mode 100644 index 000000000..7178072c2 --- /dev/null +++ b/test/functional/wiki_redirects_controller_test.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +# Redmine - project management software +# Copyright (C) 2006-2020 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +require File.expand_path('../../test_helper', __FILE__) + +class WikiRedirectsControllerTest < Redmine::ControllerTest + fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles, + :enabled_modules, :wikis, :wiki_pages, :wiki_contents, + :wiki_content_versions, :attachments, + :issues, :issue_statuses, :trackers + + def setup + User.current = nil + @request.session[:user_id] = 1 + end + + def test_destroy + wiki_page = WikiPage.find(2) + old_title = wiki_page.title + wiki_page.title = 'Test' + wiki_page.save + + wiki_redirect = WikiRedirect.find_by(title: old_title, redirects_to: 'Test') + + delete :destroy, params: {id: wiki_redirect.id, project_id: wiki_page.wiki.project_id, wiki_page_id: 'Test'} + + assert_response :success + assert_not WikiRedirect.exists?(id: wiki_redirect.id) + end + + def test_destroy_without_permission + @request.session[:user_id] = User.generate!.id + + wiki_page = WikiPage.find(2) + old_title = wiki_page.title + wiki_page.title = 'Test' + wiki_page.save + + wiki_redirect = WikiRedirect.find_by(title: old_title, redirects_to: 'Test') + + delete :destroy, params: {id: wiki_redirect.id, project_id: wiki_page.wiki.project_id, wiki_page_id: 'Test'} + + assert_response :forbidden + assert WikiRedirect.exists?(id: wiki_redirect.id) + end + + def test_invalid_redirect_should_respond_with_404 + wiki_page = WikiPage.find(1) + old_title = wiki_page.title + wiki_page.title = 'New_Title' + wiki_page.save + + other_wiki_page = WikiPage.find(2) + other_wiki_page.title = 'Other_New_Title' + other_wiki_page.save + + wiki_redirect = WikiRedirect.find_by(title: old_title, redirects_to: 'New_Title') + + delete :destroy, params: {id: wiki_redirect.id, project_id: other_wiki_page.wiki.project_id, wiki_page_id: 'Other_New_Title'} + + assert_response :not_found + assert WikiRedirect.exists?(id: wiki_redirect.id) + end +end From 65be77d6141f2b435397e5d1f43c1a40fb6b3bf3 Mon Sep 17 00:00:00 2001 From: Kevin Fischer Date: Mon, 15 Feb 2021 13:32:44 +0900 Subject: [PATCH 3/6] Redirect to Wiki page + show success message --- app/controllers/wiki_redirects_controller.rb | 9 ++++++--- test/functional/wiki_redirects_controller_test.rb | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/controllers/wiki_redirects_controller.rb b/app/controllers/wiki_redirects_controller.rb index 0496af509..ef1c2aaa0 100644 --- a/app/controllers/wiki_redirects_controller.rb +++ b/app/controllers/wiki_redirects_controller.rb @@ -21,15 +21,18 @@ class WikiRedirectsController < ApplicationController before_action :find_wiki_redirect, :authorize def destroy - @wiki_redirect.destroy + if @wiki_redirect.destroy + flash[:notice] = l(:notice_successful_delete) + redirect_to project_wiki_page_path(@page.project, @page.title) + end end private def find_wiki_redirect @project = Project.find(params[:project_id]) - page = Wiki.find_page(params[:wiki_page_id], project: @project) - @wiki_redirect= WikiRedirect.where(redirects_to: page.title).find(params[:id]) + @page = Wiki.find_page(params[:wiki_page_id], project: @project) + @wiki_redirect=WikiRedirect.where(redirects_to: @page.title).find(params[:id]) render_404 unless @wiki_redirect rescue ActiveRecord::RecordNotFound render_404 diff --git a/test/functional/wiki_redirects_controller_test.rb b/test/functional/wiki_redirects_controller_test.rb index 7178072c2..7949ec3b5 100644 --- a/test/functional/wiki_redirects_controller_test.rb +++ b/test/functional/wiki_redirects_controller_test.rb @@ -40,7 +40,8 @@ def test_destroy delete :destroy, params: {id: wiki_redirect.id, project_id: wiki_page.wiki.project_id, wiki_page_id: 'Test'} - assert_response :success + assert_redirected_to '/projects/ecookbook/wiki/Test' + assert_equal 'Successful deletion.', flash[:notice] assert_not WikiRedirect.exists?(id: wiki_redirect.id) end From 8d62d4ba81ab247a509a133497d230ef547288fa Mon Sep 17 00:00:00 2001 From: Kevin Fischer Date: Mon, 15 Feb 2021 13:33:15 +0900 Subject: [PATCH 4/6] Add functionality to delete link --- app/views/wiki/show.html.erb | 2 +- test/functional/wiki_controller_test.rb | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/views/wiki/show.html.erb b/app/views/wiki/show.html.erb index 64075b2ec..f120584dc 100644 --- a/app/views/wiki/show.html.erb +++ b/app/views/wiki/show.html.erb @@ -16,7 +16,7 @@ <%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %> <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') %> <% @redirects_to_self.map { |redirect| %> - <%= link_to("Delete redirect from #{WikiPage.pretty_title(redirect.title)}", '', :class => 'icon icon-link-break') %> + <%= link_to("Delete redirect from #{WikiPage.pretty_title(redirect.title)}", {:controller => 'wiki_redirects', :action => 'destroy', :project_id => @project.identifier, :wiki_page_id => @page.title, :id => redirect.id}, :method => :delete, :class => 'icon icon-link-break') %> <% } %> <%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del') %> <% else %> diff --git a/test/functional/wiki_controller_test.rb b/test/functional/wiki_controller_test.rb index 043b6ff51..69f52247b 100644 --- a/test/functional/wiki_controller_test.rb +++ b/test/functional/wiki_controller_test.rb @@ -237,20 +237,23 @@ def test_show_delete_redirect_links @request.session[:user_id] = 2 wiki_page = WikiPage.find_by(title: 'CookBook_documentation') - second_title = 'Old_Cookbook' - wiki_page.title = second_title + wiki_page.title = 'Old_Cookbook' wiki_page.save - new_title = 'New_Cookbook' - wiki_page.title = new_title + wiki_page.title = 'New_Cookbook' wiki_page.save - get :show, :params => {:project_id => 'ecookbook', :id => new_title} + cookbook_doc_redirect = WikiRedirect.find_by(title: 'CookBook_documentation', redirects_to: 'New_Cookbook') + old_cookbook_redirect = WikiRedirect.find_by(title: 'Old_Cookbook', redirects_to: 'New_Cookbook') + + get :show, :params => {:project_id => 'ecookbook', :id => 'New_Cookbook'} assert_select '.drdn-items' do - assert_select 'a.icon-link-break', + assert_select 'a.icon-link-break[href=?]', + "/projects/ecookbook/wiki/New_Cookbook/redirects/#{cookbook_doc_redirect.id}", text: 'Delete redirect from CookBook documentation' - assert_select 'a.icon-link-break', + assert_select 'a.icon-link-break[href=?]', + "/projects/ecookbook/wiki/New_Cookbook/redirects/#{old_cookbook_redirect.id}", text: 'Delete redirect from Old Cookbook' end end From 63ad7c8421974f86a262e839765a1f64ee27685e Mon Sep 17 00:00:00 2001 From: Kevin Fischer Date: Mon, 15 Feb 2021 13:44:14 +0900 Subject: [PATCH 5/6] Hide links without permission --- app/views/wiki/show.html.erb | 8 +++++--- test/functional/wiki_controller_test.rb | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/app/views/wiki/show.html.erb b/app/views/wiki/show.html.erb index f120584dc..beb76c1df 100644 --- a/app/views/wiki/show.html.erb +++ b/app/views/wiki/show.html.erb @@ -15,9 +15,11 @@ <%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :id => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? %> <%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %> <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') %> - <% @redirects_to_self.map { |redirect| %> - <%= link_to("Delete redirect from #{WikiPage.pretty_title(redirect.title)}", {:controller => 'wiki_redirects', :action => 'destroy', :project_id => @project.identifier, :wiki_page_id => @page.title, :id => redirect.id}, :method => :delete, :class => 'icon icon-link-break') %> - <% } %> + <% if User.current.allowed_to?(:rename_wiki_pages, @project) %> + <% @redirects_to_self.map { |redirect| %> + <%= link_to("Delete redirect from #{WikiPage.pretty_title(redirect.title)}", {:controller => 'wiki_redirects', :action => 'destroy', :project_id => @project.identifier, :wiki_page_id => @page.title, :id => redirect.id}, :method => :delete, :class => 'icon icon-link-break') %> + <% } %> + <% end %> <%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del') %> <% else %> <%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :id => @page.title, :version => @content.version }, :class => 'icon icon-cancel') %> diff --git a/test/functional/wiki_controller_test.rb b/test/functional/wiki_controller_test.rb index 69f52247b..19e20870f 100644 --- a/test/functional/wiki_controller_test.rb +++ b/test/functional/wiki_controller_test.rb @@ -258,6 +258,24 @@ def test_show_delete_redirect_links end end + def test_hide_delete_redirect_links_without_permission + @request.session[:user_id] = 2 + + wiki_page = WikiPage.find_by(title: 'CookBook_documentation') + wiki_page.title = 'Old_Cookbook' + wiki_page.save + + project = wiki_page.wiki.project + role = User.find(2).members.find_by(project: project).roles.first + role.remove_permission! :rename_wiki_pages + + get :show, :params => {:project_id => 'ecookbook', :id => 'Old_Cookbook'} + + assert_select '.drdn-items' do + assert_select 'a.icon-link-break', count: 0 + end + end + def test_get_new @request.session[:user_id] = 2 From b754d4d2be5d74d655667ac732ddc18c0d4cc3c1 Mon Sep 17 00:00:00 2001 From: Kevin Fischer Date: Mon, 15 Feb 2021 13:51:01 +0900 Subject: [PATCH 6/6] Add locale --- app/views/wiki/show.html.erb | 2 +- config/locales/de.yml | 1 + config/locales/en.yml | 1 + config/locales/ja.yml | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/wiki/show.html.erb b/app/views/wiki/show.html.erb index beb76c1df..d6db7e477 100644 --- a/app/views/wiki/show.html.erb +++ b/app/views/wiki/show.html.erb @@ -17,7 +17,7 @@ <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') %> <% if User.current.allowed_to?(:rename_wiki_pages, @project) %> <% @redirects_to_self.map { |redirect| %> - <%= link_to("Delete redirect from #{WikiPage.pretty_title(redirect.title)}", {:controller => 'wiki_redirects', :action => 'destroy', :project_id => @project.identifier, :wiki_page_id => @page.title, :id => redirect.id}, :method => :delete, :class => 'icon icon-link-break') %> + <%= link_to(l(:button_delete_redirect, :page_title => WikiPage.pretty_title(redirect.title)), {:controller => 'wiki_redirects', :action => 'destroy', :project_id => @project.identifier, :wiki_page_id => @page.title, :id => redirect.id}, :method => :delete, :class => 'icon icon-link-break') %> <% } %> <% end %> <%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del') %> diff --git a/config/locales/de.yml b/config/locales/de.yml index 50d986bc8..b7b23bfcf 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -177,6 +177,7 @@ de: button_create_and_continue: Anlegen und weiter button_delete: Löschen button_delete_my_account: Mein Benutzerkonto löschen + button_delete_redirect: "Lösche Umleitung von %{page_title}" button_download: Herunterladen button_edit: Bearbeiten button_edit_associated_wikipage: "Zugehörige Wikiseite bearbeiten: %{page_title}" diff --git a/config/locales/en.yml b/config/locales/en.yml index f9064c866..35e39290e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1176,6 +1176,7 @@ en: button_unarchive: Unarchive button_reset: Reset button_rename: Rename + button_delete_redirect: "Delete redirect from %{page_title}" button_change_password: Change password button_copy: Copy button_copy_and_follow: Copy and follow diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 0215e7555..73b8406cf 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -852,6 +852,7 @@ ja: button_unarchive: アーカイブ解除 button_reset: リセット button_rename: 名前変更 + button_delete_redirect: "%{page_title}からのリダイレクトを削除" button_change_password: パスワード変更 button_copy: コピー button_copy_and_follow: コピー後表示