Merge pull request #2452 from TracksApp/feature/user_delete

Feature/user delete
This commit is contained in:
Jyri-Petteri Paloposki 2020-08-18 15:36:28 +03:00 committed by GitHub
commit 9c9802f040
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 65 additions and 14 deletions

View file

@ -154,6 +154,13 @@ class ApplicationController < ActionController::Base
end
end
def admin_or_self_login_required
unless User.find(session['user_id']).is_admin || session['user_id'] == params[:id].to_i
render :body => t('errors.user_unauthorized'), :status => 401
return false
end
end
def redirect_back_or_home
respond_to do |format|
format.html { redirect_back_or_default root_url }

View file

@ -1,6 +1,7 @@
class UsersController < ApplicationController
before_action :admin_login_required, :only => [ :index, :show, :destroy ]
before_action :admin_login_required, :only => [ :index, :show ]
before_action :admin_or_self_login_required, :only => [ :destroy ]
skip_before_action :login_required, :only => [ :new, :create ]
prepend_before_action :login_optional, :only => [ :new, :create ]
@ -103,7 +104,7 @@ class UsersController < ApplicationController
end
format.xml do
unless current_user && current_user.is_admin
render :body => "401 Unauthorized: Only admin users are allowed access to this function.", :status => 401
render :body => t('errors.user_unauthorized'), :status => 401
return
end
unless check_create_user_params
@ -131,8 +132,14 @@ class UsersController < ApplicationController
# DELETE /users/id DELETE /users/id.xml
def destroy
@deleted_user = User.find(params[:id])
# Remove the user
@saved = @deleted_user.destroy
@total_users = User.count
# Log out the user if they've deleted their own user and it succeeded.
if @saved && current_user == @deleted_user
logout_user
end
respond_to do |format|
format.html do
@ -141,10 +148,18 @@ class UsersController < ApplicationController
else
notify :error, t('users.failed_to_delete_user', :username => @deleted_user.login)
end
redirect_to users_url
if current_user == @deleted_user
redirect_to login
else
redirect_to users_url
end
end
format.js do
@total_users = User.count
end
format.xml do
head :ok
end
format.js
format.xml { head :ok }
end
end

View file

@ -18,4 +18,14 @@ module PreferencesHelper
pref(model, pref_name) { text_field(model, pref_name, class: "form-control") }
end
def profile_delete_user(user)
return link_to(
t('users.destroy_user'),
url_for({:controller => 'users', :action => 'destroy', :id => user.id}),
{:id => "delete_user_#{user.id}",
:class => "delete_user_button btn btn-danger",
:title => t('users.destroy_user'),
:x_confirm_message => t('users.destroy_confirmation', :login => user.login)
})
end
end

View file

@ -7,7 +7,7 @@ class User < ApplicationRecord
#for will_paginate plugin
cattr_accessor :per_page
@@per_page = 5
@@per_page = 10
has_many(:contexts, -> { order 'position ASC' }, dependent: :delete_all) do
def find_by_params(params)

View file

@ -0,0 +1,4 @@
<p><%= t 'preferences.remove_introduction' %></p>
<div class="form-group">
<%= profile_delete_user(@user) %>
</div>

View file

@ -21,16 +21,20 @@
<li role="presentation">
<%= link_to t('preferences.tabs.tracks_behavior'), "#behavior", data: { toggle: "tab" } %>
</li>
<li role="presentation">
<%= link_to t('preferences.tabs.remove_account'), "#remove_account", data: { toggle: "tab" } %>
</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="profile"><%= render :partial => 'profile'%></div>
<div role="tabpanel" class="tab-pane" id="authentication"><%= render :partial => 'authentication'%></div>
<div role="tabpanel" class="tab-pane" id="date_and_time"><%= render :partial => 'date_and_time'%></div>
<div role="tabpanel" class="tab-pane" id="behavior"><%= render :partial => 'tracks_behavior'%></div>
<div role="tabpanel" class="tab-pane" id="remove_account"><%= render :partial => 'remove_account'%></div>
</div>
<div class="btn-group" role="group" aria-label="Basic example">
<button type="submit" id="prefs_submit" class="btn btn-default"><%= t('common.update') %></button>
</div>
<button type="submit" id="prefs_submit" class="btn btn-default"><%= t('common.update') %></button>
<% end %>
</div>
</div>

View file

@ -821,11 +821,13 @@ en:
authentication_header: Your authentication
current_authentication_type: Your authentication type is %{auth_type}
change_authentication_type: Change your authentication type
remove_introduction: You can remove your user account here. Note that this is irreversible and will remove all your data! After removal you will be logged out.
tabs:
authentication: Authentication
tracks_behavior: Tracks behavior
profile: Profile
date_and_time: Date and time
remove_account: Remove account
generate_new_token_confirm: Are you sure? Generating a new token will replace the existing one and break any external usages of this token.
data:
import_successful: Import was successful.

View file

@ -106,7 +106,7 @@ Rails.application.routes.draw do
# This means the controller action needs to parse the extension and set format/content type
# Needed for /todos/tag/first.last.m to work
get 'todos/tag/:name' => 'todos#tag', :as => :tag, :format => false, :name => /.*/
get 'attachments/:id/:filename' => "todos#attachment"
get 'tags.autocomplete' => "todos#tags", :format => 'autocomplete'
get 'todos/done/tag/:name' => "todos#done_tag", :as => :done_tag

View file

@ -222,6 +222,7 @@ private
def redirect_to_login
respond_to do |format|
format.html { redirect_to login_path }
format.js { render js: "redirect_to('" + login_path + "')" }
format.m { redirect_to login_path(:format => 'm') }
end
end

View file

@ -36,7 +36,7 @@ class UsersControllerTest < ActionController::TestCase
assert_equal assigns['users'],[User.where(:login => 'jane').first]
end
def test_destroy_user
def test_destroy_user_as_admin
login_as :admin_user
@no_users_before = User.count
user_id = users(:ldap_user).id
@ -44,8 +44,16 @@ class UsersControllerTest < ActionController::TestCase
assert_equal @no_users_before-1, User.count
end
def test_destroy_user_as_user
login_as :other_user
@no_users_before = User.count
user_id = users(:other_user).id
post :destroy, xhr: true, params: { :id => user_id.to_param }
assert_equal @no_users_before-1, User.count
end
def test_update_password_successful
get :change_password, params: { :id => users(:admin_user).id }
get :change_password, params: { :id => users(:admin_user).id }
# should fail because no login
assert_redirected_to login_path
login_as :admin_user

View file

@ -140,7 +140,7 @@ class ActionDispatch::IntegrationTest
end
def assert_401_unauthorized_admin
assert_response_and_body 401, "401 Unauthorized: Only admin users are allowed access to this function."
assert_response_and_body 401, "401 Unauthorized: Only administrative users are allowed access to this function."
end
def assert_responses_with_error(error_msg)