Semántica sobre los mensajes

De Wiki Diaspora*
Saltar a: navegación, buscar

Este documento describe la semántica de cada tipo de mensaje enviado de un pod de Diaspora a otro. En conjunto, constituyen la semántica de la federación de Diaspora.

Cuando Alice quiere enviar un mensaje a Bob, ella construirá uno de los mensajes detallados a continuación, y lo empaquetará y enviará utilizando el protocolo de federación de Diaspora.

Conceptos básicos

Antes de adentrarnos en la semántica de cada mensaje, tenemos que aclarar algunos conceptos básicos sobre cómo concibe Diaspora al mundo, de tal forma los mensajes tendrán más sentido.

Recuerda, además, que el protocolo de Diaspora algún día evolucionará, y será interoperable con OStatus. Sin embargo, el diseño actual de OStatus fue creado con la idea de que todas las publicaciones deben ser públicas. Esto no funciona para Diaspora. Afortunadamente, OStatus está evolucionando para soportar la distribución limitada. De tal suerte, Diaspora y OStatus convergirán.

Gente local vs. remota

Diaspora tiene una noción sobre «usuarios en el pod local», y una noción separada de «personas». Algunas personas son también usuarios en el pod local, pero otras personas viven en otros pods, y por tanto se consideran remotas.

Es importante recordar esto, pues muchos de los foros y sistemas más familiares están diseñados pensando únicamente en gente local, y nos hacen pensar solo en «usuarios». Pero cuando se diseña un sistema federado, debes incluir también en el modelo a personas remotas. [1]

Entrega local vs. remota

En ocasiones, en tu pod sucede cierta actividad que afecta a las personas locales, así como a las remotas. En dichas situaciones, las implementaciones de Diaspora deberían distribuir todas las notificaciones relevantes para la gente local, tan pronto como la necesidad de hacerlo se presente. La implementación debería también entregar información a las personas remotas, pero no debería esperar una respuesta de parte del pod remoto, antes de distribuir a la gente local.

Un ejemplo sencillo: los comentarios. Digamos que Laura y Eva viven en el mismo pod. Bob vive en un pod remoto. Laura hace una publicación que es visible tanto para Bob como para Eva. Eva comenta en la publicación de Alice. El comentario de Eva puede ser visible para Alice simplemente actualizando la base de datos interna del pod de Alice; nada tiene que ser serializado o enviado de manera remota. Esto debe suceder inmediatamente.

Sin embargo, el comentario de Eva debe enviarse de manera remota a Bob. Alice debe ser capaz de ver el comentario, incluso si nunca le llega a Bob.

Actualización en tiempo real

Si un pod es implementado a manera de sitio web, puede elegir hacer «actualizarse en tiempo real». Por ejemplo, si Alice y Eva inician sesión en el sitio web, y Eva comenta en la publicación de Alice, su pod podría elegir enviar algún tipo de notificación al navegador de Alice, sin esperar que Alice actualice la página. En la implementación de referencia esto se hace por medio de websockets. También se puede realizar a través de ajax polling.

Retransmisión

Hay algunas circunstancias, cuando Bob es el autor de la publicación a la cual responde Alice. Toda la gente que vio la publiación de Bob debe ver también la respuesta de Alice.

Imagina esta situación: Alice, Bob y Diego viven todos en distintos pods. Bob comparte con Alice y Diego, pero Alice y Diego no saben el uno de otro. Bob hace una publicación. Alice responde a la publiación de Bob. Diego debería ver la respuesta de Alice. Pero, ¿cómo se transmitirá la respuesta de Alice a Diego?

Alice enviará una respuesta «retransmitible» a Bob , y Bob determinará quién necesita ver la respuesta, y la retransmitirá en base a esto.

De tal forma, Bob puede enviarle a Diego el mensaje de Alice, aunque Alice no conoce la lista de destinatarios original de la publicación de Bob, y de hecho, podría permanecer sin saber sobre la existencia de Diego.

«Des-duplicación»

Ocasionalmente, el pod de Alice puede tener más información de la que ella misma debería tener. En este caso, Alice podría elegir utilizar esta información para agilizar la comunicación o el almacenamiento, siempre que no se muestre a nadie un mensaje que no deba ver.

