This is an automated email from the ASF dual-hosted git repository.
ephraimanierobi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new f18f48492d Validating provider description for urls in provider list
view (#40475)
f18f48492d is described below
commit f18f48492dc69f392e45567580b6ddb0c070ea58
Author: Amogh Desai <[email protected]>
AuthorDate: Fri Jun 28 17:10:56 2024 +0530
Validating provider description for urls in provider list view (#40475)
* Validating provider description for urls in provider list view
* adding unit tests
---------
Co-authored-by: adesai <[email protected]>
---
airflow/www/views.py | 9 ++++++++-
tests/www/views/test_views.py | 33 +++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/airflow/www/views.py b/airflow/www/views.py
index 5f07243ef5..229f1582ae 100644
--- a/airflow/www/views.py
+++ b/airflow/www/views.py
@@ -36,7 +36,7 @@ from functools import cached_property
from json import JSONDecodeError
from pathlib import Path
from typing import TYPE_CHECKING, Any, Collection, Iterator, Mapping,
MutableMapping, Sequence
-from urllib.parse import unquote, urlencode, urljoin, urlsplit
+from urllib.parse import unquote, urlencode, urljoin, urlparse, urlsplit
import configupdater
import flask.json
@@ -4514,6 +4514,13 @@ class ProviderView(AirflowBaseView):
def _build_link(match_obj):
text = match_obj.group(1)
url = match_obj.group(2)
+
+ # parsing the url to check if ita a valid url
+ parsed_url = urlparse(url)
+ if not (parsed_url.scheme == "http" or parsed_url.scheme ==
"https"):
+ # returning the original raw text
+ return escape(match_obj.group(0))
+
return Markup(f'<a href="{url}">{text}</a>')
cd = escape(description)
diff --git a/tests/www/views/test_views.py b/tests/www/views/test_views.py
index 067f556bb7..4c8ccdc0a8 100644
--- a/tests/www/views/test_views.py
+++ b/tests/www/views/test_views.py
@@ -23,6 +23,7 @@ from unittest import mock
from unittest.mock import patch
import pytest
+from markupsafe import Markup
from airflow import __version__ as airflow_version
from airflow.configuration import (
@@ -33,6 +34,7 @@ from airflow.configuration import (
from airflow.plugins_manager import AirflowPlugin, EntryPointSource
from airflow.utils.task_group import TaskGroup
from airflow.www.views import (
+ ProviderView,
build_scarf_url,
get_key_paths,
get_safe_url,
@@ -142,6 +144,37 @@ def
test_should_list_providers_on_page_with_details(admin_client):
check_content_in_response("Providers", resp)
[email protected](
+ "provider_description, expected",
+ [
+ ("`Airbyte <https://airbyte.com/>`__", Markup('<a
href="https://airbyte.com/">Airbyte</a>')),
+ (
+ "Amazon integration (including `Amazon Web Services (AWS)
<https://aws.amazon.com/>`__).",
+ Markup(
+ 'Amazon integration (including <a
href="https://aws.amazon.com/">Amazon Web Services ('
+ "AWS)</a>)."
+ ),
+ ),
+ (
+ "`Java Database Connectivity (JDBC)
<https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc"
+ "/>`__",
+ Markup(
+ '<a
href="https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/">Java '
+ "Database Connectivity (JDBC)</a>"
+ ),
+ ),
+ (
+ "`click me <javascript:prompt(document.domain)>`__",
+ Markup("`click me <javascript:prompt(document.domain)>`__"),
+ ),
+ ],
+)
+def test__clean_description(admin_client, provider_description, expected):
+ p = ProviderView()
+ actual = p._clean_description(provider_description)
+ assert actual == expected
+
+
def test_endpoint_should_not_be_unauthenticated(app):
resp = app.test_client().get("/provider", follow_redirects=True)
check_content_not_in_response("Providers", resp)