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
6 changes: 3 additions & 3 deletions airflow-core/newsfragments/41550.significant.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Removed deprecated ``session_lifetime_days`` and ``force_log_out_after`` configuration parameters from ``webserver`` section. Please use ``session_lifetime_minutes``.
Removed deprecated ``session_lifetime_days`` and ``force_log_out_after`` configuration parameters from ``webserver`` section. Please use ``session_lifetime_minutes`` from ``fab`` section.

Removed deprecated ``policy`` parameter from ``airflow_local_settings``. Please use ``task_policy``.

Expand All @@ -17,6 +17,6 @@ Removed deprecated ``policy`` parameter from ``airflow_local_settings``. Please

* ``airflow config lint``

* [x] ``webserver.session_lifetime_days`` → ``webserver.session_lifetime_minutes``
* [x] ``webserver.force_log_out_after`` → ``webserver.session_lifetime_minutes``
* [x] ``webserver.session_lifetime_days`` → ``fab.session_lifetime_minutes``
* [x] ``webserver.force_log_out_after`` → ``fab.session_lifetime_minutes``
* [x] ``policy`` → ``task_policy``
8 changes: 6 additions & 2 deletions airflow-core/src/airflow/cli/commands/config_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,11 +329,15 @@ def message(self) -> str | None:
),
ConfigChange(
config=ConfigParameter("webserver", "session_lifetime_days"),
renamed_to=ConfigParameter("webserver", "session_lifetime_minutes"),
renamed_to=ConfigParameter("fab", "session_lifetime_minutes"),
),
ConfigChange(
config=ConfigParameter("webserver", "force_log_out_after"),
renamed_to=ConfigParameter("webserver", "session_lifetime_minutes"),
renamed_to=ConfigParameter("fab", "session_lifetime_minutes"),
),
ConfigChange(
config=ConfigParameter("webserver", "session_lifetime_minutes"),
renamed_to=ConfigParameter("fab", "session_lifetime_minutes"),
),
ConfigChange(
config=ConfigParameter("webserver", "web_server_host"),
Expand Down
8 changes: 0 additions & 8 deletions airflow-core/src/airflow/config_templates/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1862,14 +1862,6 @@ webserver:
type: boolean
example: ~
default: "True"
session_lifetime_minutes:
description: |
The UI cookie lifetime in minutes. User will be logged out from UI after
``[webserver] session_lifetime_minutes`` of non-activity
version_added: 1.10.13
type: integer
example: ~
default: "43200"
instance_name:
description: |
Sets a custom page title for the DAGs overview page and site title for all pages
Expand Down
13 changes: 0 additions & 13 deletions airflow-core/src/airflow/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -585,19 +585,6 @@ def prepare_syspath_for_dags_folder():
sys.path.append(DAGS_FOLDER)


def get_session_lifetime_config():
"""Get session timeout configs and handle outdated configs gracefully."""
session_lifetime_minutes = conf.get("webserver", "session_lifetime_minutes", fallback=None)
minutes_per_day = 24 * 60
if not session_lifetime_minutes:
session_lifetime_days = 30
session_lifetime_minutes = minutes_per_day * session_lifetime_days

log.debug("User session lifetime is set to %s minutes.", session_lifetime_minutes)

return int(session_lifetime_minutes)


def import_local_settings():
"""Import airflow_local_settings.py files to allow overriding any configs in settings.py file."""
try:
Expand Down
26 changes: 0 additions & 26 deletions airflow-core/tests/unit/core/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@

from airflow.exceptions import AirflowClusterPolicyViolation, AirflowConfigException

from tests_common.test_utils.config import conf_vars

SETTINGS_FILE_POLICY = """
def test_policy(task_instance):
task_instance.run_as_user = "myself"
Expand Down Expand Up @@ -209,30 +207,6 @@ def test_custom_policy(self):
settings.task_must_have_owners(task_instance)


class TestUpdatedConfigNames:
@conf_vars({("webserver", "session_lifetime_minutes"): "43200"})
def test_config_val_is_default(self):
from airflow import settings

session_lifetime_config = settings.get_session_lifetime_config()
assert session_lifetime_config == 43200

@conf_vars({("webserver", "session_lifetime_minutes"): "43201"})
def test_config_val_is_not_default(self):
from airflow import settings

session_lifetime_config = settings.get_session_lifetime_config()
assert session_lifetime_config == 43201

@conf_vars({("webserver", "session_lifetime_days"): ""})
def test_uses_updated_session_timeout_config_by_default(self):
from airflow import settings

session_lifetime_config = settings.get_session_lifetime_config()
default_timeout_minutes = 30 * 24 * 60
assert session_lifetime_config == default_timeout_minutes


_local_db_path_error = pytest.raises(AirflowConfigException, match=r"Cannot use relative path:")


Expand Down
8 changes: 8 additions & 0 deletions providers/fab/provider.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ config:
type: string
example: ~
default: "airflow.providers.fab.auth_manager.api.auth.backend.session"
session_lifetime_minutes:
description: |
The UI cookie lifetime in minutes. User will be logged out from UI after
``[fab] session_lifetime_minutes`` of non-activity
version_added: 2.0.0
type: integer
example: ~
default: "43200"

auth-managers:
- airflow.providers.fab.auth_manager.fab_auth_manager.FabAuthManager
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ def get_provider_info():
"example": None,
"default": "airflow.providers.fab.auth_manager.api.auth.backend.session",
},
"session_lifetime_minutes": {
"description": "The UI cookie lifetime in minutes. User will be logged out from UI after\n``[fab] session_lifetime_minutes`` of non-activity\n",
"version_added": "2.0.0",
"type": "integer",
"example": None,
"default": "43200",
},
},
}
},
Expand Down
4 changes: 4 additions & 0 deletions providers/fab/src/airflow/providers/fab/www/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# under the License.
from __future__ import annotations

from datetime import timedelta
from os.path import isabs

from flask import Flask
Expand All @@ -40,6 +41,7 @@
init_error_handlers,
init_plugins,
)
from airflow.providers.fab.www.utils import get_session_lifetime_config

app: Flask | None = None

Expand All @@ -56,6 +58,8 @@ def create_app(enable_plugins: bool):
flask_app.secret_key = conf.get("webserver", "SECRET_KEY")
flask_app.config["SQLALCHEMY_DATABASE_URI"] = conf.get("database", "SQL_ALCHEMY_CONN")
flask_app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
flask_app.config["PERMANENT_SESSION_LIFETIME"] = timedelta(minutes=get_session_lifetime_config())

webserver_config = conf.get_mandatory_value("webserver", "config_file")
# Enable customizations in webserver_config.py to be applied via Flask.current_app.
with flask_app.app_context():
Expand Down
16 changes: 16 additions & 0 deletions providers/fab/src/airflow/providers/fab/www/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# under the License.
from __future__ import annotations

import logging
from typing import TYPE_CHECKING, Any

from flask_appbuilder.models.filters import BaseFilter
Expand All @@ -28,6 +29,7 @@
from sqlalchemy.ext.associationproxy import AssociationProxy

from airflow.api_fastapi.app import get_auth_manager
from airflow.configuration import conf
from airflow.providers.fab.www.security.permissions import (
ACTION_CAN_ACCESS_MENU,
ACTION_CAN_CREATE,
Expand All @@ -51,6 +53,20 @@
"DELETE": ACTION_CAN_DELETE,
"MENU": ACTION_CAN_ACCESS_MENU,
}
log = logging.getLogger(__name__)


def get_session_lifetime_config():
"""Get session timeout configs and handle outdated configs gracefully."""
session_lifetime_minutes = conf.get("fab", "session_lifetime_minutes", fallback=None)
minutes_per_day = 24 * 60
if not session_lifetime_minutes:
session_lifetime_days = 30
session_lifetime_minutes = minutes_per_day * session_lifetime_days

log.debug("User session lifetime is set to %s minutes.", session_lifetime_minutes)

return int(session_lifetime_minutes)


def get_fab_auth_manager() -> FabAuthManager:
Expand Down
40 changes: 40 additions & 0 deletions providers/fab/tests/unit/fab/www/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# 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.

from __future__ import annotations

from airflow.providers.fab.www.utils import get_session_lifetime_config

from tests_common.test_utils.config import conf_vars


class TestUpdatedConfigNames:
@conf_vars({("fab", "session_lifetime_minutes"): "43200"})
def test_config_val_is_default(self):
session_lifetime_config = get_session_lifetime_config()
assert session_lifetime_config == 43200

@conf_vars({("fab", "session_lifetime_minutes"): "43201"})
def test_config_val_is_not_default(self):
session_lifetime_config = get_session_lifetime_config()
assert session_lifetime_config == 43201

@conf_vars({("fab", "session_lifetime_days"): ""})
def test_uses_updated_session_timeout_config_by_default(self):
session_lifetime_config = get_session_lifetime_config()
default_timeout_minutes = 30 * 24 * 60
assert session_lifetime_config == default_timeout_minutes