From c578ddeb1aae6fb0a9f60092b53831c1e952058d Mon Sep 17 00:00:00 2001
From: Lance Stout <lancestout@gmail.com>
Date: Fri, 6 Jan 2012 23:31:58 -0500
Subject: Add support for MSN with X-MESSENGER-OAUTH2 SASL support.

NOTE: This requires already having the access token. It does NOT
perform any OAuth requests.
---
 sleekxmpp/features/feature_mechanisms/mechanisms.py    |  2 ++
 sleekxmpp/features/feature_mechanisms/stanza/auth.py   | 14 ++++++++++++--
 sleekxmpp/thirdparty/suelta/mechanisms/__init__.py     |  1 +
 .../thirdparty/suelta/mechanisms/messenger_oauth2.py   | 18 ++++++++++++++++++
 4 files changed, 33 insertions(+), 2 deletions(-)
 create mode 100644 sleekxmpp/thirdparty/suelta/mechanisms/messenger_oauth2.py

diff --git a/sleekxmpp/features/feature_mechanisms/mechanisms.py b/sleekxmpp/features/feature_mechanisms/mechanisms.py
index 2b8321c2..deff5d30 100644
--- a/sleekxmpp/features/feature_mechanisms/mechanisms.py
+++ b/sleekxmpp/features/feature_mechanisms/mechanisms.py
@@ -39,6 +39,8 @@ class feature_mechanisms(base_plugin):
                 values['username'] = self.xmpp.boundjid.user
             if 'password' in values:
                 values['password'] = self.xmpp.password
+            if 'access_token' in values:
+                values['access_token'] = self.xmpp.password
             mech.fulfill(values)
 
         sasl_callback = self.config.get('sasl_callback', None)
diff --git a/sleekxmpp/features/feature_mechanisms/stanza/auth.py b/sleekxmpp/features/feature_mechanisms/stanza/auth.py
index e069b57f..9155adf6 100644
--- a/sleekxmpp/features/feature_mechanisms/stanza/auth.py
+++ b/sleekxmpp/features/feature_mechanisms/stanza/auth.py
@@ -25,15 +25,25 @@ class Auth(StanzaBase):
     interfaces = set(('mechanism', 'value'))
     plugin_attrib = name
 
+    #: Some SASL mechs require sending values as is, 
+    #: without converting base64.
+    plain_mechs = set(['X-MESSENGER-OAUTH2'])
+
     def setup(self, xml):
         StanzaBase.setup(self, xml)
         self.xml.tag = self.tag_name()
 
     def get_value(self):
-        return base64.b64decode(bytes(self.xml.text))
+        if not self['mechanism'] in self.plain_mechs:
+            return base64.b64decode(bytes(self.xml.text))
+        else:
+            return self.xml.text
 
     def set_value(self, values):
-        self.xml.text = bytes(base64.b64encode(values)).decode('utf-8')
+        if not self['mechanism'] in self.plain_mechs:
+            self.xml.text = bytes(base64.b64encode(values)).decode('utf-8')
+        else:
+            self.xml.text = values
 
     def del_value(self):
         self.xml.text = ''
diff --git a/sleekxmpp/thirdparty/suelta/mechanisms/__init__.py b/sleekxmpp/thirdparty/suelta/mechanisms/__init__.py
index 5cb2ee3d..e115e5d5 100644
--- a/sleekxmpp/thirdparty/suelta/mechanisms/__init__.py
+++ b/sleekxmpp/thirdparty/suelta/mechanisms/__init__.py
@@ -3,3 +3,4 @@ from sleekxmpp.thirdparty.suelta.mechanisms.plain import PLAIN
 from sleekxmpp.thirdparty.suelta.mechanisms.cram_md5 import CRAM_MD5
 from sleekxmpp.thirdparty.suelta.mechanisms.digest_md5 import DIGEST_MD5
 from sleekxmpp.thirdparty.suelta.mechanisms.scram_hmac import SCRAM_HMAC
+from sleekxmpp.thirdparty.suelta.mechanisms.messenger_oauth2 import X_MESSENGER_OAUTH2
diff --git a/sleekxmpp/thirdparty/suelta/mechanisms/messenger_oauth2.py b/sleekxmpp/thirdparty/suelta/mechanisms/messenger_oauth2.py
new file mode 100644
index 00000000..c72bc0e3
--- /dev/null
+++ b/sleekxmpp/thirdparty/suelta/mechanisms/messenger_oauth2.py
@@ -0,0 +1,18 @@
+from sleekxmpp.thirdparty.suelta.util import hash, bytes
+from sleekxmpp.thirdparty.suelta.sasl import Mechanism, register_mechanism
+from sleekxmpp.thirdparty.suelta.exceptions import SASLError, SASLCancelled
+
+
+class X_MESSENGER_OAUTH2(Mechanism):
+
+    def __init__(self, sasl, name):
+        super(X_MESSENGER_OAUTH2, self).__init__(sasl, name)
+        self.check_values(['access_token'])
+
+    def process(self, challenge=None):
+        return self.values['access_token']
+
+    def okay(self):
+        return True
+
+register_mechanism('X-MESSENGER-OAUTH2', 10, X_MESSENGER_OAUTH2, use_hashes=False)
-- 
cgit v1.2.3