Permalink
Browse files

Added PLAIN authentication support

Closes #214.
  • Loading branch information...
1 parent 40db559 commit 45b816423eaf914e51a618573b3c13a4efd862a0 @mjs committed Jul 11, 2016
Showing with 52 additions and 0 deletions.
  1. +2 −0 THANKS
  2. +8 −0 doc/src/releases.rst
  3. +8 −0 imapclient/imapclient.py
  4. +34 −0 imapclient/test/test_auth.py
View
@@ -60,6 +60,8 @@ Thomas Steinacher
Eben Freeman
ID support
+Aviv Salem
+ PLAIN authentication support
Bug Reports
------------
@@ -1,6 +1,14 @@
:tocdepth: 1
===============
+ Version 1.1.0
+===============
+
+Added
+-----
+- PLAIN authentication support (via `plain_login` method)
+
+===============
Version 1.0.1
===============
@@ -241,6 +241,14 @@ def oauth2_login(self, user, access_token, mech='XOAUTH2', vendor=None):
auth_string += '\1'
return self._command_and_check('authenticate', mech, lambda x: auth_string)
+ def plain_login(self, identity, password, authorization_identity=None):
+ """Authenticate using the PLAIN method (requires server support).
+ """
+ if not authorization_identity:
+ authorization_identity = ""
+ auth_string = '%s\0%s\0%s' % (authorization_identity, identity, password)
+ return self._command_and_check('authenticate', 'PLAIN', lambda _: auth_string, unpack=True)
+
def logout(self):
"""Logout, returning the server response.
"""
@@ -0,0 +1,34 @@
+# Copyright (c) 2016, Menno Smits
+# Released subject to the New BSD License
+# Please see http://en.wikipedia.org/wiki/BSD_licenses
+
+from __future__ import unicode_literals
+
+from imapclient import IMAPClient
+from .imapclient_test import IMAPClientTest
+
+
+class TestPlainLogin(IMAPClientTest):
+
+ def assert_authenticate_call(self, expected_auth_string):
+ authenticate = self.client._imap.authenticate
+ self.assertEqual(authenticate.call_count, 1)
+ auth_type, auth_func = authenticate.call_args[0]
+ self.assertEqual(auth_type, "PLAIN")
+ self.assertEqual(auth_func(None), expected_auth_string)
+
+ def test_simple(self):
+ self.client._imap.authenticate.return_value = ('OK', [b'Success'])
+ result = self.client.plain_login("user", "secret")
+ self.assertEqual(result, b'Success')
+ self.assert_authenticate_call("\0user\0secret")
+
+ def test_fail(self):
+ self.client._imap.authenticate.return_value = ('NO', [b'Boom'])
+ self.assertRaises(IMAPClient.Error, self.client.plain_login, "user", "secret")
+
+ def test_with_authorization_identity(self):
+ self.client._imap.authenticate.return_value = ('OK', [b'Success'])
+ result = self.client.plain_login("user", "secret", "authid")
+ self.assertEqual(result, b'Success')
+ self.assert_authenticate_call("authid\0user\0secret")

0 comments on commit 45b8164

Please sign in to comment.