plugin XEP-0045: Use disco as fallback for is_room:
If a room was not joined (e.g., due to failure), `is_room` was wrongly returning `False`. Disco identity is now used as fallback to detect correctly is an entity is a room or not. This changes makes `is_room` async, and by extension `get_bare_or_full` too.
This commit is contained in:
parent
e5781641f3
commit
dc9e3e98d5
3 changed files with 21 additions and 24 deletions
|
|
@ -254,7 +254,7 @@ class Identity:
|
||||||
cb_list.append(callback)
|
cb_list.append(callback)
|
||||||
cb_list.sort(key=lambda c: c.priority, reverse=True)
|
cb_list.sort(key=lambda c: c.priority, reverse=True)
|
||||||
|
|
||||||
def get_identity_jid(self, client, peer_jid):
|
async def get_identity_jid(self, client, peer_jid):
|
||||||
"""Return jid to use to set identity metadata
|
"""Return jid to use to set identity metadata
|
||||||
|
|
||||||
if it's a jid of a room occupant, full jid will be used
|
if it's a jid of a room occupant, full jid will be used
|
||||||
|
|
@ -266,8 +266,7 @@ class Identity:
|
||||||
return client.jid.userhostJID()
|
return client.jid.userhostJID()
|
||||||
if self._m is None:
|
if self._m is None:
|
||||||
return peer_jid.userhostJID()
|
return peer_jid.userhostJID()
|
||||||
else:
|
return await self._m.get_bare_or_full(client, peer_jid)
|
||||||
return self._m.get_bare_or_full(client, peer_jid)
|
|
||||||
|
|
||||||
def check_type(self, metadata_name, value):
|
def check_type(self, metadata_name, value):
|
||||||
"""Check that type used for a metadata is the one declared in self.metadata"""
|
"""Check that type used for a metadata is the one declared in self.metadata"""
|
||||||
|
|
@ -306,7 +305,7 @@ class Identity:
|
||||||
@param use_cache: if False, cache won't be checked
|
@param use_cache: if False, cache won't be checked
|
||||||
@param prefilled_values: map of origin => value to use when `get_all` is set
|
@param prefilled_values: map of origin => value to use when `get_all` is set
|
||||||
"""
|
"""
|
||||||
entity = self.get_identity_jid(client, entity)
|
entity = await self.get_identity_jid(client, entity)
|
||||||
try:
|
try:
|
||||||
metadata = self.metadata[metadata_name]
|
metadata = self.metadata[metadata_name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|
@ -398,7 +397,7 @@ class Identity:
|
||||||
@param entity(jid.JID, None): entity for which avatar is requested
|
@param entity(jid.JID, None): entity for which avatar is requested
|
||||||
None to use profile's jid
|
None to use profile's jid
|
||||||
"""
|
"""
|
||||||
entity = self.get_identity_jid(client, entity)
|
entity = await self.get_identity_jid(client, entity)
|
||||||
metadata = self.metadata[metadata_name]
|
metadata = self.metadata[metadata_name]
|
||||||
data_filter = metadata.get("set_data_filter")
|
data_filter = metadata.get("set_data_filter")
|
||||||
if data_filter is not None:
|
if data_filter is not None:
|
||||||
|
|
@ -448,7 +447,7 @@ class Identity:
|
||||||
This method may be called by plugins when an identity metadata is available.
|
This method may be called by plugins when an identity metadata is available.
|
||||||
@param origin: namespace of the plugin which is source of the metadata
|
@param origin: namespace of the plugin which is source of the metadata
|
||||||
"""
|
"""
|
||||||
entity = self.get_identity_jid(client, entity)
|
entity = await self.get_identity_jid(client, entity)
|
||||||
if (entity, metadata_name) in client._identity_update_lock:
|
if (entity, metadata_name) in client._identity_update_lock:
|
||||||
log.debug(f"update is locked for {entity}'s {metadata_name}")
|
log.debug(f"update is locked for {entity}'s {metadata_name}")
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -396,20 +396,27 @@ class XEP_0045:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def is_room(self, client: SatXMPPEntity, entity_jid: jid.JID) -> bool:
|
async def is_room(self, client: SatXMPPEntity, entity_jid: jid.JID) -> bool:
|
||||||
"""Check if a JID is a joined MUC.
|
"""Check if a JID is a joined MUC or a known MUC service.
|
||||||
|
|
||||||
@param client: The client instance.
|
@param client: The client instance.
|
||||||
@param entity_jid: JID of the entity to check.
|
@param entity_jid: JID of the entity to check.
|
||||||
@return: True if the JID is a joined MUC.
|
@return: True if the JID is a joined MUC or a known MUC service.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.check_room_joined(client, entity_jid.userhostJID())
|
self.check_room_joined(client, entity_jid.userhostJID())
|
||||||
except exceptions.NotFound:
|
except exceptions.NotFound:
|
||||||
return False
|
# It's not a joined room (yet?), we check disco as fallback.
|
||||||
|
try:
|
||||||
|
return await self.host.memory.disco.has_identity(
|
||||||
|
client, "conference", "text", entity_jid.userhostJID()
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
log.exception(f"Can't get identity of {entity_jid.full()}")
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_bare_or_full(self, client: SatXMPPEntity, peer_jid: jid.JID) -> jid.JID:
|
async def get_bare_or_full(self, client: SatXMPPEntity, peer_jid: jid.JID) -> jid.JID:
|
||||||
"""Use full JID if peer is an occupant of a room, bare JID else.
|
"""Use full JID if peer is an occupant of a room, bare JID else.
|
||||||
|
|
||||||
@param client: The client instance.
|
@param client: The client instance.
|
||||||
|
|
@ -417,7 +424,7 @@ class XEP_0045:
|
||||||
@return: Bare or full JID.
|
@return: Bare or full JID.
|
||||||
"""
|
"""
|
||||||
if peer_jid.resource:
|
if peer_jid.resource:
|
||||||
if not self.is_room(client, peer_jid):
|
if not await self.is_room(client, peer_jid):
|
||||||
return peer_jid.userhostJID()
|
return peer_jid.userhostJID()
|
||||||
return peer_jid
|
return peer_jid
|
||||||
|
|
||||||
|
|
@ -917,19 +924,10 @@ class XEP_0045:
|
||||||
|
|
||||||
if room_jid in muc_client.joined_rooms:
|
if room_jid in muc_client.joined_rooms:
|
||||||
room = muc_client.joined_rooms[room_jid]
|
room = muc_client.joined_rooms[room_jid]
|
||||||
log.info(
|
log.info(f"{client.profile} is already in room {room_jid.userhost()}")
|
||||||
f"{client.profile} is already in room {room_jid}",
|
|
||||||
profile=client.profile,
|
|
||||||
room_jid=room_jid.userhost(),
|
|
||||||
)
|
|
||||||
raise AlreadyJoined(room)
|
raise AlreadyJoined(room)
|
||||||
|
|
||||||
log.info(
|
log.info(f"[{client.profile}] joining room {room_jid.userhost()} as {nick}")
|
||||||
f"[{client.profile}] joining room {room_jid} as {nick}",
|
|
||||||
profile=client.profile,
|
|
||||||
room=room_jid.userhost(),
|
|
||||||
nick=nick,
|
|
||||||
)
|
|
||||||
|
|
||||||
password = options.get("password")
|
password = options.get("password")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -314,7 +314,7 @@ class XEP_0444:
|
||||||
store = False
|
store = False
|
||||||
else:
|
else:
|
||||||
# we use bare JIDs for one2one message, except if the recipient is from a MUC
|
# we use bare JIDs for one2one message, except if the recipient is from a MUC
|
||||||
if self._m.is_room(client, dest_jid):
|
if await self._m.is_room(client, dest_jid):
|
||||||
# this is a private message in a room, we need to use the MUC JID
|
# this is a private message in a room, we need to use the MUC JID
|
||||||
reacting_jid = self._m.get_room_user_jid(client, dest_jid.userhostJID())
|
reacting_jid = self._m.get_room_user_jid(client, dest_jid.userhostJID())
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue