diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb index 27861d35d..a5bdd02d2 100644 --- a/app/controllers/roles_controller.rb +++ b/app/controllers/roles_controller.rb @@ -26,6 +26,8 @@ class RolesController < ApplicationController before_action :find_role, :only => [:show, :edit, :update, :destroy] accept_api_auth :index, :show + include RolesHelper + require_sudo_mode :create, :update, :destroy def index @@ -109,6 +111,12 @@ class RolesController < ApplicationController end @roles = scope.to_a @permissions = Redmine::AccessControl.permissions.select {|p| !p.public?} + respond_to do |format| + format.html + format.csv do + send_data(permissions_to_csv(@roles, @permissions), :type => 'text/csv; header=present', :filename => 'permissions_export.csv') + end + end end def update_permissions diff --git a/app/helpers/roles_helper.rb b/app/helpers/roles_helper.rb index 79b627dae..032c519c6 100644 --- a/app/helpers/roles_helper.rb +++ b/app/helpers/roles_helper.rb @@ -18,4 +18,31 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. module RolesHelper + include ApplicationHelper + + def permissions_to_csv(roles, permissions) + Redmine::Export::CSV.generate do |csv| + # csv header fields + headers = [l(:field_cvs_module), l(:label_permissions)] + roles.collect {|role| role.name} + csv << headers + # csv lines + perms_by_module = permissions.group_by {|p| p.project_module.to_s} + perms_by_module.keys.sort.each do |mod| + perms_by_module[mod].each do |p| + names = [ + l_or_humanize(p.project_module.to_s, :prefix => 'project_module_'), + l_or_humanize(p.name, :prefix => 'permission_').to_s, + ] + fields = names + roles.collect do |role| + if role.setable_permissions.include?(p) + format_object(role.permissions.include?(p.name), false) + else + "" + end + end + csv << fields + end + end + end + end end diff --git a/app/views/roles/permissions.html.erb b/app/views/roles/permissions.html.erb index 9cd71b499..ffdf28b54 100644 --- a/app/views/roles/permissions.html.erb +++ b/app/views/roles/permissions.html.erb @@ -85,3 +85,6 @@

<%= check_all_links 'permissions_form' %>

<%= submit_tag l(:button_save) %>

<% end %> +<% other_formats_links do |f| %> + <%= f.link_to 'CSV' %> +<% end %> diff --git a/test/functional/roles_controller_test.rb b/test/functional/roles_controller_test.rb index 1f2b2c36b..0041297a3 100644 --- a/test/functional/roles_controller_test.rb +++ b/test/functional/roles_controller_test.rb @@ -22,6 +22,8 @@ require File.expand_path('../../test_helper', __FILE__) class RolesControllerTest < Redmine::ControllerTest fixtures :roles, :users, :members, :member_roles, :workflows, :trackers + include Redmine::I18n + def setup User.current = nil @request.session[:user_id] = 1 # admin @@ -270,6 +272,47 @@ class RolesControllerTest < Redmine::ControllerTest assert_select 'input[name=?][type=checkbox][value=delete_issues]:not([checked])', 'permissions[3][]' end + def test_permissions_csv_export + Role.all do |r| + r.permissions=[] + r.save! + end + ['Manager', 'Developer'].each do |name| + role = Role.find_by(:name => name) + role.permissions = [:edit_issue_notes] + role.save! + end + + get( + :permissions, + :params => { + :format => 'csv' + } + ) + assert_response :success + + assert_equal 'text/csv', @response.media_type + lines = @response.body.chomp.split("\n") + # Number of lines + permissions = Redmine::AccessControl.permissions - Redmine::AccessControl.public_permissions + assert_equal permissions.size + 1, lines.size + # Headers + headers = 'Module,Permissions,' + Role.sorted.pluck(:name).join(',') + assert_equal headers, lines.first + # Order of permissions + permissions = permissions.group_by{|p| p.project_module.to_s}.sort.collect(&:last).flatten + module_permission_names = permissions.collect do |p| + [ + l_or_humanize(p.project_module.to_s, :prefix => 'project_module_').presence || '""', + l_or_humanize(p.name, :prefix => 'permission_'), + ] + end + assert_equal module_permission_names, (lines[1..-1].collect {|l| l.split(',')[0..1]}) + # Permissions of Edit notes + perm_edit_notes = lines.find {|l| l.start_with?('Issue tracking,Edit notes,')} + assert_equal 'Issue tracking,Edit notes,Yes,Yes,No,No,""', perm_edit_notes + end + def test_update_permissions post( :update_permissions,