]> code.delx.au - pymsnt/blobdiff - src/legacy/glue.py
Fixed MSN protocol dump option.
[pymsnt] / src / legacy / glue.py
index afd80385999ca80692b638169ab3dd0eff3992bc..b6947f395e43b7fe87e88a6f215d1567599f5135 100644 (file)
@@ -1,13 +1,13 @@
 # Copyright 2004-2005 James Bunton <james@delx.cjb.net>
 # Licensed for distribution under the GPL version 2, check COPYING for details
 
 # Copyright 2004-2005 James Bunton <james@delx.cjb.net>
 # Licensed for distribution under the GPL version 2, check COPYING for details
 
+import os.path
 import utils
 import utils
-from twisted.internet import task
+from twisted.internet import task, error
 from tlib.xmlw import Element
 from tlib import msn
 from debug import LogEvent, INFO, WARN, ERROR
 import disco
 from tlib.xmlw import Element
 from tlib import msn
 from debug import LogEvent, INFO, WARN, ERROR
 import disco
-import sha
 import groupchat
 import ft
 import avatar
 import groupchat
 import ft
 import avatar
@@ -17,24 +17,27 @@ import lang
 
 
 
 
 
 
-name = "MSN Transport"   # The name of the transport
 url = "http://msn-transport.jabberstudio.org"
 url = "http://msn-transport.jabberstudio.org"
-version = "0.11-dev"     # The transport version
+version = "0.11.1"       # The transport version
 mangle = True            # XDB '@' -> '%' mangling
 id = "msn"               # The transport identifier
 
 
 # Load the default avatars
 mangle = True            # XDB '@' -> '%' mangling
 id = "msn"               # The transport identifier
 
 
 # Load the default avatars
-f = open("src/legacy/defaultJabberAvatar.png")
+f = open(os.path.join("data", "defaultJabberAvatar.png"), "rb")
 defaultJabberAvatarData = f.read()
 f.close()
 
 defaultJabberAvatarData = f.read()
 f.close()
 
-f = open("src/legacy/defaultAvatar.png")
+f = open(os.path.join("data", "defaultMSNAvatar.png"), "rb")
 defaultAvatarData = f.read()
 f.close()
 defaultAvatar = avatar.AvatarCache().setAvatar(defaultAvatarData)
 
 
 defaultAvatarData = f.read()
 f.close()
 defaultAvatar = avatar.AvatarCache().setAvatar(defaultAvatarData)
 
 
+def reloadConfig():
+       msn.MSNConnection.GETALLAVATARS = config.getAllAvatars
+       msn.setDebug(config._debugLevel >= 4)
+
 def isGroupJID(jid):
        """ Returns True if the JID passed is a valid groupchat JID (for MSN, does not contain '%') """
        return (jid.find('%') == -1)
 def isGroupJID(jid):
        """ Returns True if the JID passed is a valid groupchat JID (for MSN, does not contain '%') """
        return (jid.find('%') == -1)
@@ -92,15 +95,45 @@ def updateStats(statistics):
        #stats["FailedAvatarCount"] = msnp2p.MSNP2P_Avatar.ERROR_COUNT
 
 
        #stats["FailedAvatarCount"] = msnp2p.MSNP2P_Avatar.ERROR_COUNT
 
 
-def msn2jid(msnid):
+msn2jid_cache = {}
+def msn2jid(msnid, withResource):
        """ Converts a MSN passport into a JID representation to be used with the transport """
        """ Converts a MSN passport into a JID representation to be used with the transport """
-       return msnid.replace('@', '%') + "@" + config.jid
-
-translateAccount = msn2jid # Marks this as the function to be used in jabber:iq:gateway (Service ID Translation)
-
+       global msn2jid_cache
+       global jid2msn_cache
+
+       if msn2jid_cache.has_key(msnid):
+               jid = msn2jid_cache[msnid]
+               if withResource:
+                       jid += "/msn"
+               return jid
+       else:
+               if msnid.startswith("tel:+"):
+                       msnid = msnid.replace("tel:+", "") + "%tel"
+               jid = msnid.replace('@', '%') + "@" + config.jid
+               msn2jid_cache[msnid] = jid
+               jid2msn_cache[jid] = msnid
+               return msn2jid(msnid, withResource)
+
+# Marks this as the function to be used in jabber:iq:gateway (Service ID Translation)
+def translateAccount(msnid):
+       return msn2jid(msnid, False)
+
+jid2msn_cache = {}
 def jid2msn(jid):
        """ Converts a JID representation of a MSN passport into the original MSN passport """
 def jid2msn(jid):
        """ Converts a JID representation of a MSN passport into the original MSN passport """
-       return unicode(jid[:jid.find('@')].replace('%', '@'))
+       global jid2msn_cache
+       global msn2jid_cache
+
+       if jid2msn_cache.has_key(jid):
+               msnid = jid2msn_cache[jid]
+               return msnid
+       else:
+               if jid.find("%tel@") > 0:
+                       jid = "tel:+" + jid.replace("%tel@", "@")
+               msnid = unicode(jid[:jid.find('@')].replace('%', '@')).split("/")[0]
+               jid2msn_cache[jid] = msnid
+               msn2jid_cache[msnid] = jid
+               return msnid
 
 
 def presence2state(show, ptype): 
 
 
 def presence2state(show, ptype): 
@@ -113,6 +146,7 @@ def presence2state(show, ptype):
                return msn.STATUS_BUSY
        elif show == "away" or show == "xa":
                return msn.STATUS_AWAY
                return msn.STATUS_BUSY
        elif show == "away" or show == "xa":
                return msn.STATUS_AWAY
+       return msn.STATUS_ONLINE
 
 
 def state2presence(state):
 
 
 def state2presence(state):
@@ -227,7 +261,7 @@ class LegacyConnection(msn.MSNConnection):
                self.remoteNick = ""
 
                # Init the MSN bits
                self.remoteNick = ""
 
                # Init the MSN bits
-               msn.MSNConnection.__init__(self, username, password, self.session.jabberID)
+               msn.MSNConnection.__init__(self, username, password, self.jabberID)
 
                # User typing notification stuff
                self.userTyping = dict() # Indexed by contact MSN ID, stores whether the user is typing to this contact
 
                # User typing notification stuff
                self.userTyping = dict() # Indexed by contact MSN ID, stores whether the user is typing to this contact
@@ -239,10 +273,10 @@ class LegacyConnection(msn.MSNConnection):
                
                self.legacyList = LegacyList(self.session)
        
                
                self.legacyList = LegacyList(self.session)
        
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
        
        def removeMe(self):
        
        def removeMe(self):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
        
                self.userTypingSend.stop()
        
        
                self.userTypingSend.stop()
        
@@ -251,15 +285,15 @@ class LegacyConnection(msn.MSNConnection):
                self.session = None
                self.logOut()
        
                self.session = None
                self.logOut()
        
-       def _sendShowStatus(self):
+
+       # Implemented from baseproto
+       def sendShowStatus(self, jid=None):
                if not self.session: return
                source = config.jid
                if not self.session: return
                source = config.jid
-               to = self.session.jabberID
-               self.session.sendPresence(to=to, fro=source, show=self.remoteShow, status=self.remoteStatus, nickname=self.remoteNick)
+               if not jid:
+                       jid = self.jabberID
+               self.session.sendPresence(to=jid, fro=source, show=self.remoteShow, status=self.remoteStatus, nickname=self.remoteNick)
        
        
-       
-
-       # Implemented from baseproto
        def resourceOffline(self, resource):
                pass
 
        def resourceOffline(self, resource):
                pass
 
@@ -278,6 +312,22 @@ class LegacyConnection(msn.MSNConnection):
                        self.failedMessage(dest, body)
                        raise
        
                        self.failedMessage(dest, body)
                        raise
        
+       def sendFile(self, dest, ftSend):
+               dest = jid2msn(dest)
+               def continueSendFile1((msnFileSend, d)):
+                       def continueSendFile2((success, )):
+                               if success:
+                                       ftSend.accept(msnFileSend)
+                               else:
+                                       sendFileFail()
+                       d.addCallbacks(continueSendFile2, sendFileFail)
+       
+               def sendFileFail():
+                       ftSend.reject()
+
+               d = msn.MSNConnection.sendFile(self, dest, ftSend.filename, ftSend.filesize)
+               d.addCallbacks(continueSendFile1, sendFileFail)
+       
        def setStatus(self, nickname, show, status):
                statusCode = presence2state(show, None)
                msn.MSNConnection.changeStatus(self, statusCode, nickname, status)
        def setStatus(self, nickname, show, status):
                statusCode = presence2state(show, None)
                msn.MSNConnection.changeStatus(self, statusCode, nickname, status)
