Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use batch_is_authorized_dag to check if user has permission to read DAGs #36279

Merged
merged 2 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions airflow/api_connexion/endpoints/dag_source_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,25 @@
from __future__ import annotations

from http import HTTPStatus
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Sequence

from flask import Response, current_app, request
from itsdangerous import BadSignature, URLSafeSerializer

from airflow.api_connexion import security
from airflow.api_connexion.exceptions import NotFound, PermissionDenied
from airflow.api_connexion.schemas.dag_source_schema import dag_source_schema
from airflow.api_connexion.security import get_readable_dags
from airflow.auth.managers.models.resource_details import DagAccessEntity
from airflow.auth.managers.models.resource_details import DagAccessEntity, DagDetails
from airflow.models.dag import DagModel
from airflow.models.dagcode import DagCode
from airflow.utils.session import NEW_SESSION, provide_session
from airflow.www.extensions.init_auth_manager import get_auth_manager

if TYPE_CHECKING:
from sqlalchemy.orm import Session

from airflow.auth.managers.models.batch_apis import IsAuthorizedDagRequest


@security.requires_access_dag("GET", DagAccessEntity.CODE)
@provide_session
Expand All @@ -44,9 +46,16 @@ def get_dag_source(*, file_token: str, session: Session = NEW_SESSION) -> Respon
try:
path = auth_s.loads(file_token)
dag_ids = session.query(DagModel.dag_id).filter(DagModel.fileloc == path).all()
readable_dags = get_readable_dags()
requests: Sequence[IsAuthorizedDagRequest] = [
{
"method": "GET",
"details": DagDetails(id=dag_id[0]),
}
for dag_id in dag_ids
]

# Check if user has read access to all the DAGs defined in the file
if any(dag_id[0] not in readable_dags for dag_id in dag_ids):
if not get_auth_manager().batch_is_authorized_dag(requests):
raise PermissionDenied()
dag_source = DagCode.code(path, session=session)
except (BadSignature, FileNotFoundError):
Expand Down
2 changes: 1 addition & 1 deletion generated/provider_dependencies.json
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@
"asgiref>=3.5.2",
"gcloud-aio-auth>=4.0.0,<5.0.0",
"gcloud-aio-bigquery>=6.1.2",
"gcloud-aio-storage",
"gcloud-aio-storage>=9.0.0",
Copy link
Contributor Author

@vincbeck vincbeck Dec 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No idea why this file has been modified

"gcsfs>=2023.10.0",
"google-ads>=22.1.0",
"google-api-core>=2.11.0",
Expand Down