comp AP gateway: convert pubsub item retractation to AP Delete activity:

when an item `retract` is received from a node from which an AP actor is subscribed, a
corresponding `Delete` activity is created and sent to AP followers.

Trying to retract an item from a virtual node of the gateway pubsub service now return a
`forbidden` stanza error (those nodes are handled on AP side and thus are not owned by
XMPP entities).

rel 367
This commit is contained in:
Goffi 2022-06-17 14:15:23 +02:00
commit 4e0c1fe7bf
3 changed files with 30 additions and 11 deletions

View file

@ -68,6 +68,7 @@ from .constants import (
TYPE_ACTOR,
TYPE_ITEM,
TYPE_FOLLOWERS,
TYPE_TOMBSTONE,
NS_AP_PUBLIC,
PUBLIC_TUPLE
)
@ -470,7 +471,7 @@ class APGateway:
raise exceptions.InternalError("Client is not set yet")
if jid_.host == self.client.jid.userhost():
# this is an proxy JId to an AP Actor
# this is an proxy JID to an AP Actor
return self._e.unescape(jid_.user)
if node and not jid_.user and not self.mustEncode(node):
@ -860,15 +861,32 @@ class APGateway:
actor_id = await self.getAPActorIdFromAccount(ap_account)
inbox = await self.getAPInboxFromId(actor_id)
for item in items:
mb_data = await self._m.item2mbdata(client, item, service, node)
if subscribe_comments_nodes:
# we subscribe automatically to comment nodes if any
for comment_data in mb_data.get("comments", []):
comment_service = jid.JID(comment_data["service"])
comment_node = comment_data["node"]
await self._p.subscribe(client, comment_service, comment_node)
ap_item = await self.mbdata2APitem(client, mb_data)
url_actor = ap_item["object"]["attributedTo"]
if item.name == "item":
mb_data = await self._m.item2mbdata(client, item, service, node)
if subscribe_comments_nodes:
# we subscribe automatically to comment nodes if any
for comment_data in mb_data.get("comments", []):
comment_service = jid.JID(comment_data["service"])
comment_node = comment_data["node"]
await self._p.subscribe(client, comment_service, comment_node)
ap_item = await self.mbdata2APitem(client, mb_data)
url_actor = ap_item["object"]["attributedTo"]
elif item.name == "retract":
author_account = await self.getAPAccountFromJidAndNode(client.jid, node)
author_actor_id = self.buildAPURL(TYPE_ACTOR, author_account)
url_item = self.buildAPURL(TYPE_ITEM, author_account, item["id"])
ap_item = self.createActivity(
"Delete",
author_actor_id,
{
"id": url_item,
"type": TYPE_TOMBSTONE
}
)
ap_item["to"] = [NS_AP_PUBLIC]
url_actor = author_actor_id
else:
raise exceptions.InternalError(f"unexpected element: {item.toXml()}")
resp = await self.signAndPost(inbox, url_actor, ap_item)
if resp.code >= 300:
text = await resp.text()

View file

@ -27,6 +27,7 @@ TYPE_OUTBOX = "outbox"
TYPE_FOLLOWERS = "followers"
TYPE_FOLLOWING = "following"
TYPE_ITEM = "item"
TYPE_TOMBSTONE = "Tombstone"
MEDIA_TYPE_AP = "application/activity+json"
NS_AP_PUBLIC = "https://www.w3.org/ns/activitystreams#Public"
# 3 values can be used, see https://www.w3.org/TR/activitypub/#public-addressing

View file

@ -255,7 +255,7 @@ class APPubsubService(rsm.PubSubService):
@ensure_deferred
async def retract(self, requestor, service, nodeIdentifier, itemIdentifiers):
raise NotImplementedError
raise error.StanzaError("forbidden")
@ensure_deferred
async def subscribe(self, requestor, service, nodeIdentifier, subscriber):