apache-airflow-providers-fab 1.5.3__py3-none-any.whl → 2.0.0b1__py3-none-any.whl

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 (101) hide show
  1. airflow/providers/fab/LICENSE +0 -52
  2. airflow/providers/fab/__init__.py +3 -3
  3. airflow/providers/fab/auth_manager/api/auth/backend/basic_auth.py +3 -3
  4. airflow/providers/fab/auth_manager/api/auth/backend/kerberos_auth.py +4 -4
  5. airflow/providers/fab/auth_manager/api/auth/backend/session.py +1 -1
  6. airflow/providers/fab/auth_manager/api_endpoints/role_and_permission_endpoint.py +14 -13
  7. airflow/providers/fab/auth_manager/api_endpoints/user_endpoint.py +12 -12
  8. airflow/providers/fab/auth_manager/api_fastapi/__init__.py +16 -0
  9. airflow/providers/fab/auth_manager/api_fastapi/datamodels/__init__.py +16 -0
  10. airflow/providers/fab/auth_manager/api_fastapi/datamodels/login.py +32 -0
  11. airflow/providers/fab/auth_manager/api_fastapi/openapi/__init__.py +16 -0
  12. airflow/providers/fab/auth_manager/api_fastapi/openapi/v1-generated.yaml +152 -0
  13. airflow/providers/fab/auth_manager/api_fastapi/routes/__init__.py +16 -0
  14. airflow/providers/fab/auth_manager/api_fastapi/routes/login.py +51 -0
  15. airflow/providers/fab/auth_manager/api_fastapi/services/__init__.py +16 -0
  16. airflow/providers/fab/auth_manager/api_fastapi/services/login.py +58 -0
  17. airflow/providers/fab/auth_manager/cli_commands/db_command.py +2 -4
  18. airflow/providers/fab/auth_manager/cli_commands/user_command.py +2 -2
  19. airflow/providers/fab/auth_manager/cli_commands/utils.py +10 -9
  20. airflow/providers/fab/auth_manager/fab_auth_manager.py +231 -126
  21. airflow/providers/fab/auth_manager/models/__init__.py +1 -1
  22. airflow/providers/fab/auth_manager/models/anonymous_user.py +1 -1
  23. airflow/providers/fab/auth_manager/models/db.py +22 -5
  24. airflow/providers/fab/auth_manager/schemas/user_schema.py +1 -1
  25. airflow/providers/fab/auth_manager/security_manager/override.py +71 -632
  26. airflow/providers/fab/auth_manager/views/permissions.py +1 -1
  27. airflow/providers/fab/auth_manager/views/roles_list.py +1 -1
  28. airflow/providers/fab/auth_manager/views/user.py +1 -1
  29. airflow/providers/fab/auth_manager/views/user_edit.py +1 -1
  30. airflow/providers/fab/auth_manager/views/user_stats.py +1 -1
  31. airflow/providers/fab/get_provider_info.py +22 -16
  32. airflow/providers/fab/www/airflow_flask_app.py +31 -0
  33. airflow/providers/fab/www/api_connexion/__init__.py +17 -0
  34. airflow/providers/fab/www/api_connexion/exceptions.py +197 -0
  35. airflow/providers/fab/www/api_connexion/parameters.py +131 -0
  36. airflow/providers/fab/www/api_connexion/security.py +84 -0
  37. airflow/providers/fab/www/api_connexion/types.py +30 -0
  38. airflow/providers/fab/www/app.py +112 -0
  39. airflow/providers/fab/www/auth.py +350 -0
  40. airflow/providers/fab/www/constants.py +28 -0
  41. airflow/providers/fab/www/extensions/__init__.py +16 -0
  42. airflow/providers/fab/www/extensions/init_appbuilder.py +602 -0
  43. airflow/providers/fab/www/extensions/init_jinja_globals.py +82 -0
  44. airflow/providers/fab/www/extensions/init_manifest_files.py +61 -0
  45. airflow/providers/fab/www/extensions/init_security.py +61 -0
  46. airflow/providers/fab/www/extensions/init_session.py +64 -0
  47. airflow/providers/fab/www/extensions/init_views.py +177 -0
  48. airflow/providers/fab/www/package-lock.json +10127 -0
  49. airflow/providers/fab/www/package.json +81 -0
  50. airflow/providers/fab/www/security/__init__.py +17 -0
  51. airflow/providers/fab/www/security/permissions.py +126 -0
  52. airflow/providers/fab/www/security_appless.py +44 -0
  53. airflow/providers/fab/www/security_manager.py +122 -0
  54. airflow/providers/fab/www/session.py +41 -0
  55. airflow/providers/fab/www/static/css/bootstrap-theme.css +6215 -0
  56. airflow/providers/fab/www/static/css/flash.css +57 -0
  57. airflow/providers/fab/www/static/css/loading-dots.css +60 -0
  58. airflow/providers/fab/www/static/css/main.css +676 -0
  59. airflow/providers/fab/www/static/css/material-icons.css +84 -0
  60. airflow/providers/fab/www/static/dist/airflowDefaultTheme.feec4a4075c2f3d6ae01.css +33 -0
  61. airflow/providers/fab/www/static/dist/airflowDefaultTheme.feec4a4075c2f3d6ae01.js +1 -0
  62. airflow/providers/fab/www/static/dist/flash.137b30cff85b5588e661.css +18 -0
  63. airflow/providers/fab/www/static/dist/flash.137b30cff85b5588e661.js +1 -0
  64. airflow/providers/fab/www/static/dist/jquery-ui.min.css +5 -0
  65. airflow/providers/fab/www/static/dist/jquery-ui.min.js +2 -0
  66. airflow/providers/fab/www/static/dist/jquery-ui.min.js.LICENSE.txt +4 -0
  67. airflow/providers/fab/www/static/dist/loadingDots.48ab7d5b04e66f2686b0.css +18 -0
  68. airflow/providers/fab/www/static/dist/loadingDots.48ab7d5b04e66f2686b0.js +1 -0
  69. airflow/providers/fab/www/static/dist/main.ec1d38d994d72bb083cd.css +18 -0
  70. airflow/providers/fab/www/static/dist/main.ec1d38d994d72bb083cd.js +2 -0
  71. airflow/providers/fab/www/static/dist/main.ec1d38d994d72bb083cd.js.LICENSE.txt +18 -0
  72. airflow/providers/fab/www/static/dist/manifest.json +17 -0
  73. airflow/providers/fab/www/static/dist/materialIcons.57390fa60d8f61175334.css +18 -0
  74. airflow/providers/fab/www/static/dist/materialIcons.57390fa60d8f61175334.js +1 -0
  75. airflow/providers/fab/www/static/dist/moment.4d28b37c229bdfc54575.js +2 -0
  76. airflow/providers/fab/www/static/dist/moment.4d28b37c229bdfc54575.js.LICENSE.txt +11 -0
  77. airflow/providers/fab/www/static/dist/oss-licenses.json +29 -0
  78. airflow/providers/fab/www/static/js/datetime_utils.js +134 -0
  79. airflow/providers/fab/www/static/js/main.js +324 -0
  80. airflow/providers/fab/www/static/sort_asc.png +0 -0
  81. airflow/providers/fab/www/static/sort_both.png +0 -0
  82. airflow/providers/fab/www/static/sort_desc.png +0 -0
  83. airflow/providers/fab/www/templates/airflow/_messages.html +30 -0
  84. airflow/providers/fab/www/templates/airflow/error.html +35 -0
  85. airflow/providers/fab/www/templates/airflow/main.html +78 -0
  86. airflow/providers/fab/www/templates/airflow/traceback.html +53 -0
  87. airflow/providers/fab/www/templates/appbuilder/flash.html +34 -0
  88. airflow/providers/fab/www/templates/appbuilder/index.html +20 -0
  89. airflow/providers/fab/www/templates/appbuilder/navbar.html +60 -0
  90. airflow/providers/fab/www/templates/appbuilder/navbar_menu.html +60 -0
  91. airflow/providers/fab/www/templates/appbuilder/navbar_right.html +64 -0
  92. airflow/providers/fab/www/utils.py +272 -0
  93. airflow/providers/fab/www/views.py +129 -0
  94. airflow/providers/fab/www/webpack.config.js +213 -0
  95. {apache_airflow_providers_fab-1.5.3.dist-info → apache_airflow_providers_fab-2.0.0b1.dist-info}/METADATA +17 -35
  96. apache_airflow_providers_fab-2.0.0b1.dist-info/RECORD +122 -0
  97. {apache_airflow_providers_fab-1.5.3.dist-info → apache_airflow_providers_fab-2.0.0b1.dist-info}/WHEEL +1 -1
  98. airflow/providers/fab/auth_manager/decorators/auth.py +0 -126
  99. apache_airflow_providers_fab-1.5.3.dist-info/RECORD +0 -51
  100. /airflow/providers/fab/{auth_manager/decorators → www}/__init__.py +0 -0
  101. {apache_airflow_providers_fab-1.5.3.dist-info → apache_airflow_providers_fab-2.0.0b1.dist-info}/entry_points.txt +0 -0
