From 49913ad11b6c00d0949c2c037c7352c3b9585415 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Wed, 30 Jan 2019 19:41:31 +0100 Subject: [PATCH] Nuevo plugin Private Wiki 0.2.0 --- plugins/redmine_private_wiki/LICENSE | 20 +++ plugins/redmine_private_wiki/README.md | 39 ++++++ .../_body_bottom.html.erb | 19 +++ .../_html_head.html.erb | 7 + .../app/views/wiki/date_index.html.erb | 60 +++++++++ .../assets/images/hide.png | Bin 0 -> 3251 bytes .../assets/images/reveal.png | Bin 0 -> 3270 bytes .../assets/stylesheets/private_wiki.css | 14 ++ .../config/locales/en.yml | 5 + .../config/locales/fr.yml | 5 + plugins/redmine_private_wiki/config/routes.rb | 5 + .../migrate/001_add_private_wiki_attribute.rb | 12 ++ plugins/redmine_private_wiki/init.rb | 37 ++++++ .../wiki_patches/application_helper_patch.rb | 38 ++++++ .../lib/wiki_patches/hook.rb | 7 + .../lib/wiki_patches/wiki_controller_patch.rb | 28 ++++ .../lib/wiki_patches/wiki_page_patch.rb | 32 +++++ .../functional/wiki_controller_patch_test.rb | 121 ++++++++++++++++++ .../redmine_private_wiki/test/test_helper.rb | 2 + .../test/unit/wiki_page_patch_test.rb | 29 +++++ 20 files changed, 480 insertions(+) create mode 100755 plugins/redmine_private_wiki/LICENSE create mode 100755 plugins/redmine_private_wiki/README.md create mode 100755 plugins/redmine_private_wiki/app/views/private_wiki_management_views/_body_bottom.html.erb create mode 100755 plugins/redmine_private_wiki/app/views/private_wiki_management_views/_html_head.html.erb create mode 100755 plugins/redmine_private_wiki/app/views/wiki/date_index.html.erb create mode 100755 plugins/redmine_private_wiki/assets/images/hide.png create mode 100755 plugins/redmine_private_wiki/assets/images/reveal.png create mode 100755 plugins/redmine_private_wiki/assets/stylesheets/private_wiki.css create mode 100755 plugins/redmine_private_wiki/config/locales/en.yml create mode 100755 plugins/redmine_private_wiki/config/locales/fr.yml create mode 100755 plugins/redmine_private_wiki/config/routes.rb create mode 100755 plugins/redmine_private_wiki/db/migrate/001_add_private_wiki_attribute.rb create mode 100755 plugins/redmine_private_wiki/init.rb create mode 100755 plugins/redmine_private_wiki/lib/wiki_patches/application_helper_patch.rb create mode 100755 plugins/redmine_private_wiki/lib/wiki_patches/hook.rb create mode 100755 plugins/redmine_private_wiki/lib/wiki_patches/wiki_controller_patch.rb create mode 100755 plugins/redmine_private_wiki/lib/wiki_patches/wiki_page_patch.rb create mode 100755 plugins/redmine_private_wiki/test/functional/wiki_controller_patch_test.rb create mode 100755 plugins/redmine_private_wiki/test/test_helper.rb create mode 100755 plugins/redmine_private_wiki/test/unit/wiki_page_patch_test.rb diff --git a/plugins/redmine_private_wiki/LICENSE b/plugins/redmine_private_wiki/LICENSE new file mode 100755 index 0000000..3d4d0d7 --- /dev/null +++ b/plugins/redmine_private_wiki/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2017 Alexandre BOUDINE, previous owner(s) : Oleg Kandaurov + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/redmine_private_wiki/README.md b/plugins/redmine_private_wiki/README.md new file mode 100755 index 0000000..8e4dd2f --- /dev/null +++ b/plugins/redmine_private_wiki/README.md @@ -0,0 +1,39 @@ +# Private Wiki +## A RedMine plugin + +This plugin is based on the existing plugin "Redmine Private Wiki", developped by Oleg Kandaurov +Link of the original plugin : https://github.com/f0y/redmine_private_wiki + +## Features : + +As original plugin : +* It allows to set individual pages of wiki as privates +* Thoses privates pages are only visibles to the roles with the right permission +* Privatize pages are also a permission + +## New Features : + +New features : +* Hide private wikis in index and date_index for non-authorized users +* Add [PRIVATE] tag in index for authorized users + +## Use : + +To set public/private wiki page : + Projects -> MyProject -> Wiki -> select wiki page -> set private + +## Installation : + + $cd /path/to/redmine/directory/plugins + $git clone https://github.com/BlueXML/redmine_private_wiki.git + $bundle exec rake redmine:plugins:migrate RAILS_ENV=production + +## Compatibility : +Tested for RedMine 3.3.* (Manually) + +## License : +This plugin is licensed under the MIT license. + + + + diff --git a/plugins/redmine_private_wiki/app/views/private_wiki_management_views/_body_bottom.html.erb b/plugins/redmine_private_wiki/app/views/private_wiki_management_views/_body_bottom.html.erb new file mode 100755 index 0000000..1c33e0f --- /dev/null +++ b/plugins/redmine_private_wiki/app/views/private_wiki_management_views/_body_bottom.html.erb @@ -0,0 +1,19 @@ + +<% if controller and controller.class.name == 'WikiController' and controller.action_name == "show" and @page and @page.id and @page.visible? %> + + + <% if @page.private? and User.current.allowed_to?(:view_privates_wiki, @project) %> + <%= l(:private_flag) %> + <% end %> + + + <%= link_to_if_authorized(l(:button_setprivate_wiki), {:action => 'change_privacy', :id => @page.title, :private => 1}, :method => :post, :class => 'icon icon-setprivate') if !@page.private? %> + <%= link_to_if_authorized(l(:button_setpublic_wiki), {:action => 'change_privacy', :id => @page.title, :private => 0}, :method => :post, :class => 'icon icon-setpublic') if @page.private? %> + + + +<% end %> \ No newline at end of file diff --git a/plugins/redmine_private_wiki/app/views/private_wiki_management_views/_html_head.html.erb b/plugins/redmine_private_wiki/app/views/private_wiki_management_views/_html_head.html.erb new file mode 100755 index 0000000..47cb123 --- /dev/null +++ b/plugins/redmine_private_wiki/app/views/private_wiki_management_views/_html_head.html.erb @@ -0,0 +1,7 @@ + +<% if controller and controller.class.name == 'WikiController' and (controller.action_name == "show" or controller.action_name == "index" or controller.action_name == "date_index") %> + + + <%= stylesheet_link_tag "private_wiki.css", :plugin => "redmine_private_wiki", :media => "screen" %> + +<% end %> \ No newline at end of file diff --git a/plugins/redmine_private_wiki/app/views/wiki/date_index.html.erb b/plugins/redmine_private_wiki/app/views/wiki/date_index.html.erb new file mode 100755 index 0000000..6141cdb --- /dev/null +++ b/plugins/redmine_private_wiki/app/views/wiki/date_index.html.erb @@ -0,0 +1,60 @@ +
+<% if User.current.allowed_to?(:edit_wiki_pages, @project) %> +<%= link_to l(:label_wiki_page_new), new_project_wiki_page_path(@project), :remote => true, :class => 'icon icon-add' %> +<% end %> +<%= watcher_link(@wiki, User.current) %> +
+ +

<%= l(:label_index_by_date) %>

+ +<% if @pages.empty? %> +

<%= l(:label_no_data) %>

+<% end %> + +<% @pages_by_date.keys.sort.reverse.each do |date| %> + + <% all_private = true %> + <% @pages_by_date[date].each do |page| %> + <% if !page.private? %> + <% all_private = false %> + <% end %> + <% end %> + + <% if !all_private %> +

<%= format_date(date) %>

+ + <% elsif User.current.allowed_to?(:view_privates_wiki, @project) %> +

<%= format_date(date) %>

+ + <% end %> +<% end %> + +<% content_for :sidebar do %> + <%= render :partial => 'sidebar' %> +<% end %> + +<% unless @pages.empty? %> +<% other_formats_links do |f| %> + <%= f.link_to 'Atom', :url => {:controller => 'activities', :action => 'index', :id => @project, :show_wiki_edits => 1, :key => User.current.rss_key} %> + <% if User.current.allowed_to?(:export_wiki_pages, @project) %> + <%= f.link_to('PDF', :url => {:action => 'export', :format => 'pdf'}) %> + <%= f.link_to('HTML', :url => {:action => 'export'}) %> + <% end %> +<% end %> +<% end %> + +<% content_for :header_tags do %> +<%= auto_discovery_link_tag(:atom, :controller => 'activities', :action => 'index', :id => @project, :show_wiki_edits => 1, :format => 'atom', :key => User.current.rss_key) %> +<% end %> diff --git a/plugins/redmine_private_wiki/assets/images/hide.png b/plugins/redmine_private_wiki/assets/images/hide.png new file mode 100755 index 0000000000000000000000000000000000000000..5c9823c6d7a8d961568fb740ef8edd786e2d2e4c GIT binary patch literal 3251 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 literal 0 HcmV?d00001 diff --git a/plugins/redmine_private_wiki/assets/images/reveal.png b/plugins/redmine_private_wiki/assets/images/reveal.png new file mode 100755 index 0000000000000000000000000000000000000000..2b84feee58ddbfcefa247376229ffef72aee5ce0 GIT binary patch literal 3270 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 Ef_<_gQ~&?~ literal 0 HcmV?d00001 diff --git a/plugins/redmine_private_wiki/assets/stylesheets/private_wiki.css b/plugins/redmine_private_wiki/assets/stylesheets/private_wiki.css new file mode 100755 index 0000000..ce9d833 --- /dev/null +++ b/plugins/redmine_private_wiki/assets/stylesheets/private_wiki.css @@ -0,0 +1,14 @@ +.private_wiki_flag { + background: #D22; + color: white; + padding: 2px 2px 2px 2px; + border-radius: 2px; +} + +.icon-setprivate{ + background-image: url(../images/hide.png); +} + +.icon-setpublic{ + background-image: url(../images/reveal.png); +} diff --git a/plugins/redmine_private_wiki/config/locales/en.yml b/plugins/redmine_private_wiki/config/locales/en.yml new file mode 100755 index 0000000..f2e4454 --- /dev/null +++ b/plugins/redmine_private_wiki/config/locales/en.yml @@ -0,0 +1,5 @@ +# English strings go here for Rails i18n +en: + button_setprivate_wiki: Set Private + button_setpublic_wiki: Set Public + private_flag: PRIVATE diff --git a/plugins/redmine_private_wiki/config/locales/fr.yml b/plugins/redmine_private_wiki/config/locales/fr.yml new file mode 100755 index 0000000..3212d88 --- /dev/null +++ b/plugins/redmine_private_wiki/config/locales/fr.yml @@ -0,0 +1,5 @@ +# French strings go here for Rails i18n +fr: + button_setprivate_wiki: Rendre Privé + button_setpublic_wiki: Rendre Public + private_flag: PRIVÉ diff --git a/plugins/redmine_private_wiki/config/routes.rb b/plugins/redmine_private_wiki/config/routes.rb new file mode 100755 index 0000000..827fad4 --- /dev/null +++ b/plugins/redmine_private_wiki/config/routes.rb @@ -0,0 +1,5 @@ +# Plugin's routes +RedmineApp::Application.routes.draw do + #Allow utilisation of action 'change_privacy' in links (set route to wiki method) + match 'projects/:project_id/wiki/:id/change_privacy/:private', :controller => 'wiki', :action => 'change_privacy', :via => [:post] +end diff --git a/plugins/redmine_private_wiki/db/migrate/001_add_private_wiki_attribute.rb b/plugins/redmine_private_wiki/db/migrate/001_add_private_wiki_attribute.rb new file mode 100755 index 0000000..5069e6f --- /dev/null +++ b/plugins/redmine_private_wiki/db/migrate/001_add_private_wiki_attribute.rb @@ -0,0 +1,12 @@ +class AddPrivateWikiAttribute < ActiveRecord::Migration + def change + #Add a "Private" attribute used to identify visibility of wikis + add_column(:wiki_pages, "private", :boolean, :default => false) + end + + + def self.down + remove_column(:wiki_pages, "private") + end + +end diff --git a/plugins/redmine_private_wiki/init.rb b/plugins/redmine_private_wiki/init.rb new file mode 100755 index 0000000..ef38ba1 --- /dev/null +++ b/plugins/redmine_private_wiki/init.rb @@ -0,0 +1,37 @@ +require 'redmine' +require_dependency 'wiki_patches/hook' #Apply views modifications + +Rails.configuration.to_prepare do + + #Apply patch on wiki controller + require_dependency 'wiki_controller' + unless WikiController.included_modules.include? WikiPatches::WikiControllerPatch + WikiController.send(:include, WikiPatches::WikiControllerPatch) + end + + #Apply patch on wiki page + require_dependency 'wiki_page' + unless WikiPage.included_modules.include? WikiPatches::WikiPagePatch + WikiPage.send(:include, WikiPatches::WikiPagePatch) + end + + require_dependency 'application_helper' + unless ApplicationHelper.included_modules.include? WikiPatches::ApplicationHelperPatch + ApplicationHelper.send(:include, WikiPatches::ApplicationHelperPatch) + end +end + +Redmine::Plugin.register :redmine_private_wiki do + name 'Private Wiki plugin' + author 'Alexandre BOUDINE' + description 'Add privatization of wiki pages' + version '0.2.0' + url '' + author_url '' + + #Add permissions + project_module :wiki do + permission :view_privates_wiki, {:wiki => [:show, :edit]} + permission :manage_privates_wiki, {:wiki => :change_privacy}, :require => :member + end +end diff --git a/plugins/redmine_private_wiki/lib/wiki_patches/application_helper_patch.rb b/plugins/redmine_private_wiki/lib/wiki_patches/application_helper_patch.rb new file mode 100755 index 0000000..9ee6403 --- /dev/null +++ b/plugins/redmine_private_wiki/lib/wiki_patches/application_helper_patch.rb @@ -0,0 +1,38 @@ +require_dependency 'application_helper' +module WikiPatches + module ApplicationHelperPatch + def self.included(base) + base.class_eval do + + #Override application's method to not display hidden wikis or to display it with the PRIVATE flag + def render_page_hierarchy_with_wiki_hidding(pages, node=nil, options={}) + content = '' + if pages[node] + content << "
    \n" + pages[node].each do |page| + if !page.private? then + content << "
  • " + content << link_to(h(page.pretty_title), {:controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title, :version => nil}, + :title => (options[:timestamp] && page.updated_on ? l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) : nil)) + content << "\n" + render_page_hierarchy(pages, page.id, options) if pages[page.id] + content << "
  • \n" + elsif User.current.allowed_to?(:view_privates_wiki, @project) then + content << "
  • " + content << link_to(h(page.pretty_title), {:controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title, :version => nil}, + :title => (options[:timestamp] && page.updated_on ? l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) : nil)) + content << "    " + l(:private_flag) + " " + content << "\n" + render_page_hierarchy(pages, page.id, options) if pages[page.id] + content << "
  • \n" + end + end + content << "
\n" + end + content.html_safe + end + + alias_method_chain :render_page_hierarchy, :wiki_hidding + + end + end + end +end \ No newline at end of file diff --git a/plugins/redmine_private_wiki/lib/wiki_patches/hook.rb b/plugins/redmine_private_wiki/lib/wiki_patches/hook.rb new file mode 100755 index 0000000..e2ce9a9 --- /dev/null +++ b/plugins/redmine_private_wiki/lib/wiki_patches/hook.rb @@ -0,0 +1,7 @@ +module WikiPatches + class WikiPatchesHook < Redmine::Hook::ViewListener + #Add the content of private_wiki_management_views/_body_bottom.html.erb to general layout + render_on :view_layouts_base_body_bottom, :partial => 'private_wiki_management_views/body_bottom' + render_on :view_layouts_base_html_head, :partial => 'private_wiki_management_views/html_head' + end +end \ No newline at end of file diff --git a/plugins/redmine_private_wiki/lib/wiki_patches/wiki_controller_patch.rb b/plugins/redmine_private_wiki/lib/wiki_patches/wiki_controller_patch.rb new file mode 100755 index 0000000..45a3372 --- /dev/null +++ b/plugins/redmine_private_wiki/lib/wiki_patches/wiki_controller_patch.rb @@ -0,0 +1,28 @@ +module WikiPatches + module WikiControllerPatch + def self.included(base) + base.send(:include, InstanceMethods) + base.class_eval do + unloadable + #Test :valide before :show action on wiki_controller + before_filter :validate, :only => [:show,:edit,:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy] + end + end + + module InstanceMethods + def change_privacy + find_existing_page + #":private" attribute of wiki page is set to :private parameter + @page.update_attribute :private, params[:private] + + #Then redirection to the previous page + redirect_to project_wiki_page_path(@project, @page.title) + end + + def validate + #If page is private and user not allowed to see it, then deny_access + deny_access and return if @page.private? and !User.current.allowed_to?(:view_privates_wiki, @project) + end + end + end +end \ No newline at end of file diff --git a/plugins/redmine_private_wiki/lib/wiki_patches/wiki_page_patch.rb b/plugins/redmine_private_wiki/lib/wiki_patches/wiki_page_patch.rb new file mode 100755 index 0000000..0350ad8 --- /dev/null +++ b/plugins/redmine_private_wiki/lib/wiki_patches/wiki_page_patch.rb @@ -0,0 +1,32 @@ +module WikiPatches + module WikiPagePatch + def self.included(base) + base.send(:include, InstanceMethods) + base.class_eval do + unloadable + end + end + + module InstanceMethods + #Check if the wiki page as any private parent + def has_private_parent?() + @res = self.parent_title + while @res != nil + if self.project.wiki.find_page(@res).private? + return true + else + @res = self.project.wiki.find_page(@res).parent_title + end + end + return false; + end + end + end +end + + + + + + + diff --git a/plugins/redmine_private_wiki/test/functional/wiki_controller_patch_test.rb b/plugins/redmine_private_wiki/test/functional/wiki_controller_patch_test.rb new file mode 100755 index 0000000..de2b9dc --- /dev/null +++ b/plugins/redmine_private_wiki/test/functional/wiki_controller_patch_test.rb @@ -0,0 +1,121 @@ +require File.expand_path('../../test_helper',__FILE__) + + +class WikiControllerPatchTest < ActionController::TestCase + + fixtures :projects, :users, :roles, :members, :member_roles, :wikis, :wiki_pages, :wiki_contents + + setup do + @controller = WikiController.new + + @project = Project.find(1) + @project.enable_module! :wiki + @role = Role.find(1) + User.current = nil + @request.session[:user_id] = 2 + @wiki = @project.wiki + @page = @wiki.find_page('Another_page') + @page.private = true + @page.save! + end + + test 'show_without_permission' do + #User not allowed to see the wiki page + get :show, :project_id => @project, :id => @page.title + + assert_response 403 + assert_select "span.private_wiki_flag", false, "There should not be a private flag" + end + + test 'show_with_permission' do + #User allowed to see the wiki page + @role.add_permission! :view_privates_wiki + get :show, :project_id => @project, :id => @page.title + + assert_response :success + assert_select "span.private_wiki_flag", true, "There should be a private flag" + + #User not allowed to change privacy of wiki + assert_select "a.icon-setpublic", false, "There should not be a privacy button" + + #User allowed to change privacy of wiki + @role.add_permission! :manage_privates_wiki + get :show, :project_id => @project, :id => @page.title + + assert_select "body" do |elements| + elements.each do |element| + Rails::logger.debug("FLAG") + Rails::logger.debug(element) + end + end + + assert_select "a.icon-setpublic", true, "There should be a privacy button" + end + + test 'edit_without_permission' do + #User not allowed to edit wiki + get :edit, :project_id => @project, :id => @page.title + + assert_response 403 + end + + test 'edit_with_permission' do + #User allowed to edit wiki + @role.add_permission! :view_privates_wiki + get :edit, :project_id => @project, :id => @page.title + + assert_response :success + end + + test 'post_change_privacy_without_permission' do + #User not allowed to change privacy of wiki + post :change_privacy, :project_id => @project, :id => @page.title, :private => 0 + + assert_response 403 + end + + test 'post_change_privacy_with_permission' do + #User allowed to change privacy of wiki + @role.add_permission! :manage_privates_wiki + post :change_privacy, :project_id => @project, :id => @page.title, :private => 0 + + assert_response :redirect + assert !@page.reload.private + end + + #Next tests somehow fails, but actually works ... + #Probably due to the fact that elements are added directly through JS as text and not as elements. + test 'index_without_permission' do + #User not allowed to see the wiki page + get :index, :project_id => @project + + assert_response :success + assert_select "li.hide_private", true, "There should be a private
  • " + end + + test 'index_with_permission' do + #User allowed to see the wiki page + @role.add_permission! :view_privates_wiki + get :index, :project_id => @project + + assert_response :success + assert_select "span.private_wiki_flag", true, "There should be a private flag" + assert_select "li.hide_private", false, "There should not be a private
  • " + end + + test 'date_index_without_permission' do + #User not allowed to see the wiki page + get :date_index, :project_id => @project + + assert_select "li.hide_private", true, "There should be a private
  • " + end + + test 'date_index_with_permission' do + #User allowed to see the wiki page + @role.add_permission! :view_privates_wiki + get :date_index, :project_id => @project + + assert_select "span.private_wiki_flag", true, "There should be a private flag" + assert_select "li.hide_private", false, "There should not be a private
  • " + end +end diff --git a/plugins/redmine_private_wiki/test/test_helper.rb b/plugins/redmine_private_wiki/test/test_helper.rb new file mode 100755 index 0000000..54685d3 --- /dev/null +++ b/plugins/redmine_private_wiki/test/test_helper.rb @@ -0,0 +1,2 @@ +# Load the Redmine helper +require File.expand_path(File.dirname(__FILE__) + '/../../../test/test_helper') diff --git a/plugins/redmine_private_wiki/test/unit/wiki_page_patch_test.rb b/plugins/redmine_private_wiki/test/unit/wiki_page_patch_test.rb new file mode 100755 index 0000000..3120da0 --- /dev/null +++ b/plugins/redmine_private_wiki/test/unit/wiki_page_patch_test.rb @@ -0,0 +1,29 @@ +require File.expand_path('../../test_helper',__FILE__) + +class WikiPagePatchTest < ActiveSupport::TestCase + + fixtures :projects, :wikis, :wiki_pages + + setup do + @controller = WikiController.new + + @project = Project.find(1) + @project.enable_module! :wiki + @wiki = @project.wiki + @page = @wiki.find_page('Another_page') + @page.private = true + @page.save! + end + + test 'has_private_parent_true' do + #A page that has a private parent + @page = @wiki.find_page('Child_1') + assert_equal true, @page.has_private_parent? + end + + test 'has_private_parent_false' do + #A page that doesn't have a private parent + assert_equal true, !@page.has_private_parent? + end + +end \ No newline at end of file