github-advanced-security[bot] commented on code in PR #49257:
URL: https://github.com/apache/airflow/pull/49257#discussion_r2043003325


##########
airflow-core/src/airflow/models/taskinstance.py:
##########
@@ -3174,7 +2757,83 @@
         :param exception: the exception sent in the email
         :param task:
         """
-        return _get_email_subject_content(task_instance=self, 
exception=exception, task=task)
+        # For a ti from DB (without ti.task), return the default value
+        if task is None:
+            task = getattr(self, "task")
+        use_default = task is None
+        exception_html = str(exception).replace("\n", "<br>")
+
+        default_subject = "Airflow alert: {{ti}}"
+        # For reporting purposes, we report based on 1-indexed,
+        # not 0-indexed lists (i.e. Try 1 instead of
+        # Try 0 for the first attempt).
+        default_html_content = (
+            "Try {{try_number}} out of {{max_tries + 1}}<br>"
+            "Exception:<br>{{exception_html}}<br>"
+            'Log: <a href="{{ti.log_url}}">Link</a><br>'
+            "Host: {{ti.hostname}}<br>"
+            'Mark success: <a href="{{ti.mark_success_url}}">Link</a><br>'
+        )
+
+        default_html_content_err = (
+            "Try {{try_number}} out of {{max_tries + 1}}<br>"
+            "Exception:<br>Failed attempt to attach error logs<br>"
+            'Log: <a href="{{ti.log_url}}">Link</a><br>'
+            "Host: {{ti.hostname}}<br>"
+            'Mark success: <a href="{{ti.mark_success_url}}">Link</a><br>'
+        )
+
+        additional_context: dict[str, Any] = {
+            "exception": exception,
+            "exception_html": exception_html,
+            "try_number": self.try_number,
+            "max_tries": self.max_tries,
+        }
+
+        if use_default:
+            default_context = {"ti": self, **additional_context}
+            jinja_env = jinja2.Environment(
+                loader=jinja2.FileSystemLoader(os.path.dirname(__file__)), 
autoescape=True
+            )
+            subject = 
jinja_env.from_string(default_subject).render(**default_context)
+            html_content = 
jinja_env.from_string(default_html_content).render(**default_context)
+            html_content_err = 
jinja_env.from_string(default_html_content_err).render(**default_context)
+
+        else:
+            from airflow.sdk.definitions._internal.templater import 
SandboxedEnvironment
+            from airflow.utils.context import context_merge
+
+            if TYPE_CHECKING:
+                assert self.task
+
+            # Use the DAG's get_template_env() to set force_sandboxed. Don't 
add
+            # the flag to the function on task object -- that function can be
+            # overridden, and adding a flag breaks backward compatibility.
+            dag = self.task.get_dag()
+            if dag:
+                jinja_env = dag.get_template_env(force_sandboxed=True)
+            else:
+                jinja_env = SandboxedEnvironment(cache_size=0)
+            jinja_context = self.get_template_context()
+            context_merge(jinja_context, additional_context)
+
+            def render(key: str, content: str) -> str:
+                if conf.has_option("email", key):
+                    path = conf.get_mandatory_value("email", key)
+                    try:
+                        with open(path) as f:
+                            content = f.read()
+                    except FileNotFoundError:
+                        log.warning("Could not find email template file '%s'. 
Using defaults...", path)
+                    except OSError:
+                        log.exception("Error while using email template %s. 
Using defaults...", path)

Review Comment:
   ## Clear-text logging of sensitive information
   
   This expression logs [sensitive data (secret)](1) as clear text.
   This expression logs [sensitive data (secret)](2) as clear text.
   
   [Show more 
details](https://github.com/apache/airflow/security/code-scanning/467)



##########
airflow-core/src/airflow/models/taskinstance.py:
##########
@@ -3174,7 +2757,83 @@
         :param exception: the exception sent in the email
         :param task:
         """
-        return _get_email_subject_content(task_instance=self, 
exception=exception, task=task)
+        # For a ti from DB (without ti.task), return the default value
+        if task is None:
+            task = getattr(self, "task")
+        use_default = task is None
+        exception_html = str(exception).replace("\n", "<br>")
+
+        default_subject = "Airflow alert: {{ti}}"
+        # For reporting purposes, we report based on 1-indexed,
+        # not 0-indexed lists (i.e. Try 1 instead of
+        # Try 0 for the first attempt).
+        default_html_content = (
+            "Try {{try_number}} out of {{max_tries + 1}}<br>"
+            "Exception:<br>{{exception_html}}<br>"
+            'Log: <a href="{{ti.log_url}}">Link</a><br>'
+            "Host: {{ti.hostname}}<br>"
+            'Mark success: <a href="{{ti.mark_success_url}}">Link</a><br>'
+        )
+
+        default_html_content_err = (
+            "Try {{try_number}} out of {{max_tries + 1}}<br>"
+            "Exception:<br>Failed attempt to attach error logs<br>"
+            'Log: <a href="{{ti.log_url}}">Link</a><br>'
+            "Host: {{ti.hostname}}<br>"
+            'Mark success: <a href="{{ti.mark_success_url}}">Link</a><br>'
+        )
+
+        additional_context: dict[str, Any] = {
+            "exception": exception,
+            "exception_html": exception_html,
+            "try_number": self.try_number,
+            "max_tries": self.max_tries,
+        }
+
+        if use_default:
+            default_context = {"ti": self, **additional_context}
+            jinja_env = jinja2.Environment(
+                loader=jinja2.FileSystemLoader(os.path.dirname(__file__)), 
autoescape=True
+            )
+            subject = 
jinja_env.from_string(default_subject).render(**default_context)
+            html_content = 
jinja_env.from_string(default_html_content).render(**default_context)
+            html_content_err = 
jinja_env.from_string(default_html_content_err).render(**default_context)
+
+        else:
+            from airflow.sdk.definitions._internal.templater import 
SandboxedEnvironment
+            from airflow.utils.context import context_merge
+
+            if TYPE_CHECKING:
+                assert self.task
+
+            # Use the DAG's get_template_env() to set force_sandboxed. Don't 
add
+            # the flag to the function on task object -- that function can be
+            # overridden, and adding a flag breaks backward compatibility.
+            dag = self.task.get_dag()
+            if dag:
+                jinja_env = dag.get_template_env(force_sandboxed=True)
+            else:
+                jinja_env = SandboxedEnvironment(cache_size=0)
+            jinja_context = self.get_template_context()
+            context_merge(jinja_context, additional_context)
+
+            def render(key: str, content: str) -> str:
+                if conf.has_option("email", key):
+                    path = conf.get_mandatory_value("email", key)
+                    try:
+                        with open(path) as f:
+                            content = f.read()
+                    except FileNotFoundError:
+                        log.warning("Could not find email template file '%s'. 
Using defaults...", path)

Review Comment:
   ## Clear-text logging of sensitive information
   
   This expression logs [sensitive data (secret)](1) as clear text.
   This expression logs [sensitive data (secret)](2) as clear text.
   
   [Show more 
details](https://github.com/apache/airflow/security/code-scanning/466)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@airflow.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to