Veuillez évaluer un court script Ruby pour suspendre les utilisateurs inactifs

C’est mon premier script Ruby personnalisé. :slight_smile: En près de 50 ans de codage dans plus de 20 langages et dialectes, je n’ai jamais eu besoin (ou voulu :face_with_open_eyes_and_hand_over_mouth:) écrire en Ruby, mais bon, vous m’avez eu… soyez gentil, s’il vous plaît. :pray:

Mon objectif est d’identifier les comptes utilisateurs qui n’ont pas été authentifiés par des liens par e-mail, et de suspendre les comptes afin que je puisse les vérifier avant de les supprimer. Lors de la configuration initiale, j’avais des paramètres à divers stades de développement. Les e-mails 2FA ne sont pas partis pour certains enregistrements, et il y a eu beaucoup d’enregistrements bidons que je voudrais maintenant filtrer.

Version 0.0.1

rails c

# Assurez-vous d'abord que les TL des utilisateurs sont conformes aux dernières définitions
User.all.find_each do |user|
  Promotion.recalculate(user)
end
Group.ensure_consistency!

# Préparation pour la boucle
logger = StaffActionLogger.new(User.where("id = 'admin'"))
# date temporaire, les utilisateurs seront supprimés avant cette date
suspend_till = DateTime.new(2028, 12, 31)
suspend_at = DateTime.now
reason = 'Inactive'

# Identifier les comptes potentiellement morts
User.where("views = 0 OR approved = FALSE OR last_seen_at IS NULL")
    .where("id > 0")
    .find_each do |user|
  user.suspended_till = suspend_till
  user.suspended_at = suspend_at
  user.change_trust_level!(TrustLevel[0])
  # sauvegarder l'utilisateur, enregistrer l'action, et... faire ce qui est fait pour ce déclencheur
  user.save!
  logger.log_user_suspend(user, reason)
  DiscourseEvent.trigger(:user_suspended, user: user)
  # éviter d'abuser du serveur de messagerie
  sleep(10)
end

En déclenchant l’événement, j’aimerais que des e-mails soient envoyés aux utilisateurs - il y aura un tas de rebonds, et peut-être quelques personnes qui reviendront pour s’authentifier. Après une semaine, je sélectionnerai tous les comptes qui sont toujours suspendus et je les supprimerai.

Questions :

  1. En général, cela fera-t-il ce qui est prévu ?
  2. Existe-t-il une meilleure approche ?
  3. L’enregistrement est-il redondant avec le déclenchement de l’événement ?
  4. Peut-on faire cela avec JavaScript ?
  5. Dois-je poster ceci dans une autre catégorie ?
  6. D’autres conseils ?

Merci !!

1 « J'aime »

Hmm, en regardant cela, je pense que je devrais plutôt faire taire un compte plutôt que de le suspendre. Si le compte est suspendu, l’utilisateur ne peut pas se connecter pour le récupérer.

Voici une révision…

Version 0.0.2
silence_reason = 'Inactive'
User.where("views = 0 OR approved = FALSE OR last_seen_at IS NULL")
    .where("id > 0") # éviter les utilisateurs système
    .find_each do |user|
  user.silence(reason: silence_reason)
  user.change_trust_level!(TrustLevel[0])
  user.save!
  logger.log_user_silence(user, silence_reason)
  DiscourseEvent.trigger(:user_silenced, user: user)
  sleep(5)
end

Oui, je vais faire une sauvegarde avant de faire quoi que ce soit.
Oui, je sais que certains TL existants seront mélangés et que je devrai les corriger.

De plus, au lieu de faire taire, devrais-je définir Approved=false ou Active=false ? Je pense que cela obligera l’utilisateur à cliquer sur le lien de l’e-mail plutôt que de se connecter manuellement, ce qui sert le but de valider l’adresse e-mail.

Tout cela est lié à mon récent fil de discussion : notes-on-silencing-or-deleting-users

[EDIT]
J’ai également défini “purge unactivated users grace period days” sur 7.
Un silence ou une suspension réinitialise-t-il cela ? Si oui, si les gens ne répondent pas à une action de compte dans les 7 jours, cela ne me dérange pas de les purger.

Enfin (oui, vraiment), j’ai aussi “clean up inactive users after days” réglé sur 365. Je peux le baisser à 60 pendant que le forum s’ouvre encore et laisser les comptes existants disparaître de la liste. Puis le remonter à 365. Est-ce une approche raisonnable pour l’élagage automatisé des comptes dans un nouvel environnement ?

1 « J'aime »

Pourquoi cela ne suffit-il pas à résoudre votre problème ?

Ne devrait-ce pas être ET plutôt que OU ?

Discourse les impose pour valider les adresses, donc je ne vois pas bien quel problème vous résolvez. Vous dites ceci

Il semble assez improbable que vous trouviez des utilisateurs qui voulaient se connecter mais ne pouvaient pas avant, mais vous en savez peut-être plus que moi sur votre configuration.

Et Discourse n’enverra pas d’e-mails à des adresses non validées, donc je ne pense pas que cela enverra des e-mails.

Je fais toujours ces choses sur quelques comptes, mais je regarde ce qui va se passer.

2 « J'aime »

Merci de votre intérêt, @pfaffman !

Il existe des enregistrements d’utilisateurs sans last_seen_at, créés il y a des mois, approved=False, active=False, et ils ne sont pas purgés.
Il existe des enregistrements d’utilisateurs avec last_seen_at > 7 jours (anciens de plusieurs mois) et 0 vues, et ils ne sont pas purgés.

Quels que soient les critères utilisés avec ce drapeau de période de grâce, ils ne sélectionnent pas ces enregistrements.
Quelqu’un peut-il poster la requête exacte qui est utilisée ici afin que je puisse comprendre quels autres facteurs sont impliqués ?

Non, en regardant directement la base de données, il existe des enregistrements d’utilisateurs qui correspondent à chaque critère, mais pas à tous. Il semble que la table des utilisateurs dans la base de données soit incohérente. Il existe des enregistrements avec des topics_entered ou des posts_read_count non nuls, mais avec views=0. Il existe des enregistrements avec topics_entered=0 et posts_read_count=0, mais views est non nul.

Le point clé à retenir est que pendant le développement de ce site, les paramètres n’étaient pas optimaux et des humains et des bots s’enregistraient. La clause OR semble capturer tous ces cas. Maintenant que le site est stabilisé avec des paramètres (je l’espère) sensés, je ne m’attends pas à ce que les nouvelles inscriptions entraînent les mêmes anomalies.

J’ai l’intention d’exécuter le script plusieurs fois avec des critères différents. Je vais d’abord interroger les enregistrements, en dehors de l’environnement, puis exécuter le script de silence pour cibler uniquement les enregistrements que je veux vraiment. Dans quelques semaines, je ferai une dernière exécution, je sélectionnerai uniquement les enregistrements silencieux (tous ceux qui sont réellement revenus verront le drapeau supprimé), et je les purgerai tous :

UserDestroyer.new(admin_user).destroy(user, reassign_to: archive_user)

Ma question générale est de savoir si le script v0.0.2, avec son approche de sélection, de journalisation et de silence, est correct pour un système Discourse. Je ne sais pas s’il y a autre chose à faire dans une boucle comme celle-ci. Je n’ai jamais créé et exécuté mon propre script, donc c’est une demande pour que vous vérifiiez mes erreurs de noob.

Merci !!

1 « J'aime »