Merge pull request #433 from SamR1/handle-encoded-password
Handle encoded password in EMAIL_URL
This commit is contained in:
commit
4ade698306
@ -4,6 +4,7 @@ import ssl
|
|||||||
from email.mime.multipart import MIMEMultipart
|
from email.mime.multipart import MIMEMultipart
|
||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
from typing import Dict, List, Optional, Type, Union
|
from typing import Dict, List, Optional, Type, Union
|
||||||
|
from urllib.parse import unquote
|
||||||
|
|
||||||
from babel.support import Translations
|
from babel.support import Translations
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
@ -131,7 +132,7 @@ class EmailService:
|
|||||||
parsed_url = parse_url(email_url)
|
parsed_url = parse_url(email_url)
|
||||||
if parsed_url.scheme != 'smtp':
|
if parsed_url.scheme != 'smtp':
|
||||||
raise InvalidEmailUrlScheme()
|
raise InvalidEmailUrlScheme()
|
||||||
credentials = (
|
username, password = (
|
||||||
parsed_url.auth.split(':')
|
parsed_url.auth.split(':')
|
||||||
if parsed_url.auth
|
if parsed_url.auth
|
||||||
else [None, None] # type: ignore
|
else [None, None] # type: ignore
|
||||||
@ -139,10 +140,12 @@ class EmailService:
|
|||||||
return {
|
return {
|
||||||
'host': parsed_url.host,
|
'host': parsed_url.host,
|
||||||
'port': 25 if parsed_url.port is None else parsed_url.port,
|
'port': 25 if parsed_url.port is None else parsed_url.port,
|
||||||
'use_tls': True if parsed_url.query == 'tls=True' else False,
|
'use_tls': parsed_url.query == 'tls=True',
|
||||||
'use_ssl': True if parsed_url.query == 'ssl=True' else False,
|
'use_ssl': parsed_url.query == 'ssl=True',
|
||||||
'username': credentials[0],
|
'username': username,
|
||||||
'password': credentials[1],
|
'password': (
|
||||||
|
unquote(password) if isinstance(password, str) else password
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from unittest.mock import Mock, patch
|
from unittest.mock import Mock, patch
|
||||||
|
from urllib.parse import quote
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
@ -43,6 +44,7 @@ class TestEmailServiceUrlParser(CallArgsMixin):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def assert_parsed_email(url: str) -> None:
|
def assert_parsed_email(url: str) -> None:
|
||||||
parsed_email = email_service.parse_email_url(url)
|
parsed_email = email_service.parse_email_url(url)
|
||||||
|
|
||||||
assert parsed_email['username'] is None
|
assert parsed_email['username'] is None
|
||||||
assert parsed_email['password'] is None
|
assert parsed_email['password'] is None
|
||||||
assert parsed_email['host'] == 'localhost'
|
assert parsed_email['host'] == 'localhost'
|
||||||
@ -60,7 +62,9 @@ class TestEmailServiceUrlParser(CallArgsMixin):
|
|||||||
|
|
||||||
def test_it_parses_email_url(self) -> None:
|
def test_it_parses_email_url(self) -> None:
|
||||||
url = 'smtp://test@example.com:12345678@localhost:25'
|
url = 'smtp://test@example.com:12345678@localhost:25'
|
||||||
|
|
||||||
parsed_email = email_service.parse_email_url(url)
|
parsed_email = email_service.parse_email_url(url)
|
||||||
|
|
||||||
assert parsed_email['username'] == 'test@example.com'
|
assert parsed_email['username'] == 'test@example.com'
|
||||||
assert parsed_email['password'] == '12345678'
|
assert parsed_email['password'] == '12345678'
|
||||||
assert parsed_email['host'] == 'localhost'
|
assert parsed_email['host'] == 'localhost'
|
||||||
@ -70,7 +74,9 @@ class TestEmailServiceUrlParser(CallArgsMixin):
|
|||||||
|
|
||||||
def test_it_parses_email_url_with_tls(self) -> None:
|
def test_it_parses_email_url_with_tls(self) -> None:
|
||||||
url = 'smtp://test@example.com:12345678@localhost:587?tls=True'
|
url = 'smtp://test@example.com:12345678@localhost:587?tls=True'
|
||||||
|
|
||||||
parsed_email = email_service.parse_email_url(url)
|
parsed_email = email_service.parse_email_url(url)
|
||||||
|
|
||||||
assert parsed_email['username'] == 'test@example.com'
|
assert parsed_email['username'] == 'test@example.com'
|
||||||
assert parsed_email['password'] == '12345678'
|
assert parsed_email['password'] == '12345678'
|
||||||
assert parsed_email['host'] == 'localhost'
|
assert parsed_email['host'] == 'localhost'
|
||||||
@ -80,7 +86,9 @@ class TestEmailServiceUrlParser(CallArgsMixin):
|
|||||||
|
|
||||||
def test_it_parses_email_url_with_ssl(self) -> None:
|
def test_it_parses_email_url_with_ssl(self) -> None:
|
||||||
url = 'smtp://test@example.com:12345678@localhost:465?ssl=True'
|
url = 'smtp://test@example.com:12345678@localhost:465?ssl=True'
|
||||||
|
|
||||||
parsed_email = email_service.parse_email_url(url)
|
parsed_email = email_service.parse_email_url(url)
|
||||||
|
|
||||||
assert parsed_email['username'] == 'test@example.com'
|
assert parsed_email['username'] == 'test@example.com'
|
||||||
assert parsed_email['password'] == '12345678'
|
assert parsed_email['password'] == '12345678'
|
||||||
assert parsed_email['host'] == 'localhost'
|
assert parsed_email['host'] == 'localhost'
|
||||||
@ -88,6 +96,21 @@ class TestEmailServiceUrlParser(CallArgsMixin):
|
|||||||
assert parsed_email['use_tls'] is False
|
assert parsed_email['use_tls'] is False
|
||||||
assert parsed_email['use_ssl'] is True
|
assert parsed_email['use_ssl'] is True
|
||||||
|
|
||||||
|
def test_it_parses_email_url_with_encoded_password(self) -> None:
|
||||||
|
username = "user_name@example.com"
|
||||||
|
password = "passwordWith@And&And?"
|
||||||
|
encoded_password = quote(password)
|
||||||
|
url = f"smtp://{username}:{encoded_password}@localhost:465?ssl=True"
|
||||||
|
|
||||||
|
parsed_email = email_service.parse_email_url(url)
|
||||||
|
|
||||||
|
assert parsed_email['username'] == username
|
||||||
|
assert parsed_email['password'] == password
|
||||||
|
assert parsed_email['host'] == 'localhost'
|
||||||
|
assert parsed_email['port'] == 465
|
||||||
|
assert parsed_email['use_tls'] is False
|
||||||
|
assert parsed_email['use_ssl'] is True
|
||||||
|
|
||||||
|
|
||||||
class TestEmailServiceSend(CallArgsMixin):
|
class TestEmailServiceSend(CallArgsMixin):
|
||||||
email_data = {
|
email_data = {
|
||||||
|
Loading…
Reference in New Issue
Block a user