@@ -302,7 +352,7 @@ class LegacyConnection(msn.MSNConnection):
                for contact in self.contactTyping.keys():
                        self.contactTyping[contact] += 1
                        if self.contactTyping[contact] >= 3:
                for contact in self.contactTyping.keys():
                        self.contactTyping[contact] += 1
                        if self.contactTyping[contact] >= 3:
-                               self.session.sendTypingNotification(self.session.jabberID, msn2jid(contact), False)
+                               self.session.sendTypingNotification(self.jabberID, msn2jid(contact, True), False)
                                del self.contactTyping[contact]
        
        def userTypingNotification(self, dest, resource, composing):
                                del self.contactTyping[contact]
        
        def userTypingNotification(self, dest, resource, composing):
@@ -316,90 +366,93 @@ class LegacyConnection(msn.MSNConnection):
 
        # Implement callbacks from msn.MSNConnection
        def connectionFailed(self, reason):
 
        # Implement callbacks from msn.MSNConnection
        def connectionFailed(self, reason):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                text = lang.get(self.session.lang).msnConnectFailed % reason
                text = lang.get(self.session.lang).msnConnectFailed % reason
-               self.session.sendMessage(to=self.session.jabberID, fro=config.jid, body=text)
+               self.session.sendMessage(to=self.jabberID, fro=config.jid, body=text)
                self.session.removeMe()
 
        def loginFailed(self, reason):
                self.session.removeMe()
 
        def loginFailed(self, reason):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                text = lang.get(self.session.lang).msnLoginFailure % (self.session.username)
                text = lang.get(self.session.lang).msnLoginFailure % (self.session.username)
-               self.session.sendErrorMessage(to=self.session.jabberID, fro=config.jid, etype="auth", condition="not-authorized", explanation=text, body="Login Failure")
+               self.session.sendErrorMessage(to=self.jabberID, fro=config.jid, etype="auth", condition="not-authorized", explanation=text, body="Login Failure")
                self.session.removeMe()
        
        def connectionLost(self, reason):
                self.session.removeMe()
        
        def connectionLost(self, reason):
-               LogEvent(INFO, self.session.jabberID)
-               text = lang.get(self.session.lang).msnDisconnected % reason
-               self.session.sendMessage(to=self.session.jabberID, fro=config.jid, body=text)
+               LogEvent(INFO, self.jabberID)
+               if reason.type != error.ConnectionDone:
+                       text = lang.get(self.session.lang).msnDisconnected % reason
+                       self.session.sendMessage(to=self.jabberID, fro=config.jid, body=text)
                self.session.removeMe() # Tear down the session
 
        def multipleLogin(self):
                self.session.removeMe() # Tear down the session
 
        def multipleLogin(self):
-               LogEvent(INFO, self.session.jabberID)
-               self.session.sendMessage(to=self.session.jabberID, fro=config.jid, body=lang.get(self.session.lang).msnMultipleLogin)
+               LogEvent(INFO, self.jabberID)
+               self.session.sendMessage(to=self.jabberID, fro=config.jid, body=lang.get(self.session.lang).msnMultipleLogin)
                self.session.removeMe()
        
        def serverGoingDown(self):
                self.session.removeMe()
        
        def serverGoingDown(self):
-               LogEvent(INFO, self.session.jabberID)
-               self.session.sendMessage(to=self.session.jabberID, fro=config.jid, body=lang.get(self.session.lang).msnMaintenance)
+               LogEvent(INFO, self.jabberID)
+               self.session.sendMessage(to=self.jabberID, fro=config.jid, body=lang.get(self.session.lang).msnMaintenance)
        
        def accountNotVerified(self):
        
        def accountNotVerified(self):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                text = lang.get(self.session.lang).msnNotVerified % (self.session.username)
                text = lang.get(self.session.lang).msnNotVerified % (self.session.username)
