Fix issue of roster data being split across multiple rosters.
Resolved by always normalizing JIDs to bare form, regardless of if they are JID objects or strings. Also simplified related code to prefer use of JID objects instead of strings so they don't need to be parsed multiple times.
This commit is contained in:
parent
f6edaa56a6
commit
917faecdcb
6 changed files with 45 additions and 48 deletions
|
@ -91,13 +91,13 @@ class BaseXMPP(XMLStream):
|
||||||
#: owner JIDs, as in the case for components. For clients
|
#: owner JIDs, as in the case for components. For clients
|
||||||
#: which only have a single JID, see :attr:`client_roster`.
|
#: which only have a single JID, see :attr:`client_roster`.
|
||||||
self.roster = roster.Roster(self)
|
self.roster = roster.Roster(self)
|
||||||
self.roster.add(self.boundjid.bare)
|
self.roster.add(self.boundjid)
|
||||||
|
|
||||||
#: The single roster for the bound JID. This is the
|
#: The single roster for the bound JID. This is the
|
||||||
#: equivalent of::
|
#: equivalent of::
|
||||||
#:
|
#:
|
||||||
#: self.roster[self.boundjid.bare]
|
#: self.roster[self.boundjid.bare]
|
||||||
self.client_roster = self.roster[self.boundjid.bare]
|
self.client_roster = self.roster[self.boundjid]
|
||||||
|
|
||||||
#: The distinction between clients and components can be
|
#: The distinction between clients and components can be
|
||||||
#: important, primarily for choosing how to handle the
|
#: important, primarily for choosing how to handle the
|
||||||
|
@ -691,17 +691,13 @@ class BaseXMPP(XMLStream):
|
||||||
msg['to'] = self.boundjid
|
msg['to'] = self.boundjid
|
||||||
self.event('message', msg)
|
self.event('message', msg)
|
||||||
|
|
||||||
def _handle_available(self, presence):
|
def _handle_available(self, pres):
|
||||||
pto = presence['to'].bare
|
self.roster[pres['to']][pres['from']].handle_available(pres)
|
||||||
pfrom = presence['from'].bare
|
|
||||||
self.roster[pto][pfrom].handle_available(presence)
|
|
||||||
|
|
||||||
def _handle_unavailable(self, presence):
|
def _handle_unavailable(self, pres):
|
||||||
pto = presence['to'].bare
|
self.roster[pres['to']][pres['from']].handle_unavailable(pres)
|
||||||
pfrom = presence['from'].bare
|
|
||||||
self.roster[pto][pfrom].handle_unavailable(presence)
|
|
||||||
|
|
||||||
def _handle_new_subscription(self, stanza):
|
def _handle_new_subscription(self, pres):
|
||||||
"""Attempt to automatically handle subscription requests.
|
"""Attempt to automatically handle subscription requests.
|
||||||
|
|
||||||
Subscriptions will be approved if the request is from
|
Subscriptions will be approved if the request is from
|
||||||
|
@ -713,8 +709,8 @@ class BaseXMPP(XMLStream):
|
||||||
If a subscription is accepted, a request for a mutual
|
If a subscription is accepted, a request for a mutual
|
||||||
subscription will be sent if :attr:`auto_subscribe` is ``True``.
|
subscription will be sent if :attr:`auto_subscribe` is ``True``.
|
||||||
"""
|
"""
|
||||||
roster = self.roster[stanza['to'].bare]
|
roster = self.roster[pres['to']]
|
||||||
item = self.roster[stanza['to'].bare][stanza['from'].bare]
|
item = self.roster[pres['to']][pres['from']]
|
||||||
if item['whitelisted']:
|
if item['whitelisted']:
|
||||||
item.authorize()
|
item.authorize()
|
||||||
elif roster.auto_authorize:
|
elif roster.auto_authorize:
|
||||||
|
@ -724,30 +720,20 @@ class BaseXMPP(XMLStream):
|
||||||
elif roster.auto_authorize == False:
|
elif roster.auto_authorize == False:
|
||||||
item.unauthorize()
|
item.unauthorize()
|
||||||
|
|
||||||
def _handle_removed_subscription(self, presence):
|
def _handle_removed_subscription(self, pres):
|
||||||
pto = presence['to'].bare
|
self.roster[pres['to']][pres['from']].handle_unauthorize(pres)
|
||||||
pfrom = presence['from'].bare
|
|
||||||
self.roster[pto][pfrom].unauthorize()
|
|
||||||
|
|
||||||
def _handle_subscribe(self, presence):
|
def _handle_subscribe(self, pres):
|
||||||
pto = presence['to'].bare
|
self.roster[pres['to']][pres['from']].handle_subscribe(pres)
|
||||||
pfrom = presence['from'].bare
|
|
||||||
self.roster[pto][pfrom].handle_subscribe(presence)
|
|
||||||
|
|
||||||
def _handle_subscribed(self, presence):
|
def _handle_subscribed(self, pres):
|
||||||
pto = presence['to'].bare
|
self.roster[pres['to']][pres['from']].handle_subscribed(pres)
|
||||||
pfrom = presence['from'].bare
|
|
||||||
self.roster[pto][pfrom].handle_subscribed(presence)
|
|
||||||
|
|
||||||
def _handle_unsubscribe(self, presence):
|
def _handle_unsubscribe(self, pres):
|
||||||
pto = presence['to'].bare
|
self.roster[pres['to']][pres['from']].handle_unsubscribe(pres)
|
||||||
pfrom = presence['from'].bare
|
|
||||||
self.roster[pto][pfrom].handle_unsubscribe(presence)
|
|
||||||
|
|
||||||
def _handle_unsubscribed(self, presence):
|
def _handle_unsubscribed(self, pres):
|
||||||
pto = presence['to'].bare
|
self.roster[pres['to']][pres['from']].handle_unsubscribed(pres)
|
||||||
pfrom = presence['from'].bare
|
|
||||||
self.roster[pto][pfrom].handle_unsubscribed(presence)
|
|
||||||
|
|
||||||
def _handle_presence(self, presence):
|
def _handle_presence(self, presence):
|
||||||
"""Process incoming presence stanzas.
|
"""Process incoming presence stanzas.
|
||||||
|
|
|
@ -158,10 +158,8 @@ class ComponentXMPP(BaseXMPP):
|
||||||
"""
|
"""
|
||||||
self.session_bind_event.set()
|
self.session_bind_event.set()
|
||||||
self.session_started_event.set()
|
self.session_started_event.set()
|
||||||
self.event("session_bind", self.xmpp.boundjid.full, direct=True)
|
self.event("session_bind", self.xmpp.boundjid, direct=True)
|
||||||
self.event("session_start")
|
self.event("session_start")
|
||||||
|
|
||||||
def _handle_probe(self, presence):
|
def _handle_probe(self, pres):
|
||||||
pto = presence['to'].bare
|
self.roster[pres['to']][pres['from']].handle_probe(pres)
|
||||||
pfrom = presence['from'].bare
|
|
||||||
self.roster[pto][pfrom].handle_probe(presence)
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ class FeatureBind(BasePlugin):
|
||||||
|
|
||||||
self.xmpp.set_jid(response['bind']['jid'])
|
self.xmpp.set_jid(response['bind']['jid'])
|
||||||
self.xmpp.bound = True
|
self.xmpp.bound = True
|
||||||
self.xmpp.event('session_bind', self.xmpp.boundjid.full, direct=True)
|
self.xmpp.event('session_bind', self.xmpp.boundjid, direct=True)
|
||||||
self.xmpp.session_bind_event.set()
|
self.xmpp.session_bind_event.set()
|
||||||
|
|
||||||
self.xmpp.features.add('bind')
|
self.xmpp.features.add('bind')
|
||||||
|
|
|
@ -94,10 +94,12 @@ class Roster(object):
|
||||||
Arguments:
|
Arguments:
|
||||||
key -- Return the roster for this JID.
|
key -- Return the roster for this JID.
|
||||||
"""
|
"""
|
||||||
if isinstance(key, JID):
|
|
||||||
key = key.bare
|
|
||||||
if key is None:
|
if key is None:
|
||||||
key = self.xmpp.boundjid.bare
|
key = self.xmpp.boundjid
|
||||||
|
if not isinstance(key, JID):
|
||||||
|
key = JID(key)
|
||||||
|
key = key.bare
|
||||||
|
|
||||||
if key not in self._rosters:
|
if key not in self._rosters:
|
||||||
self.add(key)
|
self.add(key)
|
||||||
self._rosters[key].auto_authorize = self.auto_authorize
|
self._rosters[key].auto_authorize = self.auto_authorize
|
||||||
|
@ -119,7 +121,9 @@ class Roster(object):
|
||||||
Arguments:
|
Arguments:
|
||||||
node -- The JID for the new roster node.
|
node -- The JID for the new roster node.
|
||||||
"""
|
"""
|
||||||
if isinstance(node, JID):
|
if not isinstance(node, JID):
|
||||||
|
node = JID(node)
|
||||||
|
|
||||||
node = node.bare
|
node = node.bare
|
||||||
if node not in self._rosters:
|
if node not in self._rosters:
|
||||||
self._rosters[node] = RosterNode(self.xmpp, node, self.db)
|
self._rosters[node] = RosterNode(self.xmpp, node, self.db)
|
||||||
|
|
|
@ -89,7 +89,10 @@ class RosterNode(object):
|
||||||
|
|
||||||
A new item entry will be created if one does not already exist.
|
A new item entry will be created if one does not already exist.
|
||||||
"""
|
"""
|
||||||
if isinstance(key, JID):
|
if key is None:
|
||||||
|
key = JID('')
|
||||||
|
if not isinstance(key, JID):
|
||||||
|
key = JID(key)
|
||||||
key = key.bare
|
key = key.bare
|
||||||
if key not in self._jids:
|
if key not in self._jids:
|
||||||
self.add(key, save=True)
|
self.add(key, save=True)
|
||||||
|
@ -101,7 +104,10 @@ class RosterNode(object):
|
||||||
|
|
||||||
To remove an item from the server, use the remove() method.
|
To remove an item from the server, use the remove() method.
|
||||||
"""
|
"""
|
||||||
if isinstance(key, JID):
|
if key is None:
|
||||||
|
key = JID('')
|
||||||
|
if not isinstance(key, JID):
|
||||||
|
key = JID(key)
|
||||||
key = key.bare
|
key = key.bare
|
||||||
if key in self._jids:
|
if key in self._jids:
|
||||||
del self._jids[key]
|
del self._jids[key]
|
||||||
|
|
|
@ -143,3 +143,6 @@ class JID(object):
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
"""Hash a JID based on the string version of its full JID."""
|
"""Hash a JID based on the string version of its full JID."""
|
||||||
return hash(self.full)
|
return hash(self.full)
|
||||||
|
|
||||||
|
def __copy__(self):
|
||||||
|
return JID(self.jid)
|
||||||
|
|
Loading…
Reference in a new issue