Considera esta situación: Alice y Eva viven en el mismo pod, pero Bob vive en un pod remoto. Bob hace una publiación, que es entregada a Alice y Eva.

A cada comentario se le asigna un identificador único (GUID).

Luego, Bob empaqueta el mensaje dos veces: uno encriptado con la llave RSA pública de Alice, y otro con la de Eva. Pero envía ambos mensajes al mismo pod. Los pods pueden almacenar las llaves RSA privadas de sus usuarios, y desencriptar mensajes a nombre de los usuarios, y pueden almacenar mensajes en texto simple. De hecho, esto es lo que hace la implementación de referencia. Cabe notar que la llave privada de un usuario solo se almacena en su propio pod.

Entonces, cuando Alice recibe su copia del mensaje original de Bob. El pod de Alice lo almacena en texto simple en la base de datos. Después, cuando la copia del mensaje de Eva llega, el pod de Alice se da cuenta de que el GUID del nuevo mensaje coincide con el que sen encuentra en la base de datos. De esta forma, cuando la copia del mensaje de Eva llegue, el pod de Eva decide no almacenar una segunda copia. En cambio, hace una nota en una tabla de permisos de visibilidad, especificando que Eva debería poder ver el mensaje.

Todos los comentarios pueden ser visibles para cualquiera que haya visto la publicación original. Si se usa este sistema, cuando Alice haga un comentario, el pod de Alice busca en la tabla de visibilidad, y se da cuenta de que Eva también debería poder ver el mensaje. Entonces, el comentario puede ser entregado localmente a Eva, antes de recibir el comentario retransmitido de Bob.

Cabe destacar, que esta «des-duplicación» es opcional. Un pod podría elegir almacenar mensajes duplicados. y podría esperar para entregar el comentario de Alice a Eva, hasta que el pod se entere de la retransmisión del mensaje de Bob.

Una razón por la que un pod podría decidir hacer esto es si el pod no almacena las llaves RSA de sus usuarios, y no desencripta mensajes a nombre de sus usuarios. Por tanto, el pod no puede leer mensajes para encontrar el GUID, y este proceso obviamente no se puede llevar a cabo.

Otro consideración es que utilizar este método de «des-duplicación» de esta manera, quitará a Bob la posibilidad de elegir reenviar o no el comentario a Eva. Si este proceso no se utilizar, Bob puede aplicar un filtro y moderación en el comentario de Alice.

Los mensajes

Diaspora actualmente define los siguientes mensajes:

  • Notificación de que has comenzado a compartir con alguien.
  • Notificación de que has dejado de compartir con alguien.
  • Publicaciones que has realizado.
  • Comentarios que se han hecho (por ti o por otros) en una de tus publicaciones.
  • Tus publicaciones que se han marcado como «Me gusta» (por ti o por otros).
  • Conversaciones (cada tema en la bandeja de entrada tiene un objeto que la representa).
  • Mensajes (cada mensaje individual en una Conversación).
  • Información de perfil.
  • Retracción de publicaciones.
  • Retracción de mensajes.

Hay que mencionar, sin embargo, que Diaspora está en fase alpha, y su protocolo sigue fluyendo, así que esto podría cambiar y este documento podría no estar al día. La información actualizada se encuentra siempre en el código fuente Diaspora, para la implementación de referencia, que es una aplicación de Ruby on Rails. Hay que prestar atención a los archivos que son modelos de aplicación que heredan de parte de WebHooks.

No obstante, este documento describirá los mensajes como eran al momento de crearse el código. Este documento se deberá actualizar cuando los mensajes cambien.

Compartir notificaciones

Recuerda que Diaspora utilizar un modelo asimétrico para compartir. Es decir, Alice puede elegir compartir con Bob, y Bob no tiene necesidad de aprobar esta acción, y Bob no tiene que ser recíproco. Sin embargo, el pod de Bob no debería mostar las publiaciones originales de Alice en la locación principal, a menos que Bob también esté compartiendo con Alice. Las respuestas de Alice a las publicaciones de Bob deberían mostrarse con el resto de las respuestas. No obstante, ya que Bob, en este escenario, no está compartiendo con Alice, Alice solo podrá responder a las publicaciones «públicas» de Bob.

