Feature #4687 » project_copy.patch
app/controllers/projects_controller.rb | ||
---|---|---|
24 | 24 | |
25 | 25 |
before_action :find_project, :except => [ :index, :autocomplete, :list, :new, :create, :copy ] |
26 | 26 |
before_action :authorize, :except => [ :index, :autocomplete, :list, :new, :create, :copy, :archive, :unarchive, :destroy] |
27 |
before_action :authorize_global, :only => [:new, :create] |
|
28 |
before_action :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ]
|
|
27 |
before_action :authorize_global, :only => [:new, :create, :copy]
|
|
28 |
before_action :require_admin, :only => [ :archive, :unarchive, :destroy ] |
|
29 | 29 |
accept_rss_auth :index |
30 | 30 |
accept_api_auth :index, :show, :create, :update, :destroy |
31 | 31 |
require_sudo_mode :destroy |
... | ... | |
139 | 139 |
@project = Project.new |
140 | 140 |
@project.safe_attributes = params[:project] |
141 | 141 |
if @project.copy(@source_project, :only => params[:only]) |
142 |
unless User.current.admin? |
|
143 |
@project.add_default_member(User.current) |
|
144 |
end |
|
142 | 145 |
flash[:notice] = l(:notice_successful_create) |
143 | 146 |
redirect_to settings_project_path(@project) |
144 | 147 |
elsif !@project.new_record? |
app/views/projects/show.html.erb | ||
---|---|---|
5 | 5 |
<% if User.current.allowed_to?(:add_subprojects, @project) %> |
6 | 6 |
<%= link_to l(:label_subproject_new), new_project_path(:parent_id => @project), :class => 'icon icon-add' %> |
7 | 7 |
<% end %> |
8 |
<% if User.current.allowed_to?(:add_project, @project) %> |
|
9 |
<%= link_to(l(:button_copy), copy_project_path(@project), :class => 'icon icon-copy') %> |
|
10 |
<% end %> |
|
8 | 11 |
<% if User.current.allowed_to?(:close_project, @project) %> |
9 | 12 |
<% if @project.active? %> |
10 | 13 |
<%= link_to l(:button_close), close_project_path(@project), :data => {:confirm => l(:text_are_you_sure)}, :method => :post, :class => 'icon icon-lock' %> |
lib/redmine.rb | ||
---|---|---|
80 | 80 |
Redmine::AccessControl.map do |map| |
81 | 81 |
map.permission :view_project, {:projects => [:show, :bookmark], :activities => [:index]}, :public => true, :read => true |
82 | 82 |
map.permission :search_project, {:search => :index}, :public => true, :read => true |
83 |
map.permission :add_project, {:projects => [:new, :create]}, :require => :loggedin |
|
83 |
map.permission :add_project, {:projects => [:new, :create, :copy]}, :require => :loggedin
|
|
84 | 84 |
map.permission :edit_project, {:projects => [:settings, :edit, :update]}, :require => :member |
85 | 85 |
map.permission :close_project, {:projects => [:close, :reopen]}, :require => :member, :read => true |
86 | 86 |
map.permission :select_project_modules, {:projects => :modules}, :require => :member |
test/functional/projects_controller_test.rb | ||
---|---|---|
1121 | 1121 |
end |
1122 | 1122 |
end |
1123 | 1123 | |
1124 |
def test_get_copy |
|
1124 |
def test_get_copy_by_admin_user
|
|
1125 | 1125 |
@request.session[:user_id] = 1 # admin |
1126 |
orig = Project.find(1) # Login user is no member |
|
1127 |
get(:copy, :params => {:id => orig.id}) |
|
1128 |
assert_response :success |
|
1129 | ||
1130 |
assert_select 'textarea[name=?]', 'project[description]', :text => orig.description |
|
1131 |
assert_select 'input[name=?][value=?]', 'project[enabled_module_names][]', 'issue_tracking', 1 |
|
1132 |
end |
|
1133 | ||
1134 |
def test_get_copy_by_non_admin_user_with_copy_project_permission |
|
1135 |
@request.session[:user_id] = 3 |
|
1136 |
Role.find(2).add_permission! :add_project |
|
1126 | 1137 |
orig = Project.find(1) |
1127 | 1138 | |
1128 | 1139 |
get :copy, :params => { |
... | ... | |
1134 | 1145 |
assert_select 'input[name=?][value=?]', 'project[enabled_module_names][]', 'issue_tracking', 1 |
1135 | 1146 |
end |
1136 | 1147 | |
1148 |
def test_get_copy_by_non_admin_user_without_copy_project_permission_should_respond_with_403 |
|
1149 |
@request.session[:user_id] = 3 |
|
1150 |
Role.find(2).remove_permission! :add_project |
|
1151 |
orig = Project.find(1) |
|
1152 |
get(:copy, :params => {:id => orig.id}) |
|
1153 |
assert_response 403 |
|
1154 |
end |
|
1155 | ||
1137 | 1156 |
def test_get_copy_with_invalid_source_should_respond_with_404 |
1138 | 1157 |
@request.session[:user_id] = 1 |
1139 | 1158 |
get :copy, :params => { |
... | ... | |
1195 | 1214 |
assert_redirected_to :controller => 'projects', :action => 'settings', :id => 'unique-copy' |
1196 | 1215 |
end |
1197 | 1216 | |
1217 |
def test_post_copy_by_non_admin_user_should_redirect_to_settings_when_successful |
|
1218 |
@request.session[:user_id] = 2 # manager |
|
1219 |
post :copy, :params => { |
|
1220 |
:id => 2, |
|
1221 |
:project => { |
|
1222 |
:name => 'Copy', |
|
1223 |
:identifier => 'unique-copy' |
|
1224 |
}, |
|
1225 |
:only => %w(issues) |
|
1226 |
} |
|
1227 | ||
1228 |
project = Project.find('unique-copy') |
|
1229 |
# non admin user should be added as project member |
|
1230 |
assert_equal 1, project.members.count |
|
1231 | ||
1232 |
assert_response :redirect |
|
1233 |
assert_redirected_to :controller => 'projects', :action => 'settings', :id => 'unique-copy' |
|
1234 | ||
1235 |
# is the user allowed to view the project settings |
|
1236 |
get :settings, :params => { |
|
1237 |
:id => 'unique-copy' |
|
1238 |
} |
|
1239 |
assert_response :success |
|
1240 |
end |
|
1241 | ||
1242 | ||
1198 | 1243 |
def test_post_copy_with_failure |
1199 | 1244 |
@request.session[:user_id] = 1 |
1200 | 1245 |
post :copy, :params => { |