Merge pull request #102 from caronc/101-bugfix-custom-email-userid

Custom SMTP usernames (credentials) to support email addresses
This commit is contained in:
Chris Caron 2019-04-25 21:47:15 -04:00 committed by GitHub
commit 68c8a0e6f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 118 additions and 27 deletions

View File

@ -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]
# default to our host
self.smtp_host = self.host
# Adjust email login based on the defined
# usertype
login_type = WEBBASE_LOOKUP_TABLE[i][2]\
# 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')
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)
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

View File

@ -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'