From b8a4aee67f902a5ed5e91bfd02c378bff8fdd125 Mon Sep 17 00:00:00 2001 From: uti Date: Thu, 2 Oct 2025 14:31:10 +0100 Subject: [PATCH 1/4] Added feature detection in werkzeug fab providers to allow detecting hashing algorithms available to different versions of werkzeug --- .../auth_manager/security_manager/override.py | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py b/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py index b9cfa969b7d73..7f61649fb9d8a 100644 --- a/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py +++ b/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py @@ -790,18 +790,8 @@ def _init_config(self): current_app.config.setdefault("AUTH_ROLES_SYNC_AT_LOGIN", False) current_app.config.setdefault("AUTH_API_LOGIN_ALLOW_MULTIPLE_PROVIDERS", False) - from packaging.version import Version - from werkzeug import __version__ as werkzeug_version - - parsed_werkzeug_version = Version(werkzeug_version) - if parsed_werkzeug_version < Version("3.0.0"): - current_app.config.setdefault("FAB_PASSWORD_HASH_METHOD", "pbkdf2:sha256") - current_app.config.setdefault( - "AUTH_DB_FAKE_PASSWORD_HASH_CHECK", - "pbkdf2:sha256:150000$Z3t6fmj2$22da622d94a1f8118" - "c0976a03d2f18f680bfff877c9a965db9eedc51bc0be87c", - ) - else: + try: + _ = generate_password_hash("test", method="scrypt") current_app.config.setdefault("FAB_PASSWORD_HASH_METHOD", "scrypt") current_app.config.setdefault( "AUTH_DB_FAKE_PASSWORD_HASH_CHECK", @@ -809,6 +799,13 @@ def _init_config(self): "8350189ffc4bcc71286edf1b8ad94a442c00f890224bf2b32153d0750c89ee9" "401e62f9dcee5399065e4e5", ) + except (ValueError, TypeError): + current_app.config.setdefault("FAB_PASSWORD_HASH_METHOD", "pbkdf2:sha256") + current_app.config.setdefault( + "AUTH_DB_FAKE_PASSWORD_HASH_CHECK", + "pbkdf2:sha256:150000$Z3t6fmj2$22da622d94a1f8118" + "c0976a03d2f18f680bfff877c9a965db9eedc51bc0be87c", + ) # LDAP Config if self.auth_type == AUTH_LDAP: From aafe1c049a93d34a21fa147981430caf3d4b505f Mon Sep 17 00:00:00 2001 From: uti Date: Sun, 5 Oct 2025 15:04:38 +0100 Subject: [PATCH 2/4] Using Version check as done by the upstream FAB provider --- .../auth_manager/security_manager/override.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py b/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py index 7f61649fb9d8a..44aa830b14603 100644 --- a/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py +++ b/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py @@ -100,7 +100,7 @@ from airflow.providers.fab.www.security_manager import AirflowSecurityManagerV2 from airflow.providers.fab.www.session import AirflowDatabaseSessionInterface from airflow.security.permissions import RESOURCE_BACKFILL - +from packaging.version import Version if TYPE_CHECKING: from airflow.providers.fab.www.security.permissions import ( RESOURCE_ASSET, @@ -790,7 +790,15 @@ def _init_config(self): current_app.config.setdefault("AUTH_ROLES_SYNC_AT_LOGIN", False) current_app.config.setdefault("AUTH_API_LOGIN_ALLOW_MULTIPLE_PROVIDERS", False) - try: + parsed_werkzeug_version = Version(importlib.metadata.version("werkzeug")) + if parsed_werkzeug_version < Version("3.0.0"): + current_app.config.setdefault("FAB_PASSWORD_HASH_METHOD", "pbkdf2:sha256") + current_app.config.setdefault( + "AUTH_DB_FAKE_PASSWORD_HASH_CHECK", + "pbkdf2:sha256:150000$Z3t6fmj2$22da622d94a1f8118" + "c0976a03d2f18f680bfff877c9a965db9eedc51bc0be87c", + ) + else: _ = generate_password_hash("test", method="scrypt") current_app.config.setdefault("FAB_PASSWORD_HASH_METHOD", "scrypt") current_app.config.setdefault( @@ -799,13 +807,6 @@ def _init_config(self): "8350189ffc4bcc71286edf1b8ad94a442c00f890224bf2b32153d0750c89ee9" "401e62f9dcee5399065e4e5", ) - except (ValueError, TypeError): - current_app.config.setdefault("FAB_PASSWORD_HASH_METHOD", "pbkdf2:sha256") - current_app.config.setdefault( - "AUTH_DB_FAKE_PASSWORD_HASH_CHECK", - "pbkdf2:sha256:150000$Z3t6fmj2$22da622d94a1f8118" - "c0976a03d2f18f680bfff877c9a965db9eedc51bc0be87c", - ) # LDAP Config if self.auth_type == AUTH_LDAP: From fca0b3b4ce2f54a52125d6f8b2857363fcfbf868 Mon Sep 17 00:00:00 2001 From: uti Date: Sun, 5 Oct 2025 15:07:30 +0100 Subject: [PATCH 3/4] Removing used var --- .../providers/fab/auth_manager/security_manager/override.py | 1 - 1 file changed, 1 deletion(-) diff --git a/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py b/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py index 44aa830b14603..2557c31b51626 100644 --- a/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py +++ b/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py @@ -799,7 +799,6 @@ def _init_config(self): "c0976a03d2f18f680bfff877c9a965db9eedc51bc0be87c", ) else: - _ = generate_password_hash("test", method="scrypt") current_app.config.setdefault("FAB_PASSWORD_HASH_METHOD", "scrypt") current_app.config.setdefault( "AUTH_DB_FAKE_PASSWORD_HASH_CHECK", From 501fa9781c2e01e1e5098638fd9cbf4ba6beb9dc Mon Sep 17 00:00:00 2001 From: uti Date: Sun, 5 Oct 2025 18:12:40 +0100 Subject: [PATCH 4/4] Adding missing importlib import --- .../providers/fab/auth_manager/security_manager/override.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py b/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py index 2557c31b51626..19085c835acb5 100644 --- a/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py +++ b/providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py @@ -19,6 +19,7 @@ import copy import datetime +import importlib import itertools import logging import uuid @@ -59,6 +60,7 @@ from flask_login import LoginManager from itsdangerous import want_bytes from markupsafe import Markup, escape +from packaging.version import Version from sqlalchemy import delete, func, inspect, or_, select from sqlalchemy.exc import MultipleResultsFound from sqlalchemy.orm import joinedload @@ -100,7 +102,7 @@ from airflow.providers.fab.www.security_manager import AirflowSecurityManagerV2 from airflow.providers.fab.www.session import AirflowDatabaseSessionInterface from airflow.security.permissions import RESOURCE_BACKFILL -from packaging.version import Version + if TYPE_CHECKING: from airflow.providers.fab.www.security.permissions import ( RESOURCE_ASSET, @@ -798,7 +800,7 @@ def _init_config(self): "pbkdf2:sha256:150000$Z3t6fmj2$22da622d94a1f8118" "c0976a03d2f18f680bfff877c9a965db9eedc51bc0be87c", ) - else: + else: current_app.config.setdefault("FAB_PASSWORD_HASH_METHOD", "scrypt") current_app.config.setdefault( "AUTH_DB_FAKE_PASSWORD_HASH_CHECK",