Excluindo usuários no console do Rails

Estamos usando SSO para fazer login de usuários autenticados em nosso site principal.

Um de nossos usuários recebeu uma mensagem (no login) de que houve um erro e que ela deveria entrar em contato com um administrador. Então, procuramos por ela, mas não conseguimos encontrar o perfil dela.

Fiz a primeira e melhor coisa que pude imaginar e “excluí” ela via linha de comando:

 User.find_by(email: "ex@example.com").delete

O que não foi inteligente e não funcionou de verdade. Quando ela tentou fazer login, ela se deparou com o mesmo erro. Agora, o perfil dela existe (não encontrável via busca, mas via URL), mas sem e-mail, salt ou hash de senha.

Como posso removê-la do sistema de uma forma que ela possa fazer login novamente?

Fico grato por qualquer orientação.

Em anexo, o perfil quando buscado por user.find_by:

id: 1541,
 username: "anon.nymus",
 created_at: Tue, 15 May 2018 17:25:11 UTC +00:00,
 updated_at: Sun, 02 Feb 2020 07:00:59 UTC +00:00,
 name: "Anon Nymus",
 seen_notification_id: 29204,
 last_posted_at: Mon, 28 May 2018 17:42:14 UTC +00:00,
 password_hash: nil,
 salt: nil,
 active: false,
 username_lower: "anon.nymus",
 last_seen_at: Thu, 17 May 2018 19:55:26 UTC +00:00,
 admin: false,
 last_emailed_at: Sun, 02 Feb 2020 07:01:07 UTC +00:00,
 last_emailed_at: Sun, 02 Feb 2020 07:01:07 UTC +00:00,
 trust_level: 2,
 approved: false,
 approved_by_id: nil,
 approved_at: nil,
 previous_visit_at: Wed, 16 May 2018 18:21:47 UTC +00:00,
 suspended_at: nil,
 suspended_till: nil,
 date_of_birth: nil,
 views: 0,
 flag_level: 0,
 ip_address: #################
 moderator: false,
 title: nil,
 uploaded_avatar_id: nil,
 locale: nil,
 primary_group_id: 49,
 registration_ip_address: nil,
 staged: false,
 first_seen_at: Tue, 15 May 2018 17:26:19 UTC +00:00,
 silenced_till: nil,
 group_locked_trust_level: nil,
 manual_locked_trust_level: nil,
 secure_identifier: nil>

Você deve usar o UserDestroyer para deletar um usuário corretamente. Algo assim deve funcionar:

UserDestroyer.new(Discourse.system_user).destroy(User.find_by_username_or_email("ex@example.com"), delete_posts: false)

Isso fará com que o usuário do sistema delete o usuário com o e-mail ex@example.com. Você também pode fornecer um nome de usuário em vez do e-mail.

Se quiser que os logs mostrem quem deletou o usuário, substitua Discourse.system_user por User.find_by_username_or_email("admin@example.com"), onde admin@example.com é o e-mail de um administrador do site.

Olá, Joshua, e obrigado pela sua rápida resposta.

Infelizmente, isso resultou em um erro:

UserDestroyer::PostsExistError: UserDestroyer::PostsExistError
from /var/www/discourse/app/services/user_destroyer.rb:18:in `destroy'

nota: usei o nome de usuário em vez do email para encontrar o usuário, pois o email foi excluído por minha própria imprudência.

OK, então isso significa que o usuário que você está tentando excluir possui posts: PostsExistError.

O método sugerido de resolução aqui seria revisar os posts do usuário e excluí-los um por um, caso haja algum que você deseje manter, alterando o usuário. Lembre-se de que excluir o primeiro post de um tópico também exclui o tópico.

O método “simplesmente faça” seria alterar delete_posts: false para delete_posts: true.

Vejo este erro. Encontrei o usuário pelo nome de usuário. (Não consegui usar o e-mail por algum motivo)

Discourse::InvalidAccess: can_delete_user? falhou
from /var/www/discourse/lib/guardian/ensure_magic.rb:11:in `method_missing'

O comando

UserDestroyer.new(Discourse.system_user).destroy(User.find_by(username: "someuserwhocertainlyexists"), delete_posts: true)

Encontrei o mesmo erro:

UndefinedColumn: ERROR:  coluna users.email não existe
LINE 1: SELECT "users".* FROM "users" WHERE "users"."email" = 'test'...

Acho que a resposta do jomaxro poderia ser atualizada com um exemplo funcional. :slight_smile:
Além disso, qual seria o comando para excluir um usuário usando seu endereço de e-mail?

Desculpe pelo atraso, corrigido.

Olá, estou encontrando o mesmo erro:

Discourse::InvalidAccess: can_delete_user? falhou
from /var/www/discourse/lib/guardian/ensure_magic.rb:11:in `method_missing'

Alguma ideia?

Olá, ninguém tem uma solução? Parece que isso ocorre apenas ao tentar excluir algumas contas, mas não outras, e não consigo entender o motivo.

Exemplo da minha execução de loop:

2821 : Gurpreet
2969 : GUY26
3012 : dboy3587
3015 : devilsports
3020 : jimyyyy
3029 : vdubgrub
3071 : Frank1
3126 : volgano
3172 : dawei
3307 : almolatham
3320 : embsoft
3352 : auto
3379 : sulemaninc
3447 : Baton
3463 : galvin
3465 : autopartchina
3497 : tracker
Discourse::InvalidAccess: can_delete_user? failed
from /var/www/discourse/lib/guardian/ensure_magic.rb:11:in `method_missing'

Todos os usuários foram excluídos, exceto o último. Se eu pular este, ele excluirá os próximos usuários até não conseguir excluir outro por um motivo não identificado.

edit: Tive que alterar estas configurações:
delete all post max
delete_user_max_post_age
:+1:t6:

Parece que você não pode excluir usuários administradores com este comando? :thinking:

Correto. Usuários do tipo Staff não podem ser excluídos. Para excluir o usuário, primeiro você precisa remover seu acesso de administrador.

u = User.find_by_username_or_email("ex@example.com")
u.admin = false
u.moderator = false
u.save
UserDestroyer.new(Discourse.system_user).destroy(u, delete_posts: false)

Obrigado: delete_user_max_post_age me ajuda a limpar meu banco de dados antigo (mais de 20 anos)