-               self.session.sendMessage(to=self.session.jabberID, fro=config.jid, body=text)
+               self.session.sendMessage(to=self.jabberID, fro=config.jid, body=text)
        
        def userMapping(self, passport, jid):
        
        def userMapping(self, passport, jid):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                text = lang.get(self.session.lang).userMapping % (passport, jid)
                text = lang.get(self.session.lang).userMapping % (passport, jid)
-               self.session.sendMessage(to=self.session.jabberID, fro=msn2jid(passport), body=text)
+               self.session.sendMessage(to=self.jabberID, fro=msn2jid(passport, True), body=text)
        
        def loggedIn(self):
        
        def loggedIn(self):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                self.session.ready = True
        
        def listSynchronized(self):
                self.session.ready = True
        
        def listSynchronized(self):
-               LogEvent(INFO, self.session.jabberID)
-               self.session.sendPresence(to=self.session.jabberID, fro=config.jid)
+               LogEvent(INFO, self.jabberID)
+               self.session.sendPresence(to=self.jabberID, fro=config.jid)
                self.legacyList.syncJabberLegacyLists()
                self.listSynced = True
                #self.legacyList.flushSubscriptionBuffer()
        
        def ourStatusChanged(self, statusCode, screenName, personal):
                # Send out a new presence packet to the Jabber user so that the transport icon changes
                self.legacyList.syncJabberLegacyLists()
                self.listSynced = True
                #self.legacyList.flushSubscriptionBuffer()
        
        def ourStatusChanged(self, statusCode, screenName, personal):
                # Send out a new presence packet to the Jabber user so that the transport icon changes
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                self.remoteShow, ptype = state2presence(statusCode)
                self.remoteStatus = personal
                self.remoteNick = screenName
                self.remoteShow, ptype = state2presence(statusCode)
                self.remoteStatus = personal
                self.remoteNick = screenName
-               self._sendShowStatus()
+               self.sendShowStatus()
 
        def gotMessage(self, remoteUser, text):
 
        def gotMessage(self, remoteUser, text):
-               LogEvent(INFO, self.session.jabberID)
-               source = msn2jid(remoteUser)
-               self.session.sendMessage(self.session.jabberID, fro=source, body=text, mtype="chat")
+               LogEvent(INFO, self.jabberID)
+               source = msn2jid(remoteUser, True)
+               if self.contactTyping.has_key(remoteUser):
+                       del self.contactTyping[remoteUser]
+               self.session.sendMessage(self.jabberID, fro=source, body=text, mtype="chat")
                self.session.pytrans.statistics.stats["MessageCount"] += 1
        
        def gotGroupchat(self, msnGroupchat, userHandle):
                self.session.pytrans.statistics.stats["MessageCount"] += 1
        
        def gotGroupchat(self, msnGroupchat, userHandle):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                msnGroupchat.groupchat = LegacyGroupchat(self.session, switchboardSession=msnGroupchat)
                msnGroupchat.groupchat = LegacyGroupchat(self.session, switchboardSession=msnGroupchat)
-               msnGroupchat.groupchat.sendUserInvite(msn2jid(userHandle))
+               msnGroupchat.groupchat.sendUserInvite(msn2jid(userHandle, True))
        
        def gotContactTyping(self, contact):
        
        def gotContactTyping(self, contact):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                # Check if the contact has only just started typing
                if not self.contactTyping.has_key(contact):
                # Check if the contact has only just started typing
                if not self.contactTyping.has_key(contact):
-                       self.session.sendTypingNotification(self.session.jabberID, msn2jid(contact), True)
+                       self.session.sendTypingNotification(self.jabberID, msn2jid(contact, True), True)
 
                # Reset the counter
                self.contactTyping[contact] = 0
        
        def failedMessage(self, remoteUser, message):
 
                # Reset the counter
                self.contactTyping[contact] = 0
        
        def failedMessage(self, remoteUser, message):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                self.session.pytrans.statistics.stats["FailedMessageCount"] += 1
                self.session.pytrans.statistics.stats["FailedMessageCount"] += 1
