mirror of
https://github.com/meineerde/redmine.git
synced 2025-12-19 15:01:14 +00:00
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
This commit is contained in:
parent
0e3017dc62
commit
e9f62d1209
@ -19,8 +19,8 @@ class UsersController < ApplicationController
|
|||||||
layout 'admin'
|
layout 'admin'
|
||||||
|
|
||||||
before_filter :require_admin, :except => :show
|
before_filter :require_admin, :except => :show
|
||||||
before_filter :find_user, :only => [:show, :edit, :update, :edit_membership, :destroy_membership]
|
before_filter :find_user, :only => [:show, :edit, :update, :destroy, :edit_membership, :destroy_membership]
|
||||||
accept_key_auth :index, :show, :create, :update
|
accept_key_auth :index, :show, :create, :update, :destroy
|
||||||
|
|
||||||
helper :sort
|
helper :sort
|
||||||
include SortHelper
|
include SortHelper
|
||||||
@ -177,6 +177,15 @@ class UsersController < ApplicationController
|
|||||||
redirect_to :controller => 'users', :action => 'edit', :id => @user
|
redirect_to :controller => 'users', :action => 'edit', :id => @user
|
||||||
end
|
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
|
def edit_membership
|
||||||
@membership = Member.edit_membership(params[:membership_id], params[:membership], @user)
|
@membership = Member.edit_membership(params[:membership_id], params[:membership], @user)
|
||||||
@membership.save if request.post?
|
@membership.save if request.post?
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
<div class="contextual">
|
<div class="contextual">
|
||||||
<%= link_to l(:label_profile), user_path(@user), :class => 'icon icon-user' %>
|
<%= link_to l(:label_profile), user_path(@user), :class => 'icon icon-user' %>
|
||||||
<%= change_status_link(@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>
|
</div>
|
||||||
|
|
||||||
<h2><%= link_to l(:label_user_plural), :controller => 'users', :action => 'index' %> » <%=h @user.login %></h2>
|
<h2><%= link_to l(:label_user_plural), :controller => 'users', :action => 'index' %> » <%=h @user.login %></h2>
|
||||||
|
|||||||
@ -37,7 +37,10 @@
|
|||||||
<td align="center"><%= checked_image user.admin? %></td>
|
<td align="center"><%= checked_image user.admin? %></td>
|
||||||
<td class="created_on" align="center"><%= format_time(user.created_on) %></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 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>
|
</tr>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@ -122,8 +122,7 @@ ActionController::Routing::Routes.draw do |map|
|
|||||||
map.resources :users, :member => {
|
map.resources :users, :member => {
|
||||||
:edit_membership => :post,
|
:edit_membership => :post,
|
||||||
:destroy_membership => :post
|
:destroy_membership => :post
|
||||||
},
|
}
|
||||||
:except => [:destroy]
|
|
||||||
|
|
||||||
# For nice "roadmap" in the url for the index action
|
# For nice "roadmap" in the url for the index action
|
||||||
map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
|
map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
|
||||||
|
|||||||
@ -264,6 +264,30 @@ class UsersControllerTest < ActionController::TestCase
|
|||||||
assert u.check_password?('newpass')
|
assert u.check_password?('newpass')
|
||||||
end
|
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
|
def test_edit_membership
|
||||||
post :edit_membership, :id => 2, :membership_id => 1,
|
post :edit_membership, :id => 2, :membership_id => 1,
|
||||||
:membership => { :role_ids => [2]}
|
:membership => { :role_ids => [2]}
|
||||||
|
|||||||
@ -245,26 +245,36 @@ class ApiTest::UsersTest < ActionController::IntegrationTest
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "DELETE /users/2" do
|
context "DELETE /users/2" do
|
||||||
context ".xml" do
|
context ".xml" do
|
||||||
should "not be allowed" do
|
should_allow_api_authentication(:delete,
|
||||||
assert_no_difference('User.count') do
|
'/users/2.xml',
|
||||||
delete '/users/2.xml'
|
{},
|
||||||
end
|
{:success_code => :ok})
|
||||||
|
|
||||||
assert_response :method_not_allowed
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context ".json" do
|
should "delete user" do
|
||||||
should "not be allowed" do
|
assert_difference('User.count', -1) do
|
||||||
assert_no_difference('User.count') do
|
delete '/users/2.xml', {}, :authorization => credentials('admin')
|
||||||
delete '/users/2.json'
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_response :method_not_allowed
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
assert_response :ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context ".json" 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.json', {}, :authorization => credentials('admin')
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_response :ok
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -302,6 +302,9 @@ class RoutingTest < ActionController::IntegrationTest
|
|||||||
|
|
||||||
should_route :put, "/users/444", :controller => 'users', :action => 'update', :id => '444'
|
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 :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
|
end
|
||||||
|
|
||||||
# TODO: should they all be scoped under /projects/:project_id ?
|
# TODO: should they all be scoped under /projects/:project_id ?
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user