Skip to content

Commit 45b8164

Browse files
author
Menno Smits
committed
Added PLAIN authentication support
Closes mjs#214.
1 parent 40db559 commit 45b8164

File tree

4 files changed

+52
-0
lines changed

4 files changed

+52
-0
lines changed

THANKS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ Thomas Steinacher
6060
Eben Freeman
6161
ID support
6262

63+
Aviv Salem
64+
PLAIN authentication support
6365

6466
Bug Reports
6567
------------

doc/src/releases.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
:tocdepth: 1
22

3+
===============
4+
Version 1.1.0
5+
===============
6+
7+
Added
8+
-----
9+
- PLAIN authentication support (via `plain_login` method)
10+
311
===============
412
Version 1.0.1
513
===============

imapclient/imapclient.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,14 @@ def oauth2_login(self, user, access_token, mech='XOAUTH2', vendor=None):
241241
auth_string += '\1'
242242
return self._command_and_check('authenticate', mech, lambda x: auth_string)
243243

244+
def plain_login(self, identity, password, authorization_identity=None):
245+
"""Authenticate using the PLAIN method (requires server support).
246+
"""
247+
if not authorization_identity:
248+
authorization_identity = ""
249+
auth_string = '%s\0%s\0%s' % (authorization_identity, identity, password)
250+
return self._command_and_check('authenticate', 'PLAIN', lambda _: auth_string, unpack=True)
251+
244252
def logout(self):
245253
"""Logout, returning the server response.
246254
"""

imapclient/test/test_auth.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Copyright (c) 2016, Menno Smits
2+
# Released subject to the New BSD License
3+
# Please see http://en.wikipedia.org/wiki/BSD_licenses
4+
5+
from __future__ import unicode_literals
6+
7+
from imapclient import IMAPClient
8+
from .imapclient_test import IMAPClientTest
9+
10+
11+
class TestPlainLogin(IMAPClientTest):
12+
13+
def assert_authenticate_call(self, expected_auth_string):
14+
authenticate = self.client._imap.authenticate
15+
self.assertEqual(authenticate.call_count, 1)
16+
auth_type, auth_func = authenticate.call_args[0]
17+
self.assertEqual(auth_type, "PLAIN")
18+
self.assertEqual(auth_func(None), expected_auth_string)
19+
20+
def test_simple(self):
21+
self.client._imap.authenticate.return_value = ('OK', [b'Success'])
22+
result = self.client.plain_login("user", "secret")
23+
self.assertEqual(result, b'Success')
24+
self.assert_authenticate_call("\0user\0secret")
25+
26+
def test_fail(self):
27+
self.client._imap.authenticate.return_value = ('NO', [b'Boom'])
28+
self.assertRaises(IMAPClient.Error, self.client.plain_login, "user", "secret")
29+
30+
def test_with_authorization_identity(self):
31+
self.client._imap.authenticate.return_value = ('OK', [b'Success'])
32+
result = self.client.plain_login("user", "secret", "authid")
33+
self.assertEqual(result, b'Success')
34+
self.assert_authenticate_call("authid\0user\0secret")

0 commit comments

Comments
 (0)