apache-airflow-providers-fab 1.4.1rc1__tar.gz → 1.5.0rc1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/PKG-INFO +10 -10
  2. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/README.rst +5 -5
  3. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/__init__.py +1 -1
  4. apache_airflow_providers_fab-1.5.0rc1/airflow/providers/fab/auth_manager/api/auth/backend/session.py +47 -0
  5. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/api_endpoints/role_and_permission_endpoint.py +3 -3
  6. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/api_endpoints/user_endpoint.py +3 -3
  7. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/fab_auth_manager.py +1 -4
  8. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/models/db.py +4 -5
  9. apache_airflow_providers_fab-1.5.0rc1/airflow/providers/fab/auth_manager/schemas/role_and_permission_schema.py +103 -0
  10. apache_airflow_providers_fab-1.5.0rc1/airflow/providers/fab/auth_manager/schemas/user_schema.py +73 -0
  11. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/security_manager/override.py +11 -8
  12. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/get_provider_info.py +4 -3
  13. apache_airflow_providers_fab-1.5.0rc1/airflow/providers/fab/migrations/versions/__init__.py +16 -0
  14. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/pyproject.toml +5 -5
  15. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/LICENSE +0 -0
  16. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/alembic.ini +0 -0
  17. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/__init__.py +0 -0
  18. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/api/__init__.py +0 -0
  19. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/api/auth/__init__.py +0 -0
  20. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/api/auth/backend/__init__.py +0 -0
  21. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/api/auth/backend/basic_auth.py +0 -0
  22. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/api/auth/backend/kerberos_auth.py +0 -0
  23. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/api_endpoints/__init__.py +0 -0
  24. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/cli_commands/__init__.py +0 -0
  25. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/cli_commands/db_command.py +0 -0
  26. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/cli_commands/definition.py +0 -0
  27. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/cli_commands/role_command.py +0 -0
  28. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/cli_commands/sync_perm_command.py +0 -0
  29. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/cli_commands/user_command.py +0 -0
  30. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/cli_commands/utils.py +0 -0
  31. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/decorators/__init__.py +0 -0
  32. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/decorators/auth.py +0 -0
  33. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/models/__init__.py +0 -0
  34. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/models/anonymous_user.py +0 -0
  35. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/openapi/__init__.py +0 -0
  36. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/openapi/v1.yaml +0 -0
  37. {apache_airflow_providers_fab-1.4.1rc1/airflow/providers/fab/auth_manager/views → apache_airflow_providers_fab-1.5.0rc1/airflow/providers/fab/auth_manager/schemas}/__init__.py +0 -0
  38. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/security_manager/__init__.py +0 -0
  39. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/security_manager/constants.py +0 -0
  40. {apache_airflow_providers_fab-1.4.1rc1/airflow/providers/fab/migrations → apache_airflow_providers_fab-1.5.0rc1/airflow/providers/fab/auth_manager/views}/__init__.py +0 -0
  41. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/views/permissions.py +0 -0
  42. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/views/roles_list.py +0 -0
  43. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/views/user.py +0 -0
  44. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/views/user_edit.py +0 -0
  45. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/auth_manager/views/user_stats.py +0 -0
  46. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/migrations/README +0 -0
  47. {apache_airflow_providers_fab-1.4.1rc1/airflow/providers/fab/migrations/versions → apache_airflow_providers_fab-1.5.0rc1/airflow/providers/fab/migrations}/__init__.py +0 -0
  48. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/migrations/env.py +0 -0
  49. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/migrations/script.py.mako +0 -0
  50. {apache_airflow_providers_fab-1.4.1rc1 → apache_airflow_providers_fab-1.5.0rc1}/airflow/providers/fab/migrations/versions/0001_1_4_0_placeholder_migration.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: apache-airflow-providers-fab
3
- Version: 1.4.1rc1
3
+ Version: 1.5.0rc1
4
4
  Summary: Provider package apache-airflow-providers-fab for Apache Airflow
5
5
  Keywords: airflow-provider,fab,airflow,integration
6
6
  Author-email: Apache Software Foundation <dev@airflow.apache.org>
@@ -20,9 +20,9 @@ Classifier: Programming Language :: Python :: 3.10
20
20
  Classifier: Programming Language :: Python :: 3.11
21
21
  Classifier: Programming Language :: Python :: 3.12