Si Bob está compartiendo con Diego, y Diego está compartiendo con Bob, y también comparte con Alice, entonces Alice verá las publicaciones de Diego, y podrá responder a ellas. Bob deberá ver las respuestas de Alice a las publicaciones de digeo, con el resto de las respuestas.

Esto fue un pequeño recordatorio sobre la semántica asimétrica del modelo de Diaspora. Pero esta sección trata realmente con los mensajes que se envían.

Si Alice decide compartir con Bob, entonces el pod de Alice debería transmitir una notificación de informándole a Bob. [2]

Uno notificación al empezar a compartir se ve así:

<XML>
  <post>
    <request>
      <sender_handle>[email protected]</sender_handle>
      <recipient_handle>[email protected]</sender_handle>
    </request>
  </post>
</XML>

Donde [email protected] es la dirección Webfinger de Alice, y [email protected] es la de Bob.

Alice entonces empaquetará esto, y lo enviará a Bob, de acuerdo a los métodos descritos en el protocolo de federación de Diaspora.

Notificación al dejar de compartir

Si Alice está compartiendo con Bob, y decide dejar de hacerlo, ella debería enviar una notificación a Bob, indicando que ya no comparte con él.

Esta es la estructura de tal notificación:

<XML>
  <post>
    <retraction>
      <post_guid>6c5c09f129855969</post_guid>
      <type>Person</type>
      <diaspora_handle>[email protected]</diaspora_handle>
    </retraction>
  </post>
</XML>

Aquí:

  • <post_guid> es el GUID de Alice. (Recuerda que cuando se crea un nuevo usuario en un pod, el pod debe asignar un GUID, que es una línea de 16 caracteres hexadecimales).
  • <type> es la línea Person.
  • <diaspora_handle> es el ID de Diaspora de Alice.

El formato de este mensaje es muy similar al formato de retracción de publiaciones. Esto se debe a que la implementación de referencias estructura internamente estas retracciones, con el mismo modelo utilizado en las retracciones de publicaciones. Por tal razón el campo <type> está presente. También por eso este GUID es llamado <post_guid>, y es por eso que <post_guid> existe, aunque <diaspora_handle> es suficiente para especificar globalmente a una persona.

Otras implementaciones de Diaspora no necesitan estructurar internamente retracciones de publicaciones, y retracciones para compartir de la misma manera. Pero sin importar cómo una implementación estructure una retracción para compartir, los campos listados anteriormente deben estar presentes.

Actualizaciones de estado

Alice puede elegir publicar una actualización de estado. Al publicar este mensaje, Alice debe determinar quién debe recibir la actualización.

Las implementaciones de Diaspora pueden elegir ofrecer una interfaz para manejar fácilmente los contactos de Alice, y una manera sencilla de elegir a los destinatarios. Por ejemplo, la implementación de referencia ofrece «aspectos», que son simplemente grupo de contactos conocidos por Alice. Alice organiza a sus contactos en varios aspectos. Al publicar un mensaje de estado, Alice elige qué aspectos deben recibir el mensaje.

Sin importar los destinatarios elegidos por Alice, el mensaje es enviado de la siguiente manera:

Alice serializará el mensaje así:

<XML>
  <post>
    <status_message>
      <raw_message>((status message))</raw_message>
      <guid>((guid))</guid>
      <diaspora_handle>[email protected]</diaspora_handle>
      <public>false</public>
      <created_at>2011-07-20 01:36:07 UTC</created_at>
    </status_message>
  </post>