-               fro = msn2jid(remoteUser)
-               self.session.sendErrorMessage(to=self.session.jabberID, fro=fro, etype="wait", condition="recipient-unavailable", explanation=lang.get(self.session.lang).msnFailedMessage, body=message)
+               fro = msn2jid(remoteUser, True)
+               self.session.sendErrorMessage(to=self.jabberID, fro=fro, etype="wait", condition="recipient-unavailable", explanation=lang.get(self.session.lang).msnFailedMessage, body=message)
        
        def contactAvatarChanged(self, userHandle, hash):
        
        def contactAvatarChanged(self, userHandle, hash):
-               LogEvent(INFO, self.session.jabberID)
-               jid = msn2jid(userHandle)
+               LogEvent(INFO, self.jabberID)
+               jid = msn2jid(userHandle, False)
                c = self.session.contactList.findContact(jid)
                if not c: return
 
                c = self.session.contactList.findContact(jid)
                if not c: return
 
@@ -423,10 +476,10 @@ class LegacyConnection(msn.MSNConnection):
                        c.updateAvatar(defaultAvatar)
        
        def contactStatusChanged(self, remoteUser):
                        c.updateAvatar(defaultAvatar)
        
        def contactStatusChanged(self, remoteUser):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                
                msnContact = self.getContacts().getContact(remoteUser)
                
                msnContact = self.getContacts().getContact(remoteUser)
-               c = self.session.contactList.findContact(msn2jid(remoteUser))
+               c = self.session.contactList.findContact(msn2jid(remoteUser, False))
                if not (c and msnContact): return
 
                show, ptype = state2presence(msnContact.status)
                if not (c and msnContact): return
 
                show, ptype = state2presence(msnContact.status)
@@ -437,35 +490,37 @@ class LegacyConnection(msn.MSNConnection):
                c.updatePresence(show, status, ptype, force=True)
        
        def gotFileReceive(self, fileReceive):
                c.updatePresence(show, status, ptype, force=True)
        
        def gotFileReceive(self, fileReceive):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                # FIXME
                # FIXME
-               ft.FTReceive(self.session, msn2jid(fileReceive.userHandle), fileReceive)
+               ft.FTReceive(self.session, msn2jid(fileReceive.userHandle, True), fileReceive)
        
        def contactAddedMe(self, userHandle):
        
        def contactAddedMe(self, userHandle):
-               LogEvent(INFO, self.session.jabberID)
-               self.session.contactList.getContact(msn2jid(userHandle)).contactRequestsAuth()
+               LogEvent(INFO, self.jabberID)
+               self.session.contactList.getContact(msn2jid(userHandle, False)).contactRequestsAuth()
        
        def contactRemovedMe(self, userHandle):
        
        def contactRemovedMe(self, userHandle):
-               LogEvent(INFO, self.session.jabberID)
-               c = self.session.contactList.getContact(msn2jid(userHandle))
+               LogEvent(INFO, self.jabberID)
+               c = self.session.contactList.getContact(msn2jid(userHandle, True))
                c.contactDerequestsAuth()
                c.contactRemovesAuth()
        
        def gotInitialEmailNotification(self, inboxunread, foldersunread):
                c.contactDerequestsAuth()
                c.contactRemovesAuth()
        
        def gotInitialEmailNotification(self, inboxunread, foldersunread):
-               LogEvent(INFO, self.session.jabberID)
-               text = lang.get(self.session.lang).msnInitialMail % (inboxunread, foldersunread)
-               self.session.sendMessage(to=self.session.jabberID, fro=config.jid, body=text, mtype="headline")
+               if config.mailNotifications:
+                       LogEvent(INFO, self.jabberID)
+                       text = lang.get(self.session.lang).msnInitialMail % (inboxunread, foldersunread)
+                       self.session.sendMessage(to=self.jabberID, fro=config.jid, body=text, mtype="headline")
        
        def gotRealtimeEmailNotification(self, mailfrom, fromaddr, subject):
        
        def gotRealtimeEmailNotification(self, mailfrom, fromaddr, subject):
