core, memory (sqla), plugins XEP-0277, XEP-0346: various fixes:
- `is_local`: now use `server_jid`. - `aio_func`: pass the missing `self` argument (`aio_fund` is unbound). - Declare `pubsub_service` in `core_types.SatXMPPEntity` - plugin XEP-0277: fix handling of `MbData.from_element` when node is not specified (so we use default node). - plugin XEP-0346: `IdentityData`: fix field access, following move to Pydantic model.
This commit is contained in:
parent
f862efe790
commit
50ffc8c3b4
6 changed files with 26 additions and 25 deletions
|
|
@ -110,6 +110,8 @@ class SatXMPPEntity(ABC):
|
||||||
conn_deferred: defer.Deferred
|
conn_deferred: defer.Deferred
|
||||||
xmlstream: mod_xmlstream.XmlStream
|
xmlstream: mod_xmlstream.XmlStream
|
||||||
tor: "Tor | None" = None
|
tor: "Tor | None" = None
|
||||||
|
# Default pubsub service (set by XEP-0060)
|
||||||
|
pubsub_service: "t_jid.JID | None" = None
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.plugin_data: dict[str, Any] = {}
|
self.plugin_data: dict[str, Any] = {}
|
||||||
|
|
@ -374,5 +376,5 @@ class SatXMPPClient(SatXMPPEntity):
|
||||||
class SatXMPPComponent(SatXMPPEntity):
|
class SatXMPPComponent(SatXMPPEntity):
|
||||||
|
|
||||||
def is_local(self, jid_: t_jid.JID) -> bool:
|
def is_local(self, jid_: t_jid.JID) -> bool:
|
||||||
"""Returns True if jid_ use a domain or subdomain of component's host"""
|
"""Returns True if jid_ is an account on the local server"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
|
||||||
|
|
@ -1322,10 +1322,8 @@ class SatXMPPComponent(SatXMPPEntity, core_types.SatXMPPComponent, component.Com
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def is_local(self, jid_: jid.JID) -> bool:
|
def is_local(self, jid_: jid.JID) -> bool:
|
||||||
"""Returns True if jid_ use a domain or subdomain of component's host"""
|
"""Return True if jid_ is an account on the local server."""
|
||||||
local_host = self.host.split(".")
|
return jid_.host == self.server_jid.host
|
||||||
assert local_host
|
|
||||||
return jid_.host.split(".")[-len(local_host) :] == local_host
|
|
||||||
|
|
||||||
def _create_sub_protocols(self):
|
def _create_sub_protocols(self):
|
||||||
self.messageProt = SatMessageProtocol()
|
self.messageProt = SatMessageProtocol()
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ class Storage:
|
||||||
This method is called on shutdown.
|
This method is called on shutdown.
|
||||||
"""
|
"""
|
||||||
if self.engine.dialect.name == "sqlite":
|
if self.engine.dialect.name == "sqlite":
|
||||||
await self.wal_checkpoint.aio_func()
|
await self.wal_checkpoint.aio_func(self)
|
||||||
await self.engine.dispose()
|
await self.engine.dispose()
|
||||||
|
|
||||||
async def migrate_apply(self, *args: str, log_output: bool = False) -> None:
|
async def migrate_apply(self, *args: str, log_output: bool = False) -> None:
|
||||||
|
|
@ -1464,7 +1464,7 @@ class Storage:
|
||||||
create_kwargs = {}
|
create_kwargs = {}
|
||||||
try:
|
try:
|
||||||
return await self.set_pubsub_node.aio_func(
|
return await self.set_pubsub_node.aio_func(
|
||||||
client, service, name, **create_kwargs
|
self, client, service, name, **create_kwargs
|
||||||
)
|
)
|
||||||
except IntegrityError as e:
|
except IntegrityError as e:
|
||||||
if "unique" in str(e.orig).lower():
|
if "unique" in str(e.orig).lower():
|
||||||
|
|
@ -1472,6 +1472,7 @@ class Storage:
|
||||||
# get_pubsub_node above
|
# get_pubsub_node above
|
||||||
log.debug("ignoring UNIQUE constraint error")
|
log.debug("ignoring UNIQUE constraint error")
|
||||||
return await self.get_pubsub_node.aio_func(
|
return await self.get_pubsub_node.aio_func(
|
||||||
|
self,
|
||||||
client,
|
client,
|
||||||
service,
|
service,
|
||||||
name=name,
|
name=name,
|
||||||
|
|
@ -2266,7 +2267,7 @@ class Storage:
|
||||||
If affiliation is None, the entity's affiliation is removed.
|
If affiliation is None, the entity's affiliation is removed.
|
||||||
@raise exceptions.NotFound: Node doesn't exist.
|
@raise exceptions.NotFound: Node doesn't exist.
|
||||||
"""
|
"""
|
||||||
node = await self.get_pubsub_node.aio_func(client, service, node_name)
|
node = await self.get_pubsub_node.aio_func(self, client, service, node_name)
|
||||||
if node is None:
|
if node is None:
|
||||||
raise exceptions.NotFound(f"Node {node_name!r} not found")
|
raise exceptions.NotFound(f"Node {node_name!r} not found")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -214,8 +214,9 @@ class MbData(BaseModel):
|
||||||
data = {
|
data = {
|
||||||
"id": id_,
|
"id": id_,
|
||||||
"service": service,
|
"service": service,
|
||||||
"node": node,
|
|
||||||
}
|
}
|
||||||
|
if node is not None:
|
||||||
|
data["node"] = node
|
||||||
|
|
||||||
# Set URI if node is provided
|
# Set URI if node is provided
|
||||||
# FIXME: node should alway be set in the future, check FIXME in method signature.
|
# FIXME: node should alway be set in the future, check FIXME in method signature.
|
||||||
|
|
|
||||||
|
|
@ -810,7 +810,7 @@ class PubsubSchema(object):
|
||||||
if fill_author:
|
if fill_author:
|
||||||
if not values.get("author"):
|
if not values.get("author"):
|
||||||
id_data = await self._i.get_identity(client, None, ["nicknames"])
|
id_data = await self._i.get_identity(client, None, ["nicknames"])
|
||||||
values["author"] = id_data["nicknames"][0]
|
values["author"] = id_data.nicknames[0]
|
||||||
if not values.get("author_jid"):
|
if not values.get("author_jid"):
|
||||||
values["author_jid"] = client.jid.full()
|
values["author_jid"] = client.jid.full()
|
||||||
item_id = await self.send_data_form_item(
|
item_id = await self.send_data_form_item(
|
||||||
|
|
|
||||||
|
|
@ -380,18 +380,20 @@ async def mock_get_pubsub_node(client, service, node, with_subscriptions=False,
|
||||||
return fake_cached_node
|
return fake_cached_node
|
||||||
|
|
||||||
|
|
||||||
def mock_client(jid):
|
def mock_client(client_jid):
|
||||||
client = MagicMock()
|
client = MagicMock()
|
||||||
client.jid = jid
|
client.jid = client_jid
|
||||||
client.host = "test.example"
|
client.host = "test.example"
|
||||||
|
# same derivation as SatXMPPComponent.server_jid
|
||||||
|
client.server_jid = jid.JID(client_jid.host.split(".", 1)[-1])
|
||||||
client._ap_storage.get = AsyncMock()
|
client._ap_storage.get = AsyncMock()
|
||||||
client._ap_storage.aset = AsyncMock()
|
client._ap_storage.aset = AsyncMock()
|
||||||
client.is_local = lambda jid_: SatXMPPComponent.is_local(client, jid_)
|
client.is_local = lambda jid_: SatXMPPComponent.is_local(client, jid_)
|
||||||
return client
|
return client
|
||||||
|
|
||||||
|
|
||||||
def get_virtual_client(jid):
|
def get_virtual_client(client_jid):
|
||||||
return mock_client(jid)
|
return mock_client(client_jid)
|
||||||
|
|
||||||
|
|
||||||
class FakeTReqPostResponse:
|
class FakeTReqPostResponse:
|
||||||
|
|
@ -450,12 +452,12 @@ class TestActivityPubGateway:
|
||||||
== "some_other_node---simple@test.example"
|
== "some_other_node---simple@test.example"
|
||||||
)
|
)
|
||||||
|
|
||||||
# local pubsub node
|
# pubsub node on non local pubsub service (exact domain match)
|
||||||
with patch.object(ap_gateway, "is_pubsub") as is_pubsub:
|
with patch.object(ap_gateway, "is_pubsub") as is_pubsub:
|
||||||
is_pubsub.return_value = True
|
is_pubsub.return_value = True
|
||||||
assert (
|
assert (
|
||||||
await get_account(jid_=jid.JID("pubsub.test.example"), node="some_node")
|
await get_account(jid_=jid.JID("pubsub.test.example"), node="some_node")
|
||||||
== "some_node@pubsub.test.example"
|
== "___some_node.40pubsub.2etest.2eexample@ap.test.example"
|
||||||
)
|
)
|
||||||
|
|
||||||
# non local pubsub node
|
# non local pubsub node
|
||||||
|
|
@ -505,16 +507,13 @@ class TestActivityPubGateway:
|
||||||
with patch.object(ap_gateway, "is_pubsub") as is_pubsub:
|
with patch.object(ap_gateway, "is_pubsub") as is_pubsub:
|
||||||
is_pubsub.return_value = True
|
is_pubsub.return_value = True
|
||||||
|
|
||||||
# simple local node
|
# node on non local pubsub service is not allowed with local_only
|
||||||
assert await get_jid_node("toto@pubsub.test.example") == (
|
with pytest.raises(exceptions.PermissionError):
|
||||||
jid.JID("pubsub.test.example"),
|
await get_jid_node("toto@pubsub.test.example")
|
||||||
"toto",
|
|
||||||
)
|
|
||||||
|
|
||||||
# encoded local node
|
# same with an encoded node
|
||||||
assert await get_jid_node(
|
with pytest.raises(exceptions.PermissionError):
|
||||||
"___urn.3axmpp.3amicroblog.3a0@pubsub.test.example"
|
await get_jid_node("___urn.3axmpp.3amicroblog.3a0@pubsub.test.example")
|
||||||
) == (jid.JID("pubsub.test.example"), "urn:xmpp:microblog:0")
|
|
||||||
|
|
||||||
@ed
|
@ed
|
||||||
async def test_ap_to_pubsub_conversion(self, ap_gateway, monkeypatch):
|
async def test_ap_to_pubsub_conversion(self, ap_gateway, monkeypatch):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue