Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow user deletion from admin #1262

Merged
merged 8 commits into from
Nov 6, 2024
Merged

allow user deletion from admin #1262

merged 8 commits into from
Nov 6, 2024

Conversation

mwvolo
Copy link
Member

@mwvolo mwvolo commented Oct 8, 2024

To incorporate a better customer support process and have mechanisms to comply with privacy requirements.
This adds a button to the edit user page, which allows a user account to be deleted.

@mwvolo mwvolo requested a review from Dantemss October 9, 2024 15:19
@Dantemss
Copy link
Member

Dantemss commented Oct 9, 2024

I'm thinking this will fail to delete any activated users, since it delegates to https://github.com/openstax/accounts/blob/main/app/routines/destroy_user.rb

You also need to think what you want to do with all the records that have foreign keys to user, like external_id.

It may be easier to just erase the user name, password and contact infos instead (and username but that's old)?

@Dantemss
Copy link
Member

Dantemss commented Oct 9, 2024

I think that's what GitHub does anyway. The reason why you become "ghost" when you are deleted here.

@Dantemss
Copy link
Member

Dantemss commented Oct 9, 2024

Actually they say they delete your record but associate some of your foreign keys with "ghost".

@mwvolo
Copy link
Member Author

mwvolo commented Oct 9, 2024

Are you sure this is delegated to that routine? I'm not seeing the connection, but maybe it's some rails magic I don't understand. It looks like it's only using that routine on merge_unclaimed_user and transfer_authentications.

Emptying out the identifying info seems reasonable to me, if you think that is a better way. It's what CS is doing now, so building an automated way to do that is what I'm trying to accomplish.

@mwvolo
Copy link
Member Author

mwvolo commented Oct 9, 2024

FWIW, it did work locally on an activated student and instructor account, but I guess I should make sure it deleted all those foreign keys in the DB.

@Dantemss
Copy link
Member

Dantemss commented Oct 9, 2024

@Dantemss
Copy link
Member

Dantemss commented Oct 9, 2024

If actually deleting the record:

You have to go through all the has_many/has_one in User and ensure all of them are handled.

dependent: :destroy will destroy the associated record and may be necessary for some validations

Without dependent: :destroy by default it may try to leave the record as-is or nullify the foreign key (not sure which). Need to make sure the foreign key constraint, if any, allows that. And also probably add optional: true to the belongs_to :user in the other record.

@mwvolo mwvolo marked this pull request as draft October 9, 2024 20:00
@@ -1,7 +1,7 @@
class ApplicationUser < ApplicationRecord
belongs_to :application, class_name: 'Doorkeeper::Application',
inverse_of: :application_users
belongs_to :user, inverse_of: :application_users
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably not be optional, since the DB still requires it.

class Authentication < ApplicationRecord
belongs_to :user, inverse_of: :authentications
belongs_to :user, inverse_of: :authentications, optional: true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oddly enough, optional is correct here because the column is nullable in the DB.

@@ -20,6 +22,8 @@ def display_name
protected

def check_not_last
return if user.is_deleted?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the above, you may want user.nil? || user.is_deleted? or something similar.

user.save!

user.external_ids.destroy_all
user.external_uuids.destroy_all
Copy link
Member

@Dantemss Dantemss Oct 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't even realize we had both. Maybe external_uuids can be deleted. I think they just stored the UUID that Tutor used? Eh for the purposes of this PR don't worry about it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sure we could have an entire PR dedicated to remove tutor-specific features 😂

@@ -0,0 +1,5 @@
class AddDeleteFlagToUser < ActiveRecord::Migration[5.2]
def change
add_column :users, :is_deleted, :boolean
Copy link
Member

@Dantemss Dantemss Oct 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make this null: false, default: false just to prevent having 3 possible values. Adding a column with null: false is fine as long as default is also set.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually ignore what I said because adding a column with a default rewrites the entire table and we have a ton of users.

@mwvolo mwvolo marked this pull request as ready for review October 25, 2024 01:35
@mwvolo mwvolo requested a review from Dantemss October 28, 2024 20:53
@mwvolo mwvolo merged commit 0b2e6b4 into main Nov 6, 2024
6 checks passed
@mwvolo mwvolo deleted the allow-user-delete branch November 6, 2024 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants