Dépréciation de l'utilisation de « user.groups » dans le modèle « User » en JavaScript

Ceci est lié à la fois à The road to stable, then permanent, for granular_anonymous_and_logged_in_groups_permissions et à Granular group-based permissions for anonymous and logged in users

Dans le cœur de l’application ainsi que dans de nombreux thèmes et plugins, un motif comme celui-ci est devenu assez courant :

const groupIds = this.currentUser.groups.map((g) => g.id);
const allowedGroupIds = this.siteSettings.some_group_setting.split("|").map((groupId) => parseInt(groupId, 10));

const hasPermission = allowedGroups.some((groupId) =>
  userGroupIds.includes(groupId)
);

if (!hasPermission) {
  return;
}

Cependant, ce n’est pas une méthode efficace pour vérifier les autorisations d’un utilisateur. Un utilisateur peut être membre de groupes qui ne sont pas visibles pour lui, de sorte qu’ils ne sont pas sérialisés vers le client et ne peuvent donc pas être utilisés de manière cohérente ou précise pour les vérifications de sécurité.

Pour rendre cela plus évident, nous renommerons currentUser.groups/user.groups en currentUser.visibleGroups/user.visibleGroups dans le modèle User et déprécierons l’ancienne propriété. La PR initiale pour cela est DEV: Deprecate calling user.groups on client directly - Pull Request #42711 - discourse/discourse - GitHub .

Il existe plusieurs alternatives si vous devez vérifier l’autorisation d’un utilisateur sur la base d’une liste d’identifiants de groupes côté client en JavaScript :

Pour les plugins

Étendez le sérialiseur current_user avec un nouvel attribut et vérifiez les autorisations de l’utilisateur avec scope.in_any_groups? côté serveur, ce qui couvre également les groupes pseudo comme logged_in_users et anonymous_users :

add_to_serializer(
  :current_user,
  :has_some_permission,
  include_condition: -> do
    SiteSetting.plugin_enabled
  end,
) { scope.in_any_groups?(SiteSetting.group_list_setting_map) }

Ensuite, vous pouvez utiliser this.currentUser.has_some_permission côté client.

Pour les thèmes et les composants

Pour les paramètres de thème de type list avec list_type: group, vous pouvez utiliser resolve_group_membership: true :

copy_button_allowed_groups:
  default: "1|3"
  type: list
  list_type: group
  resolve_group_membership: true

Cela remplacera settings.copy_button_allowed_groups côté client par settings.user_in_copy_button_allowed_groups (en préfixant le paramètre avec user_in_), qui est un booléen calculé côté serveur sur la base des appartenances aux groupes de l’utilisateur.

Cela fonctionne également pour les paramètres d’objet avec type: groups . Ajoutez resolve_group_membership: true à la propriété groups :

menu_sections:
  type: objects
  default:
    - name: section 1
      groups:
        - 1
        - 3
  schema:
    name: menu section
    properties:
      name:
        type: string
      groups:
        type: groups
        resolve_group_membership: true

L’accès se fait alors ainsi :

for (const section of settings.menu_sections) {
  if (section.user_in_groups) {
    // L'utilisateur appartient à au moins un groupe sélectionné pour cette section.
  }
}

Salut Martin,

Ces modifications prendront-elles effet à la fusion de la PR, ou lors de la prochaine mise à jour après la fusion ?

Pourquoi est-ce important ? Cela ne cassera rien. Il s’agira simplement d’un avertissement affiché dans la console du navigateur, invitant les développeurs à adapter leur code.

J’ai des composants de thème dont je sais qu’ils dépendent de cela, et je voulais une clarification. S’il ne s’agit que d’un avertissement mais que cela fonctionnera encore un peu, je m’inquiète moins.

En général, le code obsolète reste pris en charge jusqu’à la prochaine version de prise en charge étendue. Sinon, les forums qui l’utilisent n’auraient aucune chance de voir l’avertissement avant que les choses ne cassent.

La PR a été fusionnée, elle est donc obsolète :

Mais oui, comme le dit Moin, pour l’instant vous ne recevrez que des avertissements d’obsolescence dans la console du navigateur :slight_smile: Lors de l’introduction initiale d’une obsolescence, nous sommes contraints de corriger toutes les instances dans le cœur du système ainsi que dans les plugins et thèmes officiels. Ensuite, nous laissons l’obsolescence en place pendant un certain temps, ce qui nous permet de corriger progressivement les thèmes tiers, y compris les thèmes clients, ou de laisser les autres le faire.

Cela ne deviendra pas une suppression définitive de user.groups de sitôt, le temps d’être sûrs d’avoir identifié tous les points d’appel. Et même dans ce cas, nous commencerons par afficher un avertissement administrateur sur les sites qui appellent encore l’ancienne méthode.