potiuk commented on code in PR #34317:
URL: https://github.com/apache/airflow/pull/34317#discussion_r1359507417


##########
airflow/api_connexion/security.py:
##########
@@ -48,10 +61,194 @@ def requires_access_decorator(func: T):
         @wraps(func)
         def decorated(*args, **kwargs):
             check_authentication()
-            if appbuilder.sm.check_authorization(permissions, 
kwargs.get("dag_id")):
+            if appbuilder.sm.check_authorization(permissions):
                 return func(*args, **kwargs)
             raise PermissionDenied()
 
         return cast(T, decorated)
 
     return requires_access_decorator
+
+
+def _requires_access(*, is_authorized_callback: Callable[[], bool], func: 
Callable, args, kwargs) -> bool:
+    """
+    Define the behavior whether the user is authorized to access the resource.
+
+    :param is_authorized_callback: callback to execute to figure whether the 
user is authorized to access
+        the resource
+    :param func: the function to call if the user is authorized
+    :param args: the arguments of ``func``
+    :param kwargs: the keyword arguments ``func``
+
+    :meta private:
+    """
+    check_authentication()
+    if is_authorized_callback():
+        return func(*args, **kwargs)
+    raise PermissionDenied()
+
+
+def requires_authentication(func: T):
+    """Decorator for functions that require authentication."""
+
+    @wraps(func)
+    def decorated(*args, **kwargs):
+        check_authentication()
+        return func(*args, **kwargs)
+
+    return cast(T, decorated)
+
+
+def requires_access_configuration(method: ResourceMethod) -> Callable[[T], T]:
+    def requires_access_decorator(func: T):
+        @wraps(func)
+        def decorated(*args, **kwargs):
+            section: str | None = kwargs.get("section")
+            return _requires_access(
+                is_authorized_callback=lambda: 
get_auth_manager().is_authorized_configuration(
+                    method=method, 
details=ConfigurationDetails(section=section)
+                ),
+                func=func,
+                args=args,
+                kwargs=kwargs,
+            )
+
+        return cast(T, decorated)
+
+    return requires_access_decorator
+
+
+def requires_access_connection(method: ResourceMethod) -> Callable[[T], T]:
+    def requires_access_decorator(func: T):
+        @wraps(func)
+        def decorated(*args, **kwargs):
+            connection_id: str | None = kwargs.get("connection_id")
+            return _requires_access(
+                is_authorized_callback=lambda: 
get_auth_manager().is_authorized_connection(
+                    method=method, 
details=ConnectionDetails(conn_id=connection_id)
+                ),
+                func=func,
+                args=args,
+                kwargs=kwargs,
+            )
+
+        return cast(T, decorated)
+
+    return requires_access_decorator
+
+
+def requires_access_dag(
+    method: ResourceMethod, access_entity: DagAccessEntity | None = None
+) -> Callable[[T], T]:
+    appbuilder = get_airflow_app().appbuilder
+
+    def _is_authorized_callback(dag_id: str):
+        def callback():
+            access = get_auth_manager().is_authorized_dag(
+                method=method,
+                access_entity=access_entity,
+                details=DagDetails(id=dag_id),
+            )
+
+            # ``access`` means here:
+            # - if a DAG id is provided (``dag_id`` not None): is the user 
authorized to access this DAG
+            # - if no DAG id is provided: is the user authorized to access all 
DAGs
+            if dag_id or access:
+                return access
+
+            # No DAG id is provided and the user is not authorized to access 
all DAGs
+            # If method is "GET", return whether the user has read access to 
any DAGs
+            # If method is "PUT", return whether the user has edit access to 
any DAGs
+            return (method == "GET" and 
any(appbuilder.sm.get_readable_dag_ids())) or (

Review Comment:
   Also that plays nice with actually having "get_readable_dag_ids" as separate 
method (and default implementation involving iterating over all dags and 
individually checking if it has access - see the 
https://github.com/apache/airflow/pull/34317#discussion_r1355994191 



-- 
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