From 28f424b5aa611e909bc51dc537ff47f882db8af3 Mon Sep 17 00:00:00 2001 From: Chris Caron Date: Tue, 1 Nov 2022 18:05:27 -0400 Subject: [PATCH] Improved mailgun:// handling of from= argument (#724) --- apprise/plugins/NotifyMailgun.py | 32 +++++---- test/test_plugin_mailgun.py | 110 +++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 14 deletions(-) diff --git a/apprise/plugins/NotifyMailgun.py b/apprise/plugins/NotifyMailgun.py index 1010f8ef..598577d6 100644 --- a/apprise/plugins/NotifyMailgun.py +++ b/apprise/plugins/NotifyMailgun.py @@ -263,12 +263,19 @@ class NotifyMailgun(NotifyBase): raise TypeError(msg) # Get our From username (if specified) - self.from_name = from_name - - # Get our from email address - self.from_addr = '{user}@{host}'.format(user=self.user, host=self.host) - - if not is_email(self.from_addr): + self.from_addr = [ + self.app_id, '{user}@{host}'.format( + user=self.user, host=self.host)] + if from_name: + result = is_email(from_name) + if result: + self.from_addr = ( + result['name'] if result['name'] else False, + result['full_email']) + else: + self.from_addr[0] = from_name + + if not is_email(self.from_addr[1]): # Parse Source domain based on from_addr msg = 'Invalid ~From~ email format: {}'.format(self.from_addr) self.logger.warning(msg) @@ -291,8 +298,7 @@ class NotifyMailgun(NotifyBase): else: # If our target email list is empty we want to add ourselves to it - self.targets.append( - (self.from_name if self.from_name else False, self.from_addr)) + self.targets.append((False, self.from_addr[1])) # Validate recipients (cc:) and drop bad ones: for recipient in parse_emails(cc): @@ -386,9 +392,7 @@ class NotifyMailgun(NotifyBase): return False - reply_to = formataddr( - (self.from_name if self.from_name else False, - self.from_addr), charset='utf-8') + reply_to = formataddr(self.from_addr, charset='utf-8') # Prepare our payload payload = { @@ -584,9 +588,9 @@ class NotifyMailgun(NotifyBase): # Extend our parameters params.update(self.url_parameters(privacy=privacy, *args, **kwargs)) - if self.from_name is not None: + if self.from_addr[0]: # from_name specified; pass it back on the url - params['name'] = self.from_name + params['name'] = self.from_addr[0] if self.cc: # Handle our Carbon Copy Addresses @@ -649,7 +653,7 @@ class NotifyMailgun(NotifyBase): elif 'from' in results['qsd'] and len(results['qsd']['from']): # Extract from name to associate with from address results['from_name'] = \ - NotifyMailgun.unquote(results['qsd']['name']) + NotifyMailgun.unquote(results['qsd']['from']) if 'region' in results['qsd'] and len(results['qsd']['region']): # Extract from name to associate with from address diff --git a/test/test_plugin_mailgun.py b/test/test_plugin_mailgun.py index 30888388..697fbe63 100644 --- a/test/test_plugin_mailgun.py +++ b/test/test_plugin_mailgun.py @@ -294,3 +294,113 @@ def test_plugin_mailgun_attachments(mock_post): body='body', title='title', notify_type=NotifyType.INFO, attach=attach) is True assert mock_post.call_count == 1 + + +@mock.patch('requests.post') +def test_plugin_mailgun_header_check(mock_post): + """ + NotifyMailgun() Test Header Prep + + """ + + okay_response = requests.Request() + okay_response.status_code = requests.codes.ok + okay_response.content = "" + + # Assign our mock object our return value + mock_post.return_value = okay_response + + # API Key + apikey = 'abc123' + + obj = Apprise.instantiate( + 'mailgun://user@localhost.localdomain/{}'.format(apikey)) + assert isinstance(obj, NotifyMailgun) + assert isinstance(obj.url(), str) is True + + # No calls made yet + assert mock_post.call_count == 0 + + # Send our notification + assert obj.notify( + body='body', title='title', notify_type=NotifyType.INFO) is True + + # 2 calls were made, one to perform an email lookup, the second + # was the notification itself + assert mock_post.call_count == 1 + assert mock_post.call_args_list[0][0][0] == \ + 'https://api.mailgun.net/v3/localhost.localdomain/messages' + + payload = mock_post.call_args_list[0][1]['data'] + assert 'from' in payload + assert 'Apprise ' == payload['from'] + assert 'user@localhost.localdomain' == payload['to'] + + # Reset our mock object + mock_post.reset_mock() + + obj = Apprise.instantiate( + 'mailgun://user@localhost.localdomain/' + '{}?from=Luke%20Skywalker'.format(apikey)) + assert isinstance(obj, NotifyMailgun) + assert isinstance(obj.url(), str) is True + + # No calls made yet + assert mock_post.call_count == 0 + + # Send our notification + assert obj.notify( + body='body', title='title', notify_type=NotifyType.INFO) is True + + assert mock_post.call_count == 1 + payload = mock_post.call_args_list[0][1]['data'] + assert 'from' in payload + assert 'to' in payload + assert 'Luke Skywalker ' == payload['from'] + assert 'user@localhost.localdomain' == payload['to'] + + # Reset our mock object + mock_post.reset_mock() + + obj = Apprise.instantiate( + 'mailgun://user@localhost.localdomain/{}' + '?from=Luke%20Skywalker'.format(apikey)) + assert isinstance(obj, NotifyMailgun) + assert isinstance(obj.url(), str) is True + + # No calls made yet + assert mock_post.call_count == 0 + + # Send our notification + assert obj.notify( + body='body', title='title', notify_type=NotifyType.INFO) is True + + assert mock_post.call_count == 1 + payload = mock_post.call_args_list[0][1]['data'] + assert 'from' in payload + assert 'to' in payload + assert 'Luke Skywalker ' == payload['from'] + assert 'luke@rebels.com' == payload['to'] + + # Reset our mock object + mock_post.reset_mock() + + obj = Apprise.instantiate( + 'mailgun://user@localhost.localdomain/{}' + '?from=luke@rebels.com'.format(apikey)) + assert isinstance(obj, NotifyMailgun) + assert isinstance(obj.url(), str) is True + + # No calls made yet + assert mock_post.call_count == 0 + + # Send our notification + assert obj.notify( + body='body', title='title', notify_type=NotifyType.INFO) is True + + assert mock_post.call_count == 1 + payload = mock_post.call_args_list[0][1]['data'] + assert 'from' in payload + assert 'to' in payload + assert 'luke@rebels.com' == payload['from'] + assert 'luke@rebels.com' == payload['to']