Mercurial > libervia-backend
diff libervia/backend/plugins/plugin_comp_ap_gateway/pubsub_service.py @ 4259:49019947cc76
component AP Gateway: implement HTTP GET signature.
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 05 Jun 2024 22:34:09 +0200 |
parents | 92551baea115 |
children | 0d7bb4df2343 |
line wrap: on
line diff
--- a/libervia/backend/plugins/plugin_comp_ap_gateway/pubsub_service.py Wed Jun 05 22:33:37 2024 +0200 +++ b/libervia/backend/plugins/plugin_comp_ap_gateway/pubsub_service.py Wed Jun 05 22:34:09 2024 +0200 @@ -144,27 +144,51 @@ [(subscription.subscriber, None, items)] ) - async def ap_following_2_elt(self, ap_item: dict) -> domish.Element: - """Convert actor ID from following collection to XMPP item""" + async def ap_following_2_elt(self, requestor_actor_id: str, ap_item: dict) -> domish.Element: + """Convert actor ID from following collection to XMPP item + + @param requestor_actor_id: ID of the actor doing the request. + @param ap_item: AP item from which actor ID must be extracted. + """ actor_id = ap_item["id"] - actor_jid = await self.apg.get_jid_from_id(actor_id) + actor_jid = await self.apg.get_jid_from_id(requestor_actor_id, actor_id) subscription_elt = self.apg._pps.build_subscription_elt( self.apg._m.namespace, actor_jid ) item_elt = pubsub.Item(id=actor_id, payload=subscription_elt) return item_elt - async def ap_follower_2_elt(self, ap_item: dict) -> domish.Element: - """Convert actor ID from followers collection to XMPP item""" + async def ap_follower_2_elt( + self, + requestor_actor_id: str, + ap_item: dict + ) -> domish.Element: + """Convert actor ID from followers collection to XMPP item + + @param requestor_actor_id: ID of the actor doing the request. + @param ap_item: AP item from which actor ID must be extracted. + """ actor_id = ap_item["id"] - actor_jid = await self.apg.get_jid_from_id(actor_id) + actor_jid = await self.apg.get_jid_from_id(requestor_actor_id, actor_id) subscriber_elt = self.apg._pps.build_subscriber_elt(actor_jid) item_elt = pubsub.Item(id=actor_id, payload=subscriber_elt) return item_elt - async def generate_v_card(self, ap_account: str) -> domish.Element: - """Generate vCard4 (XEP-0292) item element from ap_account's metadata""" - actor_data = await self.apg.get_ap_actor_data_from_account(ap_account) + async def generate_v_card( + self, + requestor_actor_id: str, + ap_account: str + ) -> domish.Element: + """Generate vCard4 (XEP-0292) item element from ap_account's metadata + + @param requestor_actor_id: ID of the actor doing the request. + @param ap_account: AP account from where the vcard must be retrieved. + @return: <item> with the <vcard> element + """ + actor_data = await self.apg.get_ap_actor_data_from_account( + requestor_actor_id, + ap_account + ) identity_data = {} summary = actor_data.get("summary") @@ -190,16 +214,21 @@ async def get_avatar_data( self, client: SatXMPPEntity, + requestor_actor_id: str, ap_account: str - ) -> Dict[str, Any]: + ) -> dict[str, Any]: """Retrieve actor's avatar if any, cache it and file actor_data - ``cache_uid``, `path``` and ``media_type`` keys are always files - ``base64`` key is only filled if the file was not already in cache + @param client: client to use for the request. + @param requestor_actor_id: ID of the actor doing the request. + @param ap_account: AP account from where the avatar data must be retrieved. + @return: Avatar data. + ``cache_uid``, `path``` and ``media_type`` keys are always filed. + ``base64`` key is only filled if the file was not already in cache. """ actor_data = await self.apg.get_ap_actor_data_from_account(ap_account) - for icon in await self.apg.ap_get_list(actor_data, "icon"): + for icon in await self.apg.ap_get_list(requestor_actor_id, actor_data, "icon"): url = icon.get("url") if icon["type"] != "Image" or not url: continue @@ -249,14 +278,16 @@ async def generate_avatar_metadata( self, client: SatXMPPEntity, + requestor_actor_id: str, ap_account: str ) -> domish.Element: """Generate the metadata element for user avatar + @param requestor_actor_id: ID of the actor doing the request. @raise StanzaError("item-not-found"): no avatar is present in actor data (in ``icon`` field) """ - avatar_data = await self.get_avatar_data(client, ap_account) + avatar_data = await self.get_avatar_data(client, requestor_actor_id, ap_account) return self.apg._a.build_item_metadata_elt(avatar_data) def _blocking_b_6_4_encode_avatar(self, avatar_data: Dict[str, Any]) -> None: @@ -266,17 +297,26 @@ async def generate_avatar_data( self, client: SatXMPPEntity, + requestor_actor_id: str, ap_account: str, itemIdentifiers: Optional[List[str]], ) -> domish.Element: """Generate the data element for user avatar + @param requestor_actor_id: ID of the actor doing the request. @raise StanzaError("item-not-found"): no avatar cached with requested ID """ if not itemIdentifiers: - avatar_data = await self.get_avatar_data(client, ap_account) + avatar_data = await self.get_avatar_data( + client, + requestor_actor_id, + ap_account + ) if "base64" not in avatar_data: - await threads.deferToThread(self._blocking_b_6_4_encode_avatar, avatar_data) + await threads.deferToThread( + self._blocking_b_6_4_encode_avatar, + avatar_data + ) else: if len(itemIdentifiers) > 1: # only a single item ID is supported @@ -312,6 +352,11 @@ log.warning(f"Invalid AP account used by {requestor}: {ap_account!r}") return [], None + requestor_actor_id = self.apg.build_apurl( + TYPE_ACTOR, + await self.apg.get_ap_account_from_jid_and_node(service, node) + ) + # cached_node may be pre-filled with some nodes (e.g. attachments nodes), # otherwise it is filled when suitable cached_node = None @@ -330,14 +375,21 @@ use_cache = False elif node == self.apg._v.node: # vCard4 request - item_elt = await self.generate_v_card(ap_account) + item_elt = await self.generate_v_card(requestor_actor_id, ap_account) return [item_elt], None elif node == self.apg._a.namespace_metadata: - item_elt = await self.generate_avatar_metadata(self.apg.client, ap_account) + item_elt = await self.generate_avatar_metadata( + self.apg.client, + requestor_actor_id, + ap_account + ) return [item_elt], None elif node == self.apg._a.namespace_data: item_elt = await self.generate_avatar_data( - self.apg.client, ap_account, itemIdentifiers + self.apg.client, + requestor_actor_id, + ap_account, + itemIdentifiers ) return [item_elt], None elif self.apg._pa.is_attachment_node(node): @@ -384,8 +436,8 @@ if itemIdentifiers: items = [] for item_id in itemIdentifiers: - item_data = await self.apg.ap_get(item_id) - item_elt = await parser(item_data) + item_data = await self.apg.ap_get(item_id, requestor_actor_id) + item_elt = await parser(requestor_actor_id, item_data) items.append(item_elt) return items, None else: @@ -422,8 +474,9 @@ if self.apg._m.is_comment_node(node): parent_item = self.apg._m.get_parent_item(node) try: - parent_data = await self.apg.ap_get(parent_item) + parent_data = await self.apg.ap_get(parent_item, requestor_actor_id) collection = await self.apg.ap_get_object( + requestor_actor_id, parent_data.get("object", {}), "replies" ) @@ -433,8 +486,11 @@ text=str(e) ) else: - actor_data = await self.apg.get_ap_actor_data_from_account(ap_account) - collection = await self.apg.ap_get_object(actor_data, collection_name) + actor_data = await self.apg.get_ap_actor_data_from_account( + requestor_actor_id, + ap_account + ) + collection = await self.apg.ap_get_object(requestor_actor_id, actor_data, collection_name) if not collection: raise error.StanzaError( "item-not-found", @@ -442,7 +498,7 @@ ) kwargs["parser"] = parser - return await self.apg.get_ap_items(collection, **kwargs) + return await self.apg.get_ap_items(requestor_actor_id, collection, **kwargs) @ensure_deferred async def retract(self, requestor, service, nodeIdentifier, itemIdentifiers):