You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by vi...@apache.org on 2025/11/26 16:03:21 UTC

(airflow) branch main updated: Do not delete users from simple auth manager user file (#58688)

This is an automated email from the ASF dual-hosted git repository.

vincbeck pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 97cd1c9c990 Do not delete users from simple auth manager user file (#58688)
97cd1c9c990 is described below

commit 97cd1c9c99030be89cebaddc2e342359fc01b5b8
Author: Vincent <97...@users.noreply.github.com>
AuthorDate: Wed Nov 26 11:03:13 2025 -0500

    Do not delete users from simple auth manager user file (#58688)
---
 .../auth/managers/simple/services/login.py            |  2 +-
 .../auth/managers/simple/simple_auth_manager.py       | 19 ++++++-------------
 .../auth/managers/simple/services/test_login.py       |  3 +--
 .../auth/managers/simple/test_simple_auth_manager.py  |  7 ++-----
 4 files changed, 10 insertions(+), 21 deletions(-)

diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/services/login.py b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/services/login.py
index d4e606ebfc3..3ecfd1cd294 100644
--- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/services/login.py
+++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/services/login.py
@@ -52,7 +52,7 @@ class SimpleAuthManagerLogin:
             )
 
         users = SimpleAuthManager.get_users()
-        passwords = SimpleAuthManager.get_passwords(users)
+        passwords = SimpleAuthManager.get_passwords()
         found_users = [
             user
             for user in users
diff --git a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/simple_auth_manager.py b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/simple_auth_manager.py
index 301526d7da5..15834a2cfb1 100644
--- a/airflow-core/src/airflow/api_fastapi/auth/managers/simple/simple_auth_manager.py
+++ b/airflow-core/src/airflow/api_fastapi/auth/managers/simple/simple_auth_manager.py
@@ -102,10 +102,10 @@ class SimpleAuthManager(BaseAuthManager[SimpleAuthManagerUser]):
         return [{"username": username, "role": role} for username, role in users]
 
     @staticmethod
-    def get_passwords(users: list[dict[str, str]]) -> dict[str, str]:
+    def get_passwords() -> dict[str, str]:
         password_file = SimpleAuthManager.get_generated_password_file()
         with open(password_file, "r+") as file:
-            return SimpleAuthManager._get_passwords(users=users, stream=file)[0]
+            return SimpleAuthManager._get_passwords(file)
 
     def init(self) -> None:
         is_simple_auth_manager_all_admins = conf.getboolean("core", "simple_auth_manager_all_admins")
@@ -121,7 +121,8 @@ class SimpleAuthManager(BaseAuthManager[SimpleAuthManagerUser]):
                     # Fastapi spins up N workers, so this method is called N times in N different processes
                     # This needs to be called only once so we use the file ``password_file`` as locking mechanism
                     fcntl.flock(file, fcntl.LOCK_EX | fcntl.LOCK_NB)
-                    passwords, changed = self._get_passwords(users=users, stream=file)
+                    passwords = self._get_passwords(stream=file)
+                    changed = False
                     for user in users:
                         if user["username"] not in passwords:
                             # User does not exist in the file, adding it
@@ -359,7 +360,7 @@ class SimpleAuthManager(BaseAuthManager[SimpleAuthManagerUser]):
         return role.order >= allow_role.order
 
     @staticmethod
-    def _get_passwords(users: list[dict[str, str]], stream: TextIO) -> tuple[dict[str, str], bool]:
+    def _get_passwords(stream: TextIO) -> dict[str, str]:
         try:
             # Read passwords from file
             stream.seek(0)
@@ -369,15 +370,7 @@ class SimpleAuthManager(BaseAuthManager[SimpleAuthManagerUser]):
             log.error("Error decoding JSON from file %s", stream.name)
             raise
 
-        usernames = {user["username"] for user in users}
-        changed = bool(user_passwords_from_file.keys() - usernames)
-        user_passwords_from_file = {
-            username: password
-            for username, password in user_passwords_from_file.items()
-            if username in usernames
-        }
-
-        return user_passwords_from_file, changed
+        return user_passwords_from_file
 
     @staticmethod
     def _generate_password() -> str:
diff --git a/airflow-core/tests/unit/api_fastapi/auth/managers/simple/services/test_login.py b/airflow-core/tests/unit/api_fastapi/auth/managers/simple/services/test_login.py
index 9c8299a8a21..e6a843c75cc 100644
--- a/airflow-core/tests/unit/api_fastapi/auth/managers/simple/services/test_login.py
+++ b/airflow-core/tests/unit/api_fastapi/auth/managers/simple/services/test_login.py
@@ -56,8 +56,7 @@ class TestLogin:
             }
         ):
             auth_manager.init()
-            users = auth_manager.get_users()
-            passwords = auth_manager.get_passwords(users=users)
+            passwords = auth_manager.get_passwords()
             result = SimpleAuthManagerLogin.create_token(
                 body=LoginBody(username=test_user, password=passwords.get(test_user, "invalid_password")),
                 expiration_time_in_seconds=1,
diff --git a/airflow-core/tests/unit/api_fastapi/auth/managers/simple/test_simple_auth_manager.py b/airflow-core/tests/unit/api_fastapi/auth/managers/simple/test_simple_auth_manager.py
index 43699192fee..f5566be6595 100644
--- a/airflow-core/tests/unit/api_fastapi/auth/managers/simple/test_simple_auth_manager.py
+++ b/airflow-core/tests/unit/api_fastapi/auth/managers/simple/test_simple_auth_manager.py
@@ -47,7 +47,6 @@ class TestSimpleAuthManager:
             ("", {}),
             ('{"test1": "test1"}', {"test1": "test1"}),
             ('{"test1": "test1", "test2": "test2"}', {"test1": "test1", "test2": "test2"}),
-            ('{"test1": "test1", "test2": "test2", "test3": "test3"}', {"test1": "test1", "test2": "test2"}),
         ],
     )
     def test_get_passwords(self, auth_manager, file_content, expected):
@@ -58,8 +57,7 @@ class TestSimpleAuthManager:
         ):
             with open(auth_manager.get_generated_password_file(), "w") as file:
                 file.write(file_content)
-            users = auth_manager.get_users()
-            passwords = auth_manager.get_passwords(users)
+            passwords = auth_manager.get_passwords()
             assert passwords == expected
 
     def test_init_with_default_user(self, auth_manager):
@@ -87,8 +85,7 @@ class TestSimpleAuthManager:
         ("file_content", "expected"),
         [
             ({"test1": "test1"}, {"test1": "test1"}),
-            ({"test1": "test1", "test2": "test2"}, {"test1": "test1"}),
-            ({"test2": "test2", "test3": "test3"}, {"test1": mock.ANY}),
+            ({"test2": "test2", "test3": "test3"}, {"test1": mock.ANY, "test2": "test2", "test3": "test3"}),
         ],
     )
     def test_init_with_users_with_password(self, auth_manager, file_content, expected):