Merge pull request #1492 from paperless-ngx/feature-imap-utf-improve

Feature: Simplify IMAP login for UTF-8
This commit is contained in:
shamoon 2022-09-01 09:35:26 -07:00 committed by GitHub
commit a502fe7c5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 26 deletions

11
Pipfile.lock generated
View File

@ -501,10 +501,12 @@
"imap-tools": { "imap-tools": {
"hashes": [ "hashes": [
"sha256:4fe4c07c4cc4aab83492d126e221c39118ff530268149b721296fc0fb87de3c2", "sha256:4fe4c07c4cc4aab83492d126e221c39118ff530268149b721296fc0fb87de3c2",
"sha256:56942853be2125d509365b84eacf0f3a87ae58ea8f82bca7a6943634a60cfb60" "sha256:56942853be2125d509365b84eacf0f3a87ae58ea8f82bca7a6943634a60cfb60",
"sha256:6f5572b2e747a81a607438e0ef61ff28f323f6697820493c8ca4467465baeb76",
"sha256:9e2658f267311051e04d437aca06d5b4c7c091fc4f411f7d13ca610e0cead5cb"
], ],
"index": "pypi", "index": "pypi",
"version": "==0.56.0" "version": "==0.57.0"
}, },
"img2pdf": { "img2pdf": {
"hashes": [ "hashes": [
@ -1754,9 +1756,6 @@
"version": "==0.4.5" "version": "==0.4.5"
}, },
"coverage": { "coverage": {
"extras": [
"toml"
],
"hashes": [ "hashes": [
"sha256:01778769097dbd705a24e221f42be885c544bb91251747a8a3efdec6eb4788f2", "sha256:01778769097dbd705a24e221f42be885c544bb91251747a8a3efdec6eb4788f2",
"sha256:08002f9251f51afdcc5e3adf5d5d66bb490ae893d9e21359b085f0e03390a820", "sha256:08002f9251f51afdcc5e3adf5d5d66bb490ae893d9e21359b085f0e03390a820",
@ -2320,7 +2319,7 @@
"sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
"sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"
], ],
"markers": "python_version >= '3.7'", "markers": "python_full_version < '3.11.0a7'",
"version": "==2.0.1" "version": "==2.0.1"
}, },
"tornado": { "tornado": {

View File

@ -4,7 +4,6 @@ import tempfile
from datetime import date from datetime import date
from datetime import timedelta from datetime import timedelta
from fnmatch import fnmatch from fnmatch import fnmatch
from imaplib import IMAP4
import magic import magic
import pathvalidate import pathvalidate
@ -187,22 +186,9 @@ class MailAccountHandler(LoggingMixin):
except UnicodeEncodeError: except UnicodeEncodeError:
self.log("debug", "Falling back to AUTH=PLAIN") self.log("debug", "Falling back to AUTH=PLAIN")
try:
# rfc2595 section 6 - PLAIN SASL mechanism
client: IMAP4 = M.client
encoded = (
b"\0"
+ account.username.encode("utf8")
+ b"\0"
+ account.password.encode("utf8")
)
# Assumption is the server supports AUTH=PLAIN capability
# Could check the list with client.capability(), but then what?
# We're failing anyway then
client.authenticate("PLAIN", lambda x: encoded)
# Need to transition out of AUTH state to SELECTED try:
M.folder.set("INBOX") M.login_utf8(account.username, account.password)
except Exception as err: except Exception as err:
self.log( self.log(
"error", "error",

View File

@ -73,6 +73,13 @@ class BogusClient:
class BogusMailBox(ContextManager): class BogusMailBox(ContextManager):
# Common values so tests don't need to remember an accepted login
USERNAME: str = "admin"
ASCII_PASSWORD: str = "secret"
# Note the non-ascii characters here
UTF_PASSWORD: str = "w57äöüw4b6huwb6nhu"
def __enter__(self): def __enter__(self):
return self return self
@ -93,7 +100,12 @@ class BogusMailBox(ContextManager):
# This will raise a UnicodeEncodeError if the password is not ASCII only # This will raise a UnicodeEncodeError if the password is not ASCII only
password.encode("ascii") password.encode("ascii")
# Otherwise, check for correct values # Otherwise, check for correct values
if username != "admin" or password not in {"secret"}: if username != self.USERNAME or password != self.ASCII_PASSWORD:
raise MailboxLoginError("BAD", "OK")
def login_utf8(self, username, password):
# Expected to only be called with the UTF-8 password
if username != self.USERNAME or password != self.UTF_PASSWORD:
raise MailboxLoginError("BAD", "OK") raise MailboxLoginError("BAD", "OK")
def fetch(self, criteria, mark_seen, charset=""): def fetch(self, criteria, mark_seen, charset=""):
@ -931,9 +943,9 @@ class TestMail(DirectoriesMixin, TestCase):
account = MailAccount.objects.create( account = MailAccount.objects.create(
name="test", name="test",
imap_server="", imap_server="",
username="admin", username=BogusMailBox.USERNAME,
# Note the non-ascii characters here # Note the non-ascii characters here
password="w57äöüw4b6huwb6nhu", password=BogusMailBox.UTF_PASSWORD,
) )
_ = MailRule.objects.create( _ = MailRule.objects.create(
@ -963,7 +975,7 @@ class TestMail(DirectoriesMixin, TestCase):
account = MailAccount.objects.create( account = MailAccount.objects.create(
name="test", name="test",
imap_server="", imap_server="",
username="admin", username=BogusMailBox.USERNAME,
# Note the non-ascii characters here # Note the non-ascii characters here
# Passes the check in login, not in authenticate # Passes the check in login, not in authenticate
password="réception", password="réception",