diff --git a/sat/plugins/plugin_comp_ap_gateway/http_server.py b/sat/plugins/plugin_comp_ap_gateway/http_server.py index 189dab33..0249eaff 100644 --- a/sat/plugins/plugin_comp_ap_gateway/http_server.py +++ b/sat/plugins/plugin_comp_ap_gateway/http_server.py @@ -291,7 +291,7 @@ class HTTPAPGServer(web_resource.Resource): account_jid: jid.JID, node: Optional[str], ap_account: str, - actor_url: str, + ap_url: str, signing_actor: Optional[str] ) -> dict: inbox = self.apg.buildAPURL(TYPE_INBOX, ap_account) @@ -312,7 +312,7 @@ class HTTPAPGServer(web_resource.Resource): "https://w3id.org/security/v1" ], - "id": actor_url, + "id": ap_url, "type": "Person", "preferredUsername": preferred_username, "inbox": inbox, @@ -320,8 +320,8 @@ class HTTPAPGServer(web_resource.Resource): "followers": followers, "following": following, "publicKey": { - "id": f"{actor_url}#main-key", - "owner": actor_url, + "id": f"{ap_url}#main-key", + "owner": ap_url, "publicKeyPem": self.apg.public_key_pem }, "endpoints": { diff --git a/tests/unit/test_ap-gateway.py b/tests/unit/test_ap-gateway.py index 62ecdce2..4d0573d6 100644 --- a/tests/unit/test_ap-gateway.py +++ b/tests/unit/test_ap-gateway.py @@ -25,6 +25,7 @@ import pytest from pytest_twisted import ensureDeferred as ed from twisted.internet import defer from twisted.words.protocols.jabber import jid +from twisted.words.protocols.jabber.error import StanzaError from twisted.web.server import Request from twisted.words.xish import domish from wokkel import rsm, pubsub @@ -80,7 +81,8 @@ AP_REQUESTS = { "following": f"{TEST_BASE_URL}/users/{TEST_USER}/following", "id": f"{TEST_BASE_URL}/users/{TEST_USER}", "inbox": f"{TEST_BASE_URL}/users/{TEST_USER}/inbox", - "name": "", + "name": "test_user nickname", + "summary": "
test account
", "outbox": f"{TEST_BASE_URL}/users/{TEST_USER}/outbox", "preferredUsername": f"{TEST_USER}", "type": "Person", @@ -367,7 +369,18 @@ async def mock_treq_json(data): return dict(data) -async def mock_getItems(*args, **kwargs): +async def mock_getItems(client, service, node, *args, **kwargs): + """Mock getItems + + special kwargs can be used: + ret_items (List[Domish.Element]): items to be returned, by default XMPP_ITEMS are + returned + tested_node (str): node for which items must be returned. If specified and a + different node is requested, "item-not-found" StanzaError will be raised + """ + tested_node = kwargs.pop("tested_node", None) + if tested_node is not None and node != tested_node: + raise StanzaError("item-not-found") ret_items = kwargs.pop("ret_items", XMPP_ITEMS) rsm_resp = rsm.RSMResponse( first=ret_items[0]["id"], @@ -407,6 +420,7 @@ def ap_gateway(host): f"{gateway.ap_path}/" ) gateway.server = HTTPServer(gateway) + gateway.public_key_pem = None return gateway @@ -1088,3 +1102,43 @@ class TestActivityPubGateway: retract_elt = apply_to_elt.retract assert retract_elt is not None assert retract_elt.uri == NS_MESSAGE_RETRACT + + @ed + async def test_ap_actor_metadata_to_vcard(self, ap_gateway, monkeypatch): + """AP actor metadata are converted to XMPP/vCard4""" + monkeypatch.setattr(plugin_comp_ap_gateway.treq, "get", mock_ap_get) + monkeypatch.setattr(plugin_comp_ap_gateway.treq, "json_content", mock_treq_json) + monkeypatch.setattr(ap_gateway, "apGet", mock_ap_get) + + items, __ = await ap_gateway.pubsub_service.items( + jid.JID("toto@example.org"), + ap_gateway.getLocalJIDFromAccount(TEST_AP_ACCOUNT), + # VCard4 node + ap_gateway._v.node, + None, + None, + None + ) + assert len(items) == 1 + vcard_elt = next(items[0].elements(ap_gateway._v.namespace, "vcard")) + vcard = ap_gateway._v.vcard2Dict(vcard_elt) + assert "test_user nickname" in vcard["nicknames"] + assert vcard["description"] == "test account" + + @ed + async def test_identity_data_to_ap_actor_metadata(self, ap_gateway): + """XMPP identity is converted to AP actor metadata""" + # XXX: XMPP identity is normally an amalgam of metadata from several + # XEPs/locations (vCard4, vcard-tmp, etc) + with patch.object(ap_gateway._i, "getIdentity") as getIdentity: + getIdentity.return_value = { + "nicknames": ["nick1", "nick2"], + "description": "test description" + } + actor_data = await ap_gateway.server.resource.APActorRequest( + **self.ap_request_params(ap_gateway, ap_const.TYPE_ACTOR) + ) + + # only the first nickname should be used + assert actor_data["name"] == "nick1" + assert actor_data["summary"] == "test description"