</XML>
  • <raw_message> es el texto del mensaje que Alice desea enviar. Cabe destacar que el texto del mensaje tiene que que ser adecuado para XML, utilizando cualquier esquema de escape de caracteres. Por ejemplo, caracteres que no son seguros, como < y > deben traducirse a las entidades XML correspondientes, en este caso < y &gt. O se puede utilizar el método CDATA. [3]
  • <guid> es una línea de 16 dígitos hexadecimales. El pod de Alice debe elegir un nuevo GUID para cada mensaje de estado, y debe retener el GUID, para recibir respuestas a la publicación.
  • <diaspora_handle> es la dirección Webfinger de Alice.
  • <public> podrá ser «true» o «false». Si es «true», Bob podrá compartir la publicación de Alice con otros. Si es «false», Bob no podrá compartir la publicación nuevamente con otros en un Stream de actividad.

Actualizaciones de estado públicas

Si Alice desea marcar su publiación como «pública», puede elegir compartir dicho mensaje en otros sistema o servicios. Por ejemplo, la implementación de referencia permite a Alice marcar una publicación como «pública». La publicación estará entonces disponible para todos, en un Stream de actividad.

Sin embargo, incluso si la publicación es «pública», Alice debe encriptar el mensaje para los destinatarios específicos.

Comentarios en mensajes de estado

Si Bob envía un mensaje de estado a Alice y Eva, y Alice comenta en el mensaje, entonces Alice debe construir un mensaje con el comentario, y enviárselo a Bob. (Como se indicó antes, el pod de Alice puede hacer visible la publicación para Alice inmediatamente, si Eva vive en el mismo pod que Alice, en caso de que el pod de Eva sepa que Alice debe ver la publicación, incluso si este conocimiento no está disponible para Alice. No obstante, este comportamiento no es requerido).

Un comentario se verá así:

<XML>
  <post>
    <comment>
      <guid>((guid))</guid>
      <parent_guid>((guid))</parent_guid>
      <author_signature>((base64-encoded data))</author_signature>
      <text>I'll be there!</text>
      <diaspora_handle>[email protected]</diaspora_handle>
    </comment>
  </post>
</XML>

Los campos son:

  • <guid> es el GUID del comentario. Cada comentario debe tener un GUID asignado cuando se crea el comentario. En este caso, cuando Alice elige enviar el comentario, se le asigna a este un GUID, que se almacena en la base de datos. Un GUID es una línea de 16 caracteres hexadecimales.
  • <parent_guid> es el GUID de la publicación original de Bob, en la cual está comentando Alice.
  • <autor_signature> es la firma de Alice en el comentario. Para construir la firma:
  1. Identificar los siguientes campos:
    1. El GUID del comentario.
    2. El GUID del comentario original, donde se realiza el comentario.
    3. El texto del comentario.
    4. El ID de Diaspora del autor del comentario.
  2. Concatenar estas líneas con delimitadores «;». Por tanto, la línea se podría ver así:

a965ddb72a3d5d61;d3d4b1320ca196cd;I'll be there!;[email protected].
El texto del comentario pude tener puntos y comas «;» incluidos, no hay problema. La línea base no es una serialización que se pretenda analizar. Simplemente es una línea de caracteres arbitraria, que se puede construir por el emisor y el receptor del mensaje, de manera confiable.

  1. Firmar esta línea utilizando la llaver RSA privada de Alice, y el algoritmo SHA. Se usa SHA-0, no SHA-1 o SHA256. SHA-0 puede no estar disponible en muchos sistemas.
  2. Codificar la firma con el esquema Base64. Este es el valor de <autor_signature>.
  • <text> es el texto real del comentario que Alice realiza en la publicación. El texto del mensaje tiene que que ser adecuado para XML, utilizando cualquier esquema de escape de caracteres. Por ejemplo, caracteres que no son seguros, como < y > deben traducirse a las entidades XML correspondientes, en este caso < y &gt. O se puede utilizar el método CDATA. [3] El escape de caracteres se realiza después de que se genere la firma.
  • <diaspora_handle> es el ID de Diaspora del autor del comentario. En este caso, el ID de Diaspora de Alice, o [email protected].

Este mensaje se empaqueta, y se envía a Bob, quien escribió la publiación original, a la cual Alice está respondiendo.

Retransmitir comentarios

Cuando Bob recide un comentario por parte de Alice en su publicación, es su responsabilidad retransmitir el comentario de Alice a otros destinatarios de la publiación original de Bob. Bob debe retransmitir el mensaje, a menos que esté llevando a cabo algún tipo de moderación o tasa de limitación.