-               LogEvent(INFO, self.session.jabberID)
-               text = lang.get(self.session.lang).msnRealtimeMail % (mailfrom, fromaddr, subject)
-               self.session.sendMessage(to=self.session.jabberID, fro=config.jid, body=text, mtype="headline")
+               if config.mailNotifications:
+                       LogEvent(INFO, self.jabberID)
+                       text = lang.get(self.session.lang).msnRealtimeMail % (mailfrom, fromaddr, subject)
+                       self.session.sendMessage(to=self.jabberID, fro=config.jid, body=text, mtype="headline")
                
        def gotMSNAlert(self, text, actionurl, subscrurl):
                
        def gotMSNAlert(self, text, actionurl, subscrurl):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
 
                el = Element((None, "message"))
 
                el = Element((None, "message"))
-               el.attributes["to"] = self.session.jabberID
+               el.attributes["to"] = self.jabberID
                el.attributes["from"] = config.jid
                el.attributes["type"] = "headline"
                body = el.addElement("body")
                el.attributes["from"] = config.jid
                el.attributes["type"] = "headline"
                body = el.addElement("body")
@@ -484,9 +539,9 @@ class LegacyConnection(msn.MSNConnection):
                self.session.pytrans.send(el)
        
        def gotAvatarImageData(self, userHandle, imageData):
                self.session.pytrans.send(el)
        
        def gotAvatarImageData(self, userHandle, imageData):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                av = self.session.pytrans.avatarCache.setAvatar(imageData)
                av = self.session.pytrans.avatarCache.setAvatar(imageData)
-               jid = msn2jid(userHandle)
+               jid = msn2jid(userHandle, False)
                c = self.session.contactList.findContact(jid)
                c.updateAvatar(av)
        
                c = self.session.contactList.findContact(jid)
                c.updateAvatar(av)
        
@@ -495,38 +550,44 @@ class LegacyConnection(msn.MSNConnection):
 
 class LegacyList:
        def __init__(self, session):
 
 class LegacyList:
        def __init__(self, session):
+               self.jabberID = session.jabberID
                self.session = session
                self.session = session
-               self.subscriptionBuffer = []
        
        def removeMe(self):
        
        def removeMe(self):
-               self.subscriptionBuffer = None
                self.session = None
 
        def addContact(self, jid):
                self.session = None
 
        def addContact(self, jid):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                userHandle = jid2msn(jid)
                self.session.legacycon.addContact(msn.FORWARD_LIST, userHandle)
                userHandle = jid2msn(jid)
                self.session.legacycon.addContact(msn.FORWARD_LIST, userHandle)
+
+               # Handle adding a contact that has previously been removed
+               msnContact = self.session.legacycon.getContacts().getContact(userHandle)
+               if msnContact and msnContact.lists & msn.REVERSE_LIST:
+                       self.session.legacycon.contactAddedMe(userHandle)
+               self.authContact(jid)
                self.session.contactList.getContact(jid).contactGrantsAuth()
        
        def removeContact(self, jid):
                self.session.contactList.getContact(jid).contactGrantsAuth()
        
        def removeContact(self, jid):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                jid = jid2msn(jid)
                self.session.legacycon.remContact(msn.FORWARD_LIST, jid)
        
        
        def authContact(self, jid):
                jid = jid2msn(jid)
                self.session.legacycon.remContact(msn.FORWARD_LIST, jid)
        
        
        def authContact(self, jid):
-               LogEvent(INFO, self.session.jabberID)
-               jid = jid2msn(jid)
-               d = self.session.legacycon.remContact(msn.PENDING_LIST, jid)
+               LogEvent(INFO, self.jabberID)
+               userHandle = jid2msn(jid)
+               d = self.session.legacycon.remContact(msn.PENDING_LIST, userHandle)
                if d:
                if d:
-                       self.session.legacycon.addContact(msn.REVERSE_LIST, jid)
-               self.session.legacycon.remContact(msn.BLOCK_LIST, jid)
-               self.session.legacycon.addContact(msn.ALLOW_LIST, jid)
+                       self.session.legacycon.addContact(msn.REVERSE_LIST, userHandle)
+               self.session.legacycon.remContact(msn.BLOCK_LIST, userHandle)
+               self.session.legacycon.addContact(msn.ALLOW_LIST, userHandle)
        
        def deauthContact(self, jid):
        
        def deauthContact(self, jid):
