1
0
Fork 1
mirror of https://github.com/coddingtonbear/django-mailbox.git synced 2026-07-10 06:48:19 +02:00

testing on feature

This commit is contained in:
Alireza Lotfi 2022-09-13 21:29:14 -04:00
parent 5155192194
commit af8d283765
2 changed files with 137 additions and 63 deletions

View file

@ -31,7 +31,7 @@ from django_mailbox import utils
from django_mailbox.signals import message_received from django_mailbox.signals import message_received
from django_mailbox.transports import Pop3Transport, ImapTransport, \ from django_mailbox.transports import Pop3Transport, ImapTransport, \
MaildirTransport, MboxTransport, BabylTransport, MHTransport, \ MaildirTransport, MboxTransport, BabylTransport, MHTransport, \
MMDFTransport, GmailImapTransport, Office365ImapTransport MMDFTransport, GmailImapTransport, Office365Transport
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -216,16 +216,24 @@ class Mailbox(models.Model):
archive=self.archive archive=self.archive
) )
conn.connect(self.username, self.password) 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': elif self.type == 'office365':
conn = Office365ImapTransport( conn = Office365Transport(
self.location, self.location,
port=self.port if self.port else None, self.username,
tls=self.use_tls, folder=self.folder,
ssl=self.use_ssl, archive=self.archive
archive=self.archive,
folder=self.folder
) )
conn.connect(self.username, self.password) conn.connect(self.client_id, self.client_secret, self.tenant_id)
elif self.type == 'pop3': elif self.type == 'pop3':
conn = Pop3Transport( conn = Pop3Transport(
self.location, self.location,

View file

@ -1,65 +1,131 @@
import logging # import logging
import urllib3 # import urllib3
import json # 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
from django_mailbox.transports.imap import ImapTransport
from django.conf import settings from django.conf import settings
from .base import EmailTransport, MessageParseError
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Office365ImapTransport(ImapTransport): class Office365Transport(EmailTransport):
def connect(self, username, password): def __init__(
# Try to use oauth2 first. It's much safer self, hostname, username, archive='', folder=None
try: ):
self._connect_oauth(username) self.integration_testing_subject = getattr(
except (TypeError, ValueError) as e: settings,
logger.warning("Couldn't do oauth2 because %s" % e) 'DJANGO_MAILBOX_INTEGRATION_TESTING_SUBJECT',
self.server = self.transport(self.hostname, self.port) None
typ, msg = self.server.login(username, password) )
self.server.select() self.hostname = hostname
self.username = username
self.archive = archive
self.folder = folder
def _connect_oauth(self, username): def connect(self, client_id, client_secret, tenant_id):
# username should be an email address that has already been authorized
# for office365 access
access_token = None
while access_token is None:
try: try:
access_token = self.get_office365_access_token() import O365
except Exception as e: except ImportError:
raise ValueError( raise ValueError(
f"Could not acquire the access token for {username} exception details={e}" "Install o365 to use oauth2 auth for office365"
) )
auth_string = 'user={}\1auth=Bearer {}\1\1'.format( credentials = (client_id, client_secret)
username,
access_token
)
self.server = self.transport(self.hostname, self.port) self.account = O365.Account(credentials, auth_flow_type='credentials', tenant_id=tenant_id)
logger.info(f'[_connect_oauth] hostname = {self.hostname}') self.account.authenticate()
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): self.mailbox = self.account.mailbox(resource=self.username)
url = f"https://login.microsoftonline.com/{settings.MICROSOFT_O365_TENENT_ID}/oauth2/v2.0/token" self.mailbox_folder = self.mailbox.inbox_folder()
oauth_params = { if self.folder:
"client_id": settings.MICROSOFT_O365_CLIENT_ID, self.mailbox_folder = self.mailbox.get_folder(folder_name=self.folder)
"client_secret": settings.MICROSOFT_O365_CLIENT_SECRET,
"grant_type": "client_credentials", def get_message(self, condition=None):
"scope": "https://graph.microsoft.com/.default", archive_folder = None
} if self.archive:
http = urllib3.PoolManager() archive_folder = self.mailbox.get_folder(folder_name=self.archive)
response = http.request("POST", url, oauth_params) if not archive_folder:
if response.status == 200: archive_folder = self.mailbox.create_child_folder(self.archive)
token = json.loads(response.data).get("access_token")
logger.info(f"[get_office365_access_token] token aquired") for o365message in self.mailbox_folder.get_messages(order_by='receivedDateTime'):
return token try:
else: mime_content = o365message.get_mime_content()
raise Exception( message = self.get_email_from_bytes(mime_content)
f"[get_office365_access_token] Failed to authenticate with O365 {response.data}"
) 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