diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 360859776..c9effb503 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,13 +1,21 @@ Changelog ========= -1.7.1a1 (2024-10-24) + +1.7.1a3 (2024-10-24) -------------------- -Others +Bug fixes + +* Fix displaying dbt docs as menu item in Astro by @tatiana in #1280 -* Fix release to PyPI after rst directive disabled by @tatiana in #1281 +Docs + +* Update the URL for sample dbt docs hosted in Astronomer S3 bucket by @pankajkoti in #1283 + +Others +* Fix release after the raw rst directive disabled was disabled in PyPI by @tatiana in #1282 1.7.0 (2024-10-04) diff --git a/cosmos/__init__.py b/cosmos/__init__.py index 4c2abb664..84d522e81 100644 --- a/cosmos/__init__.py +++ b/cosmos/__init__.py @@ -6,7 +6,7 @@ Contains dags, task groups, and operators. """ -__version__ = "1.7.1a1" +__version__ = "1.7.1a3" from cosmos.airflow.dag import DbtDag diff --git a/cosmos/plugin/__init__.py b/cosmos/plugin/__init__.py index ff4d8e817..8ca93926c 100644 --- a/cosmos/plugin/__init__.py +++ b/cosmos/plugin/__init__.py @@ -2,6 +2,7 @@ from typing import Any, Dict, Optional, Tuple from urllib.parse import urlsplit +from airflow.configuration import conf from airflow.plugins_manager import AirflowPlugin from airflow.security import permissions from airflow.www.auth import has_access @@ -200,14 +201,24 @@ def create_blueprint( return super().create_blueprint(appbuilder, endpoint=endpoint, static_folder=self.static_folder) # type: ignore[no-any-return] @expose("/dbt_docs") # type: ignore[misc] - @has_access([(permissions.ACTION_CAN_READ, permissions.RESOURCE_WEBSITE)]) + @has_access( + [ + (permissions.ACTION_CAN_ACCESS_MENU, "Custom Menu"), + (permissions.ACTION_CAN_READ, permissions.RESOURCE_WEBSITE), + ] + ) def dbt_docs(self) -> str: if dbt_docs_dir is None: return self.render_template("dbt_docs_not_set_up.html") # type: ignore[no-any-return,no-untyped-call] return self.render_template("dbt_docs.html") # type: ignore[no-any-return,no-untyped-call] @expose("/dbt_docs_index.html") # type: ignore[misc] - @has_access([(permissions.ACTION_CAN_READ, permissions.RESOURCE_WEBSITE)]) + @has_access( + [ + (permissions.ACTION_CAN_ACCESS_MENU, "Custom Menu"), + (permissions.ACTION_CAN_READ, permissions.RESOURCE_WEBSITE), + ] + ) def dbt_docs_index(self) -> Tuple[str, int, Dict[str, Any]]: if dbt_docs_dir is None: abort(404) @@ -222,7 +233,12 @@ def dbt_docs_index(self) -> Tuple[str, int, Dict[str, Any]]: return html, 200, {"Content-Security-Policy": "frame-ancestors 'self'"} @expose("/catalog.json") # type: ignore[misc] - @has_access([(permissions.ACTION_CAN_READ, permissions.RESOURCE_WEBSITE)]) + @has_access( + [ + (permissions.ACTION_CAN_ACCESS_MENU, "Custom Menu"), + (permissions.ACTION_CAN_READ, permissions.RESOURCE_WEBSITE), + ] + ) def catalog(self) -> Tuple[str, int, Dict[str, Any]]: if dbt_docs_dir is None: abort(404) @@ -234,7 +250,12 @@ def catalog(self) -> Tuple[str, int, Dict[str, Any]]: return data, 200, {"Content-Type": "application/json"} @expose("/manifest.json") # type: ignore[misc] - @has_access([(permissions.ACTION_CAN_READ, permissions.RESOURCE_WEBSITE)]) + @has_access( + [ + (permissions.ACTION_CAN_ACCESS_MENU, "Custom Menu"), + (permissions.ACTION_CAN_READ, permissions.RESOURCE_WEBSITE), + ] + ) def manifest(self) -> Tuple[str, int, Dict[str, Any]]: if dbt_docs_dir is None: abort(404) @@ -251,4 +272,10 @@ def manifest(self) -> Tuple[str, int, Dict[str, Any]]: class CosmosPlugin(AirflowPlugin): name = "cosmos" - appbuilder_views = [{"name": "dbt Docs", "category": "Browse", "view": dbt_docs_view}] + item = { + "name": "dbt Docs", + "category": "Browse", + "view": dbt_docs_view, + "href": conf.get("webserver", "base_url") + "/cosmos/dbt_docs", + } + appbuilder_views = [item] diff --git a/tests/plugin/test_plugin.py b/tests/plugin/test_plugin.py index 04dc39cd8..e8812b56a 100644 --- a/tests/plugin/test_plugin.py +++ b/tests/plugin/test_plugin.py @@ -303,3 +303,14 @@ def test_open_file_local(mock_file): res = open_file("/my/path") mock_file.assert_called_with("/my/path") assert res == "mock file contents" + + +@pytest.mark.integration +@pytest.mark.parametrize( + "url_path", ["/cosmos/dbt_docs", "/cosmos/dbt_docs_index.html", "/cosmos/catalog.json", "/cosmos/manifest.json"] +) +def test_has_access_with_permissions(url_path, app): + dbt_docs_view.appbuilder.sm.check_authorization = MagicMock() + mock_check_auth = dbt_docs_view.appbuilder.sm.check_authorization + app.get(url_path) + assert mock_check_auth.call_args[0][0] == [("menu_access", "Custom Menu"), ("can_read", "Website")]