Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions airflow/providers/fab/CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,151 @@
Changelog
---------

1.5.4
.....

* ``[providers-fab/v1-5] Update dependencies for FAB provider to not be conflicting with 2.11.1 (#53029)``

.. Below changes are excluded from the changelog. Move them to
appropriate section above if needed. Do not delete the lines(!):


1.5.3
.....

Bug Fixes
~~~~~~~~~

* ``[providers-fab/v1-5] Use different default algorithms for different werkzeug versions (#46384) (#46392)``

Misc
~~~~

* ``[providers-fab/v1-5] Upgrade to FAB 4.5.3 (#45874) (#45918)``

.. Below changes are excluded from the changelog. Move them to
appropriate section above if needed. Do not delete the lines(!):

1.5.2
.....

Misc
~~~~

* ``Correctly import isabs from os.path (#45178)``
* ``[providers-fab/v1-5] Invalidate user session on password reset (#45139)``


.. Below changes are excluded from the changelog. Move them to
appropriate section above if needed. Do not delete the lines(!):

1.5.1
.....

Bug Fixes
~~~~~~~~~

* ``fab_auth_manager: allow get_user method to return the user authenticated via Kerberos (#43662)``


.. Below changes are excluded from the changelog. Move them to
appropriate section above if needed. Do not delete the lines(!):
* ``Expand and improve the kerberos api authentication documentation (#43682)``

1.5.0
.....

Features
~~~~~~~~

* ``feat(providers/fab): Use asset in common provider (#43112)``

Bug Fixes
~~~~~~~~~

* ``fix revoke Dag stale permission on airflow < 2.10 (#42844)``
* ``fix(providers/fab): alias is_authorized_dataset to is_authorized_asset (#43469)``
* ``fix: Change CustomSecurityManager method name (#43034)``

Misc
~~~~

* ``Upgrade Flask-AppBuilder to 4.5.2 (#43309)``
* ``Upgrade Flask-AppBuilder to 4.5.1 (#43251)``
* ``Move user and roles schemas to fab provider (#42869)``
* ``Move the session auth backend to FAB auth manager (#42878)``
* ``Add logging to the migration commands (#43516)``
* ``DOC fix documentation error in 'apache-airflow-providers-fab/access-control.rst' (#43495)``
* ``Rename dataset as asset in UI (#43073)``

.. Below changes are excluded from the changelog. Move them to
appropriate section above if needed. Do not delete the lines(!):
* ``Split providers out of the main "airflow/" tree into a UV workspace project (#42505)``
* ``Start porting DAG definition code to the Task SDK (#43076)``
* ``Prepare docs for Oct 2nd wave of providers (#43409)``
* ``Prepare docs for Oct 2nd wave of providers RC2 (#43540)``

1.4.1
.....

Misc
~~~~

* ``Update Rest API tests to no longer rely on FAB auth manager. Move tests specific to FAB permissions to FAB provider (#42523)``
* ``Rename dataset related python variable names to asset (#41348)``
* ``Simplify expression for get_permitted_dag_ids query (#42484)``


.. Below changes are excluded from the changelog. Move them to
appropriate section above if needed. Do not delete the lines(!):

1.4.0
.....

Features
~~~~~~~~

* ``Add FAB migration commands (#41804)``
* ``Separate FAB migration from Core Airflow migration (#41437)``

Misc
~~~~

* ``Deprecated kerberos auth removed (#41693)``
* ``Deprecated configuration removed (#42129)``
* ``Move 'is_active' user property to FAB auth manager (#42042)``
* ``Move 'register_views' to auth manager interface (#41777)``
* ``Revert "Provider fab auth manager deprecated methods removed (#41720)" (#41960)``
* ``Provider fab auth manager deprecated methods removed (#41720)``
* ``Make kerberos an optional and devel dependency for impala and fab (#41616)``


.. Below changes are excluded from the changelog. Move them to
appropriate section above if needed. Do not delete the lines(!):
* ``Add TODOs in providers code for Subdag code removal (#41963)``
* ``Add fixes by breeze/precommit-lint static checks (#41604) (#41618)``

.. Review and move the new changes to one of the sections above:
* ``Fix pre-commit for auto update of fab migration versions (#42382)``
* ``Handle 'AUTH_ROLE_PUBLIC' in FAB auth manager (#42280)``

1.3.0
.....

Features
~~~~~~~~

* ``Feature: Allow set Dag Run resource into Dag Level permission (#40703)``

Misc
~~~~

* ``Remove deprecated SubDags (#41390)``


.. Below changes are excluded from the changelog. Move them to
appropriate section above if needed. Do not delete the lines(!):

1.2.2
.....

Expand Down
2 changes: 1 addition & 1 deletion airflow/providers/fab/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

__all__ = ["__version__"]

__version__ = "1.2.2"
__version__ = "1.5.4"

if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse(
"2.9.0"
Expand Down
133 changes: 133 additions & 0 deletions airflow/providers/fab/alembic.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

# A generic, single database configuration.

[alembic]
# path to migration scripts
# Use forward slashes (/) also on windows to provide an os agnostic path
script_location = %(here)s/migrations

# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s
# Uncomment the line below if you want the files to be prepended with date and time
# see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file
# for all available tokens
# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s

# sys.path path, will be prepended to sys.path if present.
# defaults to the current working directory.
prepend_sys_path = .

# timezone to use when rendering the date within the migration file
# as well as the filename.
# If specified, requires the python>=3.9 or backports.zoneinfo library.
# Any required deps can installed by adding `alembic[tz]` to the pip requirements
# string value is passed to ZoneInfo()
# leave blank for localtime
# timezone =

# max length of characters to apply to the "slug" field
# truncate_slug_length = 40

# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false

# set to 'true' to allow .pyc and .pyo files without
# a source .py file to be detected as revisions in the
# versions/ directory
# sourceless = false

# version location specification; This defaults
# to alembic/versions. When using multiple version
# directories, initial revisions must be specified with --version-path.
# The path separator used here should be the separator specified by "version_path_separator" below.
# version_locations = %(here)s/bar:%(here)s/bat:alembic/versions

# version path separator; As mentioned above, this is the character used to split
# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep.
# If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas.
# Valid values for version_path_separator are:
#
# version_path_separator = :
# version_path_separator = ;
# version_path_separator = space
version_path_separator = os # Use os.pathsep. Default configuration used for new projects.

# set to 'true' to search source files recursively
# in each "version_locations" directory
# new in Alembic version 1.10
# recursive_version_locations = false

# the output encoding used when revision files
# are written from script.py.mako
# output_encoding = utf-8

sqlalchemy.url = scheme://localhost/airflow


[post_write_hooks]
# post_write_hooks defines scripts or Python functions that are run
# on newly generated revision scripts. See the documentation for further
# detail and examples

# format using "black" - use the console_scripts runner, against the "black" entrypoint
# hooks = black
# black.type = console_scripts
# black.entrypoint = black
# black.options = -l 79 REVISION_SCRIPT_FILENAME

# lint with attempts to fix using "ruff" - use the exec runner, execute a binary
# hooks = ruff
# ruff.type = exec
# ruff.executable = %(here)s/.venv/bin/ruff
# ruff.options = --fix REVISION_SCRIPT_FILENAME

# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = WARN
handlers = console
qualname =

[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine

[logger_alembic]
level = INFO
handlers =
qualname = alembic

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S
20 changes: 17 additions & 3 deletions airflow/providers/fab/auth_manager/api/auth/backend/basic_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from functools import wraps
from typing import TYPE_CHECKING, Any, Callable, TypeVar, cast

from flask import Response, request
from flask import Response, current_app, request
from flask_appbuilder.const import AUTH_LDAP
from flask_login import login_user

Expand Down Expand Up @@ -62,9 +62,23 @@ def requires_authentication(function: T):

@wraps(function)
def decorated(*args, **kwargs):
if auth_current_user() is not None:
# Try to authenticate the user
user = auth_current_user()
if user is not None:
return function(*args, **kwargs)
else:

# Authentication failed - check if Authorization header was provided
auth_header = request.headers.get("Authorization")
if auth_header:
# Authorization header was present but authentication failed
# This includes malformed headers that Flask couldn't parse
return Response("Unauthorized", 401, {"WWW-Authenticate": "Basic"})

# No Authorization header - check if public access is allowed
if current_app.config.get("AUTH_ROLE_PUBLIC", None):
return function(*args, **kwargs)

# No auth header and no public access
return Response("Unauthorized", 401, {"WWW-Authenticate": "Basic"})

return cast(T, decorated)
Loading
Loading