apache-airflow-providers-fab 2.0.0b1__tar.gz → 2.0.0rc2__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.
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/PKG-INFO +18 -10
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/README.rst +9 -5
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/pyproject.toml +21 -6
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/__init__.py +1 -1
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api/auth/backend/basic_auth.py +3 -4
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api/auth/backend/kerberos_auth.py +3 -3
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api/auth/backend/session.py +1 -1
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api_endpoints/role_and_permission_endpoint.py +8 -9
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api_endpoints/user_endpoint.py +7 -8
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api_fastapi/datamodels/login.py +1 -1
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api_fastapi/openapi/v1-generated.yaml +5 -4
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api_fastapi/routes/login.py +1 -1
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api_fastapi/services/login.py +5 -5
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/cli_commands/db_command.py +1 -1
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/cli_commands/utils.py +1 -1
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/fab_auth_manager.py +4 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/models/db.py +2 -2
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/openapi/v1.yaml +9 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/security_manager/override.py +0 -39
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/get_provider_info.py +7 -3
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/api_connexion/parameters.py +1 -1
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/api_connexion/security.py +3 -3
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/app.py +1 -1
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/auth.py +6 -6
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/package-lock.json +1428 -1904
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/package.json +20 -24
- apache_airflow_providers_fab-2.0.0rc2/src/airflow/providers/fab/www/static/dist/48f0ea180c40270a5b05.png +1 -0
- apache_airflow_providers_fab-2.0.0rc2/src/airflow/providers/fab/www/static/dist/649c0b07771e68fafdeb.png +1 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/dist/airflowDefaultTheme.feec4a4075c2f3d6ae01.css +2 -2
- apache_airflow_providers_fab-2.0.0rc2/src/airflow/providers/fab/www/static/dist/f7490d556a6c42e49ba4.png +1 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/dist/jquery-ui.min.css +1 -1
- apache_airflow_providers_fab-2.0.0rc2/src/airflow/providers/fab/www/static/dist/main.edb2d40dfbbc537916e3.css +18 -0
- apache_airflow_providers_fab-2.0.0b1/src/airflow/providers/fab/www/static/dist/main.ec1d38d994d72bb083cd.js → apache_airflow_providers_fab-2.0.0rc2/src/airflow/providers/fab/www/static/dist/main.edb2d40dfbbc537916e3.js +1 -1
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/dist/manifest.json +7 -4
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/dist/materialIcons.57390fa60d8f61175334.css +1 -1
- apache_airflow_providers_fab-2.0.0b1/src/airflow/providers/fab/www/static/dist/moment.4d28b37c229bdfc54575.js → apache_airflow_providers_fab-2.0.0rc2/src/airflow/providers/fab/www/static/dist/moment.624b1f00ba723d39ce06.js +2 -2
- apache_airflow_providers_fab-2.0.0b1/src/airflow/providers/fab/www/static/dist/moment.4d28b37c229bdfc54575.js.LICENSE.txt → apache_airflow_providers_fab-2.0.0rc2/src/airflow/providers/fab/www/static/dist/moment.624b1f00ba723d39ce06.js.LICENSE.txt +1 -1
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/dist/oss-licenses.json +2 -11
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/views.py +1 -1
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/webpack.config.js +2 -2
- apache_airflow_providers_fab-2.0.0b1/src/airflow/providers/fab/www/static/dist/main.ec1d38d994d72bb083cd.css +0 -18
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/LICENSE +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/alembic.ini +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api/auth/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api/auth/backend/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api_endpoints/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api_fastapi/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api_fastapi/datamodels/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api_fastapi/openapi/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api_fastapi/routes/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/api_fastapi/services/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/cli_commands/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/cli_commands/definition.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/cli_commands/role_command.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/cli_commands/sync_perm_command.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/cli_commands/user_command.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/models/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/models/anonymous_user.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/openapi/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/schemas/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/schemas/role_and_permission_schema.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/schemas/user_schema.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/security_manager/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/security_manager/constants.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/views/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/views/permissions.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/views/roles_list.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/views/user.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/views/user_edit.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/auth_manager/views/user_stats.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/migrations/README +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/migrations/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/migrations/env.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/migrations/script.py.mako +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/migrations/versions/0001_1_4_0_placeholder_migration.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/migrations/versions/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/airflow_flask_app.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/api_connexion/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/api_connexion/exceptions.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/api_connexion/types.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/constants.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/extensions/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/extensions/init_appbuilder.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/extensions/init_jinja_globals.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/extensions/init_manifest_files.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/extensions/init_security.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/extensions/init_session.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/extensions/init_views.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/security/__init__.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/security/permissions.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/security_appless.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/security_manager.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/session.py +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/css/bootstrap-theme.css +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/css/flash.css +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/css/loading-dots.css +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/css/main.css +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/css/material-icons.css +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/dist/airflowDefaultTheme.feec4a4075c2f3d6ae01.js +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/dist/flash.137b30cff85b5588e661.css +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/dist/flash.137b30cff85b5588e661.js +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/dist/jquery-ui.min.js +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/dist/jquery-ui.min.js.LICENSE.txt +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/dist/loadingDots.48ab7d5b04e66f2686b0.css +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/dist/loadingDots.48ab7d5b04e66f2686b0.js +0 -0
- /apache_airflow_providers_fab-2.0.0b1/src/airflow/providers/fab/www/static/dist/main.ec1d38d994d72bb083cd.js.LICENSE.txt → /apache_airflow_providers_fab-2.0.0rc2/src/airflow/providers/fab/www/static/dist/main.edb2d40dfbbc537916e3.js.LICENSE.txt +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/dist/materialIcons.57390fa60d8f61175334.js +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/js/datetime_utils.js +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/js/main.js +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/sort_asc.png +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/sort_both.png +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/static/sort_desc.png +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/templates/airflow/_messages.html +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/templates/airflow/error.html +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/templates/airflow/main.html +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/templates/airflow/traceback.html +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/templates/appbuilder/flash.html +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/templates/appbuilder/index.html +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/templates/appbuilder/navbar.html +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/templates/appbuilder/navbar_menu.html +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/templates/appbuilder/navbar_right.html +0 -0
- {apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/src/airflow/providers/fab/www/utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: apache-airflow-providers-fab
|
3
|
-
Version: 2.0.
|
3
|
+
Version: 2.0.0rc2
|
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>
|
@@ -21,16 +21,20 @@ Classifier: Programming Language :: Python :: 3.11
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.12
|
22
22
|
Classifier: Topic :: System :: Monitoring
|
23
23
|
Requires-Dist: apache-airflow>=3.0.0.dev0
|
24
|
-
Requires-Dist: apache-airflow-providers-common-compat>=1.2.
|
25
|
-
Requires-Dist:
|
24
|
+
Requires-Dist: apache-airflow-providers-common-compat>=1.2.1rc0
|
25
|
+
Requires-Dist: blinker>=1.6.2
|
26
|
+
Requires-Dist: flask>=2.2.1,<2.3
|
26
27
|
Requires-Dist: flask-appbuilder==4.5.3
|
27
28
|
Requires-Dist: flask-login>=0.6.2
|
29
|
+
Requires-Dist: flask-session>=0.4.0,<0.6
|
30
|
+
Requires-Dist: flask-wtf>=1.1.0
|
28
31
|
Requires-Dist: connexion[flask]>=2.14.2,<3.0
|
29
32
|
Requires-Dist: jmespath>=0.7.0
|
33
|
+
Requires-Dist: werkzeug>=2.2,<4
|
30
34
|
Requires-Dist: kerberos>=1.3.0 ; extra == "kerberos"
|
31
35
|
Project-URL: Bug Tracker, https://github.com/apache/airflow/issues
|
32
|
-
Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.
|
33
|
-
Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.
|
36
|
+
Project-URL: Changelog, https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.0/changelog.html
|
37
|
+
Project-URL: Documentation, https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.0
|
34
38
|
Project-URL: Mastodon, https://fosstodon.org/@airflow
|
35
39
|
Project-URL: Slack Chat, https://s.apache.org/airflow-slack
|
36
40
|
Project-URL: Source Code, https://github.com/apache/airflow
|
@@ -62,7 +66,7 @@ Provides-Extra: kerberos
|
|
62
66
|
|
63
67
|
Package ``apache-airflow-providers-fab``
|
64
68
|
|
65
|
-
Release: ``2.0.
|
69
|
+
Release: ``2.0.0``
|
66
70
|
|
67
71
|
|
68
72
|
`Flask App Builder <https://flask-appbuilder.readthedocs.io/>`__
|
@@ -75,7 +79,7 @@ This is a provider package for ``fab`` provider. All classes for this provider p
|
|
75
79
|
are in ``airflow.providers.fab`` python package.
|
76
80
|
|
77
81
|
You can find package information and changelog for the provider
|
78
|
-
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.
|
82
|
+
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.0/>`_.
|
79
83
|
|
80
84
|
Installation
|
81
85
|
------------
|
@@ -94,18 +98,22 @@ PIP package Version required
|
|
94
98
|
========================================== ==================
|
95
99
|
``apache-airflow`` ``>=3.0.0.dev0``
|
96
100
|
``apache-airflow-providers-common-compat`` ``>=1.2.1``
|
97
|
-
``
|
101
|
+
``blinker`` ``>=1.6.2``
|
102
|
+
``flask`` ``>=2.2.1,<2.3``
|
98
103
|
``flask-appbuilder`` ``==4.5.3``
|
99
104
|
``flask-login`` ``>=0.6.2``
|
105
|
+
``flask-session`` ``>=0.4.0,<0.6``
|
106
|
+
``flask-wtf`` ``>=1.1.0``
|
100
107
|
``connexion[flask]`` ``>=2.14.2,<3.0``
|
101
108
|
``jmespath`` ``>=0.7.0``
|
109
|
+
``werkzeug`` ``>=2.2,<4``
|
102
110
|
========================================== ==================
|
103
111
|
|
104
112
|
Cross provider package dependencies
|
105
113
|
-----------------------------------
|
106
114
|
|
107
115
|
Those are dependencies that might be needed in order to use all the features of the package.
|
108
|
-
You need to install the specified
|
116
|
+
You need to install the specified providers in order to use them.
|
109
117
|
|
110
118
|
You can install such cross-provider dependencies when installing from PyPI. For example:
|
111
119
|
|
@@ -121,5 +129,5 @@ Dependent package
|
|
121
129
|
================================================================================================================== =================
|
122
130
|
|
123
131
|
The changelog for the provider package can be found in the
|
124
|
-
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.
|
132
|
+
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.0/changelog.html>`_.
|
125
133
|
|
@@ -23,7 +23,7 @@
|
|
23
23
|
|
24
24
|
Package ``apache-airflow-providers-fab``
|
25
25
|
|
26
|
-
Release: ``2.0.
|
26
|
+
Release: ``2.0.0``
|
27
27
|
|
28
28
|
|
29
29
|
`Flask App Builder <https://flask-appbuilder.readthedocs.io/>`__
|
@@ -36,7 +36,7 @@ This is a provider package for ``fab`` provider. All classes for this provider p
|
|
36
36
|
are in ``airflow.providers.fab`` python package.
|
37
37
|
|
38
38
|
You can find package information and changelog for the provider
|
39
|
-
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.
|
39
|
+
in the `documentation <https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.0/>`_.
|
40
40
|
|
41
41
|
Installation
|
42
42
|
------------
|
@@ -55,18 +55,22 @@ PIP package Version required
|
|
55
55
|
========================================== ==================
|
56
56
|
``apache-airflow`` ``>=3.0.0.dev0``
|
57
57
|
``apache-airflow-providers-common-compat`` ``>=1.2.1``
|
58
|
-
``
|
58
|
+
``blinker`` ``>=1.6.2``
|
59
|
+
``flask`` ``>=2.2.1,<2.3``
|
59
60
|
``flask-appbuilder`` ``==4.5.3``
|
60
61
|
``flask-login`` ``>=0.6.2``
|
62
|
+
``flask-session`` ``>=0.4.0,<0.6``
|
63
|
+
``flask-wtf`` ``>=1.1.0``
|
61
64
|
``connexion[flask]`` ``>=2.14.2,<3.0``
|
62
65
|
``jmespath`` ``>=0.7.0``
|
66
|
+
``werkzeug`` ``>=2.2,<4``
|
63
67
|
========================================== ==================
|
64
68
|
|
65
69
|
Cross provider package dependencies
|
66
70
|
-----------------------------------
|
67
71
|
|
68
72
|
Those are dependencies that might be needed in order to use all the features of the package.
|
69
|
-
You need to install the specified
|
73
|
+
You need to install the specified providers in order to use them.
|
70
74
|
|
71
75
|
You can install such cross-provider dependencies when installing from PyPI. For example:
|
72
76
|
|
@@ -82,4 +86,4 @@ Dependent package
|
|
82
86
|
================================================================================================================== =================
|
83
87
|
|
84
88
|
The changelog for the provider package can be found in the
|
85
|
-
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.
|
89
|
+
`changelog <https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.0/changelog.html>`_.
|
{apache_airflow_providers_fab-2.0.0b1 → apache_airflow_providers_fab-2.0.0rc2}/pyproject.toml
RENAMED
@@ -20,12 +20,12 @@
|
|
20
20
|
# IF YOU WANT TO MODIFY THIS FILE EXCEPT DEPENDENCIES, YOU SHOULD MODIFY THE TEMPLATE
|
21
21
|
# `pyproject_TEMPLATE.toml.jinja2` IN the `dev/breeze/src/airflow_breeze/templates` DIRECTORY
|
22
22
|
[build-system]
|
23
|
-
requires = ["flit_core==3.
|
23
|
+
requires = ["flit_core==3.12.0"]
|
24
24
|
build-backend = "flit_core.buildapi"
|
25
25
|
|
26
26
|
[project]
|
27
27
|
name = "apache-airflow-providers-fab"
|
28
|
-
version = "2.0.
|
28
|
+
version = "2.0.0.rc2"
|
29
29
|
description = "Provider package apache-airflow-providers-fab for Apache Airflow"
|
30
30
|
readme = "README.rst"
|
31
31
|
authors = [
|
@@ -58,8 +58,14 @@ requires-python = "~=3.9"
|
|
58
58
|
# After you modify the dependencies, and rebuild your Breeze CI image with ``breeze ci-image build``
|
59
59
|
dependencies = [
|
60
60
|
"apache-airflow>=3.0.0.dev0",
|
61
|
-
"apache-airflow-providers-common-compat>=1.2.
|
62
|
-
|
61
|
+
"apache-airflow-providers-common-compat>=1.2.1rc0",
|
62
|
+
# Blinker use for signals in Flask, this is an optional dependency in Flask 2.2 and lower.
|
63
|
+
# In Flask 2.3 it becomes a mandatory dependency, and flask signals are always available.
|
64
|
+
"blinker>=1.6.2",
|
65
|
+
# Flask 2.3 is scheduled to introduce a number of deprecation removals - some of them might be breaking
|
66
|
+
# for our dependencies - notably `_app_ctx_stack` and `_request_ctx_stack` removals.
|
67
|
+
# We should remove the limitation after 2.3 is released and our dependencies are updated to handle it
|
68
|
+
"flask>=2.2.1,<2.3",
|
63
69
|
# We are tightly coupled with FAB version as we vendored-in part of FAB code related to security manager
|
64
70
|
# This is done as part of preparation to removing FAB as dependency, but we are not ready for it yet
|
65
71
|
# Every time we update FAB version here, please make sure that you review the classes and models in
|
@@ -67,8 +73,16 @@ dependencies = [
|
|
67
73
|
# In particular, make sure any breaking changes, for example any new methods, are accounted for.
|
68
74
|
"flask-appbuilder==4.5.3",
|
69
75
|
"flask-login>=0.6.2",
|
76
|
+
# Flask-Session 0.6 add new arguments into the SqlAlchemySessionInterface constructor as well as
|
77
|
+
# all parameters now are mandatory which make AirflowDatabaseSessionInterface incompatible with this version.
|
78
|
+
"flask-session>=0.4.0,<0.6",
|
79
|
+
"flask-wtf>=1.1.0",
|
70
80
|
"connexion[flask]>=2.14.2,<3.0",
|
71
81
|
"jmespath>=0.7.0",
|
82
|
+
# Werkzug 3 breaks Flask-Login 0.6.2
|
83
|
+
# we should remove this limitation when FAB supports Flask 2.3
|
84
|
+
"werkzeug>=2.2,<4",
|
85
|
+
|
72
86
|
]
|
73
87
|
|
74
88
|
# The optional dependencies should be modified in place in the generated file
|
@@ -86,6 +100,7 @@ dev = [
|
|
86
100
|
"apache-airflow-providers-common-compat",
|
87
101
|
# Additional devel dependencies (do not remove this line and add extra development dependencies)
|
88
102
|
"kerberos>=1.3.0",
|
103
|
+
"requests_kerberos>=0.14.0",
|
89
104
|
]
|
90
105
|
|
91
106
|
[tool.uv.sources]
|
@@ -99,8 +114,8 @@ apache-airflow-providers-fab = {workspace = true}
|
|
99
114
|
apache-airflow-providers-standard = {workspace = true}
|
100
115
|
|
101
116
|
[project.urls]
|
102
|
-
"Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.
|
103
|
-
"Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.
|
117
|
+
"Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.0"
|
118
|
+
"Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-fab/2.0.0/changelog.html"
|
104
119
|
"Bug Tracker" = "https://github.com/apache/airflow/issues"
|
105
120
|
"Source Code" = "https://github.com/apache/airflow"
|
106
121
|
"Slack Chat" = "https://s.apache.org/airflow-slack"
|
@@ -29,7 +29,7 @@ from airflow import __version__ as airflow_version
|
|
29
29
|
|
30
30
|
__all__ = ["__version__"]
|
31
31
|
|
32
|
-
__version__ = "2.0.
|
32
|
+
__version__ = "2.0.0"
|
33
33
|
|
34
34
|
if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
|
35
35
|
"3.0.0.dev0"
|
@@ -26,9 +26,9 @@ from flask_appbuilder.const import AUTH_LDAP
|
|
26
26
|
from flask_login import login_user
|
27
27
|
|
28
28
|
from airflow.api_fastapi.app import get_auth_manager
|
29
|
-
from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager
|
30
29
|
|
31
30
|
if TYPE_CHECKING:
|
31
|
+
from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager
|
32
32
|
from airflow.providers.fab.auth_manager.models import User
|
33
33
|
|
34
34
|
CLIENT_AUTH: tuple[str, str] | Any | None = None
|
@@ -45,8 +45,7 @@ def auth_current_user() -> User | None:
|
|
45
45
|
auth = request.authorization
|
46
46
|
if auth is None or not auth.username or not auth.password:
|
47
47
|
return None
|
48
|
-
|
49
|
-
security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
|
48
|
+
security_manager = cast("FabAuthManager", get_auth_manager()).security_manager
|
50
49
|
user = None
|
51
50
|
if security_manager.auth_type == AUTH_LDAP:
|
52
51
|
user = security_manager.auth_user_ldap(auth.username, auth.password)
|
@@ -67,4 +66,4 @@ def requires_authentication(function: T):
|
|
67
66
|
else:
|
68
67
|
return Response("Unauthorized", 401, {"WWW-Authenticate": "Basic"})
|
69
68
|
|
70
|
-
return cast(T, decorated)
|
69
|
+
return cast("T", decorated)
|
@@ -28,11 +28,11 @@ from requests_kerberos import HTTPKerberosAuth
|
|
28
28
|
|
29
29
|
from airflow.api_fastapi.app import get_auth_manager
|
30
30
|
from airflow.configuration import conf
|
31
|
-
from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager
|
32
31
|
from airflow.utils.net import getfqdn
|
33
32
|
|
34
33
|
if TYPE_CHECKING:
|
35
34
|
from airflow.api_fastapi.auth.managers.models.base_user import BaseUser
|
35
|
+
from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager
|
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(FabAuthManager, 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
|
|
@@ -143,4 +143,4 @@ def requires_authentication(function: T, find_user: Callable[[str], BaseUser] |
|
|
143
143
|
return _forbidden()
|
144
144
|
return _unauthorized()
|
145
145
|
|
146
|
-
return cast(T, decorated)
|
146
|
+
return cast("T", decorated)
|
@@ -25,7 +25,6 @@ from marshmallow import ValidationError
|
|
25
25
|
from sqlalchemy import asc, desc, func, select
|
26
26
|
|
27
27
|
from airflow.api_fastapi.app import get_auth_manager
|
28
|
-
from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager
|
29
28
|
from airflow.providers.fab.auth_manager.models import Action, Role
|
30
29
|
from airflow.providers.fab.auth_manager.schemas.role_and_permission_schema import (
|
31
30
|
ActionCollection,
|
@@ -40,6 +39,7 @@ from airflow.providers.fab.www.api_connexion.security import requires_access_cus
|
|
40
39
|
from airflow.providers.fab.www.security import permissions
|
41
40
|
|
42
41
|
if TYPE_CHECKING:
|
42
|
+
from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager
|
43
43
|
from airflow.providers.fab.auth_manager.security_manager.override import FabAirflowSecurityManagerOverride
|
44
44
|
from airflow.providers.fab.www.api_connexion.types import APIResponse, UpdateMask
|
45
45
|
|
@@ -60,7 +60,7 @@ def _check_action_and_resource(sm: FabAirflowSecurityManagerOverride, perms: lis
|
|
60
60
|
@requires_access_custom_view("GET", permissions.RESOURCE_ROLE)
|
61
61
|
def get_role(*, role_name: str) -> APIResponse:
|
62
62
|
"""Get role."""
|
63
|
-
security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
|
63
|
+
security_manager = cast("FabAuthManager", get_auth_manager()).security_manager
|
64
64
|
role = security_manager.find_role(name=role_name)
|
65
65
|
if not role:
|
66
66
|
raise NotFound(title="Role not found", detail=f"Role with name {role_name!r} was not found")
|
@@ -71,7 +71,7 @@ def get_role(*, role_name: str) -> APIResponse:
|
|
71
71
|
@format_parameters({"limit": check_limit})
|
72
72
|
def get_roles(*, order_by: str = "name", limit: int, offset: int | None = None) -> APIResponse:
|
73
73
|
"""Get roles."""
|
74
|
-
security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
|
74
|
+
security_manager = cast("FabAuthManager", get_auth_manager()).security_manager
|
75
75
|
session = security_manager.get_session
|
76
76
|
total_entries = session.scalars(select(func.count(Role.id))).one()
|
77
77
|
direction = desc if order_by.startswith("-") else asc
|
@@ -81,8 +81,7 @@ def get_roles(*, order_by: str = "name", limit: int, offset: int | None = None)
|
|
81
81
|
allowed_sort_attrs = ["role_id", "name"]
|
82
82
|
if order_by not in allowed_sort_attrs:
|
83
83
|
raise BadRequest(
|
84
|
-
detail=f"Ordering with '{order_by}' is disallowed or "
|
85
|
-
f"the attribute does not exist on the model"
|
84
|
+
detail=f"Ordering with '{order_by}' is disallowed or the attribute does not exist on the model"
|
86
85
|
)
|
87
86
|
|
88
87
|
query = select(Role)
|
@@ -99,7 +98,7 @@ def get_roles(*, order_by: str = "name", limit: int, offset: int | None = None)
|
|
99
98
|
@format_parameters({"limit": check_limit})
|
100
99
|
def get_permissions(*, limit: int, offset: int | None = None) -> APIResponse:
|
101
100
|
"""Get permissions."""
|
102
|
-
security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
|
101
|
+
security_manager = cast("FabAuthManager", get_auth_manager()).security_manager
|
103
102
|
session = security_manager.get_session
|
104
103
|
total_entries = session.scalars(select(func.count(Action.id))).one()
|
105
104
|
query = select(Action)
|
@@ -110,7 +109,7 @@ def get_permissions(*, limit: int, offset: int | None = None) -> APIResponse:
|
|
110
109
|
@requires_access_custom_view("DELETE", permissions.RESOURCE_ROLE)
|
111
110
|
def delete_role(*, role_name: str) -> APIResponse:
|
112
111
|
"""Delete a role."""
|
113
|
-
security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
|
112
|
+
security_manager = cast("FabAuthManager", get_auth_manager()).security_manager
|
114
113
|
|
115
114
|
role = security_manager.find_role(name=role_name)
|
116
115
|
if not role:
|
@@ -122,7 +121,7 @@ def delete_role(*, role_name: str) -> APIResponse:
|
|
122
121
|
@requires_access_custom_view("PUT", permissions.RESOURCE_ROLE)
|
123
122
|
def patch_role(*, role_name: str, update_mask: UpdateMask = None) -> APIResponse:
|
124
123
|
"""Update a role."""
|
125
|
-
security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
|
124
|
+
security_manager = cast("FabAuthManager", get_auth_manager()).security_manager
|
126
125
|
body = request.json
|
127
126
|
try:
|
128
127
|
data = role_schema.load(body)
|
@@ -155,7 +154,7 @@ def patch_role(*, role_name: str, update_mask: UpdateMask = None) -> APIResponse
|
|
155
154
|
@requires_access_custom_view("POST", permissions.RESOURCE_ROLE)
|
156
155
|
def post_role() -> APIResponse:
|
157
156
|
"""Create a new role."""
|
158
|
-
security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
|
157
|
+
security_manager = cast("FabAuthManager", get_auth_manager()).security_manager
|
159
158
|
body = request.json
|
160
159
|
try:
|
161
160
|
data = role_schema.load(body)
|
@@ -26,7 +26,6 @@ from sqlalchemy import asc, desc, func, select
|
|
26
26
|
from werkzeug.security import generate_password_hash
|
27
27
|
|
28
28
|
from airflow.api_fastapi.app import get_auth_manager
|
29
|
-
from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager
|
30
29
|
from airflow.providers.fab.auth_manager.models import User
|
31
30
|
from airflow.providers.fab.auth_manager.schemas.user_schema import (
|
32
31
|
UserCollection,
|
@@ -40,6 +39,7 @@ from airflow.providers.fab.www.api_connexion.security import requires_access_cus
|
|
40
39
|
from airflow.providers.fab.www.security import permissions
|
41
40
|
|
42
41
|
if TYPE_CHECKING:
|
42
|
+
from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager
|
43
43
|
from airflow.providers.fab.auth_manager.models import Role
|
44
44
|
from airflow.providers.fab.www.api_connexion.types import APIResponse, UpdateMask
|
45
45
|
|
@@ -47,7 +47,7 @@ if TYPE_CHECKING:
|
|
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(FabAuthManager, 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(FabAuthManager, 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
|
@@ -76,8 +76,7 @@ def get_users(*, limit: int, order_by: str = "id", offset: str | None = None) ->
|
|
76
76
|
]
|
77
77
|
if order_by not in allowed_sort_attrs:
|
78
78
|
raise BadRequest(
|
79
|
-
detail=f"Ordering with '{order_by}' is disallowed or "
|
80
|
-
f"the attribute does not exist on the model"
|
79
|
+
detail=f"Ordering with '{order_by}' is disallowed or the attribute does not exist on the model"
|
81
80
|
)
|
82
81
|
|
83
82
|
query = select(User).order_by(direction(getattr(User, order_param))).offset(offset).limit(limit)
|
@@ -94,7 +93,7 @@ def post_user() -> APIResponse:
|
|
94
93
|
except ValidationError as e:
|
95
94
|
raise BadRequest(detail=str(e.messages))
|
96
95
|
|
97
|
-
security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
|
96
|
+
security_manager = cast("FabAuthManager", get_auth_manager()).security_manager
|
98
97
|
username = data["username"]
|
99
98
|
email = data["email"]
|
100
99
|
|
@@ -137,7 +136,7 @@ def patch_user(*, username: str, update_mask: UpdateMask = None) -> APIResponse:
|
|
137
136
|
except ValidationError as e:
|
138
137
|
raise BadRequest(detail=str(e.messages))
|
139
138
|
|
140
|
-
security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
|
139
|
+
security_manager = cast("FabAuthManager", get_auth_manager()).security_manager
|
141
140
|
|
142
141
|
user = security_manager.find_user(username=username)
|
143
142
|
if user is None:
|
@@ -201,7 +200,7 @@ def patch_user(*, username: str, update_mask: UpdateMask = None) -> APIResponse:
|
|
201
200
|
@requires_access_custom_view("DELETE", permissions.RESOURCE_USER)
|
202
201
|
def delete_user(*, username: str) -> APIResponse:
|
203
202
|
"""Delete a user."""
|
204
|
-
security_manager = cast(FabAuthManager, get_auth_manager()).security_manager
|
203
|
+
security_manager = cast("FabAuthManager", get_auth_manager()).security_manager
|
205
204
|
|
206
205
|
user = security_manager.find_user(username=username)
|
207
206
|
if user is None:
|
@@ -89,7 +89,8 @@ components:
|
|
89
89
|
detail:
|
90
90
|
anyOf:
|
91
91
|
- type: string
|
92
|
-
-
|
92
|
+
- additionalProperties: true
|
93
|
+
type: object
|
93
94
|
title: Detail
|
94
95
|
type: object
|
95
96
|
required:
|
@@ -121,12 +122,12 @@ components:
|
|
121
122
|
description: API Token serializer for requests.
|
122
123
|
LoginResponse:
|
123
124
|
properties:
|
124
|
-
|
125
|
+
access_token:
|
125
126
|
type: string
|
126
|
-
title:
|
127
|
+
title: Access Token
|
127
128
|
type: object
|
128
129
|
required:
|
129
|
-
-
|
130
|
+
- access_token
|
130
131
|
title: LoginResponse
|
131
132
|
description: API Token serializer for responses.
|
132
133
|
ValidationError:
|
@@ -47,5 +47,5 @@ def create_token(body: LoginBody) -> LoginResponse:
|
|
47
47
|
def create_token_cli(body: LoginBody) -> LoginResponse:
|
48
48
|
"""Generate a new CLI API token."""
|
49
49
|
return FABAuthManagerLogin.create_token(
|
50
|
-
body=body,
|
50
|
+
body=body, expiration_time_in_seconds=conf.getint("api_auth", "jwt_cli_expiration_time")
|
51
51
|
)
|
@@ -24,9 +24,9 @@ from starlette.exceptions import HTTPException
|
|
24
24
|
from airflow.api_fastapi.app import get_auth_manager
|
25
25
|
from airflow.configuration import conf
|
26
26
|
from airflow.providers.fab.auth_manager.api_fastapi.datamodels.login import LoginBody, LoginResponse
|
27
|
-
from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager
|
28
27
|
|
29
28
|
if TYPE_CHECKING:
|
29
|
+
from airflow.providers.fab.auth_manager.fab_auth_manager import FabAuthManager
|
30
30
|
from airflow.providers.fab.auth_manager.models import User
|
31
31
|
|
32
32
|
|
@@ -35,7 +35,7 @@ class FABAuthManagerLogin:
|
|
35
35
|
|
36
36
|
@classmethod
|
37
37
|
def create_token(
|
38
|
-
cls, body: LoginBody,
|
38
|
+
cls, body: LoginBody, expiration_time_in_seconds: int = conf.getint("api_auth", "jwt_expiration_time")
|
39
39
|
) -> LoginResponse:
|
40
40
|
"""Create a new token."""
|
41
41
|
if not body.username or not body.password:
|
@@ -43,15 +43,15 @@ class FABAuthManagerLogin:
|
|
43
43
|
status_code=status.HTTP_400_BAD_REQUEST, detail="Username and password must be provided"
|
44
44
|
)
|
45
45
|
|
46
|
-
auth_manager = cast(FabAuthManager, get_auth_manager())
|
46
|
+
auth_manager = cast("FabAuthManager", get_auth_manager())
|
47
47
|
user: User = auth_manager.security_manager.find_user(username=body.username)
|
48
48
|
if not user:
|
49
49
|
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid username")
|
50
50
|
|
51
51
|
if auth_manager.security_manager.check_password(username=body.username, password=body.password):
|
52
52
|
return LoginResponse(
|
53
|
-
|
54
|
-
user=user, expiration_time_in_seconds=
|
53
|
+
access_token=auth_manager.generate_jwt(
|
54
|
+
user=user, expiration_time_in_seconds=expiration_time_in_seconds
|
55
55
|
)
|
56
56
|
)
|
57
57
|
else:
|
@@ -17,7 +17,7 @@
|
|
17
17
|
from __future__ import annotations
|
18
18
|
|
19
19
|
from airflow import settings
|
20
|
-
from airflow.cli.commands.
|
20
|
+
from airflow.cli.commands.db_command import run_db_downgrade_command, run_db_migrate_command
|
21
21
|
from airflow.providers.fab.auth_manager.models.db import _REVISION_HEADS_MAP, FABDBManager
|
22
22
|
from airflow.utils import cli as cli_utils
|
23
23
|
from airflow.utils.providers_configuration_loader import providers_configuration_loaded
|
@@ -59,7 +59,7 @@ def get_application_builder() -> Generator[AirflowAppBuilder, None, None]:
|
|
59
59
|
url = make_url(flask_app.config["SQLALCHEMY_DATABASE_URI"])
|
60
60
|
if url.drivername == "sqlite" and url.database and not isabs(url.database):
|
61
61
|
raise AirflowConfigException(
|
62
|
-
f
|
62
|
+
f"Cannot use relative path: `{conf.get('database', 'SQL_ALCHEMY_CONN')}` to connect to sqlite. "
|
63
63
|
"Please use absolute path such as `sqlite:////tmp/airflow.db`."
|
64
64
|
)
|
65
65
|
flask_app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
|
@@ -521,6 +521,10 @@ class FabAuthManager(BaseAuthManager[User]):
|
|
521
521
|
if self._is_authorized(method="MENU", resource_type=item["resource_type"], user=user)
|
522
522
|
]
|
523
523
|
|
524
|
+
@staticmethod
|
525
|
+
def get_db_manager() -> str | None:
|
526
|
+
return "airflow.providers.fab.auth_manager.models.db.FABDBManager"
|
527
|
+
|
524
528
|
def _is_authorized(
|
525
529
|
self,
|
526
530
|
*,
|
@@ -54,8 +54,8 @@ class FABDBManager(BaseDBManager):
|
|
54
54
|
alembic_file = (PACKAGE_DIR / "alembic.ini").as_posix()
|
55
55
|
supports_table_dropping = True
|
56
56
|
|
57
|
-
def
|
58
|
-
super().
|
57
|
+
def create_db_from_orm(self):
|
58
|
+
super().create_db_from_orm()
|
59
59
|
_get_flask_db(settings.SQL_ALCHEMY_CONN).create_all()
|
60
60
|
|
61
61
|
def upgradedb(self, to_revision=None, from_revision=None, show_sql_only=False):
|
@@ -687,12 +687,21 @@ components:
|
|
687
687
|
Basic:
|
688
688
|
type: http
|
689
689
|
scheme: basic
|
690
|
+
description: To authenticate FAB auth manager API requests, clients have the option to use basic
|
691
|
+
authentication. To learn more about FAB auth manager API authentication, please read
|
692
|
+
https://airflow.apache.org/docs/apache-airflow-providers-fab/stable/auth-manager/api-authentication.html#basic-authentication.
|
690
693
|
GoogleOpenId:
|
691
694
|
type: openIdConnect
|
692
695
|
openIdConnectUrl: https://accounts.google.com/.well-known/openid-configuration
|
696
|
+
description: To authenticate FAB auth manager API requests, clients have the option to use Google OpenID.
|
697
|
+
To learn more about Google OpenID authentication, please read
|
698
|
+
https://airflow.apache.org/docs/apache-airflow-providers-google/stable/api-auth-backend/google-openid.html.
|
693
699
|
Kerberos:
|
694
700
|
type: http
|
695
701
|
scheme: negotiate
|
702
|
+
description: To authenticate FAB auth manager API requests, clients have the option to use Kerberos
|
703
|
+
authentication. To learn more about FAB auth manager API authentication, please read
|
704
|
+
https://airflow.apache.org/docs/apache-airflow-providers-fab/stable/auth-manager/api-authentication.html#kerberos-authentication.
|
696
705
|
|
697
706
|
tags:
|
698
707
|
- name: Role
|
@@ -21,8 +21,6 @@ import copy
|
|
21
21
|
import datetime
|
22
22
|
import itertools
|
23
23
|
import logging
|
24
|
-
import os
|
25
|
-
import random
|
26
24
|
import uuid
|
27
25
|
from collections.abc import Collection, Iterable, Mapping
|
28
26
|
from typing import TYPE_CHECKING, Any
|
@@ -740,43 +738,6 @@ class FabAirflowSecurityManagerOverride(AirflowSecurityManagerV2):
|
|
740
738
|
"""Get the builtin roles."""
|
741
739
|
return self._builtin_roles
|
742
740
|
|
743
|
-
def create_admin_standalone(self) -> tuple[str | None, str | None]:
|
744
|
-
"""Create an Admin user with a random password so that users can access airflow."""
|
745
|
-
from airflow.configuration import AIRFLOW_HOME, make_group_other_inaccessible
|
746
|
-
|
747
|
-
user_name = "admin"
|
748
|
-
|
749
|
-
# We want a streamlined first-run experience, but we do not want to
|
750
|
-
# use a preset password as people will inevitably run this on a public
|
751
|
-
# server. Thus, we make a random password and store it in AIRFLOW_HOME,
|
752
|
-
# with the reasoning that if you can read that directory, you can see
|
753
|
-
# the database credentials anyway.
|
754
|
-
password_path = os.path.join(AIRFLOW_HOME, "standalone_admin_password.txt")
|
755
|
-
|
756
|
-
user_exists = self.find_user(user_name) is not None
|
757
|
-
we_know_password = os.path.isfile(password_path)
|
758
|
-
|
759
|
-
# If the user does not exist, make a random password and make it
|
760
|
-
if not user_exists:
|
761
|
-
print(f"FlaskAppBuilder Authentication Manager: Creating {user_name} user")
|
762
|
-
if (role := self.find_role("Admin")) is None:
|
763
|
-
raise AirflowException("Unable to find role 'Admin'")
|
764
|
-
# password does not contain visually similar characters: ijlIJL1oO0
|
765
|
-
password = "".join(random.choices("abcdefghkmnpqrstuvwxyzABCDEFGHKMNPQRSTUVWXYZ23456789", k=16))
|
766
|
-
with open(password_path, "w") as file:
|
767
|
-
file.write(password)
|
768
|
-
make_group_other_inaccessible(password_path)
|
769
|
-
self.add_user(user_name, "Admin", "User", "admin@example.com", role, password)
|
770
|
-
print(f"FlaskAppBuilder Authentication Manager: Created {user_name} user")
|
771
|
-
# If the user does exist, and we know its password, read the password
|
772
|
-
elif user_exists and we_know_password:
|
773
|
-
with open(password_path) as file:
|
774
|
-
password = file.read().strip()
|
775
|
-
# Otherwise we don't know the password
|
776
|
-
else:
|
777
|
-
password = None
|
778
|
-
return user_name, password
|
779
|
-
|
780
741
|
def _init_config(self):
|
781
742
|
"""
|
782
743
|
Initialize config.
|