En este ejemplo, Alice y Eva fueron los destinatarios de la publicación original de Bob. Así que cuando Bob reciba el paquete que contiene el comentario de Alice, preparará el comentario para su retransmisión, y lo enviará tanto a Eva como a Alice. Si Bob ha elegido retransmitir el mensaje, debe enviarlo a todos los destinatarios, incluso Alice, la autora del comentario. De esta manera, Alice sabe que su comentario ha sido recibido. Sin embargo, el pod de Alice puede elegir mostrar el comentario en su lugar, incluso antes de recibir confirmación por parte de Bob.

El mensaje que Bob construye se ve así:

 <XML>
  <post>
    <comment>
      <guid>((guid))</guid>
      <parent_guid>((guid))</parent_guid>
      <parent_author_signature>((base64-encoded data))</parent_author_signature>
      <author_signature>((base64-encoded data))</author_signature>
      <text>I'll be there!</text>
      <diaspora_handle>[email protected]</diaspora_handle>
    </comment>
  </post>
</XML>

Todos los campos son idénticos a aquellos que Bob recibió de Alice. La única diferencia es la adición del campo <parent_author_signature>. Bob firma el mensaje antes de enviarlo, para probar que realmente él decidió retransmitir el mensaje, y que no fue un impostor.

Bob estructura <parent_author_signature> de la misma manera que Alice construyó su <author_signature>, excepto que él firma con su llave privada, no la de Alice (la cual por supuesto él no tiene).

«Me gusta» en mensajes de estado

Si Bb envía un mensaje de estado a Alice y Eva, y Alice marca como «me gusta» el mensaje, entonces Alice debe construir un mensaje de «me gusta» y enviarlo a Bob. (Como se indicó antes, el pod de Alice puede hacer visible la publicación para Alice inmediatamente, si Eva vive en el mismo pod que Alice, en caso de que el pod de Eva sepa que Alice debe ver la publiación, incluso si este conocimiento no está disponible para Alice. No obstante, este comportamiento no es requerido).

 <XML>
  <post>
    <like>
      <target_type>Post</target_type>
      <guid>((guid))</guid>
      <parent_guid>((guid))</parent_guid>
      <author_signature>((base64-encoded data))</author_signature>
      <positive>true</positive>
      <diaspora_handle>[email protected]</diaspora_handle>
    </like>
  </post>
</XML>

Los campos son:

  • <guid> es el GUID de cada «me gusta». Cada comentario debe tener un GUID asignado cuando es creado. El GUID es elegido por el pod de Alice. En este caso, cuando Alice decide marcar como «me gusta», a este se le asigna un GUID, que se almacena en la base de datos del pod de Alice. Un GUID es una línea de 16 caracteres hexadecimales.
  • <parent_guid> es el GUID de la publiación orignal de Bob, la cual está marcando como «me gusta» Alice.
  • <author_signature> es la firma de Alice para este «me gusta». Para construir la firma:
  1. Identificar los siguientes campos:
    1. EL GUID del «me gusta».
    2. El valor del campo <target_type>. En este caso, la linea «Post».
    3. El GUID de la publiación original, a la cual se está respondiendo.
    4. El texto del campo <positive>. En este caso, la línea «true».
    5. EL ID de Diaspora del autor del comentario.
  2. Concatenar aquellas líneas con delimitadores «;». Por tanto las líneas se verán como sigue:

a965ddb72a3d5d61;Post;d3d4b1320ca196cd;true;[email protected].

  1. Firmar la línea con la llave RSA privada de Alice, y el algoritmo SHA (SHA-0).
  2. Codificar con el esquema Base64 la firma. Este el el valor de <author_signature>.
  • <target_type> es la línea «Post», si se está marcando como me gusta un mensaje de estado. Es «Comment» cuando se marca como «me gusta» un comentario. (Marcar como «me gusta» los comentarios se discute más adelante).
  • <positive> se la línea «true» si Alice marca como «me gusta» esta publicación. Es «false» si Alice se retracta de haber marcado como «me gusta».
  • <diaspora_handle> es el ID de Diaspora de quien marca como «me gusta». En este caso, el ID de Diaspora de Alice, o [email protected].

