Merge pull request #5576 from tchak/soft-delete-users

Soft delete users
This commit is contained in:
Paul Chavard 2020-09-17 11:35:52 +02:00 committed by GitHub
commit bf0d3914ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 67 additions and 5 deletions

View file

@ -1,5 +1,10 @@
module Manager
class UsersController < Manager::ApplicationController
def scoped_resource
# Don't display discarded users
User.kept
end
def update
user = User.find(params[:id])
new_email = params[:user][:email]
@ -36,10 +41,10 @@ module Manager
def delete
user = User.find(params[:id])
if !user.can_be_deleted?
fail "Impossible de supprimer cet utilisateur. Il a des dossiers en instruction ou il est administrateur."
if !user.can_be_discarded?
fail "Impossible de supprimer cet utilisateur. Il est instructeur ou administrateur."
end
user.delete_and_keep_track_dossiers(current_administration)
user.delete_or_discard!(current_administration)
logger.info("L'utilisateur #{user.id} est supprimé par #{current_administration.id}")
flash[:notice] = "L'utilisateur #{user.id} est supprimé"

View file

@ -8,6 +8,8 @@
# confirmed_at :datetime
# current_sign_in_at :datetime
# current_sign_in_ip :string
# discard_reason :string
# discarded_at :datetime
# email :string default(""), not null
# encrypted_password :string default(""), not null
# failed_attempts :integer default(0), not null
@ -29,6 +31,7 @@
#
class User < ApplicationRecord
include EmailSanitizableConcern
include Discard::Model
enum loged_in_with_france_connect: {
particulier: 'particulier',
@ -56,6 +59,10 @@ class User < ApplicationRecord
# Override of Devise::Models::Confirmable#send_confirmation_instructions
def send_confirmation_instructions
if discarded?
return
end
unless @raw_confirmation_token
generate_confirmation_token!
end
@ -139,8 +146,12 @@ class User < ApplicationRecord
last_sign_in_at.present?
end
def can_be_discarded?
administrateur.nil? && instructeur.nil?
end
def can_be_deleted?
administrateur.nil? && instructeur.nil? && dossiers.with_discarded.state_instruction_commencee.empty?
can_be_discarded? && dossiers.with_discarded.state_instruction_commencee.empty?
end
def delete_and_keep_track_dossiers(administration)
@ -155,6 +166,32 @@ class User < ApplicationRecord
destroy!
end
def discard_and_anonymize!(reason)
if !can_be_discarded?
raise "Cannot discard this user because they are also instructeur or administrateur"
end
discard!
update_columns(
discard_reason: reason,
email: "#{SecureRandom.hex}@anonymous.org",
encrypted_password: SecureRandom.hex,
unconfirmed_email: nil,
current_sign_in_at: nil,
current_sign_in_ip: nil,
last_sign_in_at: nil,
last_sign_in_ip: nil
)
end
def delete_or_discard!(administration)
if can_be_deleted?
delete_and_keep_track_dossiers(administration)
else
discard_and_anonymize!("Discarded by Manager##{administration.id}")
end
end
private
def link_invites!

View file

@ -0,0 +1,6 @@
class AddDiscardReasonAndDiscardedAtToUsers < ActiveRecord::Migration[6.0]
def change
add_column :users, :discard_reason, :string
add_column :users, :discarded_at, :datetime
end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_09_02_103047) do
ActiveRecord::Schema.define(version: 2020_09_16_113507) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -650,6 +650,8 @@ ActiveRecord::Schema.define(version: 2020_09_02_103047) do
t.datetime "locked_at"
t.bigint "instructeur_id"
t.bigint "administrateur_id"
t.string "discard_reason"
t.datetime "discarded_at"
t.index ["administrateur_id"], name: "index_users_on_administrateur_id"
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
t.index ["email"], name: "index_users_on_email", unique: true

View file

@ -293,4 +293,16 @@ describe User, type: :model do
end
end
end
describe '#discard_and_anonymize!' do
let(:user) { create(:user) }
before { user.discard_and_anonymize!('HS1234') }
it 'should discard user and make it anonymous' do
expect(user.discarded?).to be_truthy
expect(user.email).to end_with '@anonymous.org'
expect(user.discard_reason).to eq('HS1234')
end
end
end