Skip to content

Commit cb97f27

Browse files
committed
chore: resolve review comment
1 parent f228676 commit cb97f27

File tree

4 files changed

+21
-23
lines changed

4 files changed

+21
-23
lines changed

Doc/library/poplib.rst

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,17 @@ A :class:`POP3` instance has the following methods:
249249

250250
Authenticate using the POP3 ``AUTH`` command as specified in :rfc:`5034`.
251251

252-
If *initial_response* is provided (``bytes`` or ``str``), it is
253-
base64-encoded and appended to the command after a single space.
252+
If *initial_response_ok* is true, ``authobject()`` is called first with no
253+
arguments to obtain an optional initial response. It may return :class:`bytes`
254+
or :class:`str`; if it returns :const:`None`, no initial response is sent.
255+
The returned value is base64-encoded before being sent.
254256

255-
If *authobject* is provided, it is called with the server’s ``bytes``
256-
challenge (already base64-decoded) and must return the client response
257-
(``bytes`` or ``str``). Return ``b'*'`` to abort the exchange.
257+
For each server challenge, ``authobject(challenge)`` is called with the
258+
base64-decoded ``bytes`` challenge and must return the client response as
259+
:class:`bytes` or :class:`str`. If it returns :const:`None`, an empty response
260+
is sent. To abort the exchange, return ``b'*'`` (the client sends ``'*'``).
261+
262+
.. versionadded:: next
258263

259264

260265
Instances of :class:`POP3_SSL` have no additional methods. The interface of this

Lib/poplib.py

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313

1414
# Imports
1515

16+
import base64
1617
import binascii
1718
import errno
1819
import re
1920
import socket
2021
import sys
21-
import base64
2222

2323
try:
2424
import ssl
@@ -221,6 +221,7 @@ def pass_(self, pswd):
221221
"""
222222
return self._shortcmd('PASS %s' % pswd)
223223

224+
224225
def stat(self):
225226
"""Get mailbox status.
226227
@@ -428,18 +429,12 @@ def stls(self, context=None):
428429
return resp
429430

430431
def auth(self, mechanism, authobject, *, initial_response_ok=True):
431-
"""Authenticate to the POP3 server using AUTH (RFC 5034).
432-
433-
Result is 'response'.
434-
"""
432+
"""Authenticate to the POP3 server using AUTH (RFC 5034)."""
435433
mech = mechanism.upper()
436434

437435
initial = None
438-
if initial_response_ok:
439-
try:
440-
initial = authobject()
441-
except TypeError:
442-
initial = None
436+
if initial_response_ok and callable(authobject):
437+
initial = authobject()
443438
if isinstance(initial, str):
444439
initial = initial.encode('ascii', 'strict')
445440
if initial is not None and not isinstance(initial, (bytes, bytearray)):
@@ -448,7 +443,7 @@ def auth(self, mechanism, authobject, *, initial_response_ok=True):
448443
if initial is not None:
449444
b64 = base64.b64encode(initial).decode('ascii')
450445
cmd = f'AUTH {mech} {b64}'
451-
if len(cmd.encode('ascii')) + 2 <= 255:
446+
if len(cmd.encode('ascii')) <= 253:
452447
self._putcmd(cmd)
453448
else:
454449
self._putcmd(f'AUTH {mech}')
@@ -465,12 +460,12 @@ def auth(self, mechanism, authobject, *, initial_response_ok=True):
465460
if line.startswith(b'-ERR'):
466461
raise error_proto(line.decode('ascii', 'replace'))
467462
# Challenge line: "+ <b64>" or just "+" (empty challenge)
468-
if not (line == b'+' or line.startswith(b'+ ')):
463+
if line != b'+' and not line.startswith(b'+ '):
469464
raise error_proto(f'malformed AUTH challenge line: {line!r}')
470465

471466
auth_challenge_count += 1
472467
if auth_challenge_count > _MAXCHALLENGE:
473-
raise error_proto('Server AUTH mechanism infinite loop')
468+
raise error_proto('Server AUTH mechanism infinite loop. Last response: ', repr(line))
474469

475470
chal = line[1:]
476471
if chal.startswith(b' '):
@@ -500,10 +495,7 @@ def auth(self, mechanism, authobject, *, initial_response_ok=True):
500495
self._putcmd(base64.b64encode(resp).decode('ascii'))
501496

502497
def auth_plain(self, user, password, authzid=''):
503-
"""Return an authobject suitable for SASL PLAIN.
504-
505-
Result is 'str'.
506-
"""
498+
"""Return an authobject suitable for SASL PLAIN."""
507499
def _auth_plain(challenge=None):
508500
# Per RFC 4616, the response is: authzid UTF8 NUL authcid UTF8 NUL passwd UTF8
509501
return f"{authzid}\0{user}\0{password}"

Lib/test/test_poplib.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
# Modified by Giampaolo Rodola' to give poplib.POP3 and poplib.POP3_SSL
44
# a real test suite
5+
56
import base64
67
import poplib
78
import socket
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Add RFC 5034 AUTH support to poplib
1+
:mod:`poplib`: add :rfc:`5034` ``AUTH`` support.

0 commit comments

Comments
 (0)