-               LogEvent(INFO, self.session.jabberID)
+               LogEvent(INFO, self.jabberID)
                jid = jid2msn(jid)
                self.session.legacycon.remContact(msn.ALLOW_LIST, jid)
                jid = jid2msn(jid)
                self.session.legacycon.remContact(msn.ALLOW_LIST, jid)
+               self.session.legacycon.remContact(msn.PENDING_LIST, jid)
                self.session.legacycon.addContact(msn.BLOCK_LIST, jid)
 
 
                self.session.legacycon.addContact(msn.BLOCK_LIST, jid)
 
 
@@ -538,8 +599,8 @@ class LegacyList:
 
                # We have to make an MSNContactList from the XDB data, then compare it with the one the server sent
                # Any subscription changes must be sent to the client, as well as changed in the XDB
 
                # We have to make an MSNContactList from the XDB data, then compare it with the one the server sent
                # Any subscription changes must be sent to the client, as well as changed in the XDB
-               LogEvent(INFO, self.session.jabberID, "Start.")
-               result = self.session.pytrans.xdb.request(self.session.jabberID, disco.IQROSTER)
+               LogEvent(INFO, self.jabberID, "Start.")
+               result = self.session.pytrans.xdb.request(self.jabberID, disco.IQROSTER)
                oldContactList = msn.MSNContactList()
                if result:
                        for item in result.elements():
                oldContactList = msn.MSNContactList()
                if result:
                        for item in result.elements():
@@ -576,7 +637,7 @@ class LegacyList:
                        # Create the Jabber representation of the
                        # contact base on the old list data and then
                        # sync it with current
                        # Create the Jabber representation of the
                        # contact base on the old list data and then
                        # sync it with current
-                       jabContact = self.session.contactList.createContact(msn2jid(contact.userHandle), msnlist2jabsub(oldLists))
+                       jabContact = self.session.contactList.createContact(msn2jid(contact.userHandle, False), msnlist2jabsub(oldLists))
                        jabContact.updateAvatar(defaultAvatar, push=False)
 
                        if addedToList(msn.FORWARD_LIST):
                        jabContact.updateAvatar(defaultAvatar, push=False)
 
                        if addedToList(msn.FORWARD_LIST):
@@ -597,6 +658,8 @@ class LegacyList:
 
                        if removedFromList(msn.REVERSE_LIST):
                                jabContact.contactDerequestsAuth()
 
                        if removedFromList(msn.REVERSE_LIST):
                                jabContact.contactDerequestsAuth()
+
+                       jabContact.syncRoster()
                        
                        item = newXDB.addElement("item")
                        item.attributes["jid"] = contact.userHandle
                        
                        item = newXDB.addElement("item")
                        item.attributes["jid"] = contact.userHandle
@@ -604,8 +667,8 @@ class LegacyList:
                        item.attributes["lists"] = str(lists)
                
                # Update the XDB
                        item.attributes["lists"] = str(lists)
                
                # Update the XDB
-               self.session.pytrans.xdb.set(self.session.jabberID, disco.IQROSTER, newXDB)
-               LogEvent(INFO, self.session.jabberID, "End.")
+               self.session.pytrans.xdb.set(self.jabberID, disco.IQROSTER, newXDB)
+               LogEvent(INFO, self.jabberID, "End.")
        
        def saveLegacyList(self):
                contactList = self.session.legacycon.getContacts()
        
        def saveLegacyList(self):
                contactList = self.session.legacycon.getContacts()
@@ -620,7 +683,7 @@ class LegacyList:
                        item.attributes["subscription"] = msnlist2jabsub(contact.lists) # Backwards compat
                        item.attributes["lists"] = str(contact.lists)
 
                        item.attributes["subscription"] = msnlist2jabsub(contact.lists) # Backwards compat
                        item.attributes["lists"] = str(contact.lists)
 
-               self.session.pytrans.xdb.set(self.session.jabberID, disco.IQROSTER, newXDB)
-               LogEvent(INFO, self.session.jabberID, "Finished saving list.")
+               self.session.pytrans.xdb.set(self.jabberID, disco.IQROSTER, newXDB)
+               LogEvent(INFO, self.jabberID, "Finished saving list.")