-
Notifications
You must be signed in to change notification settings - Fork 296
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve Jinja Template feedback and error handling (#884)
* Improve feedback so template errors are given to user * Add security error logging * Add limits for templates, payloads, results * Show popup error notification for webhook errors and template errors that don't have a result * Update tests * Split exceptions into warnings/errors to give more control when previewing, rendering, saving templates * Limit title lengths * Make TypeError a warning * Adjust title length limit * Remove length limiting on urlize since it is being done on template render * Fix tests * Add KeyError and ValueError to warnings * No longer enforcing json result when saving webhook in case it is dependent on payload * Add tests for expected exceptions coming from apply_jinja_template * Update changelog * Send raw post if template result is not JSON
- Loading branch information
Showing
18 changed files
with
204 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,42 @@ | ||
from jinja2 import TemplateSyntaxError, UndefinedError | ||
import logging | ||
|
||
from django.conf import settings | ||
from jinja2 import TemplateAssertionError, TemplateSyntaxError, UndefinedError | ||
from jinja2.exceptions import SecurityError | ||
|
||
from .jinja_template_env import jinja_template_env | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class JinjaTemplateError(Exception): | ||
def __init__(self, fallback_message): | ||
self.fallback_message = f"Template Error: {fallback_message}" | ||
|
||
|
||
class JinjaTemplateWarning(Exception): | ||
def __init__(self, fallback_message): | ||
self.fallback_message = f"Template Warning: {fallback_message}" | ||
|
||
|
||
def apply_jinja_template(template, payload=None, result_length_limit=settings.JINJA_RESULT_MAX_LENGTH, **kwargs): | ||
if len(template) > settings.JINJA_TEMPLATE_MAX_LENGTH: | ||
raise JinjaTemplateError( | ||
f"Template exceeds length limit ({len(template)} > {settings.JINJA_TEMPLATE_MAX_LENGTH})" | ||
) | ||
|
||
def apply_jinja_template(template, payload=None, **kwargs): | ||
try: | ||
template = jinja_template_env.from_string(template) | ||
result = template.render(payload=payload, **kwargs) | ||
return result, True | ||
except (UndefinedError, TypeError, ValueError, KeyError, TemplateSyntaxError): | ||
return None, False | ||
compiled_template = jinja_template_env.from_string(template) | ||
result = compiled_template.render(payload=payload, **kwargs) | ||
except SecurityError as e: | ||
logger.warning(f"SecurityError process template={template} payload={payload}") | ||
raise JinjaTemplateError(str(e)) | ||
except (TemplateAssertionError, TemplateSyntaxError) as e: | ||
raise JinjaTemplateError(str(e)) | ||
except (TypeError, KeyError, ValueError, UndefinedError) as e: | ||
raise JinjaTemplateWarning(str(e)) | ||
except Exception as e: | ||
logger.error(f"Unexpected template error: {str(e)} template={template} payload={payload}") | ||
raise JinjaTemplateError(str(e)) | ||
|
||
return (result[:result_length_limit] + "..") if len(result) > result_length_limit else result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,20 @@ | ||
from django.utils import timezone | ||
from jinja2 import BaseLoader | ||
from jinja2.exceptions import SecurityError | ||
from jinja2.sandbox import SandboxedEnvironment | ||
|
||
from .filters import datetimeformat, iso8601_to_time, regex_replace, to_pretty_json | ||
|
||
|
||
def raise_security_exception(name): | ||
raise SecurityError(f"use of '{name}' is restricted") | ||
|
||
|
||
jinja_template_env = SandboxedEnvironment(loader=BaseLoader()) | ||
|
||
jinja_template_env.filters["datetimeformat"] = datetimeformat | ||
jinja_template_env.filters["iso8601_to_time"] = iso8601_to_time | ||
jinja_template_env.filters["tojson_pretty"] = to_pretty_json | ||
jinja_template_env.globals["time"] = timezone.now | ||
jinja_template_env.globals["range"] = lambda *args: raise_security_exception("range") | ||
jinja_template_env.filters["regex_replace"] = regex_replace |
Oops, something went wrong.