Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ httpserver mode
This mode is faster than ``cmd`` and a bit slower than ``tcpserver``, but you can use official MJML API https://mjml.io/api
or run your own HTTP-server (for example https://github.com/danihodovic/mjml-server) to render templates.

You can use any Authentication backend supported by requests (or provide your own).
See https://requests.readthedocs.io/en/latest/user/authentication/ for details.

Configure your Django::

MJML_BACKEND_MODE = 'httpserver'
Expand Down
12 changes: 10 additions & 2 deletions mjml/settings.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from django.conf import settings
try:
from requests.auth import AuthBase
except ImportError:
AuthBase = None

MJML_BACKEND_MODE = getattr(settings, 'MJML_BACKEND_MODE', 'cmd')
assert MJML_BACKEND_MODE in {'cmd', 'tcpserver', 'httpserver'}
Expand All @@ -24,6 +28,10 @@
assert 'URL' in t and isinstance(t['URL'], str)
if 'HTTP_AUTH' in t:
http_auth = t['HTTP_AUTH']
assert isinstance(http_auth, (type(None), list, tuple))
if http_auth is not None:
if AuthBase:
assert isinstance(http_auth, (type(None), list, tuple, AuthBase))
else:
assert isinstance(http_auth, (type(None), list, tuple))

if isinstance(http_auth, (list, tuple)):
assert len(http_auth) == 2 and isinstance(http_auth[0], str) and isinstance(http_auth[1], str)
7 changes: 6 additions & 1 deletion mjml/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,12 @@ def _mjml_render_by_httpserver(mjml_code: str) -> str:
timeouts = 0
for server_conf in servers:
http_auth = server_conf.get('HTTP_AUTH')
auth = requests.auth.HTTPBasicAuth(*http_auth) if http_auth else None

auth = (
http_auth
if isinstance(http_auth, (type(None), requests.auth.AuthBase))
else requests.auth.HTTPBasicAuth(*http_auth)
)

try:
response = requests.post(
Expand Down
29 changes: 28 additions & 1 deletion testprj/tests_httpserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def test_http_server_error(self) -> None:
self.assertIn(' Tag: mj-button Message: mj-button ', str(cm.exception))

@mock.patch('requests.post')
def test_http_auth(self, post_mock) -> None:
def test_http_basic_auth(self, post_mock) -> None:
with safe_change_mjml_settings():
for server_conf in mjml_settings.MJML_HTTPSERVERS:
server_conf['HTTP_AUTH'] = ('testuser', 'testpassword')
Expand All @@ -93,6 +93,33 @@ def test_http_auth(self, post_mock) -> None:
self.assertEqual(post_mock.call_args[1]['auth'].username, 'testuser')
self.assertEqual(post_mock.call_args[1]['auth'].password, 'testpassword')

@mock.patch('requests.post')
def test_http_auth(self, post_mock) -> None:
with safe_change_mjml_settings():
for server_conf in mjml_settings.MJML_HTTPSERVERS:
server_conf['HTTP_AUTH'] = requests.auth.HTTPBasicAuth('testuser', 'testpassword')

response = requests.Response()
response.status_code = 200
response._content = force_bytes(json.dumps({
'errors': [],
'html': 'html_string',
'mjml': 'mjml_string',
'mjml_version': '4.5.1',
}))
response.encoding = 'utf-8'
response.headers['Content-Type'] = 'text/html; charset=utf-8'
response.headers['Content-Length'] = len(response._content)
post_mock.return_value = response

render_tpl(self.TPLS['simple'])

self.assertTrue(post_mock.called)
self.assertIn('auth', post_mock.call_args[1])
self.assertIsInstance(post_mock.call_args[1]['auth'], requests.auth.HTTPBasicAuth)
self.assertEqual(post_mock.call_args[1]['auth'].username, 'testuser')
self.assertEqual(post_mock.call_args[1]['auth'].password, 'testpassword')

@unittest.skip('to run locally')
def test_public_api(self) -> None:
with safe_change_mjml_settings():
Expand Down