Browse Source

Improvements from comments

pull/79/head
Antonio Espinosa 8 years ago
parent
commit
bff8062527
  1. 6
      mail_tracking_mailgun/README.rst
  2. 5
      mail_tracking_mailgun/models/ir_mail_server.py
  3. 22
      mail_tracking_mailgun/models/mail_tracking_email.py
  4. 13
      mail_tracking_mailgun/tests/test_mailgun.py

6
mail_tracking_mailgun/README.rst

@ -20,14 +20,14 @@ Configuration
You must configure Mailgun webhooks in order to receive mail events: You must configure Mailgun webhooks in order to receive mail events:
1. Got a Mailgun account and validate your sending domain. 1. Got a Mailgun account and validate your sending domain.
2. Go to Webhook tab and configure this URL for each event you want to track:
2. Go to Webhook tab and configure the below URL for each event:
.. code:: html .. code:: html
https://<your_domain>/mail/tracking/all/<your_database> https://<your_domain>/mail/tracking/all/<your_database>
Replace '<your_domain>' by your Odoo install domain name
and '<your_database>' by your database name.
Replace '<your_domain>' with your Odoo install domain name
and '<your_database>' with your database name.
In order to validate Mailgun webhooks you have to save Mailgun api_key in In order to validate Mailgun webhooks you have to save Mailgun api_key in
a system parameter named 'mailgun.apikey'. You can find Mailgun api_key in your a system parameter named 'mailgun.apikey'. You can find Mailgun api_key in your

5
mail_tracking_mailgun/models/ir_mail_server.py

@ -3,7 +3,6 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import json import json
import threading
from openerp import models from openerp import models
@ -15,7 +14,9 @@ class IrMailServer(models.Model):
tracking_email_id, headers) tracking_email_id, headers)
headers = headers or {} headers = headers or {}
metadata = { metadata = {
'odoo_db': getattr(threading.currentThread(), 'dbname', None),
# NOTE: We can not use 'self.env.cr.dbname' because self is
# ir.mail_server object in old API (osv.osv)
'odoo_db': self.pool.db_name,
'tracking_email_id': tracking_email_id, 'tracking_email_id': tracking_email_id,
} }
headers['X-Mailgun-Variables'] = json.dumps(metadata) headers['X-Mailgun-Variables'] = json.dumps(metadata)

22
mail_tracking_mailgun/models/mail_tracking_email.py

@ -4,7 +4,6 @@
import hashlib import hashlib
import hmac import hmac
import threading
from datetime import datetime from datetime import datetime
from openerp import models, api, fields from openerp import models, api, fields
@ -19,16 +18,18 @@ class MailTrackingEmail(models.Model):
country = False country = False
if country_code: if country_code:
country = self.env['res.country'].search([ country = self.env['res.country'].search([
('code', '=ilike', country_code),
('code', '=', country_code.capitalize()),
]) ])
if country: if country:
return country.id return country.id
return False return False
@property
def _mailgun_mandatory_fields(self): def _mailgun_mandatory_fields(self):
return ('event', 'timestamp', 'token', 'signature', return ('event', 'timestamp', 'token', 'signature',
'tracking_email_id', 'odoo_db') 'tracking_email_id', 'odoo_db')
@property
def _mailgun_event_type_mapping(self): def _mailgun_event_type_mapping(self):
return { return {
# Mailgun event type: tracking event type # Mailgun event type: tracking event type
@ -41,13 +42,14 @@ class MailTrackingEmail(models.Model):
'dropped': 'reject', 'dropped': 'reject',
} }
@property
def _mailgun_supported_event_types(self): def _mailgun_supported_event_types(self):
return self._mailgun_event_type_mapping().keys()
return self._mailgun_event_type_mapping.keys()
def _mailgun_event_type_verify(self, event): def _mailgun_event_type_verify(self, event):
event = event or {} event = event or {}
mailgun_event_type = event.get('event') mailgun_event_type = event.get('event')
if mailgun_event_type not in self._mailgun_supported_event_types():
if mailgun_event_type not in self._mailgun_supported_event_types:
_logger.info("Mailgun: event type '%s' not supported", _logger.info("Mailgun: event type '%s' not supported",
mailgun_event_type) mailgun_event_type)
return False return False
@ -76,8 +78,8 @@ class MailTrackingEmail(models.Model):
signature = event.get('signature') signature = event.get('signature')
event_digest = self._mailgun_signature(api_key, timestamp, token) event_digest = self._mailgun_signature(api_key, timestamp, token)
if signature != event_digest: if signature != event_digest:
_logger.info("Mailgun: Invalid signature '%s' != '%s'",
signature, event_digest)
_logger.error("Mailgun: Invalid signature '%s' != '%s'",
signature, event_digest)
return False return False
# OK, signature is valid # OK, signature is valid
return True return True
@ -85,7 +87,7 @@ class MailTrackingEmail(models.Model):
def _db_verify(self, event): def _db_verify(self, event):
event = event or {} event = event or {}
odoo_db = event.get('odoo_db') odoo_db = event.get('odoo_db')
current_db = getattr(threading.currentThread(), 'dbname', None)
current_db = self.env.cr.dbname
if odoo_db != current_db: if odoo_db != current_db:
_logger.info("Mailgun: Database '%s' is not the current database", _logger.info("Mailgun: Database '%s' is not the current database",
odoo_db) odoo_db)
@ -152,12 +154,12 @@ class MailTrackingEmail(models.Model):
tracking = False tracking = False
tracking_email_id = event.get('tracking_email_id', False) tracking_email_id = event.get('tracking_email_id', False)
if tracking_email_id and tracking_email_id.isdigit(): if tracking_email_id and tracking_email_id.isdigit():
tracking = self.search([('id', '=', tracking_email_id)])
tracking = self.search([('id', '=', tracking_email_id)], limit=1)
return tracking return tracking
def _event_is_from_mailgun(self, event): def _event_is_from_mailgun(self, event):
event = event or {} event = event or {}
return all([k in event for k in self._mailgun_mandatory_fields()])
return all([k in event for k in self._mailgun_mandatory_fields])
@api.model @api.model
def event_process(self, request, post, metadata, event_type=None): def event_process(self, request, post, metadata, event_type=None):
@ -174,7 +176,7 @@ class MailTrackingEmail(models.Model):
res = 'OK' res = 'OK'
if res == 'OK': if res == 'OK':
mailgun_event_type = post.get('event') mailgun_event_type = post.get('event')
mapped_event_type = self._mailgun_event_type_mapping().get(
mapped_event_type = self._mailgun_event_type_mapping.get(
mailgun_event_type) or event_type mailgun_event_type) or event_type
if not mapped_event_type: # pragma: no cover if not mapped_event_type: # pragma: no cover
res = 'ERROR: Bad event' res = 'ERROR: Bad event'

