diff --git a/apprise/plugins/NotifyEmail.py b/apprise/plugins/NotifyEmail.py index f871319e..106565f9 100644 --- a/apprise/plugins/NotifyEmail.py +++ b/apprise/plugins/NotifyEmail.py @@ -62,7 +62,7 @@ SECURE_MODES = ( # To attempt to make this script stupid proof, if we detect an email address # that is part of the this table, we can pre-use a lot more defaults if they # aren't otherwise specified on the users input. -WEBBASE_LOOKUP_TABLE = ( +EMAIL_TEMPLATES = ( # Google GMail ( 'Google Mail', @@ -303,44 +303,49 @@ class NotifyEmail(NotifyBase): # over-riding any smarts to be applied return - for i in range(len(WEBBASE_LOOKUP_TABLE)): # pragma: no branch + for i in range(len(EMAIL_TEMPLATES)): # pragma: no branch self.logger.debug('Scanning %s against %s' % ( - self.to_addr, WEBBASE_LOOKUP_TABLE[i][0] + self.to_addr, EMAIL_TEMPLATES[i][0] )) - match = WEBBASE_LOOKUP_TABLE[i][1].match(self.from_addr) + match = EMAIL_TEMPLATES[i][1].match(self.from_addr) if match: self.logger.info( 'Applying %s Defaults' % - WEBBASE_LOOKUP_TABLE[i][0], + EMAIL_TEMPLATES[i][0], ) - self.port = WEBBASE_LOOKUP_TABLE[i][2]\ + self.port = EMAIL_TEMPLATES[i][2]\ .get('port', self.port) - self.secure = WEBBASE_LOOKUP_TABLE[i][2]\ + self.secure = EMAIL_TEMPLATES[i][2]\ .get('secure', self.secure) - self.secure_mode = WEBBASE_LOOKUP_TABLE[i][2]\ + self.secure_mode = EMAIL_TEMPLATES[i][2]\ .get('secure_mode', self.secure_mode) - self.smtp_host = WEBBASE_LOOKUP_TABLE[i][2]\ + self.smtp_host = EMAIL_TEMPLATES[i][2]\ .get('smtp_host', self.smtp_host) if self.smtp_host is None: - # Detect Server if possible - self.smtp_host = re.split(r'[\s@]+', self.from_addr)[-1] - - # Adjust email login based on the defined - # usertype - login_type = WEBBASE_LOOKUP_TABLE[i][2]\ + # default to our host + self.smtp_host = self.host + + # Adjust email login based on the defined usertype. If no entry + # was specified, then we default to having them all set (which + # basically implies that there are no restrictions and use use + # whatever was specified) + login_type = EMAIL_TEMPLATES[i][2]\ .get('login_type', []) - if is_email(self.user) and \ - WebBaseLogin.EMAIL not in login_type: - # Email specified but login type - # not supported; switch it to user id - self.user = match.group('id') - - elif WebBaseLogin.USERID not in login_type: - # user specified but login type - # not supported; switch it to email - self.user = '%s@%s' % (self.user, self.host) + if login_type: + # only apply additional logic to our user if a login_type + # was specified. + if is_email(self.user) and \ + WebBaseLogin.EMAIL not in login_type: + # Email specified but login type + # not supported; switch it to user id + self.user = match.group('id') + + elif WebBaseLogin.USERID not in login_type: + # user specified but login type + # not supported; switch it to email + self.user = '%s@%s' % (self.user, self.host) break diff --git a/test/test_email_plugin.py b/test/test_email_plugin.py index fead763b..03c7eeb1 100644 --- a/test/test_email_plugin.py +++ b/test/test_email_plugin.py @@ -315,7 +315,7 @@ def test_webbase_lookup(mock_smtp, mock_smtpssl): """ # Insert a test email at the head of our table - NotifyEmailBase.WEBBASE_LOOKUP_TABLE = ( + NotifyEmailBase.EMAIL_TEMPLATES = ( ( # Testing URL 'Testing Lookup', @@ -327,7 +327,7 @@ def test_webbase_lookup(mock_smtp, mock_smtpssl): 'login_type': (NotifyEmailBase.WebBaseLogin.USERID, ) }, ), - ) + NotifyEmailBase.WEBBASE_LOOKUP_TABLE + ) + NotifyEmailBase.EMAIL_TEMPLATES obj = Apprise.instantiate( 'mailto://user:pass@l2g.com', suppress_exceptions=True) @@ -341,6 +341,12 @@ def test_webbase_lookup(mock_smtp, mock_smtpssl): assert obj.port == 123 assert obj.smtp_host == 'smtp.l2g.com' + # We get the same results if an email is identified as the username + # because the USERID variable forces that we can't use an email + obj = Apprise.instantiate( + 'mailto://_:pass@l2g.com?user=user@test.com', suppress_exceptions=True) + assert obj.user == 'user' + @mock.patch('smtplib.SMTP') def test_smtplib_init_fail(mock_smtplib): @@ -426,5 +432,85 @@ def test_email_url_escaping(): suppress_exceptions=False) assert isinstance(obj, plugins.NotifyEmail) is True - # The password is escapped 'once' at this point - assert obj.password == ' %20' + +def test_email_url_variations(): + """ + API: Test email variations to ensure parsing is correct + + """ + # Test variations of username required to be an email address + # user@example.com + obj = Apprise.instantiate( + 'mailto://{user}:{passwd}@example.com'.format( + user='apprise%40example21.ca', + passwd='abcd123'), + suppress_exceptions=False) + assert isinstance(obj, plugins.NotifyEmail) is True + + assert obj.password == 'abcd123' + assert obj.user == 'apprise@example21.ca' + + # test username specified in the url body (as an argument) + # this always over-rides the entry at the front of the url + obj = Apprise.instantiate( + 'mailto://_:{passwd}@example.com?user={user}'.format( + user='apprise%40example21.ca', + passwd='abcd123'), + suppress_exceptions=False) + assert isinstance(obj, plugins.NotifyEmail) is True + + assert obj.password == 'abcd123' + assert obj.user == 'apprise@example21.ca' + + # test user and password specified in the url body (as an argument) + # this always over-rides the entries at the front of the url + obj = Apprise.instantiate( + 'mailto://_:_@example.com?user={user}&pass={passwd}'.format( + user='apprise%40example21.ca', + passwd='abcd123'), + suppress_exceptions=False) + assert isinstance(obj, plugins.NotifyEmail) is True + + assert obj.password == 'abcd123' + assert obj.user == 'apprise@example21.ca' + assert obj.to_addr == 'apprise@example.com' + assert obj.to_addr == obj.from_addr + + # test user and password specified in the url body (as an argument) + # this always over-rides the entries at the front of the url + # this is similar to the previous test except we're only specifying + # this information in the kwargs + obj = Apprise.instantiate( + 'mailto://example.com?user={user}&pass={passwd}'.format( + user='apprise%40example21.ca', + passwd='abcd123'), + suppress_exceptions=False) + assert isinstance(obj, plugins.NotifyEmail) is True + + assert obj.password == 'abcd123' + assert obj.user == 'apprise@example21.ca' + assert obj.to_addr == 'apprise@example.com' + assert obj.to_addr == obj.from_addr + assert obj.smtp_host == 'example.com' + + # test a complicated example + obj = Apprise.instantiate( + 'mailtos://{user}:{passwd}@{host}:{port}' + '?smtp={smtp_host}&format=text&from={this}&to={that}'.format( + user='apprise%40example21.ca', + passwd='abcd123', + host='example.com', + port=1234, + this='from@example.jp', + that='to@example.jp', + smtp_host='smtp.example.edu'), + suppress_exceptions=False) + assert isinstance(obj, plugins.NotifyEmail) is True + + assert obj.password == 'abcd123' + assert obj.user == 'apprise@example21.ca' + assert obj.host == 'example.com' + assert obj.port == 1234 + assert obj.smtp_host == 'smtp.example.edu' + assert obj.to_addr == 'to@example.jp' + assert obj.from_addr == 'from@example.jp'