22
22
  Classifier: Topic :: System :: Monitoring
23
- Requires-Dist: apache-airflow-providers-common-compat>=1.2.0rc0
23
+ Requires-Dist: apache-airflow-providers-common-compat>=1.2.1rc0
24
24
  Requires-Dist: apache-airflow>=2.9.0rc0
25
- Requires-Dist: flask-appbuilder==4.5.0
25
+ Requires-Dist: flask-appbuilder==4.5.2
26
26
  Requires-Dist: flask-login>=0.6.2
27
27
  Requires-Dist: flask>=2.2,<2.3
28
28
  Requires-Dist: google-re2>=1.0
@@ -30,8 +30,8 @@ Requires-Dist: jmespath>=0.7.0
30
30
  Requires-Dist: apache-airflow-providers-common-compat ; extra == "common.compat"
31
31
  Requires-Dist: kerberos>=1.3.0 ; extra == "kerberos"
32
32
  Project-URL: Bug Tracker, https://github.com/apache/airflow/issues
33
- Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-fab/1.4.1/changelog.html
34
- Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-fab/1.4.1
33
+ Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-fab/1.5.0/changelog.html
34
+ Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-fab/1.5.0
35
35
  Project-URL: Slack Chat, https://s.apache.org/airflow-slack
36
36
  Project-URL: Source Code, https://github.com/apache/airflow
37
37
  Project-URL: Twitter, https://twitter.com/ApacheAirflow
@@ -83,7 +83,7 @@ Provides-Extra: kerberos
83
83
 
84
84
  Package ``apache-airflow-providers-fab``
85
85
 
86
- Release: ``1.4.1.rc1``
86
+ Release: ``1.5.0.rc1``
87
87
 
88
88
 
89
89
  `Flask App Builder <https://flask-appbuilder.readthedocs.io/>`__
@@ -96,7 +96,7 @@ This is a provider package for ``fab`` provider. All classes for this provider p
96
96
  are in ``airflow.providers.fab`` python package.
97
97
 
98
98
  You can find package information and changelog for the provider
99
- in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-fab/1.4.1/>`_.
99
+ in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-fab/1.5.0/>`_.
100
100
 
101
101
  Installation
102
102
  ------------
@@ -114,9 +114,9 @@ Requirements
114
114
  PIP package Version required
115
115
  ========================================== ==================
116
116
  ``apache-airflow`` ``>=2.9.0``
117
- ``apache-airflow-providers-common-compat`` ``>=1.2.0``
117
+ ``apache-airflow-providers-common-compat`` ``>=1.2.1``
118
118
  ``flask`` ``>=2.2,<2.3``
119
- ``flask-appbuilder`` ``==4.5.0``
119
+ ``flask-appbuilder`` ``==4.5.2``
120
120
  ``flask-login`` ``>=0.6.2``
121
121
  ``google-re2`` ``>=1.0``
122
122
  ``jmespath`` ``>=0.7.0``
@@ -142,4 +142,4 @@ Dependent package
142
142
  ================================================================================================================== =================
143
143
 
144
144
  The changelog for the provider package can be found in the
145
- `changelog <https://airflow.apache.org/docs/apache-airflow-providers-fab/1.4.1/changelog.html>`_.
145
+ `changelog <https://airflow.apache.org/docs/apache-airflow-providers-fab/1.5.0/changelog.html>`_.
@@ -42,7 +42,7 @@
42
42
 
43
43
  Package ``apache-airflow-providers-fab``
44
44
 
45
- Release: ``1.4.1.rc1``
45
+ Release: ``1.5.0.rc1``
46
46
 
47
47
 
48
48
  `Flask App Builder <https://flask-appbuilder.readthedocs.io/>`__
@@ -55,7 +55,7 @@ This is a provider package for ``fab`` provider. All classes for this provider p
55
55
  are in ``airflow.providers.fab`` python package.
56
56
 
57
57
  You can find package information and changelog for the provider
58
- in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-fab/1.4.1/>`_.
58
+ in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-fab/1.5.0/>`_.
59
59
 
60
60
  Installation
61
61
  ------------
@@ -73,9 +73,9 @@ Requirements
73
73
  PIP package Version required
74
74
  ========================================== ==================
75
75
  ``apache-airflow`` ``>=2.9.0``
