From cdda047f9f2472ca2836d6674214c0b19035c71e Mon Sep 17 00:00:00 2001 From: Scott Stafford Date: Mon, 25 Feb 2019 22:02:14 -0500 Subject: [PATCH 01/17] Improve the workaround of https://bugs.python.org/issue27321 in coddingtonbear#136. Attempt to use patch from https://bugs.python.org/msg308362. --- django_mailbox/models.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/django_mailbox/models.py b/django_mailbox/models.py index 9f7ffc21..122f8dd5 100644 --- a/django_mailbox/models.py +++ b/django_mailbox/models.py @@ -372,8 +372,13 @@ def _process_message(self, message): except KeyError as exc: # email.message.replace_header may raise 'KeyError' if the header # 'content-transfer-encoding' is missing - logger.warning("Failed to parse message: %s", exc,) - return None + try: + # Before we give up, let's try mailman's approach: + # https://bugs.python.org/msg308362 + body = message.as_bytes(self).decode('ascii', 'replace') + except KeyError as exc: + logger.warning("Failed to parse message: %s", exc,) + return None msg.set_body(body) if message['in-reply-to']: try: From 43557c5734a31c09f772f51d16809474bc7de46f Mon Sep 17 00:00:00 2001 From: Scott Stafford Date: Tue, 26 Feb 2019 13:50:49 -0500 Subject: [PATCH 02/17] =?UTF-8?q?Bump=20version:=204.7.1=20=E2=86=92=204.7?= =?UTF-8?q?.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- django_mailbox/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 51ae89a0..ee0b2abe 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 4.7.1 +current_version = 4.7.2 commit = True tag = True tag_name = {new_version} diff --git a/django_mailbox/__init__.py b/django_mailbox/__init__.py index 176119c3..0b472167 100644 --- a/django_mailbox/__init__.py +++ b/django_mailbox/__init__.py @@ -1,3 +1,3 @@ -__version__ = '4.7.1' +__version__ = '4.7.2' default_app_config = 'django_mailbox.apps.MailBoxConfig' From fd33ce34ef11e837ee159f39ff59b7e6bd7112f3 Mon Sep 17 00:00:00 2001 From: Scott Stafford Date: Wed, 27 Nov 2019 11:27:59 -0500 Subject: [PATCH 03/17] Update version so pip works right. --- django_mailbox/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/django_mailbox/__init__.py b/django_mailbox/__init__.py index 0b472167..ab62cef8 100644 --- a/django_mailbox/__init__.py +++ b/django_mailbox/__init__.py @@ -1,3 +1,3 @@ -__version__ = '4.7.2' +__version__ = "5.0.1" -default_app_config = 'django_mailbox.apps.MailBoxConfig' +default_app_config = "django_mailbox.apps.MailBoxConfig" From 2932403417f51e51bec7ca2146cd294b3faef4a4 Mon Sep 17 00:00:00 2001 From: Nick McCullum Date: Wed, 23 Mar 2022 08:48:45 -0400 Subject: [PATCH 04/17] Django 4 compatability. --- django_mailbox/signals.py | 2 +- .../0006_auto__add_field_message_in_reply_to.py | 4 ++-- .../south_migrations/0009_remove_references_table.py | 4 ++-- .../south_migrations/0012_auto__add_messageattachment.py | 4 ++-- .../0015_auto__add_field_messageattachment_headers.py | 4 ++-- django_mailbox/tests/test_process_email.py | 6 +++--- docs/conf.py | 6 +++--- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/django_mailbox/signals.py b/django_mailbox/signals.py index b445183e..9af4af77 100644 --- a/django_mailbox/signals.py +++ b/django_mailbox/signals.py @@ -1,3 +1,3 @@ from django.dispatch.dispatcher import Signal -message_received = Signal(providing_args=['message']) +message_received = Signal() diff --git a/django_mailbox/south_migrations/0006_auto__add_field_message_in_reply_to.py b/django_mailbox/south_migrations/0006_auto__add_field_message_in_reply_to.py index 4287fb26..9c17019a 100644 --- a/django_mailbox/south_migrations/0006_auto__add_field_message_in_reply_to.py +++ b/django_mailbox/south_migrations/0006_auto__add_field_message_in_reply_to.py @@ -15,8 +15,8 @@ def forwards(self, orm): # Adding M2M table for field references on 'Message' db.create_table('django_mailbox_message_references', ( ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), - ('from_message', models.ForeignKey(orm['django_mailbox.message'], null=False)), - ('to_message', models.ForeignKey(orm['django_mailbox.message'], null=False)) + ('from_message', models.ForeignKey(orm['django_mailbox.message'], on_delete=models.CASCADE, null=False)), + ('to_message', models.ForeignKey(orm['django_mailbox.message'], on_delete=models.CASCADE, null=False)) )) db.create_unique('django_mailbox_message_references', ['from_message_id', 'to_message_id']) diff --git a/django_mailbox/south_migrations/0009_remove_references_table.py b/django_mailbox/south_migrations/0009_remove_references_table.py index 38685851..70cf0dec 100644 --- a/django_mailbox/south_migrations/0009_remove_references_table.py +++ b/django_mailbox/south_migrations/0009_remove_references_table.py @@ -15,8 +15,8 @@ def backwards(self, orm): # Adding M2M table for field references on 'Message' db.create_table('django_mailbox_message_references', ( ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), - ('from_message', models.ForeignKey(orm['django_mailbox.message'], null=False)), - ('to_message', models.ForeignKey(orm['django_mailbox.message'], null=False)) + ('from_message', models.ForeignKey(orm['django_mailbox.message'], on_delete=models.CASCADE, null=False)), + ('to_message', models.ForeignKey(orm['django_mailbox.message'], on_delete=models.CASCADE, null=False)) )) db.create_unique('django_mailbox_message_references', ['from_message_id', 'to_message_id']) diff --git a/django_mailbox/south_migrations/0012_auto__add_messageattachment.py b/django_mailbox/south_migrations/0012_auto__add_messageattachment.py index b62e50e9..945be81b 100644 --- a/django_mailbox/south_migrations/0012_auto__add_messageattachment.py +++ b/django_mailbox/south_migrations/0012_auto__add_messageattachment.py @@ -17,8 +17,8 @@ def forwards(self, orm): # Adding M2M table for field attachments on 'Message' db.create_table('django_mailbox_message_attachments', ( ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), - ('message', models.ForeignKey(orm['django_mailbox.message'], null=False)), - ('messageattachment', models.ForeignKey(orm['django_mailbox.messageattachment'], null=False)) + ('message', models.ForeignKey(orm['django_mailbox.message'], on_delete=models.CASCADE, null=False)), + ('messageattachment', models.ForeignKey(orm['django_mailbox.messageattachment'], on_delete=models.CASCADE, null=False)) )) db.create_unique('django_mailbox_message_attachments', ['message_id', 'messageattachment_id']) diff --git a/django_mailbox/south_migrations/0015_auto__add_field_messageattachment_headers.py b/django_mailbox/south_migrations/0015_auto__add_field_messageattachment_headers.py index 71ecfbdc..da15c664 100644 --- a/django_mailbox/south_migrations/0015_auto__add_field_messageattachment_headers.py +++ b/django_mailbox/south_migrations/0015_auto__add_field_messageattachment_headers.py @@ -20,8 +20,8 @@ def backwards(self, orm): # Adding M2M table for field attachments on 'Message' db.create_table('django_mailbox_message_attachments', ( ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), - ('message', models.ForeignKey(orm['django_mailbox.message'], null=False)), - ('messageattachment', models.ForeignKey(orm['django_mailbox.messageattachment'], null=False)) + ('message', models.ForeignKey(orm['django_mailbox.message'], on_delete=models.CASCADE, null=False)), + ('messageattachment', models.ForeignKey(orm['django_mailbox.messageattachment'], on_delete=models.CASCADE, null=False)) )) db.create_unique('django_mailbox_message_attachments', ['message_id', 'messageattachment_id']) diff --git a/django_mailbox/tests/test_process_email.py b/django_mailbox/tests/test_process_email.py index a6dbd044..ee71f4cc 100644 --- a/django_mailbox/tests/test_process_email.py +++ b/django_mailbox/tests/test_process_email.py @@ -9,7 +9,7 @@ from django_mailbox.utils import convert_header_to_unicode from django_mailbox import utils from django_mailbox.tests.base import EmailMessageTestCase -from django.utils.encoding import force_text +from django.utils.encoding import force_str from django.core.mail import EmailMessage __all__ = ['TestProcessEmail'] @@ -367,12 +367,12 @@ def test_message_with_long_content(self): email_object = self._get_email_object( 'message_with_long_content.eml', ) - size = len(force_text(email_object.as_string())) + size = len(force_str(email_object.as_string())) msg = self.mailbox.process_incoming_message(email_object) self.assertEqual(size, - len(force_text(msg.get_email_object().as_string()))) + len(force_str(msg.get_email_object().as_string()))) def test_message_saved(self): message = self._get_email_object('generic_message.eml') diff --git a/docs/conf.py b/docs/conf.py index 974706f8..c015980d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -244,7 +244,7 @@ import inspect import django from django.utils.html import strip_tags -from django.utils.encoding import force_text +from django.utils.encoding import force_str from django.conf import settings settings.configure(INSTALLED_APPS=['django_mailbox', ]) django.setup() @@ -265,11 +265,11 @@ def process_docstring(app, what, name, obj, options, lines): continue # Decode and strip any html out of the field's help text - help_text = strip_tags(force_text(field.help_text)) + help_text = strip_tags(force_str(field.help_text)) # Decode and capitalize the verbose name, for use if there isn't # any help text - verbose_name = force_text(field.verbose_name).capitalize() + verbose_name = force_str(field.verbose_name).capitalize() if help_text: # Add the model field to the end of the docstring as a param From bc9eb6ab34336be2c8597b439202ad213c0e1b7b Mon Sep 17 00:00:00 2001 From: Alireza Lotfi Date: Tue, 13 Sep 2022 11:22:30 -0400 Subject: [PATCH 05/17] django-mailbox: support office365 oauth2 --- django_mailbox/models.py | 10 ++++- django_mailbox/transports/__init__.py | 1 + django_mailbox/transports/office365.py | 58 ++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 django_mailbox/transports/office365.py diff --git a/django_mailbox/models.py b/django_mailbox/models.py index 616a1320..55316248 100644 --- a/django_mailbox/models.py +++ b/django_mailbox/models.py @@ -31,7 +31,7 @@ from django_mailbox.signals import message_received from django_mailbox.transports import Pop3Transport, ImapTransport, \ MaildirTransport, MboxTransport, BabylTransport, MHTransport, \ - MMDFTransport, GmailImapTransport + MMDFTransport, GmailImapTransport, Office365ImapTransport logger = logging.getLogger(__name__) @@ -216,6 +216,14 @@ def get_connection(self): archive=self.archive ) conn.connect(self.username, self.password) + elif self.type == 'office365': + conn = Office365ImapTransport( + self.location, + port=self.port if self.port else None, + ssl=True, + archive=self.archive + ) + conn.connect(self.username, self.password) elif self.type == 'pop3': conn = Pop3Transport( self.location, diff --git a/django_mailbox/transports/__init__.py b/django_mailbox/transports/__init__.py index 7aeef95e..6e31435c 100644 --- a/django_mailbox/transports/__init__.py +++ b/django_mailbox/transports/__init__.py @@ -8,3 +8,4 @@ from django_mailbox.transports.mh import MHTransport from django_mailbox.transports.mmdf import MMDFTransport from django_mailbox.transports.gmail import GmailImapTransport +from django_mailbox.transports.office365 import Office365ImapTransport diff --git a/django_mailbox/transports/office365.py b/django_mailbox/transports/office365.py new file mode 100644 index 00000000..e3e454be --- /dev/null +++ b/django_mailbox/transports/office365.py @@ -0,0 +1,58 @@ +import logging +import urllib3 +import json + +from django_mailbox.transports.imap import ImapTransport +from django.conf import settings + + +logger = logging.getLogger(__name__) + + +class Office365ImapTransport(ImapTransport): + def connect(self, username, password): + # Try to use oauth2 first. It's much safer + try: + self._connect_oauth(username) + except (TypeError, ValueError) as e: + logger.warning("Couldn't do oauth2 because %s" % e) + self.server = self.transport(self.hostname, self.port) + typ, msg = self.server.login(username, password) + self.server.select() + + def _connect_oauth(self, username): + # username should be an email address that has already been authorized + # for office365 access + + access_token = None + while access_token is None: + try: + access_token = self.get_office365_access_token() + except Exception as e: + raise ValueError( + f"Could not acquire the access token for {username} exception details={e}" + ) + + auth_string = f"user={username}\1auth=Bearer {access_token}\1\1" + self.server = self.transport(self.hostname, self.port) + self.server.authenticate("XOAUTH2", lambda x: auth_string) + self.server.select() + + def get_office365_access_token(): + url = f"https://login.microsoftonline.com/{settings.MICROSOFT_0365_TENENT_ID}/oauth2/v2.0/token" + oauth_params = { + "client_id": settings.MICROSOFT_0365_CLIENT_ID, + "client_secret": settings.MICROSOFT_0365_CLIENT_SECRET, + "grant_type": "client_credentials", + "scope": "https://graph.microsoft.com/.default", + } + http = urllib3.PoolManager() + response = http.request("POST", url, oauth_params) + if response.status == 200: + token = json.loads(response.data).get("access_token") + logger.info(f"[get_office365_access_token] token aquired") + return token + else: + raise Exception( + f"[get_office365_access_token] Failed to authenticate with O365 {response.data}" + ) \ No newline at end of file From 281786bfca8678d75aff12c9c26411806e71d12c Mon Sep 17 00:00:00 2001 From: Alireza Lotfi Date: Tue, 13 Sep 2022 15:55:46 -0400 Subject: [PATCH 06/17] office365-imap: fix a bug --- django_mailbox/transports/office365.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/django_mailbox/transports/office365.py b/django_mailbox/transports/office365.py index e3e454be..b3d67518 100644 --- a/django_mailbox/transports/office365.py +++ b/django_mailbox/transports/office365.py @@ -38,7 +38,7 @@ def _connect_oauth(self, username): self.server.authenticate("XOAUTH2", lambda x: auth_string) self.server.select() - def get_office365_access_token(): + def get_office365_access_token(self): url = f"https://login.microsoftonline.com/{settings.MICROSOFT_0365_TENENT_ID}/oauth2/v2.0/token" oauth_params = { "client_id": settings.MICROSOFT_0365_CLIENT_ID, From a375f901347740762c1545d7689943621764e28a Mon Sep 17 00:00:00 2001 From: Alireza Lotfi Date: Tue, 13 Sep 2022 16:47:38 -0400 Subject: [PATCH 07/17] office365-imap: fix a typo --- django_mailbox/transports/office365.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/django_mailbox/transports/office365.py b/django_mailbox/transports/office365.py index b3d67518..66f6555e 100644 --- a/django_mailbox/transports/office365.py +++ b/django_mailbox/transports/office365.py @@ -39,10 +39,10 @@ def _connect_oauth(self, username): self.server.select() def get_office365_access_token(self): - url = f"https://login.microsoftonline.com/{settings.MICROSOFT_0365_TENENT_ID}/oauth2/v2.0/token" + url = f"https://login.microsoftonline.com/{settings.MICROSOFT_O365_TENENT_ID}/oauth2/v2.0/token" oauth_params = { - "client_id": settings.MICROSOFT_0365_CLIENT_ID, - "client_secret": settings.MICROSOFT_0365_CLIENT_SECRET, + "client_id": settings.MICROSOFT_O365_CLIENT_ID, + "client_secret": settings.MICROSOFT_O365_CLIENT_SECRET, "grant_type": "client_credentials", "scope": "https://graph.microsoft.com/.default", } From 09bbab87652413d4c56e249b861da7e76499b2da Mon Sep 17 00:00:00 2001 From: Alireza Lotfi Date: Tue, 13 Sep 2022 17:35:12 -0400 Subject: [PATCH 08/17] office365-imap: test on feature --- django_mailbox/transports/office365.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/django_mailbox/transports/office365.py b/django_mailbox/transports/office365.py index 66f6555e..dc87cdc9 100644 --- a/django_mailbox/transports/office365.py +++ b/django_mailbox/transports/office365.py @@ -33,9 +33,13 @@ def _connect_oauth(self, username): f"Could not acquire the access token for {username} exception details={e}" ) - auth_string = f"user={username}\1auth=Bearer {access_token}\1\1" + auth_string = 'user={}\1auth=Bearer {}\1\1'.format( + username, + access_token + ) self.server = self.transport(self.hostname, self.port) - self.server.authenticate("XOAUTH2", lambda x: auth_string) + typ, dat = self.server.authenticate("XOAUTH2", lambda x: auth_string) + logger.info(f'[_connect_oauth] auth string is: {auth_string} and typ={typ} dat={dat}') self.server.select() def get_office365_access_token(self): From bb980bae78932709a28aa485a47682040419248b Mon Sep 17 00:00:00 2001 From: Alireza Lotfi Date: Tue, 13 Sep 2022 20:27:03 -0400 Subject: [PATCH 09/17] testing on feature --- django_mailbox/transports/office365.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/django_mailbox/transports/office365.py b/django_mailbox/transports/office365.py index dc87cdc9..2f21e68c 100644 --- a/django_mailbox/transports/office365.py +++ b/django_mailbox/transports/office365.py @@ -37,7 +37,10 @@ def _connect_oauth(self, username): username, access_token ) + self.server = self.transport(self.hostname, self.port) + logger.info(f'[_connect_oauth] hostname = {self.hostname}') + logger.info(f'[_connect_oauth] auth string is: {auth_string}') typ, dat = self.server.authenticate("XOAUTH2", lambda x: auth_string) logger.info(f'[_connect_oauth] auth string is: {auth_string} and typ={typ} dat={dat}') self.server.select() From 51551921946fed0e492e3529a1843a5da8a786a9 Mon Sep 17 00:00:00 2001 From: Alireza Lotfi Date: Tue, 13 Sep 2022 21:08:06 -0400 Subject: [PATCH 10/17] testing on feature --- django_mailbox/models.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/django_mailbox/models.py b/django_mailbox/models.py index 55316248..9a45fa48 100644 --- a/django_mailbox/models.py +++ b/django_mailbox/models.py @@ -220,8 +220,10 @@ def get_connection(self): conn = Office365ImapTransport( self.location, port=self.port if self.port else None, - ssl=True, - archive=self.archive + tls=self.use_tls, + ssl=self.use_ssl, + archive=self.archive, + folder=self.folder ) conn.connect(self.username, self.password) elif self.type == 'pop3': From af8d283765e3a24ed08a7dcd43c4dae6948b62e1 Mon Sep 17 00:00:00 2001 From: Alireza Lotfi Date: Tue, 13 Sep 2022 21:29:14 -0400 Subject: [PATCH 11/17] testing on feature --- django_mailbox/models.py | 24 ++-- django_mailbox/transports/office365.py | 174 +++++++++++++++++-------- 2 files changed, 136 insertions(+), 62 deletions(-) diff --git a/django_mailbox/models.py b/django_mailbox/models.py index 9a45fa48..3ad282a0 100644 --- a/django_mailbox/models.py +++ b/django_mailbox/models.py @@ -31,7 +31,7 @@ from django_mailbox.signals import message_received from django_mailbox.transports import Pop3Transport, ImapTransport, \ MaildirTransport, MboxTransport, BabylTransport, MHTransport, \ - MMDFTransport, GmailImapTransport, Office365ImapTransport + MMDFTransport, GmailImapTransport, Office365Transport logger = logging.getLogger(__name__) @@ -216,16 +216,24 @@ def get_connection(self): archive=self.archive ) conn.connect(self.username, self.password) + # elif self.type == 'office365': + # conn = Office365ImapTransport( + # self.location, + # port=self.port if self.port else None, + # tls=self.use_tls, + # ssl=self.use_ssl, + # archive=self.archive, + # folder=self.folder + # ) + # conn.connect(self.username, self.password) elif self.type == 'office365': - conn = Office365ImapTransport( + conn = Office365Transport( self.location, - port=self.port if self.port else None, - tls=self.use_tls, - ssl=self.use_ssl, - archive=self.archive, - folder=self.folder + self.username, + folder=self.folder, + archive=self.archive ) - conn.connect(self.username, self.password) + conn.connect(self.client_id, self.client_secret, self.tenant_id) elif self.type == 'pop3': conn = Pop3Transport( self.location, diff --git a/django_mailbox/transports/office365.py b/django_mailbox/transports/office365.py index 2f21e68c..53e7aa3c 100644 --- a/django_mailbox/transports/office365.py +++ b/django_mailbox/transports/office365.py @@ -1,65 +1,131 @@ +# import logging +# import urllib3 +# import json + +# from django_mailbox.transports.imap import ImapTransport +# from django.conf import settings + + +# logger = logging.getLogger(__name__) + + +# class Office365ImapTransport(ImapTransport): +# def connect(self, username, password): +# # Try to use oauth2 first. It's much safer +# try: +# self._connect_oauth(username) +# except (TypeError, ValueError) as e: +# logger.warning("Couldn't do oauth2 because %s" % e) +# self.server = self.transport(self.hostname, self.port) +# typ, msg = self.server.login(username, password) +# self.server.select() + +# def _connect_oauth(self, username): +# # username should be an email address that has already been authorized +# # for office365 access + +# access_token = None +# while access_token is None: +# try: +# access_token = self.get_office365_access_token() +# except Exception as e: +# raise ValueError( +# f"Could not acquire the access token for {username} exception details={e}" +# ) + +# auth_string = 'user={}\1auth=Bearer {}\1\1'.format( +# username, +# access_token +# ) + +# self.server = self.transport(self.hostname, self.port) +# logger.info(f'[_connect_oauth] hostname = {self.hostname}') +# logger.info(f'[_connect_oauth] auth string is: {auth_string}') +# typ, dat = self.server.authenticate("XOAUTH2", lambda x: auth_string) +# logger.info(f'[_connect_oauth] auth string is: {auth_string} and typ={typ} dat={dat}') +# self.server.select() + +# def get_office365_access_token(self): +# url = f"https://login.microsoftonline.com/{settings.MICROSOFT_O365_TENENT_ID}/oauth2/v2.0/token" +# oauth_params = { +# "client_id": settings.MICROSOFT_O365_CLIENT_ID, +# "client_secret": settings.MICROSOFT_O365_CLIENT_SECRET, +# "grant_type": "client_credentials", +# "scope": "https://graph.microsoft.com/.default", +# } +# http = urllib3.PoolManager() +# response = http.request("POST", url, oauth_params) +# if response.status == 200: +# token = json.loads(response.data).get("access_token") +# logger.info(f"[get_office365_access_token] token aquired") +# return token +# else: +# raise Exception( +# f"[get_office365_access_token] Failed to authenticate with O365 {response.data}" +# ) + import logging -import urllib3 -import json -from django_mailbox.transports.imap import ImapTransport from django.conf import settings +from .base import EmailTransport, MessageParseError logger = logging.getLogger(__name__) -class Office365ImapTransport(ImapTransport): - def connect(self, username, password): - # Try to use oauth2 first. It's much safer +class Office365Transport(EmailTransport): + def __init__( + self, hostname, username, archive='', folder=None + ): + self.integration_testing_subject = getattr( + settings, + 'DJANGO_MAILBOX_INTEGRATION_TESTING_SUBJECT', + None + ) + self.hostname = hostname + self.username = username + self.archive = archive + self.folder = folder + + def connect(self, client_id, client_secret, tenant_id): try: - self._connect_oauth(username) - except (TypeError, ValueError) as e: - logger.warning("Couldn't do oauth2 because %s" % e) - self.server = self.transport(self.hostname, self.port) - typ, msg = self.server.login(username, password) - self.server.select() - - def _connect_oauth(self, username): - # username should be an email address that has already been authorized - # for office365 access - - access_token = None - while access_token is None: + import O365 + except ImportError: + raise ValueError( + "Install o365 to use oauth2 auth for office365" + ) + + credentials = (client_id, client_secret) + + self.account = O365.Account(credentials, auth_flow_type='credentials', tenant_id=tenant_id) + self.account.authenticate() + + self.mailbox = self.account.mailbox(resource=self.username) + self.mailbox_folder = self.mailbox.inbox_folder() + if self.folder: + self.mailbox_folder = self.mailbox.get_folder(folder_name=self.folder) + + def get_message(self, condition=None): + archive_folder = None + if self.archive: + archive_folder = self.mailbox.get_folder(folder_name=self.archive) + if not archive_folder: + archive_folder = self.mailbox.create_child_folder(self.archive) + + for o365message in self.mailbox_folder.get_messages(order_by='receivedDateTime'): try: - access_token = self.get_office365_access_token() - except Exception as e: - raise ValueError( - f"Could not acquire the access token for {username} exception details={e}" - ) - - auth_string = 'user={}\1auth=Bearer {}\1\1'.format( - username, - access_token - ) + mime_content = o365message.get_mime_content() + message = self.get_email_from_bytes(mime_content) + + if condition and not condition(message): + continue + + yield message + except MessageParseError: + continue + + if self.archive and archive_folder: + o365message.copy(archive_folder) - self.server = self.transport(self.hostname, self.port) - logger.info(f'[_connect_oauth] hostname = {self.hostname}') - logger.info(f'[_connect_oauth] auth string is: {auth_string}') - typ, dat = self.server.authenticate("XOAUTH2", lambda x: auth_string) - logger.info(f'[_connect_oauth] auth string is: {auth_string} and typ={typ} dat={dat}') - self.server.select() - - def get_office365_access_token(self): - url = f"https://login.microsoftonline.com/{settings.MICROSOFT_O365_TENENT_ID}/oauth2/v2.0/token" - oauth_params = { - "client_id": settings.MICROSOFT_O365_CLIENT_ID, - "client_secret": settings.MICROSOFT_O365_CLIENT_SECRET, - "grant_type": "client_credentials", - "scope": "https://graph.microsoft.com/.default", - } - http = urllib3.PoolManager() - response = http.request("POST", url, oauth_params) - if response.status == 200: - token = json.loads(response.data).get("access_token") - logger.info(f"[get_office365_access_token] token aquired") - return token - else: - raise Exception( - f"[get_office365_access_token] Failed to authenticate with O365 {response.data}" - ) \ No newline at end of file + o365message.delete() + return From 53ab53034b49d1796e7aaadf43eda30adff8a7ad Mon Sep 17 00:00:00 2001 From: Alireza Lotfi Date: Tue, 13 Sep 2022 21:32:31 -0400 Subject: [PATCH 12/17] testing on feature --- django_mailbox/models.py | 2 +- django_mailbox/transports/office365.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/django_mailbox/models.py b/django_mailbox/models.py index 3ad282a0..e499841f 100644 --- a/django_mailbox/models.py +++ b/django_mailbox/models.py @@ -233,7 +233,7 @@ def get_connection(self): folder=self.folder, archive=self.archive ) - conn.connect(self.client_id, self.client_secret, self.tenant_id) + conn.connect() elif self.type == 'pop3': conn = Pop3Transport( self.location, diff --git a/django_mailbox/transports/office365.py b/django_mailbox/transports/office365.py index 53e7aa3c..f8d4a292 100644 --- a/django_mailbox/transports/office365.py +++ b/django_mailbox/transports/office365.py @@ -87,7 +87,7 @@ def __init__( self.archive = archive self.folder = folder - def connect(self, client_id, client_secret, tenant_id): + def connect(self): try: import O365 except ImportError: @@ -95,9 +95,9 @@ def connect(self, client_id, client_secret, tenant_id): "Install o365 to use oauth2 auth for office365" ) - credentials = (client_id, client_secret) + credentials = (settings.MICROSOFT_O365_CLIENT_ID, settings.MICROSOFT_O365_CLIENT_SECRET) - self.account = O365.Account(credentials, auth_flow_type='credentials', tenant_id=tenant_id) + self.account = O365.Account(credentials, auth_flow_type='credentials', tenant_id=settings.MICROSOFT_O365_TENENT_ID) self.account.authenticate() self.mailbox = self.account.mailbox(resource=self.username) From 1325482389c705a9d459af00e7b33998c990dcfa Mon Sep 17 00:00:00 2001 From: Alireza Lotfi Date: Tue, 13 Sep 2022 21:45:31 -0400 Subject: [PATCH 13/17] testing on feature --- django_mailbox/transports/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/django_mailbox/transports/__init__.py b/django_mailbox/transports/__init__.py index 6e31435c..9f733e34 100644 --- a/django_mailbox/transports/__init__.py +++ b/django_mailbox/transports/__init__.py @@ -8,4 +8,4 @@ from django_mailbox.transports.mh import MHTransport from django_mailbox.transports.mmdf import MMDFTransport from django_mailbox.transports.gmail import GmailImapTransport -from django_mailbox.transports.office365 import Office365ImapTransport +from django_mailbox.transports.office365 import Office365Transport From 2322c3191338a18c2357f58145e2e76426d3fe39 Mon Sep 17 00:00:00 2001 From: Alireza Lotfi Date: Wed, 14 Sep 2022 10:59:03 -0400 Subject: [PATCH 14/17] office365-imap: update token path --- django_mailbox/transports/office365.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/django_mailbox/transports/office365.py b/django_mailbox/transports/office365.py index f8d4a292..c7dffa9e 100644 --- a/django_mailbox/transports/office365.py +++ b/django_mailbox/transports/office365.py @@ -65,6 +65,7 @@ # ) import logging +import os from django.conf import settings @@ -97,7 +98,11 @@ def connect(self): credentials = (settings.MICROSOFT_O365_CLIENT_ID, settings.MICROSOFT_O365_CLIENT_SECRET) - self.account = O365.Account(credentials, auth_flow_type='credentials', tenant_id=settings.MICROSOFT_O365_TENENT_ID) + if not os.path.isdir(settings.O365_TOKEN_PATH): + os.mkdir(settings.O365_TOKEN_PATH) + + token_path=os.path.join(settings.O365_TOKEN_PATH, 'token.txt') + self.account = O365.Account(credentials, auth_flow_type='credentials', tenant_id=settings.MICROSOFT_O365_TENENT_ID, token_path=token_path) self.account.authenticate() self.mailbox = self.account.mailbox(resource=self.username) From 01ed3337b1b4eb2ab824f07ce5e771824d616dbb Mon Sep 17 00:00:00 2001 From: Alireza Lotfi Date: Wed, 14 Sep 2022 12:04:53 -0400 Subject: [PATCH 15/17] testing on feature --- django_mailbox/models.py | 28 +-- django_mailbox/transports/office365.py | 229 +++++++++++++------------ 2 files changed, 129 insertions(+), 128 deletions(-) diff --git a/django_mailbox/models.py b/django_mailbox/models.py index e499841f..2c7a4978 100644 --- a/django_mailbox/models.py +++ b/django_mailbox/models.py @@ -216,24 +216,24 @@ def get_connection(self): archive=self.archive ) conn.connect(self.username, self.password) - # elif self.type == 'office365': - # conn = Office365ImapTransport( - # self.location, - # port=self.port if self.port else None, - # tls=self.use_tls, - # ssl=self.use_ssl, - # archive=self.archive, - # folder=self.folder - # ) - # conn.connect(self.username, self.password) elif self.type == 'office365': conn = Office365Transport( self.location, - self.username, - folder=self.folder, - archive=self.archive + port=self.port if self.port else None, + tls=self.use_tls, + ssl=self.use_ssl, + archive=self.archive, + folder=self.folder ) - conn.connect() + conn.connect(self.username, self.password) + # elif self.type == 'office365': + # conn = Office365Transport( + # self.location, + # self.username, + # folder=self.folder, + # archive=self.archive + # ) + # conn.connect() elif self.type == 'pop3': conn = Pop3Transport( self.location, diff --git a/django_mailbox/transports/office365.py b/django_mailbox/transports/office365.py index c7dffa9e..c889e112 100644 --- a/django_mailbox/transports/office365.py +++ b/django_mailbox/transports/office365.py @@ -1,136 +1,137 @@ -# import logging -# import urllib3 -# import json +import logging +import urllib3 +import json -# from django_mailbox.transports.imap import ImapTransport -# from django.conf import settings +from django_mailbox.transports.imap import ImapTransport +from django.conf import settings -# logger = logging.getLogger(__name__) +logger = logging.getLogger(__name__) -# class Office365ImapTransport(ImapTransport): -# def connect(self, username, password): -# # Try to use oauth2 first. It's much safer -# try: -# self._connect_oauth(username) -# except (TypeError, ValueError) as e: -# logger.warning("Couldn't do oauth2 because %s" % e) -# self.server = self.transport(self.hostname, self.port) -# typ, msg = self.server.login(username, password) -# self.server.select() - -# def _connect_oauth(self, username): -# # username should be an email address that has already been authorized -# # for office365 access - -# access_token = None -# while access_token is None: -# try: -# access_token = self.get_office365_access_token() -# except Exception as e: -# raise ValueError( -# f"Could not acquire the access token for {username} exception details={e}" -# ) - -# auth_string = 'user={}\1auth=Bearer {}\1\1'.format( -# username, -# access_token -# ) +class Office365Transport(ImapTransport): + def connect(self, username, password): + # Try to use oauth2 first. It's much safer + try: + self._connect_oauth(username) + except (TypeError, ValueError) as e: + logger.warning("Couldn't do oauth2 because %s" % e) + self.server = self.transport(self.hostname, self.port) + typ, msg = self.server.login(username, password) + self.server.select() + + def _connect_oauth(self, username): + # username should be an email address that has already been authorized + # for office365 access + + access_token = None + while access_token is None: + try: + access_token = self.get_office365_access_token() + except Exception as e: + raise ValueError( + f"Could not acquire the access token for {username} exception details={e}" + ) + + auth_string = 'user={}\1auth=Bearer {}\1\1'.format( + username, + access_token + ) -# self.server = self.transport(self.hostname, self.port) -# logger.info(f'[_connect_oauth] hostname = {self.hostname}') -# logger.info(f'[_connect_oauth] auth string is: {auth_string}') -# typ, dat = self.server.authenticate("XOAUTH2", lambda x: auth_string) -# logger.info(f'[_connect_oauth] auth string is: {auth_string} and typ={typ} dat={dat}') -# self.server.select() - -# def get_office365_access_token(self): -# url = f"https://login.microsoftonline.com/{settings.MICROSOFT_O365_TENENT_ID}/oauth2/v2.0/token" -# oauth_params = { -# "client_id": settings.MICROSOFT_O365_CLIENT_ID, -# "client_secret": settings.MICROSOFT_O365_CLIENT_SECRET, -# "grant_type": "client_credentials", -# "scope": "https://graph.microsoft.com/.default", -# } -# http = urllib3.PoolManager() -# response = http.request("POST", url, oauth_params) -# if response.status == 200: -# token = json.loads(response.data).get("access_token") -# logger.info(f"[get_office365_access_token] token aquired") -# return token -# else: -# raise Exception( -# f"[get_office365_access_token] Failed to authenticate with O365 {response.data}" -# ) + logger.info(f'[_connect_oauth] port = {self.port}') + self.server = self.transport(self.hostname, self.port) + logger.info(f'[_connect_oauth] hostname = {self.hostname}') + logger.info(f'[_connect_oauth] auth string is: {auth_string}') + typ, dat = self.server.authenticate("XOAUTH2", lambda x: auth_string) + logger.info(f'[_connect_oauth] auth string is: {auth_string} and typ={typ} dat={dat}') + self.server.select() + + def get_office365_access_token(self): + url = f"https://login.microsoftonline.com/{settings.MICROSOFT_O365_TENENT_ID}/oauth2/v2.0/token" + oauth_params = { + "client_id": settings.MICROSOFT_O365_CLIENT_ID, + "client_secret": settings.MICROSOFT_O365_CLIENT_SECRET, + "grant_type": "client_credentials", + "scope": "https://graph.microsoft.com/.default", + } + http = urllib3.PoolManager() + response = http.request("POST", url, oauth_params) + if response.status == 200: + token = json.loads(response.data).get("access_token") + logger.info(f"[get_office365_access_token] token aquired") + return token + else: + raise Exception( + f"[get_office365_access_token] Failed to authenticate with O365 {response.data}" + ) -import logging -import os +# import logging +# import os -from django.conf import settings +# from django.conf import settings -from .base import EmailTransport, MessageParseError +# from .base import EmailTransport, MessageParseError -logger = logging.getLogger(__name__) +# logger = logging.getLogger(__name__) -class Office365Transport(EmailTransport): - def __init__( - self, hostname, username, archive='', folder=None - ): - self.integration_testing_subject = getattr( - settings, - 'DJANGO_MAILBOX_INTEGRATION_TESTING_SUBJECT', - None - ) - self.hostname = hostname - self.username = username - self.archive = archive - self.folder = folder +# class Office365Transport(EmailTransport): +# def __init__( +# self, hostname, username, archive='', folder=None +# ): +# self.integration_testing_subject = getattr( +# settings, +# 'DJANGO_MAILBOX_INTEGRATION_TESTING_SUBJECT', +# None +# ) +# self.hostname = hostname +# self.username = username +# self.archive = archive +# self.folder = folder - def connect(self): - try: - import O365 - except ImportError: - raise ValueError( - "Install o365 to use oauth2 auth for office365" - ) +# def connect(self): +# try: +# import O365 +# except ImportError: +# raise ValueError( +# "Install o365 to use oauth2 auth for office365" +# ) - credentials = (settings.MICROSOFT_O365_CLIENT_ID, settings.MICROSOFT_O365_CLIENT_SECRET) +# credentials = (settings.MICROSOFT_O365_CLIENT_ID, settings.MICROSOFT_O365_CLIENT_SECRET) - if not os.path.isdir(settings.O365_TOKEN_PATH): - os.mkdir(settings.O365_TOKEN_PATH) - - token_path=os.path.join(settings.O365_TOKEN_PATH, 'token.txt') - self.account = O365.Account(credentials, auth_flow_type='credentials', tenant_id=settings.MICROSOFT_O365_TENENT_ID, token_path=token_path) - self.account.authenticate() +# if not os.path.isdir(settings.O365_TOKEN_PATH): +# os.mkdir(settings.O365_TOKEN_PATH) - self.mailbox = self.account.mailbox(resource=self.username) - self.mailbox_folder = self.mailbox.inbox_folder() - if self.folder: - self.mailbox_folder = self.mailbox.get_folder(folder_name=self.folder) +# token_path=os.path.join(settings.O365_TOKEN_PATH, 'token.txt') +# self.account = O365.Account(credentials, auth_flow_type='credentials', tenant_id=settings.MICROSOFT_O365_TENENT_ID, token_path=token_path) +# self.account.authenticate() - def get_message(self, condition=None): - archive_folder = None - if self.archive: - archive_folder = self.mailbox.get_folder(folder_name=self.archive) - if not archive_folder: - archive_folder = self.mailbox.create_child_folder(self.archive) +# self.mailbox = self.account.mailbox(resource=self.username) +# self.mailbox_folder = self.mailbox.inbox_folder() +# if self.folder: +# self.mailbox_folder = self.mailbox.get_folder(folder_name=self.folder) - for o365message in self.mailbox_folder.get_messages(order_by='receivedDateTime'): - try: - mime_content = o365message.get_mime_content() - message = self.get_email_from_bytes(mime_content) +# def get_message(self, condition=None): +# archive_folder = None +# if self.archive: +# archive_folder = self.mailbox.get_folder(folder_name=self.archive) +# if not archive_folder: +# archive_folder = self.mailbox.create_child_folder(self.archive) + +# for o365message in self.mailbox_folder.get_messages(order_by='receivedDateTime'): +# try: +# mime_content = o365message.get_mime_content() +# message = self.get_email_from_bytes(mime_content) - if condition and not condition(message): - continue +# if condition and not condition(message): +# continue - yield message - except MessageParseError: - continue +# yield message +# except MessageParseError: +# continue - if self.archive and archive_folder: - o365message.copy(archive_folder) +# if self.archive and archive_folder: +# o365message.copy(archive_folder) - o365message.delete() - return +# o365message.delete() +# return From d0b9b501d4680193eb0354bb1e273a0775aa71a3 Mon Sep 17 00:00:00 2001 From: Alireza Lotfi Date: Thu, 15 Sep 2022 16:24:04 -0400 Subject: [PATCH 16/17] testing on feature --- django_mailbox/models.py | 28 +-- django_mailbox/transports/office365.py | 228 ++++++++++++------------- 2 files changed, 128 insertions(+), 128 deletions(-) diff --git a/django_mailbox/models.py b/django_mailbox/models.py index 2c7a4978..df098689 100644 --- a/django_mailbox/models.py +++ b/django_mailbox/models.py @@ -216,24 +216,24 @@ def get_connection(self): archive=self.archive ) conn.connect(self.username, self.password) - elif self.type == 'office365': - conn = Office365Transport( - self.location, - port=self.port if self.port else None, - tls=self.use_tls, - ssl=self.use_ssl, - archive=self.archive, - folder=self.folder - ) - conn.connect(self.username, self.password) # elif self.type == 'office365': # conn = Office365Transport( # self.location, - # self.username, - # folder=self.folder, - # archive=self.archive + # port=self.port if self.port else None, + # tls=self.use_tls, + # ssl=self.use_ssl, + # archive=self.archive, + # folder=self.folder # ) - # conn.connect() + # conn.connect(self.username, self.password) + elif self.type == 'office365': + conn = Office365Transport( + self.location, + self.username, + folder=self.folder, + archive=self.archive + ) + conn.connect() elif self.type == 'pop3': conn = Pop3Transport( self.location, diff --git a/django_mailbox/transports/office365.py b/django_mailbox/transports/office365.py index c889e112..62bb6154 100644 --- a/django_mailbox/transports/office365.py +++ b/django_mailbox/transports/office365.py @@ -1,137 +1,137 @@ -import logging -import urllib3 -import json +# import logging +# import urllib3 +# import json -from django_mailbox.transports.imap import ImapTransport -from django.conf import settings +# from django_mailbox.transports.imap import ImapTransport +# from django.conf import settings -logger = logging.getLogger(__name__) +# logger = logging.getLogger(__name__) -class Office365Transport(ImapTransport): - def connect(self, username, password): - # Try to use oauth2 first. It's much safer - try: - self._connect_oauth(username) - except (TypeError, ValueError) as e: - logger.warning("Couldn't do oauth2 because %s" % e) - self.server = self.transport(self.hostname, self.port) - typ, msg = self.server.login(username, password) - self.server.select() - - def _connect_oauth(self, username): - # username should be an email address that has already been authorized - # for office365 access - - access_token = None - while access_token is None: - try: - access_token = self.get_office365_access_token() - except Exception as e: - raise ValueError( - f"Could not acquire the access token for {username} exception details={e}" - ) - - auth_string = 'user={}\1auth=Bearer {}\1\1'.format( - username, - access_token - ) +# class Office365Transport(ImapTransport): +# def connect(self, username, password): +# # Try to use oauth2 first. It's much safer +# try: +# self._connect_oauth(username) +# except (TypeError, ValueError) as e: +# logger.warning("Couldn't do oauth2 because %s" % e) +# self.server = self.transport(self.hostname, self.port) +# typ, msg = self.server.login(username, password) +# self.server.select() + +# def _connect_oauth(self, username): +# # username should be an email address that has already been authorized +# # for office365 access + +# access_token = None +# while access_token is None: +# try: +# access_token = self.get_office365_access_token() +# except Exception as e: +# raise ValueError( +# f"Could not acquire the access token for {username} exception details={e}" +# ) + +# auth_string = 'user={}\1auth=Bearer {}\1\1'.format( +# username, +# access_token +# ) - logger.info(f'[_connect_oauth] port = {self.port}') - self.server = self.transport(self.hostname, self.port) - logger.info(f'[_connect_oauth] hostname = {self.hostname}') - logger.info(f'[_connect_oauth] auth string is: {auth_string}') - typ, dat = self.server.authenticate("XOAUTH2", lambda x: auth_string) - logger.info(f'[_connect_oauth] auth string is: {auth_string} and typ={typ} dat={dat}') - self.server.select() - - def get_office365_access_token(self): - url = f"https://login.microsoftonline.com/{settings.MICROSOFT_O365_TENENT_ID}/oauth2/v2.0/token" - oauth_params = { - "client_id": settings.MICROSOFT_O365_CLIENT_ID, - "client_secret": settings.MICROSOFT_O365_CLIENT_SECRET, - "grant_type": "client_credentials", - "scope": "https://graph.microsoft.com/.default", - } - http = urllib3.PoolManager() - response = http.request("POST", url, oauth_params) - if response.status == 200: - token = json.loads(response.data).get("access_token") - logger.info(f"[get_office365_access_token] token aquired") - return token - else: - raise Exception( - f"[get_office365_access_token] Failed to authenticate with O365 {response.data}" - ) +# logger.info(f'[_connect_oauth] port = {self.port}') +# self.server = self.transport(self.hostname, self.port) +# logger.info(f'[_connect_oauth] hostname = {self.hostname}') +# logger.info(f'[_connect_oauth] auth string is: {auth_string}') +# typ, dat = self.server.authenticate("XOAUTH2", lambda x: auth_string) +# logger.info(f'[_connect_oauth] auth string is: {auth_string} and typ={typ} dat={dat}') +# self.server.select() + +# def get_office365_access_token(self): +# url = f"https://login.microsoftonline.com/{settings.MICROSOFT_O365_TENENT_ID}/oauth2/v2.0/token" +# oauth_params = { +# "client_id": settings.MICROSOFT_O365_CLIENT_ID, +# "client_secret": settings.MICROSOFT_O365_CLIENT_SECRET, +# "grant_type": "client_credentials", +# "scope": "https://graph.microsoft.com/.default", +# } +# http = urllib3.PoolManager() +# response = http.request("POST", url, oauth_params) +# if response.status == 200: +# token = json.loads(response.data).get("access_token") +# logger.info(f"[get_office365_access_token] token aquired") +# return token +# else: +# raise Exception( +# f"[get_office365_access_token] Failed to authenticate with O365 {response.data}" +# ) -# import logging -# import os +import logging +import os -# from django.conf import settings +from django.conf import settings -# from .base import EmailTransport, MessageParseError +from .base import EmailTransport, MessageParseError -# logger = logging.getLogger(__name__) +logger = logging.getLogger(__name__) -# class Office365Transport(EmailTransport): -# def __init__( -# self, hostname, username, archive='', folder=None -# ): -# self.integration_testing_subject = getattr( -# settings, -# 'DJANGO_MAILBOX_INTEGRATION_TESTING_SUBJECT', -# None -# ) -# self.hostname = hostname -# self.username = username -# self.archive = archive -# self.folder = folder +class Office365Transport(EmailTransport): + def __init__( + self, hostname, username, archive='', folder=None + ): + self.integration_testing_subject = getattr( + settings, + 'DJANGO_MAILBOX_INTEGRATION_TESTING_SUBJECT', + None + ) + self.hostname = hostname + self.username = username + self.archive = archive + self.folder = folder -# def connect(self): -# try: -# import O365 -# except ImportError: -# raise ValueError( -# "Install o365 to use oauth2 auth for office365" -# ) + def connect(self): + try: + import O365 + except ImportError: + raise ValueError( + "Install o365 to use oauth2 auth for office365" + ) -# credentials = (settings.MICROSOFT_O365_CLIENT_ID, settings.MICROSOFT_O365_CLIENT_SECRET) + credentials = (settings.MICROSOFT_O365_CLIENT_ID, settings.MICROSOFT_O365_CLIENT_SECRET) -# if not os.path.isdir(settings.O365_TOKEN_PATH): -# os.mkdir(settings.O365_TOKEN_PATH) + if not os.path.isdir(settings.O365_TOKEN_PATH): + os.mkdir(settings.O365_TOKEN_PATH) -# token_path=os.path.join(settings.O365_TOKEN_PATH, 'token.txt') -# self.account = O365.Account(credentials, auth_flow_type='credentials', tenant_id=settings.MICROSOFT_O365_TENENT_ID, token_path=token_path) -# self.account.authenticate() + token_path=os.path.join(settings.O365_TOKEN_PATH, 'token.txt') + self.account = O365.Account(credentials, auth_flow_type='credentials', tenant_id=settings.MICROSOFT_O365_TENENT_ID, token_path=token_path) + self.account.authenticate() -# self.mailbox = self.account.mailbox(resource=self.username) -# self.mailbox_folder = self.mailbox.inbox_folder() -# if self.folder: -# self.mailbox_folder = self.mailbox.get_folder(folder_name=self.folder) + self.mailbox = self.account.mailbox(resource=self.username) + self.mailbox_folder = self.mailbox.inbox_folder() + if self.folder: + self.mailbox_folder = self.mailbox.get_folder(folder_name=self.folder) -# def get_message(self, condition=None): -# archive_folder = None -# if self.archive: -# archive_folder = self.mailbox.get_folder(folder_name=self.archive) -# if not archive_folder: -# archive_folder = self.mailbox.create_child_folder(self.archive) + def get_message(self, condition=None): + archive_folder = None + if self.archive: + archive_folder = self.mailbox.get_folder(folder_name=self.archive) + if not archive_folder: + archive_folder = self.mailbox.create_child_folder(self.archive) -# for o365message in self.mailbox_folder.get_messages(order_by='receivedDateTime'): -# try: -# mime_content = o365message.get_mime_content() -# message = self.get_email_from_bytes(mime_content) + for o365message in self.mailbox_folder.get_messages(order_by='receivedDateTime'): + try: + mime_content = o365message.get_mime_content() + message = self.get_email_from_bytes(mime_content) -# if condition and not condition(message): -# continue + if condition and not condition(message): + continue -# yield message -# except MessageParseError: -# continue + yield message + except MessageParseError: + continue -# if self.archive and archive_folder: -# o365message.copy(archive_folder) + if self.archive and archive_folder: + o365message.copy(archive_folder) -# o365message.delete() -# return + o365message.delete() + return From f40ee8832fd348ee247c1fb289ba0b3466f0a017 Mon Sep 17 00:00:00 2001 From: Alireza Lotfi Date: Fri, 16 Sep 2022 10:50:26 -0400 Subject: [PATCH 17/17] office365-imap: remove extra comments --- django_mailbox/models.py | 10 ---- django_mailbox/transports/office365.py | 67 -------------------------- 2 files changed, 77 deletions(-) diff --git a/django_mailbox/models.py b/django_mailbox/models.py index df098689..30364407 100644 --- a/django_mailbox/models.py +++ b/django_mailbox/models.py @@ -216,16 +216,6 @@ def get_connection(self): archive=self.archive ) conn.connect(self.username, self.password) - # elif self.type == 'office365': - # conn = Office365Transport( - # self.location, - # port=self.port if self.port else None, - # tls=self.use_tls, - # ssl=self.use_ssl, - # archive=self.archive, - # folder=self.folder - # ) - # conn.connect(self.username, self.password) elif self.type == 'office365': conn = Office365Transport( self.location, diff --git a/django_mailbox/transports/office365.py b/django_mailbox/transports/office365.py index 62bb6154..053fc8dd 100644 --- a/django_mailbox/transports/office365.py +++ b/django_mailbox/transports/office365.py @@ -1,70 +1,3 @@ -# import logging -# import urllib3 -# import json - -# from django_mailbox.transports.imap import ImapTransport -# from django.conf import settings - - -# logger = logging.getLogger(__name__) - - -# class Office365Transport(ImapTransport): -# def connect(self, username, password): -# # Try to use oauth2 first. It's much safer -# try: -# self._connect_oauth(username) -# except (TypeError, ValueError) as e: -# logger.warning("Couldn't do oauth2 because %s" % e) -# self.server = self.transport(self.hostname, self.port) -# typ, msg = self.server.login(username, password) -# self.server.select() - -# def _connect_oauth(self, username): -# # username should be an email address that has already been authorized -# # for office365 access - -# access_token = None -# while access_token is None: -# try: -# access_token = self.get_office365_access_token() -# except Exception as e: -# raise ValueError( -# f"Could not acquire the access token for {username} exception details={e}" -# ) - -# auth_string = 'user={}\1auth=Bearer {}\1\1'.format( -# username, -# access_token -# ) - -# logger.info(f'[_connect_oauth] port = {self.port}') -# self.server = self.transport(self.hostname, self.port) -# logger.info(f'[_connect_oauth] hostname = {self.hostname}') -# logger.info(f'[_connect_oauth] auth string is: {auth_string}') -# typ, dat = self.server.authenticate("XOAUTH2", lambda x: auth_string) -# logger.info(f'[_connect_oauth] auth string is: {auth_string} and typ={typ} dat={dat}') -# self.server.select() - -# def get_office365_access_token(self): -# url = f"https://login.microsoftonline.com/{settings.MICROSOFT_O365_TENENT_ID}/oauth2/v2.0/token" -# oauth_params = { -# "client_id": settings.MICROSOFT_O365_CLIENT_ID, -# "client_secret": settings.MICROSOFT_O365_CLIENT_SECRET, -# "grant_type": "client_credentials", -# "scope": "https://graph.microsoft.com/.default", -# } -# http = urllib3.PoolManager() -# response = http.request("POST", url, oauth_params) -# if response.status == 200: -# token = json.loads(response.data).get("access_token") -# logger.info(f"[get_office365_access_token] token aquired") -# return token -# else: -# raise Exception( -# f"[get_office365_access_token] Failed to authenticate with O365 {response.data}" -# ) - import logging import os