diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 42df37c89c..42e6f1f3bc 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -13,6 +13,8 @@ #++ class IssuesController < ApplicationController + EXPORT_FORMATS = %w[atom rss api xls csv pdf] + menu_item :new_issue, :only => [:new, :create] menu_item :view_all_issues, :only => [:all] default_search_scope :issues @@ -22,6 +24,7 @@ class IssuesController < ApplicationController before_filter :check_project_uniqueness, :only => [:move, :perform_move] before_filter :find_project, :only => [:new, :create] before_filter :authorize, :except => [:index, :all] + before_filter :protect_from_unauthorized_export, :only => [:index, :all] before_filter :find_optional_project, :only => [:index, :all] before_filter :check_for_default_issue_status, :only => [:new, :create] before_filter :build_new_issue_from_params, :only => [:new, :create] @@ -320,4 +323,16 @@ private attributes[:custom_field_values].reject! {|k,v| v.blank?} if attributes[:custom_field_values] attributes end + + def protect_from_unauthorized_export + return true unless EXPORT_FORMATS.include? params[:format] + + find_optional_project + return true if User.current.allowed_to? :export_issues, @project + + # otherwise deny access + params[:format] = 'html' + deny_access + return false + end end diff --git a/app/views/issues/index.rhtml b/app/views/issues/index.rhtml index 72e593278b..f66c0fb43a 100644 --- a/app/views/issues/index.rhtml +++ b/app/views/issues/index.rhtml @@ -76,7 +76,7 @@ <%= f.link_to 'Atom', :url => { :project_id => @project, :query_id => (@query.new_record? ? nil : @query), :key => User.current.rss_key } %> <%= f.link_to 'CSV', :url => { :project_id => @project } %> <%= f.link_to 'PDF', :url => { :project_id => @project } %> -<% end %> +<% end if User.current.allowed_to? :export_issues, @project %> <% end %> <%= call_hook(:view_issues_index_bottom, { :issues => @issues, :project => @project, :query => @query }) %> diff --git a/lib/redmine.rb b/lib/redmine.rb index 359165c5ec..e70f5f223c 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -81,6 +81,7 @@ Redmine::AccessControl.map do |map| :journals => [:index, :diff], :queries => :index, :reports => [:issue_report, :issue_report_details]} + map.permission :export_issues, {:issues => [:index, :all]} map.permission :add_issues, {:issues => [:new, :create, :update_form]} map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new]} map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]} diff --git a/test/fixtures/roles.yml b/test/fixtures/roles.yml index cd2538cca9..afd33d0bc8 100644 --- a/test/fixtures/roles.yml +++ b/test/fixtures/roles.yml @@ -52,6 +52,7 @@ roles_001: - :manage_repository - :view_changesets - :manage_project_activities + - :export_issues position: 1 roles_002: diff --git a/test/unit/project_test.rb b/test/unit/project_test.rb index 575621ed39..7d7ec54a6c 100644 --- a/test/unit/project_test.rb +++ b/test/unit/project_test.rb @@ -725,7 +725,12 @@ class ProjectTest < ActiveSupport::TestCase assert_nil project.versions.detect {|v| v.completed? && v.status != 'closed'} assert_not_nil project.versions.detect {|v| !v.completed? && v.status == 'open'} end - + + def test_export_issues_is_allowed + project = Project.find(1) + assert project.allows_to?(:export_issues) + end + context "Project#copy" do setup do ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index b677eee30f..e5863e4ca3 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -443,6 +443,12 @@ class UserTest < ActiveSupport::TestCase assert @jsmith.allowed_to?(:delete_messages, project) #Manager assert ! @dlopper.allowed_to?(:delete_messages, project) #Developper end + + should "only managers are allowed to export tickets" do + project = Project.find(1) + assert @jsmith.allowed_to?(:export_issues, project) #Manager + assert ! @dlopper.allowed_to?(:export_issues, project) #Developper + end end context "with multiple projects" do