El mensaje es empaquetado, y enviado a Bob, quien escribió la publicación original, a la cual está respondiendo Alice.

Alice no debe enviar un «me gusta» para una publicación, si ya lo ha hecho antes. Es decir, solo puede marcar una vez como «me gusta» una publicación.

Si Bob recibe un «me gusta» de parte de Alice, y ya ha recibido un «me gusta» por parte de Alice para esta misma publiación, Bob debe ignorar este segundo.

Reenviar un «me gusta»

Cuando Bob recibe un «me gusta» por parte de Alice en una de sus publicaciones, es su responsabilidad retransmitir este a los demás destinatarios de la publicación original. Bob debería retransmitir el mensaje, a menos que esté haciendo moderación o taza de limitación.

En este ejemplo, Alice y Eva fueron los destinatarios de la publiación original de Bob. Entonces, cuando Bob recibe el paquete que contiene el «me gusta» de Alice, preparará la retransmisión del comentario, y lo enviará a Eva y Alice. Si Bob ha elegido retransmitir el mensaje, debe enviarlo a todos los destinatarios, incluso Alice, quien marco la publicación como «me gusta». De esta forma, Alice sabe que el «me gusta» ha sido recibido. Sin embargo, el pod de Alice puede elegir mostrar el «me gusta» en su lugar, incluso antes de que reciba confirmación por parte de Bob.

Cabe notar que Bob debe aceptar cuando mucho un «me gusta» de cada persona, para cada mensaje de estado. Bob debe ignorar todos los «me gusta» negativos por parte de Alice, si no ha recibido aún uno positivo. Bob debe ignorar todos los «me gusta» positivos de parte de Alice si ya ha recibido un «me gusta» de ella.

Si Bob acepta el «me gusta» de Alice, el mensaje se construye así:

 <XML>
  <post>
    <like>
      <guid>((guid))</guid>
      <target_type>Post</target_type>
      <parent_guid>((guid))</parent_guid>
      <parent_author_signature>((base64-encoded data))</parent_author_signature>
      <author_signature>((base64-encoded data))</author_signature>
      <positive>true</positive>
      <diaspora_handle>[email protected]</diaspora_handle>
    </like>
  </post>
</XML>

Todos los campos son idénticos a aquellos que Bob recibió de Alice. La única diferencia se la adición del campo <parent_author_signature>. Bob firma el mensaje antes de enviarlo, para probar que realmente él está retransmitiendo el mensaje, y no un impostor.

Bob estructura el campo <parent_author_signature> de la misma manera en que Alice construyó el suyo <parent_signature>, pero él firma con su llave privada, y no la de Alice (la cual, por supuesto él no tiene).

«No me gusta»

Si Alice ha marcado previamente una publiación de Bob como «me gusta», y ella decide retractarse de este «me gusta», envía entonces un «no me gusta» a Bob, quien deberá retransmitirlo. Tanto el «no me gusta» de Alice, y la retransmisión de Bob se estructuran de la misma forma que se indicó anteriormente. La diferencia es que en el «no me gusta», el campo <positive> contiene la línea «false».

Alice no debe enviar el «no me gusta» para una publiación que no haya marcado como «me gusta» anteriormente (de manera exitosa: donde «éxito» significa que Alice ha recibido la retransmisión por parte de Bob). Alice no debe enviar un «me gusta» pra un mensaje que ya haya marcado de esta manera exitosamente.

Si Bob recibe un «no me gusta» pra un mensaje que Alice no haya marcado como «me gusta» antes, entonces Bob debe ignorar el mensaje.

Notas

  1. Véase «How to OStatus-enable Your Application» para obtener más información sobre el modelo de usuarios remotos.
  2. En la implementación de referencia, estas se conocen como «peticiones»; esto es un remanente de cuando Diaspora empleaba un modelo simétrico para compartir.
  3. 3,0 3,1 Véanse las especificaciones de XML.