Ajout d'attributs utilisateur au sérialiseur d'éléments du répertoire

Un client m’a sollicité pour créer un annuaire d’utilisateurs basé sur des cartes.

Étant donné qu’il est hébergé sur discourse.org, j’ai initialement indiqué que cela ne serait pas possible (outre d’éventuels problèmes de performance), car les attributs nécessaires pour remplir une carte utilisateur ne sont pas disponibles dans l’objet utilisateur sérialisé avec les éléments de l’annuaire.

Cependant, après en avoir discuté plus en détail, j’ai déterminé qu’une approche possible consisterait à proposer une PR dans le cœur du projet afin d’ajouter les attributs utilisateur au sérialiseur des éléments de l’annuaire via un paramètre du site. L’idée est que cette fonctionnalité sera utile pour divers styles d’annuaires d’utilisateurs nécessitant différentes combinaisons d’attributs utilisateur (exemple ci-dessous).

En expérimentant cette approche, j’ai élaboré une méthode relativement simple, que vous pouvez consulter dans ce diff :

https://github.com/discourse/discourse/compare/master...angusmcleod:directory_user_attribute_whitelist

À savoir :

  1. Créer un sérialiseur dédié DirectoryItemUserSerializer (le « UserSerializer » actuel intégré dans le DirectoryItemSerializer m’a toujours semblé un peu étrange).

  2. Si l’administrateur du site a sélectionné des attributs utilisateur à ajouter :

    1. Créer un utilisateur sérialisé pour bénéficier des protections offertes par ce sérialiseur, par exemple pour les attributs réservés au personnel, privés ou non fiables.

    2. Sérialiser les attributs ajoutés qui passent le filtre du UserSerializer.

Les objectifs ici sont :

  1. Ne pas affecter le comportement existant d’aucune manière.

  2. Sérialiser uniquement les attributs demandés.

Si vous êtes partants pour cette approche / cette demande, je finaliserai le travail en :

  1. Ajoutant une validation sur le paramètre du site (c’est-à-dire pour s’assurer que la chaîne saisie correspond bien à un attribut utilisateur).

  2. Ajoutant des tests.

Cependant, j’ai pensé qu’il était préférable de vous soumettre cela en premier lieu.

Exemple

À titre d’exemple du type de fonctionnalité que cela permettrait, la capture d’écran ci-dessous provient de mon environnement local, utilisant uniquement cette modification du cœur du projet ainsi qu’un composant de thème qui remplace l’annuaire existant et utilise une version modifiée du composant carte utilisateur :

@sam Penses-tu que cette approche est réalisable dans une PR ?

Je pense que @blake et @awesomerobot travaillent avec un autre client ayant des besoins similaires. Je suis plutôt ouvert à l’idée d’un paramètre du site, comme nous en avons un pour always_include_topic_excerpts.

La seule réserve est que je souhaiterais que cela soit testé et que le paramètre du site soit masqué.

Je sais que @david s’est également intéressé à ce problème. Je suis un peu partagé, mais peut-être qu’une solution à plus long terme, plus propre, serait :

  1. Ajouter des paramètres du site masqués pour « autoriser les plugins et les thèmes à opter pour des informations supplémentaires sérialisées », désactivés par défaut.
  2. Ensuite, établir un protocole dans les thèmes/plugins pour « demander » ces informations supplémentaires.

L’avantage ici est que certains thèmes auront alors ces informations supplémentaires sérialisées, tandis que d’autres non.

Je préférerais attendre un peu David avant de vous donner le feu vert.

Et si le sérialiseur du répertoire des utilisateurs acceptait un nouveau paramètre comme users.json?include_profile=true ?

Nous pourrions alors ajouter une API de plugin JS permettant aux thèmes d’ajouter ce paramètre :

api.userListIncludeProfile(true)

Le « profil » inclurait tout ce qui se trouve dans le sérialiseur utilisateur standard (en veillant à ne pas introduire de requêtes N+1). Je ne pense pas que la spécification de champs individuels ait un impact significatif sur les performances, donc à mon avis, nous devrions rester simples.

La même approche pourrait fonctionner pour les listes de sujets, par exemple ?include_excerpts=true.

J’aime aussi cette idée car cela signifie que la « configuration du sérialiseur par thème » ne sera pas cassée par le cache anonyme !

Qu’en penses-tu @sam ?

C’est presque ça, mais cela ne fonctionne pas proprement car lorsque vous accédez à la page d’accueil du site ou au chemin /u, vous n’avez pas la possibilité d’ajouter un paramètre au chemin. Il faut modifier les valeurs par défaut :frowning:

Oh oui :pleurer:

Dans ce cas, je pense qu’un paramètre de site masqué est un bon point de départ. Ce serait bien de le rendre spécifique à chaque thème, mais nous devons d’abord mettre en place une infrastructure à cet effet. Je pense toujours qu’un paramètre booléen « la liste des utilisateurs inclut le profil » sera plus facile à gérer.

Cela inclurait-il des propriétés comme featured_user_badges utilisées dans la carte utilisateur ?

Oui, je pense que oui — tout ce qui est inclus dans le sérialiseur utilisateur standard (tant que cela peut être fait sans introduire de problème N+1)

Super. Faites-nous savoir si vous envisagez cela comme un pr-welcome et sous quelle forme, et nous serons ravis d’en créer un. De notre côté, @fzngagan s’en chargera désormais.

Poursuivons avec un seul paramètre de site caché de type booléen, qui ajoute toutes les informations pertinentes.

Merci pour l’info ici @david. Je commencerai à m’en occuper à partir de lundi.

Une chose à clarifier ici concerne le protocol pour demander des données supplémentaires. Pouvons-nous nous fier au paramètre du site côté frontend pour demander les données, ou, comme vous l’avez suggéré, ajouter une autre API dans plugin-api ?

Restons simples : ignorez mon message concernant les paramètres et les API JavaScript.

Si le paramètre du site est activé sur le serveur, renvoyez les informations supplémentaires. S’il est désactivé, ne le faites pas.

Pour le moment, les administrateurs devront activer manuellement ce paramètre. Nous pourrions envisager à l’avenir de permettre aux thèmes de basculer automatiquement ce paramètre.

Bien sûr. Le composant thème devrait consommer les champs supplémentaires de manière conditionnelle lorsque le paramètre est activé, n’est-ce pas ?

De plus, le serveur ne doit envoyer les champs supplémentaires que lorsque le paramètre est activé.

@david Merci David. Nous allons préparer la PR et revenir vers vous.

@david J’ai fait une PR ici

cc @angus

Bouclons la boucle ici. Nous avons décidé de ne pas ajouter d’autres attributs au sérialiseur de répertoire. À la place, nous avons considérablement amélioré les performances de la sérialisation des utilisateurs. Nous avons séparé les cartes utilisateur sur leur propre route et ajouté une nouvelle route qui renvoie plusieurs cartes en une seule fois.

Vous pouvez trouver un exemple d’utilisation de cette nouvelle route dans ce composant de thème :