Skip to content

Bump flask-appbuilder to 5.2.1 and mirror new auth event hooks#66841

Merged
potiuk merged 1 commit into
apache:mainfrom
potiuk:bump-flask-appbuilder-5.2.1
May 16, 2026
Merged

Bump flask-appbuilder to 5.2.1 and mirror new auth event hooks#66841
potiuk merged 1 commit into
apache:mainfrom
potiuk:bump-flask-appbuilder-5.2.1

Conversation

@potiuk
Copy link
Copy Markdown
Member

@potiuk potiuk commented May 13, 2026

Summary

Upstream Flask-AppBuilder 5.2.1 was released to PyPI on 2026-04-09 (commit 5dae8164 titled "release: 5.2.1"). The maintainer did not cut a GitHub release / tag, which is why gh api .../tags still shows v5.2.0 as the latest. The release has three changes that matter for our vendored BaseSecurityManager:

Upstream change Effect on Airflow
PR #2450 — new on_user_login / on_user_login_failed / on_user_logout no-op hooks; update_user_auth_stat now calls on_user_login{,_failed}; AuthView.logout / SAML SLO call on_user_logout Vendoredupdate_user_auth_stat is in override.py, so the hook calls must be mirrored or the hooks never fire in Airflow. This PR mirrors them.
PR #2451_is_user_detached / _get_safe_user helpers; has_access rewrite handling DetachedInstanceError on g.user (LocalProxy or detached ORM) Inherited automatically — has_access is not vendored in override.py. No mirror needed.
PR #2440 — security log redactions: OAuth tokens / responses no longer logged at debug level Inherited automatically — the redacted code paths are not vendored.

Changes

  1. providers/fab/pyproject.toml — bump flask-appbuilder==5.2.0==5.2.1
  2. providers/fab/src/airflow/providers/fab/auth_manager/security_manager/override.py — add no-op on_user_login / on_user_login_failed / on_user_logout mirroring FAB's defaults; append the hook dispatch at the end of update_user_auth_stat matching the upstream call order (after update_user, so counters and last_login are persisted before the hook runs).
  3. providers/fab/tests/unit/fab/auth_manager/security_manager/test_fab_alignment.py — bump EXPECTED_FAB_VERSION to "5.2.1".
  4. uv.lock — re-resolved.

generated/provider_dependencies.json and providers/fab/docs/index.rst regenerated by prek.

Validation

  • test_fab_alignment.py — all 7 alignment tests pass with flask-appbuilder==5.2.1 installed (the test compares FabAirflowSecurityManagerOverride against BaseSecurityManager from FAB).
  • providers/fab/tests/unit/fab/auth_manager/security_manager/ — all 39 unit tests pass.

Note on the upstream PyJWT root cause

This PR builds on #66840 (parent branch pin-pyjwt-in-fab-provider), which adds a defensive pyjwt>=2.11.0 pin to providers/fab/pyproject.toml to keep the FAB provider installable against older airflow-core releases. The actual root cause is in flask-jwt-extended, not FAB:

  • flask_jwt_extended/tokens.py does from jwt.types import Options, and jwt.types.Options was first added in PyJWT 2.11.0
  • flask-jwt-extended 4.7.3 (2026-05-08) bumped requirements.txt to PyJWT==2.12.1 but did not lift the floor in setup.py::install_requires, which still reads PyJWT>=2.0,<3.0
  • That gap means downstream consumers can resolve flask-jwt-extended 4.7.3 with PyJWT 2.10.x and still hit the broken import

A follow-up issue against vimalloc/flask-jwt-extended to lift their distributed-package install_requires floor to PyJWT>=2.11.0 would be the cleanest long-term fix; until then, FAB's PyJWT>=2.0.0,<3.0.0 pin is also too permissive but matches flask-jwt-extended's. Our airflow-side defensive pin (#66840) closes the loop without waiting on either upstream.

Test plan

  • CI green on this branch
  • test_fab_alignment.py passes in CI (it was the canary test we were supposed to run on every FAB version bump per the comment at pyproject.toml:80)
  • Compat-3.0.6 matrix job collects providers/fab tests cleanly (the original failure that motivated the parent PR)

related: #66840


Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 4.7)

Generated-by: Claude Code (Opus 4.7) following the guidelines

@github-actions
Copy link
Copy Markdown
Contributor

uv.lock on main just moved via commit 79a7a41 and this PR currently conflicts.

Quickest fix:

git fetch upstream main && git rebase upstream/main
rm uv.lock && uv lock
git add uv.lock && git rebase --continue
git push --force-with-lease

Automated nudge — ignore if you're not ready to rebase. This comment is updated in place on future uv.lock bumps.

Upstream FAB 5.2.1 was released to PyPI on 2026-04-09 (no GitHub release
was cut, only a master commit `5dae8164` titled "release: 5.2.1"). It
adds three vendored-relevant items on top of 5.2.0:

  - PR apache#2450 (commit 63e7708e) — three new no-op hook methods on
    BaseSecurityManager: on_user_login, on_user_login_failed,
    on_user_logout. update_user_auth_stat now calls on_user_login or
    on_user_login_failed at the end. AuthView.logout / SAML SLO call
    on_user_logout. Hook defaults are no-ops; subclasses can override
    for audit logging.
  - PR apache#2451 — _is_user_detached / _get_safe_user helpers + a rewrite
    of has_access to handle DetachedInstanceError on g.user (LocalProxy
    or detached ORM instance after some session boundary). Inherited
    automatically; not vendored in override.py so no mirror needed.
  - PR apache#2440 — security log redactions: OAuth tokens / responses no
    longer logged at debug level. Inherited; the redacted code paths
    are not vendored in override.py.

Mirror the auth-event-hook pieces into FabAirflowSecurityManagerOverride
since update_user_auth_stat is vendored. Without this mirror, the new
hooks would not fire in Airflow because override.py shadows the upstream
implementation.

Specifically:

  - Add no-op on_user_login / on_user_login_failed / on_user_logout
    methods on FabAirflowSecurityManagerOverride mirroring the FAB
    defaults.
  - Append the on_user_login / on_user_login_failed dispatch at the
    end of FabAirflowSecurityManagerOverride.update_user_auth_stat,
    matching the upstream order (called after update_user, so the
    counters / last_login are already persisted before the hook runs).

Bump EXPECTED_FAB_VERSION in test_fab_alignment.py to 5.2.1; all 7
alignment tests + 39 security_manager unit tests pass locally with
flask-appbuilder==5.2.1 installed.

The pyjwt floor pin from the parent commit on this branch is unchanged;
the lock-file bump for it is included here because uv re-resolved the
graph for the FAB version bump.
@potiuk potiuk force-pushed the bump-flask-appbuilder-5.2.1 branch from dfed5e1 to a7cef48 Compare May 13, 2026 18:47
@potiuk potiuk merged commit c72b661 into apache:main May 16, 2026
106 checks passed
@potiuk potiuk deleted the bump-flask-appbuilder-5.2.1 branch May 16, 2026 00:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants