Skip to content

Commit 4a15ac1

Browse files
pierrejeambrunLee-W
authored andcommitted
AIP-84 Add Auth to plugins (apache#47504)
* AIP-84 Add Auth to plugins * Better return type * fix: fix import path change --------- Co-authored-by: Wei Lee <[email protected]>
1 parent 610b06b commit 4a15ac1

File tree

4 files changed

+34
-2
lines changed

4 files changed

+34
-2
lines changed

airflow/api_fastapi/core_api/openapi/v1-generated.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4078,6 +4078,8 @@ paths:
40784078
- Plugin
40794079
summary: Get Plugins
40804080
operationId: get_plugins
4081+
security:
4082+
- OAuth2PasswordBearer: []
40814083
parameters:
40824084
- name: limit
40834085
in: query

airflow/api_fastapi/core_api/routes/public/plugins.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,22 @@
1919

2020
from typing import cast
2121

22+
from fastapi import Depends
23+
24+
from airflow.api_fastapi.auth.managers.models.resource_details import AccessView
2225
from airflow.api_fastapi.common.parameters import QueryLimit, QueryOffset
2326
from airflow.api_fastapi.common.router import AirflowRouter
2427
from airflow.api_fastapi.core_api.datamodels.plugins import PluginCollectionResponse, PluginResponse
28+
from airflow.api_fastapi.core_api.security import requires_access_view
2529
from airflow.plugins_manager import get_plugin_info
2630

2731
plugins_router = AirflowRouter(tags=["Plugin"], prefix="/plugins")
2832

2933

30-
@plugins_router.get("")
34+
@plugins_router.get(
35+
"",
36+
dependencies=[Depends(requires_access_view(AccessView.PLUGINS))],
37+
)
3138
def get_plugins(
3239
limit: QueryLimit,
3340
offset: QueryOffset,

airflow/api_fastapi/core_api/security.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from airflow.api_fastapi.app import get_auth_manager
2727
from airflow.api_fastapi.auth.managers.models.base_user import BaseUser
2828
from airflow.api_fastapi.auth.managers.models.resource_details import (
29+
AccessView,
2930
AssetAliasDetails,
3031
AssetDetails,
3132
ConfigurationDetails,
@@ -177,6 +178,20 @@ def inner(
177178
return inner
178179

179180

181+
def requires_access_view(access_view: AccessView) -> Callable[[Request, BaseUser | None], None]:
182+
def inner(
183+
request: Request,
184+
user: Annotated[BaseUser | None, Depends(get_user)] = None,
185+
) -> None:
186+
_requires_access(
187+
is_authorized_callback=lambda: get_auth_manager().is_authorized_view(
188+
access_view=access_view, user=user
189+
),
190+
)
191+
192+
return inner
193+
194+
180195
def requires_access_asset_alias(method: ResourceMethod) -> Callable:
181196
def inner(
182197
request: Request,

tests/api_fastapi/core_api/routes/public/test_plugins.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
pytestmark = pytest.mark.db_test
2222

2323

24-
class TestGetConnections:
24+
class TestGetPlugins:
2525
@pytest.mark.parametrize(
2626
"query_params, expected_total_entries, expected_names",
2727
[
@@ -62,3 +62,11 @@ def test_should_respond_200(
6262
body = response.json()
6363
assert body["total_entries"] == expected_total_entries
6464
assert [plugin["name"] for plugin in body["plugins"]] == expected_names
65+
66+
def test_should_response_401(self, unauthenticated_test_client):
67+
response = unauthenticated_test_client.get("/public/plugins")
68+
assert response.status_code == 401
69+
70+
def test_should_response_403(self, unauthorized_test_client):
71+
response = unauthorized_test_client.get("/public/plugins")
72+
assert response.status_code == 403

0 commit comments

Comments
 (0)