diff --git a/Dockerfile b/Dockerfile index cf4552ab56ea1..402357402c467 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1088,13 +1088,17 @@ function create_www_user() { exit 1 fi - airflow users create \ - --username "${_AIRFLOW_WWW_USER_USERNAME="admin"}" \ - --firstname "${_AIRFLOW_WWW_USER_FIRSTNAME="Airflow"}" \ - --lastname "${_AIRFLOW_WWW_USER_LASTNAME="Admin"}" \ - --email "${_AIRFLOW_WWW_USER_EMAIL="airflowadmin@example.com"}" \ - --role "${_AIRFLOW_WWW_USER_ROLE="Admin"}" \ - --password "${local_password}" || true + if airflow config get-value core auth_manager | grep -q "FabAuthManager"; then + airflow users create \ + --username "${_AIRFLOW_WWW_USER_USERNAME="admin"}" \ + --firstname "${_AIRFLOW_WWW_USER_FIRSTNAME="Airflow"}" \ + --lastname "${_AIRFLOW_WWW_USER_LASTNAME="Admin"}" \ + --email "${_AIRFLOW_WWW_USER_EMAIL="airflowadmin@example.com"}" \ + --role "${_AIRFLOW_WWW_USER_ROLE="Admin"}" \ + --password "${local_password}" || true + else + echo "Skipping user creation as auth manager different from Fab is used" + fi } function create_system_user_if_missing() { diff --git a/Dockerfile.ci b/Dockerfile.ci index cd52d13497123..d6208cc2dbd21 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1029,9 +1029,13 @@ function start_api_server_with_examples(){ echo airflow dags reserialize echo "Example dags parsing finished" - echo "Create admin user" - airflow users create -u admin -p admin -f Thor -l Administrator -r Admin -e admin@email.domain - echo "Admin user created" + if airflow config get-value core auth_manager | grep -q "FabAuthManager"; then + echo "Create admin user" + airflow users create -u admin -p admin -f Thor -l Administrator -r Admin -e admin@email.domain || true + echo "Admin user created" + else + echo "Skipping user creation as auth manager different from Fab is used" + fi echo echo "${COLOR_BLUE}Starting airflow api server${COLOR_RESET}" echo diff --git a/airflow/api_fastapi/auth/managers/simple/simple_auth_manager.py b/airflow/api_fastapi/auth/managers/simple/simple_auth_manager.py index dfb535fe8266a..66e3a825e0218 100644 --- a/airflow/api_fastapi/auth/managers/simple/simple_auth_manager.py +++ b/airflow/api_fastapi/auth/managers/simple/simple_auth_manager.py @@ -120,15 +120,17 @@ def init(self) -> None: return users = self.get_users() passwords = self.get_passwords(users) + changed = False for user in users: if user["username"] not in passwords: # User dot not exist in the file, adding it passwords[user["username"]] = self._generate_password() + self._print_output(f"Password for user '{user['username']}': {passwords[user['username']]}") + changed = True - self._print_output(f"Password for user '{user['username']}': {passwords[user['username']]}") - - with open(self.get_generated_password_file(), "w") as file: - file.write(json.dumps(passwords)) + if changed: + with open(self.get_generated_password_file(), "w") as file: + file.write(json.dumps(passwords) + "\n") def get_url_login(self, **kwargs) -> str: """Return the login page url.""" @@ -151,7 +153,12 @@ def is_authorized_configuration( user: SimpleAuthManagerUser, details: ConfigurationDetails | None = None, ) -> bool: - return self._is_authorized(method=method, allow_role=SimpleAuthManagerRole.OP, user=user) + return self._is_authorized( + method=method, + allow_get_role=SimpleAuthManagerRole.VIEWER, + allow_role=SimpleAuthManagerRole.OP, + user=user, + ) def is_authorized_connection( self, diff --git a/airflow/config_templates/config.yml b/airflow/config_templates/config.yml index e771f0ffabff7..4d95c88462705 100644 --- a/airflow/config_templates/config.yml +++ b/airflow/config_templates/config.yml @@ -82,13 +82,13 @@ core: version_added: 2.7.0 type: string example: ~ - default: "airflow.providers.fab.auth_manager.fab_auth_manager.FabAuthManager" + default: "airflow.api_fastapi.auth.managers.simple.simple_auth_manager.SimpleAuthManager" simple_auth_manager_users: description: | The list of users and their associated role in simple auth manager. If the simple auth manager is used in your environment, this list controls who can access the environment. - List of user-role delimited with a space. Each user-role is a comma delimited couple of username and + List of user-role delimited with a comma. Each user-role is a colon delimited couple of username and role. Roles are predefined in simple auth managers: viewer, user, op, admin. version_added: 3.0.0 type: string diff --git a/clients/python/test_python_client.py b/clients/python/test_python_client.py index 0f4de597782a5..4227a414cf7e2 100644 --- a/clients/python/test_python_client.py +++ b/clients/python/test_python_client.py @@ -29,13 +29,15 @@ import sys import time import uuid +from typing import cast import airflow_client.client import pytest -from airflow.api_fastapi.app import create_app +from airflow.api_fastapi.app import create_app, get_auth_manager from airflow.api_fastapi.auth.managers.simple.datamodels.login import LoginBody -from airflow.providers.fab.auth_manager.api_fastapi.services.login import FABAuthManagerLogin +from airflow.api_fastapi.auth.managers.simple.services.login import SimpleAuthManagerLogin +from airflow.api_fastapi.auth.managers.simple.simple_auth_manager import SimpleAuthManager try: # If you have rich installed, you will have nice colored output of the API responses @@ -62,9 +64,14 @@ # privileges in Airflow # Used to initialize FAB and the auth manager, necessary for creating the token. -create_app() -access_token = FABAuthManagerLogin.create_token(LoginBody(username="admin", password="admin")).jwt_token + +create_app() +auth_manager = cast(get_auth_manager(), SimpleAuthManager) +users = auth_manager.get_users() +passwords = auth_manager.get_passwords(users) +username, password = next(iter(passwords.items())) +access_token = SimpleAuthManagerLogin.create_token(LoginBody(username=username, password=password)).jwt_token configuration = airflow_client.client.Configuration( host="http://localhost:8080/public", ) diff --git a/dev/breeze/doc/images/output_start-airflow.svg b/dev/breeze/doc/images/output_start-airflow.svg index b0a796a15ff1b..3dde897a7c784 100644 --- a/dev/breeze/doc/images/output_start-airflow.svg +++ b/dev/breeze/doc/images/output_start-airflow.svg @@ -1,4 +1,4 @@ - +