diff --git a/lib/gollum/app.rb b/lib/gollum/app.rb index 08179589..349481df 100644 --- a/lib/gollum/app.rb +++ b/lib/gollum/app.rb @@ -89,6 +89,7 @@ module Precious settings.wiki_options[:allow_editing] = settings.wiki_options.fetch(:allow_editing, true) @allow_editing = settings.wiki_options[:allow_editing] @critic_markup = settings.wiki_options[:critic_markup] + @redirects_enabled = settings.wiki_options.fetch(:redirects_enabled, true) @per_page_uploads = settings.wiki_options[:per_page_uploads] forbid unless @allow_editing || request.request_method == "GET" @@ -158,15 +159,15 @@ module Precious end end - get %r{/(edit|create)/(custom|mathjax\.config)\.(js|css)} do + get %r{/(edit|create)/(\.redirects.gollum|(custom|mathjax\.config)\.(js|css))} do forbid('Changing this resource is not allowed.') end - post %r{/(delete|rename|edit|create)/(custom|mathjax\.config)\.(js|css)} do + post %r{/(delete|rename|edit|create)/(\.redirects.gollum|(custom|mathjax\.config)\.(js|css))} do forbid('Changing this resource is not allowed.') end - post %r{/revert/(custom|mathjax\.config\.)\.(js|css)/.*/.*} do + post %r{/revert/(\.redirects.gollum|(custom|mathjax\.config\.)\.(js|css)/.*/.*)} do forbid('Changing this resource is not allowed.') end @@ -274,9 +275,13 @@ module Precious return end committer.commit - + # Renaming preserves format, so add the page's format to the renamed path to retrieve the renamed page - page = wiki_page("#{rename}.#{Gollum::Page.format_to_ext(page.format)}").page + new_path = "#{rename}.#{Gollum::Page.format_to_ext(page.format)}" + # Add a redirect from the old page to the new + wiki.add_redirect(page.url_path, clean_url(new_path)) if @redirects_enabled + + page = wiki_page(new_path).page return if page.nil? redirect to("/#{page.escaped_url_path}") end @@ -496,7 +501,7 @@ module Precious @newable = true mustache :overview end - end + end # gollum namespace get %r{/(.+?)/([0-9a-f]{40})} do file_path = params[:captures][0] @@ -520,6 +525,10 @@ module Precious end end + get '/\.redirects\.gollum' do + forbid('Accessing this resource is not allowed.') + end + get '/*' do show_page_or_file(params[:splat].first) end @@ -545,6 +554,8 @@ module Precious mustache :page elsif file = wiki.file(fullpath, wiki.ref, true) show_file(file) + elsif @redirects_enabled && redirect_path = wiki.redirects[fullpath] + redirect to("#{encodeURIComponent(redirect_path)}?redirected_from=#{encodeURIComponent(fullpath)}") else if @allow_editing path = fullpath[-1] == '/' ? "#{fullpath}#{wiki.index_page}" : fullpath # Append default index page if no page name is supplied diff --git a/lib/gollum/helpers.rb b/lib/gollum/helpers.rb index d0dad08e..f94ecf8a 100644 --- a/lib/gollum/helpers.rb +++ b/lib/gollum/helpers.rb @@ -17,7 +17,7 @@ module Precious # Remove all slashes from the start of string. # Remove all double slashes - def clean_url url + def clean_url(url) return url if url.nil? url.gsub('%2F', '/').gsub(/^\/+/, '').gsub('//', '/') end diff --git a/lib/gollum/public/gollum/javascript/gollum.js.erb b/lib/gollum/public/gollum/javascript/gollum.js.erb index f26a77d8..3a99f7ec 100755 --- a/lib/gollum/public/gollum/javascript/gollum.js.erb +++ b/lib/gollum/public/gollum/javascript/gollum.js.erb @@ -102,6 +102,12 @@ function preparePage () { } } +function flashNotice(type, notice) { + // accepted types: info, success, warn, error + html = '

' + notice + '

'; + $('#wiki-content h1').before(html); +} + // ua $(document).ready(function() { // for deleting the current page @@ -148,6 +154,7 @@ $(document).ready(function() { } } + if ($('#minibutton-upload-page').length) { new ClipboardJS('#ClipboardJSlink'); $('#minibutton-upload-page').parent().removeClass('jaws'); @@ -600,7 +607,11 @@ $(document).ready(function() { if($('.markdown-body').length ){ // Set text direction (LTR or RTL) preparePage(); - + // Check if there was a redirect here + if (match = new RegExp(/[?&]redirected\_from=([^?]*)/).exec(window.location.href)) { + notice = "The page you requested was renamed or moved. You've been successfully redirected to its new location."; + flashNotice('success', notice); + } // Set the 'e' hotkey for editing pages. Mousetrap.bind(['e'], function( e ) { e.preventDefault(); diff --git a/test/test_allow_editing.rb b/test/test_allow_editing.rb index 0ef0be6d..63835371 100644 --- a/test/test_allow_editing.rb +++ b/test/test_allow_editing.rb @@ -25,6 +25,17 @@ context "Precious::Views::Editing" do assert page.nil? end + test ".redirects.gollum file should not be accessible" do + Precious::App.set(:wiki_options, { allow_editing: true, allow_uploads: true }) + get '/.redirects.gollum' + assert_match /Accessing this resource is not allowed/, last_response.body + end + + test ".redirects.gollum file should not be editable" do + Precious::App.set(:wiki_options, { allow_editing: true, allow_uploads: true }) + get '/gollum/edit/.redirects.gollum' + assert_match /Changing this resource is not allowed/, last_response.body + end test "frontend links for editing are not blocked" do Precious::App.set(:wiki_options, { allow_editing: true, allow_uploads: true }) diff --git a/test/test_app.rb b/test/test_app.rb index 43e6d763..92274b5d 100644 --- a/test/test_app.rb +++ b/test/test_app.rb @@ -169,7 +169,7 @@ context "Frontend" do assert_nil @wiki.page("B") page_2 = @wiki.page('C') assert_equal "INITIAL\n\nSPAM2\n", page_2.raw_data - assert_equal 'def', page_2.version.message + assert_equal 'def', page_2.last_version.message assert_not_equal page_1.version.sha, page_2.version.sha end @@ -216,7 +216,7 @@ context "Frontend" do assert_nil @wiki.page("G/H") page_2 = @wiki.page('I/C') assert_equal "INITIAL\n\nSPAM2\n", page_2.raw_data - assert_equal 'def', page_2.version.message + assert_equal 'def', page_2.last_version.message assert_not_equal page_1.version.sha, page_2.version.sha end @@ -233,7 +233,7 @@ context "Frontend" do assert_nil @wiki.page("G/H") page_2 = @wiki.page('G/K/C') assert_equal "INITIAL\n\nSPAM2\n", page_2.raw_data - assert_equal 'def', page_2.version.message + assert_equal 'def', page_2.last_version.message assert_not_equal page_1.version.sha, page_2.version.sha end