diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index c5c98d6fd..ee09d3ba3 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -24,8 +24,8 @@ class ProjectsController < ApplicationController before_action :find_project, :except => [ :index, :autocomplete, :list, :new, :create, :copy ] before_action :authorize, :except => [ :index, :autocomplete, :list, :new, :create, :copy, :archive, :unarchive, :destroy] - before_action :authorize_global, :only => [:new, :create] - before_action :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ] + before_action :authorize_global, :only => [:new, :create, :copy] + before_action :require_admin, :only => [ :archive, :unarchive, :destroy ] accept_rss_auth :index accept_api_auth :index, :show, :create, :update, :destroy require_sudo_mode :destroy @@ -139,6 +139,9 @@ class ProjectsController < ApplicationController @project = Project.new @project.safe_attributes = params[:project] if @project.copy(@source_project, :only => params[:only]) + unless User.current.admin? + @project.add_default_member(User.current) + end flash[:notice] = l(:notice_successful_create) redirect_to settings_project_path(@project) elsif !@project.new_record? diff --git a/app/views/projects/show.html.erb b/app/views/projects/show.html.erb index de99eeabe..54910f500 100644 --- a/app/views/projects/show.html.erb +++ b/app/views/projects/show.html.erb @@ -5,6 +5,9 @@ <% if User.current.allowed_to?(:add_subprojects, @project) %> <%= link_to l(:label_subproject_new), new_project_path(:parent_id => @project), :class => 'icon icon-add' %> <% end %> + <% if User.current.allowed_to?(:add_project, @project) %> + <%= link_to(l(:button_copy), copy_project_path(@project), :class => 'icon icon-copy') %> + <% end %> <% if User.current.allowed_to?(:close_project, @project) %> <% if @project.active? %> <%= link_to l(:button_close), close_project_path(@project), :data => {:confirm => l(:text_are_you_sure)}, :method => :post, :class => 'icon icon-lock' %> diff --git a/lib/redmine.rb b/lib/redmine.rb index 9ecca63c3..73513e37c 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -80,7 +80,7 @@ Redmine::Scm::Base.add "Filesystem" Redmine::AccessControl.map do |map| map.permission :view_project, {:projects => [:show, :bookmark], :activities => [:index]}, :public => true, :read => true map.permission :search_project, {:search => :index}, :public => true, :read => true - map.permission :add_project, {:projects => [:new, :create]}, :require => :loggedin + map.permission :add_project, {:projects => [:new, :create, :copy]}, :require => :loggedin map.permission :edit_project, {:projects => [:settings, :edit, :update]}, :require => :member map.permission :close_project, {:projects => [:close, :reopen]}, :require => :member, :read => true map.permission :select_project_modules, {:projects => :modules}, :require => :member diff --git a/test/functional/projects_controller_test.rb b/test/functional/projects_controller_test.rb index 975e3bb6a..fd75ec9da 100644 --- a/test/functional/projects_controller_test.rb +++ b/test/functional/projects_controller_test.rb @@ -1121,8 +1121,19 @@ class ProjectsControllerTest < Redmine::ControllerTest end end - def test_get_copy + def test_get_copy_by_admin_user @request.session[:user_id] = 1 # admin + orig = Project.find(1) # Login user is no member + get(:copy, :params => {:id => orig.id}) + assert_response :success + + assert_select 'textarea[name=?]', 'project[description]', :text => orig.description + assert_select 'input[name=?][value=?]', 'project[enabled_module_names][]', 'issue_tracking', 1 + end + + def test_get_copy_by_non_admin_user_with_copy_project_permission + @request.session[:user_id] = 3 + Role.find(2).add_permission! :add_project orig = Project.find(1) get :copy, :params => { @@ -1134,6 +1145,14 @@ class ProjectsControllerTest < Redmine::ControllerTest assert_select 'input[name=?][value=?]', 'project[enabled_module_names][]', 'issue_tracking', 1 end + def test_get_copy_by_non_admin_user_without_copy_project_permission_should_respond_with_403 + @request.session[:user_id] = 3 + Role.find(2).remove_permission! :add_project + orig = Project.find(1) + get(:copy, :params => {:id => orig.id}) + assert_response 403 + end + def test_get_copy_with_invalid_source_should_respond_with_404 @request.session[:user_id] = 1 get :copy, :params => { @@ -1195,6 +1214,32 @@ class ProjectsControllerTest < Redmine::ControllerTest assert_redirected_to :controller => 'projects', :action => 'settings', :id => 'unique-copy' end + def test_post_copy_by_non_admin_user_should_redirect_to_settings_when_successful + @request.session[:user_id] = 2 # manager + post :copy, :params => { + :id => 2, + :project => { + :name => 'Copy', + :identifier => 'unique-copy' + }, + :only => %w(issues) + } + + project = Project.find('unique-copy') + # non admin user should be added as project member + assert_equal 1, project.members.count + + assert_response :redirect + assert_redirected_to :controller => 'projects', :action => 'settings', :id => 'unique-copy' + + # is the user allowed to view the project settings + get :settings, :params => { + :id => 'unique-copy' + } + assert_response :success + end + + def test_post_copy_with_failure @request.session[:user_id] = 1 post :copy, :params => {