Project

General

Profile

Feature #13767 » 13767.patch

Yuichi HARADA, 2021-03-03 09:13

View differences:

app/controllers/roles_controller.rb
26 26
  before_action :find_role, :only => [:show, :edit, :update, :destroy]
27 27
  accept_api_auth :index, :show
28 28

  
29
  include RolesHelper
30

  
29 31
  require_sudo_mode :create, :update, :destroy
30 32

  
31 33
  def index
......
109 111
    end
110 112
    @roles = scope.to_a
111 113
    @permissions = Redmine::AccessControl.permissions.select {|p| !p.public?}
114
    respond_to do |format|
115
      format.html
116
      format.csv do
117
        send_data(permissions_to_csv(@roles, @permissions), :type => 'text/csv; header=present', :filename => 'permissions_export.csv')
118
      end
119
    end
112 120
  end
113 121

  
114 122
  def update_permissions
app/helpers/roles_helper.rb
18 18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 19

  
20 20
module RolesHelper
21
  include ApplicationHelper
22

  
23
  def permissions_to_csv(roles, permissions)
24
    Redmine::Export::CSV.generate do |csv|
25
      # csv header fields
26
      headers = [l(:field_cvs_module), l(:label_permissions)] + roles.collect {|role| role.name}
27
      csv << headers
28
      # csv lines
29
      perms_by_module = permissions.group_by {|p| p.project_module.to_s}
30
      perms_by_module.keys.sort.each do |mod|
31
        perms_by_module[mod].each do |p|
32
          names = [
33
            l_or_humanize(p.project_module.to_s, :prefix => 'project_module_'),
34
            l_or_humanize(p.name, :prefix => 'permission_').to_s,
35
          ]
36
          fields = names + roles.collect do |role|
37
            if role.setable_permissions.include?(p)
38
              format_object(role.permissions.include?(p.name), false)
39
            else
40
              ""
41
            end
42
          end
43
          csv << fields
44
        end
45
      end
46
    end
47
  end
21 48
end
app/views/roles/permissions.html.erb
85 85
<p><%= check_all_links 'permissions_form' %></p>
86 86
<p><%= submit_tag l(:button_save) %></p>
87 87
<% end %>
88
<% other_formats_links do |f| %>
89
  <%= f.link_to 'CSV' %>
90
<% end %>
test/functional/roles_controller_test.rb
22 22
class RolesControllerTest < Redmine::ControllerTest
23 23
  fixtures :roles, :users, :members, :member_roles, :workflows, :trackers
24 24

  
25
  include Redmine::I18n
26

  
25 27
  def setup
26 28
    User.current = nil
27 29
    @request.session[:user_id] = 1 # admin
......
270 272
    assert_select 'input[name=?][type=checkbox][value=delete_issues]:not([checked])', 'permissions[3][]'
271 273
  end
272 274

  
275
  def test_permissions_csv_export
276
    Role.all do |r|
277
      r.permissions=[]
278
      r.save!
279
    end
280
    ['Manager', 'Developer'].each do |name|
281
      role = Role.find_by(:name => name)
282
      role.permissions = [:edit_issue_notes]
283
      role.save!
284
    end
285

  
286
    get(
287
      :permissions,
288
      :params => {
289
        :format => 'csv'
290
      }
291
    )
292
    assert_response :success
293

  
294
    assert_equal 'text/csv', @response.media_type
295
    lines = @response.body.chomp.split("\n")
296
    # Number of lines
297
    permissions = Redmine::AccessControl.permissions - Redmine::AccessControl.public_permissions
298
    assert_equal permissions.size + 1, lines.size
299
    # Headers
300
    headers = 'Module,Permissions,' + Role.sorted.pluck(:name).join(',')
301
    assert_equal headers, lines.first
302
    # Order of permissions
303
    permissions = permissions.group_by{|p| p.project_module.to_s}.sort.collect(&:last).flatten
304
    module_permission_names = permissions.collect do |p|
305
      [
306
        l_or_humanize(p.project_module.to_s, :prefix => 'project_module_').presence || '""',
307
        l_or_humanize(p.name, :prefix => 'permission_'),
308
      ]
309
    end
310
    assert_equal module_permission_names, (lines[1..-1].collect {|l| l.split(',')[0..1]})
311
    # Permissions of Edit notes
312
    perm_edit_notes = lines.find {|l| l.start_with?('Issue tracking,Edit notes,')}
313
    assert_equal 'Issue tracking,Edit notes,Yes,Yes,No,No,""', perm_edit_notes
314
  end
315

  
273 316
  def test_update_permissions
274 317
    post(
275 318
      :update_permissions,
(2-2/4)