diff options
author | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2011-01-16 15:23:11 +0000 |
---|---|---|
committer | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2011-01-16 15:23:11 +0000 |
commit | e9f62d1209bfa81df33bcb390eb67ba4cab90c0a (patch) | |
tree | 40dff8ceb02a30dce788799904d4a8c145d0d6e2 | |
parent | 0e3017dc62c672a291cda6053aaba6bda39b2de4 (diff) | |
download | redmine-e9f62d1209bfa81df33bcb390eb67ba4cab90c0a.tar.gz redmine-e9f62d1209bfa81df33bcb390eb67ba4cab90c0a.zip |
Enable ability for administrators to delete users (#7296).
User's personal data (eg. preferences, tokens, private queries...) are deleted, public data (eg. issues, wiki edits, attachments...) are reassigned to the anonymous user.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@4729 e93f8b46-1217-0410-a6f0-8f06a7374b81
-rw-r--r-- | app/controllers/users_controller.rb | 13 | ||||
-rw-r--r-- | app/views/users/edit.rhtml | 1 | ||||
-rw-r--r-- | app/views/users/index.rhtml | 5 | ||||
-rw-r--r-- | config/routes.rb | 3 | ||||
-rw-r--r-- | test/functional/users_controller_test.rb | 24 | ||||
-rw-r--r-- | test/integration/api_test/users_test.rb | 40 | ||||
-rw-r--r-- | test/integration/routing_test.rb | 3 |
7 files changed, 69 insertions, 20 deletions
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 2a213f5e8..c7f9dcf1b 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -19,8 +19,8 @@ class UsersController < ApplicationController layout 'admin' before_filter :require_admin, :except => :show - before_filter :find_user, :only => [:show, :edit, :update, :edit_membership, :destroy_membership] - accept_key_auth :index, :show, :create, :update + before_filter :find_user, :only => [:show, :edit, :update, :destroy, :edit_membership, :destroy_membership] + accept_key_auth :index, :show, :create, :update, :destroy helper :sort include SortHelper @@ -177,6 +177,15 @@ class UsersController < ApplicationController redirect_to :controller => 'users', :action => 'edit', :id => @user end + verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed } + def destroy + @user.destroy + respond_to do |format| + format.html { redirect_to(users_url) } + format.api { head :ok } + end + end + def edit_membership @membership = Member.edit_membership(params[:membership_id], params[:membership], @user) @membership.save if request.post? diff --git a/app/views/users/edit.rhtml b/app/views/users/edit.rhtml index 0d9cb0133..0c5883e8b 100644 --- a/app/views/users/edit.rhtml +++ b/app/views/users/edit.rhtml @@ -1,6 +1,7 @@ <div class="contextual"> <%= link_to l(:label_profile), user_path(@user), :class => 'icon icon-user' %> <%= change_status_link(@user) %> +<%= link_to(l(:button_delete), @user, :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del') if User.current != @user %> </div> <h2><%= link_to l(:label_user_plural), :controller => 'users', :action => 'index' %> » <%=h @user.login %></h2> diff --git a/app/views/users/index.rhtml b/app/views/users/index.rhtml index 69ad73747..07308265e 100644 --- a/app/views/users/index.rhtml +++ b/app/views/users/index.rhtml @@ -37,7 +37,10 @@ <td align="center"><%= checked_image user.admin? %></td> <td class="created_on" align="center"><%= format_time(user.created_on) %></td> <td class="last_login_on" align="center"><%= format_time(user.last_login_on) unless user.last_login_on.nil? %></td> - <td><small><%= change_status_link(user) %></small></td> + <td class="buttons"> + <%= change_status_link(user) %> + <%= link_to(l(:button_delete), user, :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del') unless User.current == user %> + </td> </tr> <% end -%> </tbody> diff --git a/config/routes.rb b/config/routes.rb index 3b37b5150..383d9cf89 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -122,8 +122,7 @@ ActionController::Routing::Routes.draw do |map| map.resources :users, :member => { :edit_membership => :post, :destroy_membership => :post - }, - :except => [:destroy] + } # For nice "roadmap" in the url for the index action map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index' diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb index 8aa311ebb..6837deab4 100644 --- a/test/functional/users_controller_test.rb +++ b/test/functional/users_controller_test.rb @@ -264,6 +264,30 @@ class UsersControllerTest < ActionController::TestCase assert u.check_password?('newpass') end + def test_destroy + assert_difference 'User.count', -1 do + delete :destroy, :id => 2 + end + assert_redirected_to '/users' + assert_nil User.find_by_id(2) + end + + def test_destroy_should_not_accept_get_requests + assert_no_difference 'User.count' do + get :destroy, :id => 2 + end + assert_response 405 + end + + def test_destroy_should_be_denied_for_non_admin_users + @request.session[:user_id] = 3 + + assert_no_difference 'User.count' do + get :destroy, :id => 2 + end + assert_response 403 + end + def test_edit_membership post :edit_membership, :id => 2, :membership_id => 1, :membership => { :role_ids => [2]} diff --git a/test/integration/api_test/users_test.rb b/test/integration/api_test/users_test.rb index e1eb7a237..00dc4cc95 100644 --- a/test/integration/api_test/users_test.rb +++ b/test/integration/api_test/users_test.rb @@ -245,26 +245,36 @@ class ApiTest::UsersTest < ActionController::IntegrationTest end end end + end - context "DELETE /users/2" do - context ".xml" do - should "not be allowed" do - assert_no_difference('User.count') do - delete '/users/2.xml' - end - - assert_response :method_not_allowed + context "DELETE /users/2" do + context ".xml" do + should_allow_api_authentication(:delete, + '/users/2.xml', + {}, + {:success_code => :ok}) + + should "delete user" do + assert_difference('User.count', -1) do + delete '/users/2.xml', {}, :authorization => credentials('admin') end + + assert_response :ok end - - context ".json" do - should "not be allowed" do - assert_no_difference('User.count') do - delete '/users/2.json' - end + end + + context ".json" do + should_allow_api_authentication(:delete, + '/users/2.xml', + {}, + {:success_code => :ok}) - assert_response :method_not_allowed + should "delete user" do + assert_difference('User.count', -1) do + delete '/users/2.json', {}, :authorization => credentials('admin') end + + assert_response :ok end end end diff --git a/test/integration/routing_test.rb b/test/integration/routing_test.rb index 4b18e317a..1198081fc 100644 --- a/test/integration/routing_test.rb +++ b/test/integration/routing_test.rb @@ -302,6 +302,9 @@ class RoutingTest < ActionController::IntegrationTest should_route :put, "/users/444", :controller => 'users', :action => 'update', :id => '444' should_route :put, "/users/444.xml", :controller => 'users', :action => 'update', :id => '444', :format => 'xml' + + should_route :delete, "/users/44", :controller => 'users', :action => 'destroy', :id => '44' + should_route :delete, "/users/44.xml", :controller => 'users', :action => 'destroy', :id => '44', :format => 'xml' end # TODO: should they all be scoped under /projects/:project_id ? |