1
0
Fork 0

Office365 API mailbox support (#251)

* Update models.py, __init__.py, and office365.py

* Update setup.py

* Office365Transport properties

* Update .gitignore

* wrong folder stage

* Update models.py

* Update office365.py and models.py

* office365 implementation

* Update office365.py

* clear code

* fix import

* Update readme.rst

* archive and delete

* fix and documentation

* removed build folder

* missing archive

Co-authored-by: Pietro Mingo <p.mingo@intac.it>
Co-authored-by: Serafim Bordei <s.bordei@intac.it>
This commit is contained in:
Pietro Mingo 2023-01-16 22:23:38 +01:00 committed by GitHub
parent 40263b6670
commit cefbcdebd2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 129 additions and 3 deletions

View file

@ -31,7 +31,7 @@ from django_mailbox import utils
from django_mailbox.signals import message_received
from django_mailbox.transports import Pop3Transport, ImapTransport, \
MaildirTransport, MboxTransport, BabylTransport, MHTransport, \
MMDFTransport, GmailImapTransport
MMDFTransport, GmailImapTransport, Office365Transport
logger = logging.getLogger(__name__)
@ -189,6 +189,30 @@ class Mailbox(models.Model):
return None
return folder[0]
@property
def client_id(self):
"""Returns (if specified) the client id for Office365."""
client_id = self._query_string.get('client_id', None)
if not client_id:
return None
return client_id[0]
@property
def client_secret(self):
"""Returns (if specified) the client secret for Office365."""
client_secret = self._query_string.get('client_secret', None)
if not client_secret:
return None
return client_secret[0]
@property
def tenant_id(self):
"""Returns (if specified) the tenant id for Office365."""
tenant_id = self._query_string.get('tenant_id', None)
if not tenant_id:
return None
return tenant_id[0]
def get_connection(self):
"""Returns the transport instance for this mailbox.
@ -223,6 +247,14 @@ class Mailbox(models.Model):
ssl=self.use_ssl
)
conn.connect(self.username, self.password)
elif self.type == 'office365':
conn = Office365Transport(
self.location,
self.username,
folder=self.folder,
archive=self.archive
)
conn.connect(self.client_id, self.client_secret, self.tenant_id)
elif self.type == 'maildir':
conn = MaildirTransport(self.location)
elif self.type == 'mbox':

View file

@ -8,3 +8,4 @@ from django_mailbox.transports.babyl import BabylTransport
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 Office365Transport

View file

@ -9,3 +9,4 @@ class EmailTransport:
message = email.message_from_bytes(contents)
return message

View file

@ -0,0 +1,66 @@
import logging
from django.conf import settings
from .base import EmailTransport, MessageParseError
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
def connect(self, client_id, client_secret, tenant_id):
try:
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:
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)
o365message.delete()
return