This is an automated email from the ASF dual-hosted git repository.

eladkal 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 12a760f6df Affix webserver access_denied warning to be configurable 
(#33022)
12a760f6df is described below

commit 12a760f6df831c1d53d035e4d169a69887e8bb26
Author: Amogh Desai <[email protected]>
AuthorDate: Thu Aug 3 14:34:31 2023 +0530

    Affix webserver access_denied warning to be configurable (#33022)
    
    * Affix webserver access_denied warning to be configurable
---
 airflow/config_templates/config.yml |  7 +++++++
 airflow/www/auth.py                 |  6 +++++-
 tests/www/test_security.py          | 18 ++++++++++++++++++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/airflow/config_templates/config.yml 
b/airflow/config_templates/config.yml
index b550c25932..6cd249a9ce 100644
--- a/airflow/config_templates/config.yml
+++ b/airflow/config_templates/config.yml
@@ -1349,6 +1349,13 @@ operators:
 webserver:
   description: ~
   options:
+    access_denied_message:
+      description: |
+        The message displayed when a user attempts to execute actions beyond 
their authorised privileges.
+      version_added: 2.7.0
+      type: string
+      example: ~
+      default: "Access is Denied"
     config_file:
       description: |
         Path of webserver config file used for configuring the webserver 
parameters
diff --git a/airflow/www/auth.py b/airflow/www/auth.py
index 9afe995054..f4cb53886e 100644
--- a/airflow/www/auth.py
+++ b/airflow/www/auth.py
@@ -28,6 +28,10 @@ from airflow.www.extensions.init_auth_manager import 
get_auth_manager
 T = TypeVar("T", bound=Callable)
 
 
+def get_access_denied_message():
+    return conf.get("webserver", "access_denied_message")
+
+
 def has_access(permissions: Sequence[tuple[str, str]] | None = None) -> 
Callable[[T], T]:
     """Factory for decorator that checks current user's permissions against 
required permissions."""
 
@@ -59,7 +63,7 @@ def has_access(permissions: Sequence[tuple[str, str]] | None 
= None) -> Callable
                     403,
                 )
             else:
-                access_denied = "Access is Denied"
+                access_denied = get_access_denied_message()
                 flash(access_denied, "danger")
             return redirect(get_auth_manager().get_url_login(next=request.url))
 
diff --git a/tests/www/test_security.py b/tests/www/test_security.py
index 99659de2c7..dec262f25f 100644
--- a/tests/www/test_security.py
+++ b/tests/www/test_security.py
@@ -20,6 +20,7 @@ from __future__ import annotations
 import contextlib
 import datetime
 import logging
+import os
 from unittest import mock
 from unittest.mock import patch
 
@@ -32,12 +33,14 @@ from sqlalchemy import Column, Date, Float, Integer, String
 from airflow.auth.managers.fab.auth.anonymous_user import AnonymousUser
 from airflow.auth.managers.fab.fab_auth_manager import FabAuthManager
 from airflow.auth.managers.fab.models import User, assoc_permission_role
+from airflow.configuration import initialize_config
 from airflow.exceptions import AirflowException
 from airflow.models import DagModel
 from airflow.models.base import Base
 from airflow.models.dag import DAG
 from airflow.security import permissions
 from airflow.www import app as application
+from airflow.www.auth import get_access_denied_message
 from airflow.www.utils import CustomSQLAInterface
 from tests.test_utils.api_connexion_utils import (
     create_user,
@@ -969,3 +972,18 @@ def test_users_can_be_found(app, security_manager, 
session, caplog):
     assert len(users) == 1
     delete_user(app, "Test")
     assert "Error adding new user to database" in caplog.text
+
+
+def test_default_access_denied_message():
+    initialize_config()
+    assert get_access_denied_message() == "Access is Denied"
+
+
+def test_custom_access_denied_message():
+    with mock.patch.dict(
+        os.environ,
+        {"AIRFLOW__WEBSERVER__ACCESS_DENIED_MESSAGE": "My custom access denied 
message"},
+        clear=True,
+    ):
+        initialize_config()
+        assert get_access_denied_message() == "My custom access denied message"

Reply via email to