76
- ``apache-airflow-providers-common-compat`` ``>=1.2.0``
76
+ ``apache-airflow-providers-common-compat`` ``>=1.2.1``
77
77
  ``flask`` ``>=2.2,<2.3``
78
- ``flask-appbuilder`` ``==4.5.0``
78
+ ``flask-appbuilder`` ``==4.5.2``
79
79
  ``flask-login`` ``>=0.6.2``
80
80
  ``google-re2`` ``>=1.0``
81
81
  ``jmespath`` ``>=0.7.0``
@@ -101,4 +101,4 @@ Dependent package
101
101
  ================================================================================================================== =================
102
102
 
103
103
  The changelog for the provider package can be found in the
104
- `changelog <https://airflow.apache.org/docs/apache-airflow-providers-fab/1.4.1/changelog.html>`_.
104
+ `changelog <https://airflow.apache.org/docs/apache-airflow-providers-fab/1.5.0/changelog.html>`_.
@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
29
29
 
30
30
  __all__ = ["__version__"]
31
31
 
32
- __version__ = "1.4.1"
32
+ __version__ = "1.5.0"
33
33
 
34
34
  if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
35
35
  "2.9.0"
@@ -0,0 +1,47 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The ASF licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+ """Session authentication backend."""
18
+
19
+ from __future__ import annotations
20
+
21
+ from functools import wraps
22
+ from typing import Any, Callable, TypeVar, cast
23
+
24
+ from flask import Response
25
+
26
+ from airflow.www.extensions.init_auth_manager import get_auth_manager
27
+
28
+ CLIENT_AUTH: tuple[str, str] | Any | None = None
29
+
30
+
31
+ def init_app(_):
32
+ """Initialize authentication backend."""
33
+
34
+
35
+ T = TypeVar("T", bound=Callable)
36
+
37
+
38
+ def requires_authentication(function: T):
39
+ """Decorate functions that require authentication."""
40
+
41
+ @wraps(function)
42
+ def decorated(*args, **kwargs):
43
+ if not get_auth_manager().is_logged_in():
44
+ return Response("Unauthorized", 401, {})
45
+ return function(*args, **kwargs)
46
+
47
+ return cast(T, decorated)
@@ -26,15 +26,15 @@ from sqlalchemy import asc, desc, func, select
26
26
 
27
27
  from airflow.api_connexion.exceptions import AlreadyExists, BadRequest, NotFound
28
28
  from airflow.api_connexion.parameters import check_limit, format_parameters