@@ -199,55 +199,3 @@ distributed under the License is distributed on an "AS IS" BASIS,
199
199
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
200
  See the License for the specific language governing permissions and
201
201
  limitations under the License.
202
-
203
- ============================================================================
204
- APACHE AIRFLOW SUBCOMPONENTS:
205
-
206
- The Apache Airflow project contains subcomponents with separate copyright
207
- notices and license terms. Your use of the source code for the these
208
- subcomponents is subject to the terms and conditions of the following
209
- licenses.
210
-
211
-
212
- ========================================================================
213
- Third party Apache 2.0 licenses
214
- ========================================================================
215
-
216
- The following components are provided under the Apache 2.0 License.
217
- See project link for details. The text of each license is also included
218
- at 3rd-party-licenses/LICENSE-[project].txt.
219
-
220
- (ALv2 License) hue v4.3.0 (https://github.com/cloudera/hue/)
221
- (ALv2 License) jqclock v2.3.0 (https://github.com/JohnRDOrazio/jQuery-Clock-Plugin)
222
- (ALv2 License) bootstrap3-typeahead v4.0.2 (https://github.com/bassjobsen/Bootstrap-3-Typeahead)
223
- (ALv2 License) connexion v2.7.0 (https://github.com/zalando/connexion)
224
-
225
- ========================================================================
226
- MIT licenses
227
- ========================================================================
228
-
229
- The following components are provided under the MIT License. See project link for details.
230
- The text of each license is also included at 3rd-party-licenses/LICENSE-[project].txt.
231
-
232
- (MIT License) jquery v3.5.1 (https://jquery.org/license/)
233
- (MIT License) dagre-d3 v0.6.4 (https://github.com/cpettitt/dagre-d3)
234
- (MIT License) bootstrap v3.4.1 (https://github.com/twbs/bootstrap/)
235
- (MIT License) d3-tip v0.9.1 (https://github.com/Caged/d3-tip)
236
- (MIT License) dataTables v1.10.25 (https://datatables.net)
237
- (MIT License) normalize.css v3.0.2 (http://necolas.github.io/normalize.css/)
238
- (MIT License) ElasticMock v1.3.2 (https://github.com/vrcmarcos/elasticmock)
239
- (MIT License) MomentJS v2.24.0 (http://momentjs.com/)
240
- (MIT License) eonasdan-bootstrap-datetimepicker v4.17.49 (https://github.com/eonasdan/bootstrap-datetimepicker/)
241
-
242
- ========================================================================
243
- BSD 3-Clause licenses
244
- ========================================================================
245
- The following components are provided under the BSD 3-Clause license. See project links for details.
246
- The text of each license is also included at 3rd-party-licenses/LICENSE-[project].txt.
247
-
248
- (BSD 3 License) d3 v5.16.0 (https://d3js.org)
249
- (BSD 3 License) d3-shape v2.1.0 (https://github.com/d3/d3-shape)
250
- (BSD 3 License) cgroupspy 0.2.1 (https://github.com/cloudsigma/cgroupspy)
251
-
252
- ========================================================================
253
- See 3rd-party-licenses/LICENSES-ui.txt for packages used in `/airflow/www`
@@ -29,11 +29,11 @@ from airflow import __version__ as airflow_version
29
29
 
30
30
  __all__ = ["__version__"]
31
31
 
32
- __version__ = "1.5.3"
32
+ __version__ = "2.0.0b1"
33
33
 
34
34
  if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
35
- "2.9.0"
35
+ "3.0.0.dev0"
36
36
  ):
37
37
  raise RuntimeError(
38
- f"The package `apache-airflow-providers-fab:{__version__}` needs Apache Airflow 2.9.0+"
38
+ f"The package `apache-airflow-providers-fab:{__version__}` needs Apache Airflow 3.0.0.dev0+"
39
39
  )
@@ -25,8 +25,8 @@ from flask import Response, current_app, request
25
25
  from flask_appbuilder.const import AUTH_LDAP
26
26
  from flask_login import login_user
27
27
 
28
- from airflow.providers.fab.auth_manager.security_manager.override import FabAirflowSecurityManagerOverride
29
- from airflow.www.extensions.init_auth_manager import get_auth_manager
28
+ from airflow.api_fastapi.app import get_auth_manager
29
+ from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager
30
30
 
31
31
  if TYPE_CHECKING:
32
32
  from airflow.providers.fab.auth_manager.models import User
@@ -46,7 +46,7 @@ def auth_current_user() -> User | None:
46
46
  if auth is None or not auth.username or not auth.password:
47
47
  return None
48
48
 
49
- security_manager = cast(FabAirflowSecurityManagerOverride, get_auth_manager().security_manager)
49
+ security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
50
50
  user = None
51
51
  if security_manager.auth_type == AUTH_LDAP:
52
52
  user = security_manager.auth_user_ldap(auth.username, auth.password)
@@ -26,13 +26,13 @@ import kerberos
26
26
  from flask import Response, current_app, g, make_response, request
27
27
  from requests_kerberos import HTTPKerberosAuth
28
28
 
29
+ from airflow.api_fastapi.app import get_auth_manager
29
30
  from airflow.configuration import conf
30
- from airflow.providers.fab.auth_manager.security_manager.override import FabAirflowSecurityManagerOverride
31
+ from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager
31
32
  from airflow.utils.net import getfqdn
32
- from airflow.www.extensions.init_auth_manager import get_auth_manager
33
33
 
34
34
  if TYPE_CHECKING:
35
- from airflow.auth.managers.models.base_user import BaseUser
35
+ from airflow.api_fastapi.auth.managers.models.base_user import BaseUser
36
36
 
37
37
  log = logging.getLogger(__name__)
38
38
 
@@ -115,7 +115,7 @@ T = TypeVar("T", bound=Callable)
115
115
 
116
116
 
117
117
  def find_user(username=None, email=None):
118
- security_manager = cast(FabAirflowSecurityManagerOverride, get_auth_manager().security_manager)
118
+ security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
119
119
  return security_manager.find_user(username=username, email=email)
120
120
 
121
121
 
@@ -23,7 +23,7 @@ from typing import Any, Callable, TypeVar, cast
23
23
 
24
24
  from flask import Response
25
25
 
26
- from airflow.www.extensions.init_auth_manager import get_auth_manager
26
+ from airflow.api_fastapi.app import get_auth_manager
27
27
 
28
28
  CLIENT_AUTH: tuple[str, str] | Any | None = None
29
29
 
@@ -24,9 +24,8 @@ from flask import request
24
24
  from marshmallow import ValidationError
25
25
  from sqlalchemy import asc, desc, func, select
26
26
 
27
- from airflow.api_connexion.exceptions import AlreadyExists, BadRequest, NotFound
28
- from airflow.api_connexion.parameters import check_limit, format_parameters
29
- from airflow.api_connexion.security import requires_access_custom_view
27
+ from airflow.api_fastapi.app import get_auth_manager
28
+ from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager
30
29
  from airflow.providers.fab.auth_manager.models import Action, Role
31
30
  from airflow.providers.fab.auth_manager.schemas.role_and_permission_schema import (
32
31
  ActionCollection,
@@ -35,12 +34,14 @@ from airflow.providers.fab.auth_manager.schemas.role_and_permission_schema impor
35
34
  role_collection_schema,
36
35
  role_schema,
37
36
  )
38
- from airflow.providers.fab.auth_manager.security_manager.override import FabAirflowSecurityManagerOverride
39
- from airflow.security import permissions
40
- from airflow.www.extensions.init_auth_manager import get_auth_manager
37
+ from airflow.providers.fab.www.api_connexion.exceptions import AlreadyExists, BadRequest, NotFound
38
+ from airflow.providers.fab.www.api_connexion.parameters import check_limit, format_parameters
39
+ from airflow.providers.fab.www.api_connexion.security import requires_access_custom_view
40
+ from airflow.providers.fab.www.security import permissions
41
41
 
42
42
  if TYPE_CHECKING:
43
- from airflow.api_connexion.types import APIResponse, UpdateMask
43
+ from airflow.providers.fab.auth_manager.security_manager.override import FabAirflowSecurityManagerOverride
44
+ from airflow.providers.fab.www.api_connexion.types import APIResponse, UpdateMask
44
45
 
45
46
 
46
47
  def _check_action_and_resource(sm: FabAirflowSecurityManagerOverride, perms: list[tuple[str, str]]) -> None:
@@ -59,7 +60,7 @@ def _check_action_and_resource(sm: FabAirflowSecurityManagerOverride, perms: lis
59
60
  @requires_access_custom_view("GET", permissions.RESOURCE_ROLE)
60
61
  def get_role(*, role_name: str) -> APIResponse:
61
62
  """Get role."""
62
- security_manager = cast(FabAirflowSecurityManagerOverride, get_auth_manager().security_manager)
63
+ security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
63
64
  role = security_manager.find_role(name=role_name)
64
65
  if not role:
65
66
  raise NotFound(title="Role not found", detail=f"Role with name {role_name!r} was not found")
@@ -70,7 +71,7 @@ def get_role(*, role_name: str) -> APIResponse:
70
71
  @format_parameters({"limit": check_limit})
71
72
  def get_roles(*, order_by: str = "name", limit: int, offset: int | None = None) -> APIResponse:
72
73
  """Get roles."""
73
- security_manager = cast(FabAirflowSecurityManagerOverride, get_auth_manager().security_manager)
74
+ security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
74
75
  session = security_manager.get_session
75
76
  total_entries = session.scalars(select(func.count(Role.id))).one()
76
77
  direction = desc if order_by.startswith("-") else asc
@@ -98,7 +99,7 @@ def get_roles(*, order_by: str = "name", limit: int, offset: int | None = None)
98
99
  @format_parameters({"limit": check_limit})
99
100
  def get_permissions(*, limit: int, offset: int | None = None) -> APIResponse:
100
101
  """Get permissions."""
101
- security_manager = cast(FabAirflowSecurityManagerOverride, get_auth_manager().security_manager)
102
+ security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
102
103
  session = security_manager.get_session
103
104
  total_entries = session.scalars(select(func.count(Action.id))).one()
104
105
  query = select(Action)
@@ -109,7 +110,7 @@ def get_permissions(*, limit: int, offset: int | None = None) -> APIResponse:
109
110
  @requires_access_custom_view("DELETE", permissions.RESOURCE_ROLE)
110
111
  def delete_role(*, role_name: str) -> APIResponse:
111
112
  """Delete a role."""
112
- security_manager = cast(FabAirflowSecurityManagerOverride, get_auth_manager().security_manager)
113
+ security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
113
114
 
114
115
  role = security_manager.find_role(name=role_name)
115
116
  if not role:
@@ -121,7 +122,7 @@ def delete_role(*, role_name: str) -> APIResponse:
121
122
  @requires_access_custom_view("PUT", permissions.RESOURCE_ROLE)
122
123
  def patch_role(*, role_name: str, update_mask: UpdateMask = None) -> APIResponse:
123
124
  """Update a role."""
124
- security_manager = cast(FabAirflowSecurityManagerOverride, get_auth_manager().security_manager)
125
+ security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
125
126
  body = request.json
126
127
  try:
127
128
  data = role_schema.load(body)
@@ -154,7 +155,7 @@ def patch_role(*, role_name: str, update_mask: UpdateMask = None) -> APIResponse
154
155
  @requires_access_custom_view("POST", permissions.RESOURCE_ROLE)
155
156
  def post_role() -> APIResponse:
156
157
  """Create a new role."""
157
- security_manager = cast(FabAirflowSecurityManagerOverride, get_auth_manager().security_manager)
158
+ security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
158
159
  body = request.json
159
160
  try:
160
161
  data = role_schema.load(body)
@@ -25,9 +25,8 @@ from marshmallow import ValidationError
25
25
  from sqlalchemy import asc, desc, func, select
26
26
  from werkzeug.security import generate_password_hash
27
27
 
28
- from airflow.api_connexion.exceptions import AlreadyExists, BadRequest, NotFound, Unknown
29
- from airflow.api_connexion.parameters import check_limit, format_parameters
30
- from airflow.api_connexion.security import requires_access_custom_view
28
+ from airflow.api_fastapi.app import get_auth_manager
29
+ from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager
31
30
  from airflow.providers.fab.auth_manager.models import User
32
31
  from airflow.providers.fab.auth_manager.schemas.user_schema import (
33
32
  UserCollection,
@@ -35,19 +34,20 @@ from airflow.providers.fab.auth_manager.schemas.user_schema import (
35
34
  user_collection_schema,
36
35
  user_schema,
37
36
  )
38
- from airflow.providers.fab.auth_manager.security_manager.override import FabAirflowSecurityManagerOverride
39
- from airflow.security import permissions
40
- from airflow.www.extensions.init_auth_manager import get_auth_manager
37
+ from airflow.providers.fab.www.api_connexion.exceptions import AlreadyExists, BadRequest, NotFound, Unknown
38
+ from airflow.providers.fab.www.api_connexion.parameters import check_limit, format_parameters
39
+ from airflow.providers.fab.www.api_connexion.security import requires_access_custom_view
40
+ from airflow.providers.fab.www.security import permissions
41
41
 
42
42
  if TYPE_CHECKING:
43
- from airflow.api_connexion.types import APIResponse, UpdateMask
44
43
  from airflow.providers.fab.auth_manager.models import Role
44
+ from airflow.providers.fab.www.api_connexion.types import APIResponse, UpdateMask
45
45
 
46
46
 
47
47
  @requires_access_custom_view("GET", permissions.RESOURCE_USER)
48
48
  def get_user(*, username: str) -> APIResponse:
49
49
  """Get a user."""
50
- security_manager = cast(FabAirflowSecurityManagerOverride, get_auth_manager().security_manager)
50
+ security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
51
51
  user = security_manager.find_user(username=username)
52
52
  if not user:
53
53
  raise NotFound(title="User not found", detail=f"The User with username `{username}` was not found")
@@ -58,7 +58,7 @@ def get_user(*, username: str) -> APIResponse:
58
58
  @format_parameters({"limit": check_limit})
59
59
  def get_users(*, limit: int, order_by: str = "id", offset: str | None = None) -> APIResponse:
60
60
  """Get users."""
61
- security_manager = cast(FabAirflowSecurityManagerOverride, get_auth_manager().security_manager)
61
+ security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
62
62
  session = security_manager.get_session
63
63
  total_entries = session.execute(select(func.count(User.id))).scalar()
64
64
  direction = desc if order_by.startswith("-") else asc
@@ -94,7 +94,7 @@ def post_user() -> APIResponse:
94
94
  except ValidationError as e:
95
95
  raise BadRequest(detail=str(e.messages))
96
96
 
97
- security_manager = cast(FabAirflowSecurityManagerOverride, get_auth_manager().security_manager)
97
+ security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
98
98
  username = data["username"]
99
99
  email = data["email"]
100
100
 
@@ -137,7 +137,7 @@ def patch_user(*, username: str, update_mask: UpdateMask = None) -> APIResponse:
137
137
  except ValidationError as e:
138
138
  raise BadRequest(detail=str(e.messages))
139
139
 
140
- security_manager = cast(FabAirflowSecurityManagerOverride, get_auth_manager().security_manager)
140
+ security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
141
141
 
142
142
  user = security_manager.find_user(username=username)
143
143
  if user is None:
@@ -201,7 +201,7 @@ def patch_user(*, username: str, update_mask: UpdateMask = None) -> APIResponse:
201
201
  @requires_access_custom_view("DELETE", permissions.RESOURCE_USER)
202
202
  def delete_user(*, username: str) -> APIResponse:
203
203
  """Delete a user."""
204
- security_manager = cast(FabAirflowSecurityManagerOverride, get_auth_manager().security_manager)
204
+ security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
205
205
 
206
206
  user = security_manager.find_user(username=username)
207
207
  if user is None:
@@ -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.
@@ -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.
@@ -0,0 +1,32 @@
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 airflow.api_fastapi.core_api.base import BaseModel
20
+
21
+
22
+ class LoginResponse(BaseModel):
23
+ """API Token serializer for responses."""
24
+
25
+ jwt_token: str
26
+
27
+
28
+ class LoginBody(BaseModel):
29
+ """API Token serializer for requests."""
30
+
31
+ username: str
32
+ password: str
@@ -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.
@@ -0,0 +1,152 @@
1
+ openapi: 3.1.0
2
+ info:
3
+ title: FAB auth manager API
4
+ description: This is FAB auth manager API. This API is only available if the auth
5
+ manager used in the Airflow environment is FAB auth manager. This API provides
6
+ endpoints to manage users and permissions managed by the FAB auth manager.
7
+ version: 0.1.0
8
+ paths:
9
+ /token:
10
+ post:
11
+ tags:
12
+ - FabAuthManager
13
+ summary: Create Token
14
+ description: Generate a new API token.
15
+ operationId: create_token
16
+ requestBody:
17
+ content:
18
+ application/json:
19
+ schema:
20
+ $ref: '#/components/schemas/LoginBody'
21
+ required: true
22
+ responses:
23
+ '201':
24
+ description: Successful Response
25
+ content:
26
+ application/json:
27
+ schema:
28
+ $ref: '#/components/schemas/LoginResponse'
29
+ '400':
30
+ description: Bad Request
31
+ content:
32
+ application/json:
33
+ schema:
34
+ $ref: '#/components/schemas/HTTPExceptionResponse'
35
+ '401':
36
+ description: Unauthorized
37
+ content:
38
+ application/json:
39
+ schema:
40
+ $ref: '#/components/schemas/HTTPExceptionResponse'
41
+ '422':
42
+ description: Validation Error
43
+ content:
44
+ application/json:
45
+ schema:
46
+ $ref: '#/components/schemas/HTTPValidationError'
47
+ /token/cli:
48
+ post:
49
+ tags:
50
+ - FabAuthManager
51
+ summary: Create Token Cli
52
+ description: Generate a new CLI API token.
53
+ operationId: create_token_cli
54
+ requestBody:
55
+ content:
56
+ application/json:
57
+ schema:
58
+ $ref: '#/components/schemas/LoginBody'
59
+ required: true
60
+ responses:
61
+ '201':
62
+ description: Successful Response
63
+ content:
64
+ application/json:
65
+ schema:
66
+ $ref: '#/components/schemas/LoginResponse'
67
+ '400':
68
+ description: Bad Request
69
+ content:
70
+ application/json:
71
+ schema:
72
+ $ref: '#/components/schemas/HTTPExceptionResponse'
73
+ '401':
74
+ description: Unauthorized
75
+ content:
76
+ application/json:
77
+ schema:
78
+ $ref: '#/components/schemas/HTTPExceptionResponse'
79
+ '422':
80
+ description: Validation Error
81
+ content:
82
+ application/json:
83
+ schema:
84
+ $ref: '#/components/schemas/HTTPValidationError'
85
+ components:
86
+ schemas:
87
+ HTTPExceptionResponse:
88
+ properties:
89
+ detail:
90
+ anyOf:
91
+ - type: string
92
+ - type: object
93
+ title: Detail
94
+ type: object
95
+ required:
96
+ - detail
97
+ title: HTTPExceptionResponse
98
+ description: HTTPException Model used for error response.
99
+ HTTPValidationError:
100
+ properties:
101
+ detail:
102
+ items:
103
+ $ref: '#/components/schemas/ValidationError'
104
+ type: array
105
+ title: Detail
106
+ type: object
107
+ title: HTTPValidationError
108
+ LoginBody:
109
+ properties:
110
+ username:
111
+ type: string
112
+ title: Username
113
+ password:
114
+ type: string
115
+ title: Password
116
+ type: object
117
+ required:
118
+ - username
119
+ - password
120
+ title: LoginBody
121
+ description: API Token serializer for requests.
122
+ LoginResponse:
123
+ properties:
124
+ jwt_token:
125
+ type: string
126
+ title: Jwt Token
127
+ type: object
128
+ required:
129
+ - jwt_token
130
+ title: LoginResponse
131
+ description: API Token serializer for responses.
132
+ ValidationError:
133
+ properties:
134
+ loc:
135
+ items:
136
+ anyOf:
137
+ - type: string
138
+ - type: integer
139
+ type: array
140
+ title: Location
141
+ msg:
142
+ type: string
143
+ title: Message
144
+ type:
145
+ type: string
146
+ title: Error Type
147
+ type: object
148
+ required:
149
+ - loc
150
+ - msg
151
+ - type
152
+ title: ValidationError
@@ -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.
@@ -0,0 +1,51 @@
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 starlette import status
20
+
21
+ from airflow.api_fastapi.common.router import AirflowRouter
22
+ from airflow.api_fastapi.core_api.openapi.exceptions import create_openapi_http_exception_doc
23
+ from airflow.configuration import conf
24
+ from airflow.providers.fab.auth_manager.api_fastapi.datamodels.login import LoginBody, LoginResponse
25
+ from airflow.providers.fab.auth_manager.api_fastapi.services.login import FABAuthManagerLogin
26
+
27
+ login_router = AirflowRouter(tags=["FabAuthManager"])
28
+
29
+
30
+ @login_router.post(
31
+ "/token",
32
+ response_model=LoginResponse,
33
+ status_code=status.HTTP_201_CREATED,
34
+ responses=create_openapi_http_exception_doc([status.HTTP_400_BAD_REQUEST, status.HTTP_401_UNAUTHORIZED]),
35
+ )
36
+ def create_token(body: LoginBody) -> LoginResponse:
37
+ """Generate a new API token."""
38
+ return FABAuthManagerLogin.create_token(body=body)
39
+
40
+
41
+ @login_router.post(
42
+ "/token/cli",
43
+ response_model=LoginResponse,
44
+ status_code=status.HTTP_201_CREATED,
45
+ responses=create_openapi_http_exception_doc([status.HTTP_400_BAD_REQUEST, status.HTTP_401_UNAUTHORIZED]),
46
+ )
47
+ def create_token_cli(body: LoginBody) -> LoginResponse:
48
+ """Generate a new CLI API token."""
49
+ return FABAuthManagerLogin.create_token(
50
+ body=body, expiration_time_in_sec=conf.getint("api_auth", "jwt_cli_expiration_time")
51
+ )
@@ -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.