13
mail_tracking_mailgun/tests/test_mailgun.py

@ -2,7 +2,6 @@
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> # Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import threading
from openerp.tests.common import TransactionCase from openerp.tests.common import TransactionCase
@ -28,8 +27,8 @@ class TestMailgun(TransactionCase):
self.api_key = u'key-12345678901234567890123456789012' self.api_key = u'key-12345678901234567890123456789012'
self.token = u'f1349299097a51b9a7d886fcb5c2735b426ba200ada6e9e149' self.token = u'f1349299097a51b9a7d886fcb5c2735b426ba200ada6e9e149'
self.timestamp = u'1471021089' self.timestamp = u'1471021089'
self.signature = u'%s' % self.env['mail.tracking.email'].\
_mailgun_signature(self.api_key, self.timestamp, self.token)
self.signature = ('4fb6d4dbbe10ce5d620265dcd7a3c0b8'
'ca0dede1433103891bc1ae4086e9d5b2')
self.env['ir.config_parameter'].set_param( self.env['ir.config_parameter'].set_param(
'mailgun.apikey', self.api_key) 'mailgun.apikey', self.api_key)
self.event = { self.event = {
@ -42,7 +41,7 @@ class TestMailgun(TransactionCase):
'domain': u'example.com', 'domain': u'example.com',
'message-headers': u'[]', 'message-headers': u'[]',
'recipient': self.recipient, 'recipient': self.recipient,
'odoo_db': getattr(threading.currentThread(), 'dbname', None),
'odoo_db': self.env.cr.dbname,
'tracking_email_id': u'%s' % self.tracking_email.id 'tracking_email_id': u'%s' % self.tracking_email.id
} }
self.metadata = { self.metadata = {
@ -91,9 +90,9 @@ class TestMailgun(TransactionCase):
self.assertEqual('ERROR: Invalid DB', response) self.assertEqual('ERROR: Invalid DB', response)
def test_bad_ts(self): def test_bad_ts(self):
timestamp = u'7a', # Now time will be used instead
signature = u'%s' % self.env['mail.tracking.email'].\
_mailgun_signature(self.api_key, timestamp, self.token)
timestamp = u'7a' # Now time will be used instead
signature = ('06cc05680f6e8110e59b41152b2d1c0f'
'1045d755ef2880ff922344325c89a6d4')
self.event.update({ self.event.update({
'event': u'delivered', 'event': u'delivered',
'timestamp': timestamp, 'timestamp': timestamp,

Loading…
Cancel
Save