29
- from airflow.api_connexion.schemas.role_and_permission_schema import (
29
+ from airflow.api_connexion.security import requires_access_custom_view
30
+ from airflow.providers.fab.auth_manager.models import Action, Role
31
+ from airflow.providers.fab.auth_manager.schemas.role_and_permission_schema import (
30
32
  ActionCollection,
31
33
  RoleCollection,
32
34
  action_collection_schema,
33
35
  role_collection_schema,
34
36
  role_schema,
35
37
  )
36
- from airflow.api_connexion.security import requires_access_custom_view
37
- from airflow.providers.fab.auth_manager.models import Action, Role
38
38
  from airflow.providers.fab.auth_manager.security_manager.override import FabAirflowSecurityManagerOverride
39
39
  from airflow.security import permissions
40
40
  from airflow.www.extensions.init_auth_manager import get_auth_manager
@@ -27,14 +27,14 @@ from werkzeug.security import generate_password_hash
27
27
 
28
28
  from airflow.api_connexion.exceptions import AlreadyExists, BadRequest, NotFound, Unknown
29
29
  from airflow.api_connexion.parameters import check_limit, format_parameters
30
- from airflow.api_connexion.schemas.user_schema import (
30
+ from airflow.api_connexion.security import requires_access_custom_view
31
+ from airflow.providers.fab.auth_manager.models import User
32
+ from airflow.providers.fab.auth_manager.schemas.user_schema import (
31
33
  UserCollection,
32
34
  user_collection_item_schema,
33
35
  user_collection_schema,
34
36
  user_schema,
35
37
  )
36
- from airflow.api_connexion.security import requires_access_custom_view
37
- from airflow.providers.fab.auth_manager.models import User
38
38
  from airflow.providers.fab.auth_manager.security_manager.override import FabAirflowSecurityManagerOverride
39
39
  from airflow.security import permissions
40
40
  from airflow.www.extensions.init_auth_manager import get_auth_manager
@@ -96,10 +96,7 @@ if TYPE_CHECKING:
96
96
  from airflow.providers.fab.auth_manager.security_manager.override import FabAirflowSecurityManagerOverride
97
97
  from airflow.security.permissions import RESOURCE_ASSET
98
98
  else:
99
- try:
100
- from airflow.security.permissions import RESOURCE_ASSET
101
- except ImportError:
102
- from airflow.security.permissions import RESOURCE_DATASET as RESOURCE_ASSET
99
+ from airflow.providers.common.compat.security.permissions import RESOURCE_ASSET
103
100
 
104
101
 
105
102
  _MAP_DAG_ACCESS_ENTITY_TO_FAB_RESOURCE_TYPE: dict[DagAccessEntity, tuple[str, ...]] = {
@@ -16,16 +16,15 @@
16
16
  # under the License.
17
17
  from __future__ import annotations
18
18
 
19
- import os
19
+ from pathlib import Path
20
20
 
21
- import airflow
22
21
  from airflow import settings
23
22
  from airflow.exceptions import AirflowException
24
23
  from airflow.providers.fab.auth_manager.models import metadata
25
24
  from airflow.utils.db import _offline_migration, print_happy_cat
26
25
  from airflow.utils.db_manager import BaseDBManager
27
26
 
28
- PACKAGE_DIR = os.path.dirname(airflow.__file__)
27
+ PACKAGE_DIR = Path(__file__).parents[2]
29
28
 
30
29
  _REVISION_HEADS_MAP: dict[str, str] = {
31
30
  "1.4.0": "6709f7a774b9",
@@ -37,8 +36,8 @@ class FABDBManager(BaseDBManager):
37
36
 
38
37
  metadata = metadata
39
38
  version_table_name = "alembic_version_fab"
40
- migration_dir = os.path.join(PACKAGE_DIR, "providers/fab/migrations")
41
- alembic_file = os.path.join(PACKAGE_DIR, "providers/fab/alembic.ini")
39
+ migration_dir = (PACKAGE_DIR / "migrations").as_posix()
40
+ alembic_file = (PACKAGE_DIR / "alembic.ini").as_posix()
42
41
  supports_table_dropping = True
43
42
 
44
43
  def upgradedb(self, to_revision=None, from_revision=None, show_sql_only=False):
@@ -0,0 +1,103 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The ASF licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+ from __future__ import annotations
18
+
19
+ from typing import NamedTuple
20
+
21
+ from marshmallow import Schema, fields
22
+ from marshmallow_sqlalchemy import SQLAlchemySchema, auto_field
23
+
24
+ from airflow.providers.fab.auth_manager.models import Action, Permission, Resource, Role
25
+
26
+
27
+ class ActionSchema(SQLAlchemySchema):
28
+ """Action Schema."""
29
+
30
+ class Meta:
31
+ """Meta."""
32
+
33
+ model = Action
34
+
35
+ name = auto_field()
36
+
37
+
38
+ class ResourceSchema(SQLAlchemySchema):
39
+ """View menu Schema."""
40
+
41
+ class Meta:
42
+ """Meta."""
43
+
44
+ model = Resource
45
+
46
+ name = auto_field()
47
+
48
+
49
+ class ActionCollection(NamedTuple):
50
+ """Action Collection."""
51
+
52
+ actions: list[Action]
53
+ total_entries: int
54
+
55
+
56
+ class ActionCollectionSchema(Schema):
57
+ """Permissions list schema."""
58
+
59
+ actions = fields.List(fields.Nested(ActionSchema))
60
+ total_entries = fields.Int()
61
+
62
+
63
+ class ActionResourceSchema(SQLAlchemySchema):
64
+ """Action View Schema."""
65
+
66
+ class Meta:
67
+ """Meta."""
68
+
69
+ model = Permission
70
+
71
+ action = fields.Nested(ActionSchema, data_key="action")
72
+ resource = fields.Nested(ResourceSchema, data_key="resource")
73
+
74
+
75
+ class RoleSchema(SQLAlchemySchema):
76
+ """Role item schema."""
77
+
78
+ class Meta:
79
+ """Meta."""
80
+
81
+ model = Role
82
+
83
+ name = auto_field()
84
+ permissions = fields.List(fields.Nested(ActionResourceSchema), data_key="actions")
85
+
86
+
87
+ class RoleCollection(NamedTuple):
88
+ """List of roles."""
89
+
90
+ roles: list[Role]
91
+ total_entries: int
92
+
93
+
94
+ class RoleCollectionSchema(Schema):
95
+ """List of roles."""
96
+
97
+ roles = fields.List(fields.Nested(RoleSchema))
98
+ total_entries = fields.Int()
99
+
100
+
101
+ role_schema = RoleSchema()
102
+ role_collection_schema = RoleCollectionSchema()
103
+ action_collection_schema = ActionCollectionSchema()
@@ -0,0 +1,73 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The ASF licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+ from __future__ import annotations
18
+
19
+ from typing import NamedTuple
20
+
21
+ from marshmallow import Schema, fields
22
+ from marshmallow_sqlalchemy import SQLAlchemySchema, auto_field
23
+
24
+ from airflow.api_connexion.parameters import validate_istimezone
25
+ from airflow.providers.fab.auth_manager.models import User
26
+ from airflow.providers.fab.auth_manager.schemas.role_and_permission_schema import RoleSchema
27
+
28
+
29
+ class UserCollectionItemSchema(SQLAlchemySchema):
30
+ """user collection item schema."""
31
+
32
+ class Meta:
33
+ """Meta."""
34
+
35
+ model = User
36
+ dateformat = "iso"
37
+
38
+ first_name = auto_field()
39
+ last_name = auto_field()
40
+ username = auto_field()
41
+ active = auto_field(dump_only=True)
42
+ email = auto_field()
43
+ last_login = auto_field(dump_only=True)
44
+ login_count = auto_field(dump_only=True)
45
+ fail_login_count = auto_field(dump_only=True)
46
+ roles = fields.List(fields.Nested(RoleSchema, only=("name",)))
47
+ created_on = auto_field(validate=validate_istimezone, dump_only=True)
48
+ changed_on = auto_field(validate=validate_istimezone, dump_only=True)
49
+
50
+
51
+ class UserSchema(UserCollectionItemSchema):
52
+ """User schema."""
53
+
54
+ password = auto_field(load_only=True)
55
+
56
+
57
+ class UserCollection(NamedTuple):
58
+ """User collection."""
59
+
60
+ users: list[User]
61
+ total_entries: int
62
+
63
+
64
+ class UserCollectionSchema(Schema):
65
+ """User collection schema."""
66
+
67
+ users = fields.List(fields.Nested(UserCollectionItemSchema))
68
+ total_entries = fields.Int()
69
+
70
+
71
+ user_collection_item_schema = UserCollectionItemSchema()
72
+ user_schema = UserSchema()
73
+ user_collection_schema = UserCollectionSchema()
@@ -117,10 +117,7 @@ if TYPE_CHECKING:
117
117
  from airflow.auth.managers.base_auth_manager import ResourceMethod
118
118
  from airflow.security.permissions import RESOURCE_ASSET
119
119
  else:
120
- try:
121
- from airflow.security.permissions import RESOURCE_ASSET
122
- except ImportError:
123
- from airflow.security.permissions import RESOURCE_DATASET as RESOURCE_ASSET
120
+ from airflow.providers.common.compat.security.permissions import RESOURCE_ASSET
124
121
 
125
122
  log = logging.getLogger(__name__)
126
123
 
@@ -1110,7 +1107,7 @@ class FabAirflowSecurityManagerOverride(AirflowSecurityManagerV2):
1110
1107
  def sync_perm_for_dag(
1111
1108
  self,
1112
1109
  dag_id: str,
1113
- access_control: dict[str, dict[str, Collection[str]]] | None = None,
1110
+ access_control: dict[str, dict[str, Collection[str]] | Collection[str]] | None = None,
1114
1111
  ) -> None:
1115
1112
  """
1116
1113
  Sync permissions for given dag id.
@@ -1152,7 +1149,7 @@ class FabAirflowSecurityManagerOverride(AirflowSecurityManagerV2):
1152
1149
  def _sync_dag_view_permissions(
1153
1150
  self,
1154
1151
  dag_id: str,
1155
- access_control: dict[str, dict[str, Collection[str]]],
1152
+ access_control: dict[str, dict[str, Collection[str]] | Collection[str]],
1156
1153
  ) -> None:
1157
1154
  """
1158
1155
  Set the access policy on the given DAG's ViewModel.
@@ -1178,7 +1175,13 @@ class FabAirflowSecurityManagerOverride(AirflowSecurityManagerV2):
1178
1175
  for perm in existing_dag_perms:
1179
1176
  non_admin_roles = [role for role in perm.role if role.name != "Admin"]
1180
1177
  for role in non_admin_roles:
1181
- target_perms_for_role = access_control.get(role.name, {}).get(resource_name, set())
1178
+ access_control_role = access_control.get(role.name)
1179
+ target_perms_for_role = set()
1180
+ if access_control_role:
1181
+ if isinstance(access_control_role, set):
1182
+ target_perms_for_role = access_control_role
1183
+ elif isinstance(access_control_role, dict):
1184
+ target_perms_for_role = access_control_role.get(resource_name, set())
1182
1185
  if perm.action.name not in target_perms_for_role:
1183
1186
  self.log.info(
1184
1187
  "Revoking '%s' on DAG '%s' for role '%s'",
@@ -1197,7 +1200,7 @@ class FabAirflowSecurityManagerOverride(AirflowSecurityManagerV2):
1197
1200
  f"'{rolename}', but that role does not exist"
1198
1201
  )
1199
1202
 
1200
- if isinstance(resource_actions, (set, list)):
1203
+ if not isinstance(resource_actions, dict):
1201
1204
  # Support for old-style access_control where only the actions are specified
1202
1205
  resource_actions = {permissions.RESOURCE_DAG: set(resource_actions)}
1203
1206
 
@@ -28,8 +28,9 @@ def get_provider_info():
28
28
  "name": "Fab",
29
29
  "description": "`Flask App Builder <https://flask-appbuilder.readthedocs.io/>`__\n",
30
30
  "state": "ready",
31
- "source-date-epoch": 1728485088,
31
+ "source-date-epoch": 1730012648,
32
32
  "versions": [
33
+ "1.5.0",
33
34
  "1.4.1",
34
35
  "1.4.0",
35
36
  "1.3.0",
@@ -46,9 +47,9 @@ def get_provider_info():
46
47
  ],
47
48
  "dependencies": [
48
49
  "apache-airflow>=2.9.0",
49
- "apache-airflow-providers-common-compat>=1.2.0",
50
+ "apache-airflow-providers-common-compat>=1.2.1",
50
51
  "flask>=2.2,<2.3",
51
- "flask-appbuilder==4.5.0",
52
+ "flask-appbuilder==4.5.2",
52
53
  "flask-login>=0.6.2",
53
54
  "google-re2>=1.0",
54
55
  "jmespath>=0.7.0",
@@ -0,0 +1,16 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The ASF licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
@@ -28,7 +28,7 @@ build-backend = "flit_core.buildapi"
28
28
 
29
29
  [project]
30
30
  name = "apache-airflow-providers-fab"
31
- version = "1.4.1.rc1"
31
+ version = "1.5.0.rc1"
32
32
  description = "Provider package apache-airflow-providers-fab for Apache Airflow"
33
33
  readme = "README.rst"
34
34
  authors = [
@@ -55,9 +55,9 @@ classifiers = [
55
55
  ]
56
56
  requires-python = "~=3.9"
57
57
  dependencies = [
58
- "apache-airflow-providers-common-compat>=1.2.0rc0",
58
+ "apache-airflow-providers-common-compat>=1.2.1rc0",
59
59
  "apache-airflow>=2.9.0rc0",
60
- "flask-appbuilder==4.5.0",
60
+ "flask-appbuilder==4.5.2",
61
61
  "flask-login>=0.6.2",
62
62
  "flask>=2.2,<2.3",
63
63
  "google-re2>=1.0",
@@ -65,8 +65,8 @@ dependencies = [
65
65
  ]
66
66
 
67
67
  [project.urls]
68
- "Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-fab/1.4.1"
69
- "Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-fab/1.4.1/changelog.html"
68
+ "Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-fab/1.5.0"
69
+ "Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-fab/1.5.0/changelog.html"
70
70
  "Bug Tracker" = "https://github.com/apache/airflow/issues"
71
71
  "Source Code" = "https://github.com/apache/airflow"
72
72
  "Slack Chat" = "https://s.apache.org/airflow-slack"