Index: test/functional/wiki_controller_test.rb =================================================================== --- test/functional/wiki_controller_test.rb (revision 1382) +++ test/functional/wiki_controller_test.rb (working copy) @@ -160,4 +160,44 @@ get :index, :id => 999 assert_response 404 end + + + def test_show_page_with_edit_link + @request.session[:user_id] = 2 + get :index, :id => 1 + assert_response :success + assert_template 'show' + assert_tag :tag => 'a', :attributes => { :href => '/wiki/1/CookBook_documentation/edit' } + end + + def test_show_page_without_edit_link + @request.session[:user_id] = 4 + get :index, :id => 1 + assert_response :success + assert_template 'show' + assert_no_tag :tag => 'a', :attributes => { :href => '/wiki/1/CookBook_documentation/edit' } + end + + def test_edit_unprotected_page + # Non members can edit unprotected wiki pages + @request.session[:user_id] = 4 + get :edit, :id => 1, :page => 'Another_page' + assert_response :success + assert_template 'edit' + end + + def test_edit_protected_page_by_nonmember + # Non members can't edit protected wiki pages + @request.session[:user_id] = 4 + get :edit, :id => 1, :page => 'CookBook_documentation' + assert_response 403 + end + + def test_edit_protected_page_by_member + @request.session[:user_id] = 2 + get :edit, :id => 1, :page => 'CookBook_documentation' + assert_response :success + assert_template 'edit' + end + end Index: test/fixtures/roles.yml =================================================================== --- test/fixtures/roles.yml (revision 1382) +++ test/fixtures/roles.yml (working copy) @@ -29,6 +29,7 @@ - :manage_documents - :view_wiki_pages - :edit_wiki_pages + - :protect_wiki_pages - :delete_wiki_pages - :rename_wiki_pages - :add_messages @@ -69,6 +70,7 @@ - :manage_documents - :view_wiki_pages - :edit_wiki_pages + - :protect_wiki_pages - :delete_wiki_pages - :add_messages - :manage_boards @@ -104,6 +106,7 @@ - :manage_documents - :view_wiki_pages - :edit_wiki_pages + - :protect_wiki_pages - :delete_wiki_pages - :add_messages - :manage_boards Index: test/fixtures/wiki_pages.yml =================================================================== --- test/fixtures/wiki_pages.yml (revision 1382) +++ test/fixtures/wiki_pages.yml (working copy) @@ -4,19 +4,23 @@ title: CookBook_documentation id: 1 wiki_id: 1 + protected: true wiki_pages_002: created_on: 2007-03-08 00:18:07 +01:00 title: Another_page id: 2 wiki_id: 1 + protected: false wiki_pages_003: created_on: 2007-03-08 00:18:07 +01:00 title: Start_page id: 3 wiki_id: 2 + protected: false wiki_pages_004: created_on: 2007-03-08 00:18:07 +01:00 title: Page_with_an_inline_image id: 4 wiki_id: 1 + protected: false \ No newline at end of file Index: app/controllers/wiki_controller.rb =================================================================== --- app/controllers/wiki_controller.rb (revision 1382) +++ app/controllers/wiki_controller.rb (working copy) @@ -30,8 +30,9 @@ def index page_title = params[:page] @page = @wiki.find_or_new_page(page_title) + @editable = editable? if @page.new_record? - if User.current.allowed_to?(:edit_wiki_pages, @project) + if User.current.allowed_to?(:edit_wiki_pages, @project) && @editable edit render :action => 'edit' else @@ -54,6 +55,7 @@ # edit an existing page or a new one def edit @page = @wiki.find_or_new_page(params[:page]) + return render_403 unless editable? @page.content = WikiContent.new(:page => @page) if @page.new_record? @content = @page.content_for_version(params[:version]) @@ -152,6 +154,7 @@ def preview page = @wiki.find_page(params[:page]) + return render_403 unless editable?(page) @attachements = page.attachments if page @text = params[:content][:text] render :partial => 'common/preview' @@ -159,16 +162,25 @@ def add_attachment @page = @wiki.find_page(params[:page]) + return render_403 unless editable? attach_files(@page, params[:attachments]) redirect_to :action => 'index', :page => @page.title end def destroy_attachment @page = @wiki.find_page(params[:page]) + return render_403 unless editable? @page.attachments.find(params[:attachment_id]).destroy redirect_to :action => 'index', :page => @page.title end + def protect + page = @wiki.find_page(params[:page]) + page.protected = !page.protected? + page.save + redirect_to :action => 'index', :page => page.title + end + private def find_wiki @@ -178,4 +190,9 @@ rescue ActiveRecord::RecordNotFound render_404 end + + def editable?(page = @page) + !page.protected? || User.current.allowed_to?(:protect_wiki_pages, @project) + end + end Index: app/views/wiki/show.rhtml =================================================================== --- app/views/wiki/show.rhtml (revision 1382) +++ app/views/wiki/show.rhtml (working copy) @@ -1,8 +1,10 @@
-<%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :page => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) if @content.version == @page.content.version %> +<%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :page => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) if @content.version == @page.content.version && @editable %> <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :page => @page.title}, :class => 'icon icon-move') if @content.version == @page.content.version %> <%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :page => @page.title}, :method => :post, :confirm => l(:text_are_you_sure), :class => 'icon icon-del') %> <%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :page => @page.title, :version => @content.version }, :class => 'icon icon-cancel') if @content.version < @page.content.version %> +<%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :page => @page.title}, :class => 'icon icon-lock') if !@page.protected? %> +<%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :page => @page.title}, :class => 'icon icon-unlock') if @page.protected? %> <%= link_to(l(:label_history), {:action => 'history', :page => @page.title}, :class => 'icon icon-history') %>
@@ -24,7 +26,7 @@ <%= link_to_attachments @page.attachments, :delete_url => (authorize_for('wiki', 'destroy_attachment') ? {:controller => 'wiki', :action => 'destroy_attachment', :page => @page.title} : nil) %> -<% if authorize_for('wiki', 'add_attachment') %> +<% if authorize_for('wiki', 'add_attachment') && @editable %>

<%= link_to l(:label_attachment_new), {}, :onclick => "Element.show('add_attachment_form'); Element.hide(this); Element.scrollTo('add_attachment_form'); return false;", :id => 'attach_files_link' %>

<% form_tag({ :controller => 'wiki', :action => 'add_attachment', :page => @page.title }, :multipart => true, :id => "add_attachment_form", :style => "display:none;") do %> Index: db/migrate/093_add_wiki_pages_protected.rb =================================================================== --- db/migrate/093_add_wiki_pages_protected.rb (revision 0) +++ db/migrate/093_add_wiki_pages_protected.rb (revision 0) @@ -0,0 +1,9 @@ +class AddWikiPagesProtected < ActiveRecord::Migration + def self.up + add_column :wiki_pages, :protected, :boolean, :default => false, :null => false + end + + def self.down + remove_column :wiki_pages, :protected + end +end Index: lib/redmine.rb =================================================================== --- lib/redmine.rb (revision 1382) +++ lib/redmine.rb (working copy) @@ -76,6 +76,7 @@ map.permission :delete_wiki_pages, {:wiki => :destroy}, :require => :member map.permission :view_wiki_pages, :wiki => [:index, :history, :diff, :annotate, :special] map.permission :edit_wiki_pages, :wiki => [:edit, :preview, :add_attachment, :destroy_attachment] + map.permission :protect_wiki_pages, :wiki => [:protect] end map.project_module :repository do |map|