Permissions fines pour PubSub

goffi 12 years ago projet technique SàT jabber-xmpp Libre

Attention ce billet est technique.

Comme vous le savez peut-être, « Salut à Toi » permet de faire du microblogage par groupes, c'est à dire que vous pouvez envoyer des messages réservés à un groupe de votre roster (par exemple « famille » ou « amis »). Cette fonctionnalité est disponible depuis près d'un an, mais était basée sur un bidouillage assez sale (et qui ne fonctionne qu'avec OpenFire), qui permettait surtout de tester le concept.

Il est nécessaire d'obtenir un système de permissions simple qui va au delà du microblogage, quelque chose de générique, qui étendrait PubSub.
Plutôt que de partir sur des tonnes de nœuds pubsub avec des accès différents à chaque fois (par exemple, un nœud pour la famille, un pour les amis), il faut un moyen de gérer plus finement les permissions, par élément (item).

Aussi j'ai commencé un composant pubsub qui permet de valider le concept, et qui va être utilisé par SàT pour gérer le microblogage. Si l'idée se montre solide en pratique, je vais en parler sur une des listes de diffusion de la XSF pour tenter de la faire standardiser.

Le fonctionnement est assez simple: on prend exactement la même syntaxe que les accès du nœud (« Node Access Models » (http://xmpp.org/extensions/xep-0060.html#accessmodels) qu'on applique aux éléments.
L'accès du nœud est appliqué en premier, puis celui des éléments (c'est à dire qu'un élément avec un accès ouvert (open) ne sera pas accessible à quelqu'un qui n'est pas dans le groupe prévu si le nœud a un accès par groupe (roster)).
Le composant PubSub parse l'élément, applique les permissions, puis le sauvegarde (sans la partie configuration).
Quand quelqu'un veut récupérer les éléments du nœud, le composant pubsub vérifie d'abord qu'il a accès au nœud (en vérifiant le « access model »), puis lui envoi uniquement les élements qui correspondent à son accès.

Imaginons que Louise a un nœud avec 3 éléments: 1 qui a un accès ouvert (A), 1 qui a un accès par groupes, autorisé pour le groupe « famille » (B), et un qui a un accès par groupes, autorisé pour les groupes « Amis », et « Collègues » (C).
Pierre qui est un ami de Louise aura accès aux élements A et C. Le frère de Louise aura accès aux éléments A et B.

Il y a là 2 avantages principaux: premièrement ce protocole reste compatible avec la XEP-0060 - il n'y a donc aucun changement à faire côté client pour retrouver les élements -, et deuxièmement les clients n'ont qu'un seul nœud à surveiller par entitée suivie.

Quelques mots sur l'implémentation de test: j'ai pris pour base le composant PubSub « Idavoll », fait par Ralph Meijer*, que j'ai légèrement modifié pour faire les tests. La difficulté principale est qu'actuellement un composant a un accès très limité au serveur, et ne peut notamment pas acceder au roster des entités.
Pour contourner le problème, j'utilise un protocole expérimental, qui permet d'accéder à un roster distant. Malheureusement, ce protocole ne permet que d'accéder à une partie du roster, aussi j'ai du modifier l'implémentation de Prosody pour récupérer le roster complet.
Enfin, j'ai simplifié en considérant que le créateur du nœud était aussi son propriétaire, et l'auteur des billets (creator = owner = publisher). Ce qui est souvent vrai pour du microblogage, mais limite beaucoup les possibilités offertes par la XEP-0060.

Bref, ça fonctionne, mais il y a encore du travail à faire (et qui doit passer par une phase de standardisation) avant que ça soit propre.

Voici un exemple de dialogue avec le serveur. Nous avons ici Pierre et Louise qui sont amis, Louise est dans le groupe « amis » de Pierre. Ce dernier publie un microbillet comme suit**:
<iq from="pierre@example.net/SàT" type="set" id="H_77" to="sat-pubsub.example.net">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <publish node="urn:xmpp:groupblog:pierre@example.net">
      <item id="8f532cc8-be1d-11e1-b5d3-00c0ca4f1546">
        <entry xmlns="">
          <title>Salut les amis !</title>
          <id>8f532cc8-be1d-11e1-b5d3-00c0ca4f1546</id>
          <updated>2012-06-24T18:56:36+02:00</updated>
          <author><name>pierre@example.net</name></author>
        </entry>
        <x xmlns="jabber:x:data" type="submit">
          <field var="FORM_TYPE" type="hidden">
            <value>http://jabber.org/protocol/pubsub#item-config</value>
          </field>
          <field var="pubsub#access_model">
            <value>roster</value>
          </field>
          <field var="pubsub#roster_groups_allowed">
            <value>amis</value>
          </field>
        </x>
      </item>
    </publish>
  </pubsub>
</iq>

En recevant ceci, le serveur analyse les données de configuration (le formulaire « http://jabber.org/protocol/pubsub#item-config »***), supprime cette partie du message, stocke l'élements avec les permissions voulues (accès par groupes, uniquement pour le groupe « amis »), et envoi une notification uniquement aux membres du groupe « amis », soit à Louise.

La notification est envoyée comme suit:

<message to="louise@example.net" from="sat-pubsub.example.net">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <items node="urn:xmpp:groupblog:pierre@example.net">
      <item id="8f532cc8-be1d-11e1-b5d3-00c0ca4f1546">
        <entry xmlns="">
          <title>Salut les amis !</title>
          <id>8f532cc8-be1d-11e1-b5d3-00c0ca4f1546</id>
          <updated>2012-06-24T18:56:36+02:00</updated>
          <author><name>pierre@example.net</name></author>
        </entry>
      </item>
    </items>
  </event>
</message>

Rien ne permet de savoir à quel groupe Louise appartient dans le roster de Pierre (c'est une notification traditionnelle). Même si un client XMPP ne gère pas les permissions fines, il recevra les notifications et pourra les traîter comme d'habitude.

J'ai relicencié le composant en AGPL V3, vous pouvez trouver le code dans mon dépôt (http://repos.goffi.org/sat_pubsub/). J'invite les différents membres de la communauté XMPP (auteur de clients/serveurs ou autre) à utiliser le code, ou à apporter des critiques au principe.

Les permissions fines sont à mon avis une fonctionnalité essentielle et nécessaire dans XMPP, et elles vont être de plus en plus utilisées par le projet « Salut à Toi ». Il s'agissait de la dernière grosse brique de l'architecture de SàT, une nouvelle version devrait suivre rapidement.


Restez en ligne :)
Goffi

* Ralph Meijer est aussi un contributeur de Twisted et l'auteur de la bibliothèque « Wokkel » qui sont au cœur de SàT, en plus d'être un des auteurs de la XEP PubSub. Un grand merci à lui pour ses précieuses contributions.
** Normalement le microblogage utilise PEP, mais les limitations des composants évoquées plus haut m'ont obligé à utiliser une variante du protocole qui ne passe pas par PEP.
*** J'ai du utiliser un espace de nommage en « jabber.org » plutôt qu'un « goffi.org », comme j'aurais du le faire pour une fonctionnalité expérimentale, pour pouvoir être parsé par le service PubSub de Wokkel.