Skip to content

Commit 12bfb57

Browse files
committed
Check user is active (#26635)
(cherry picked from commit 59707cd)
1 parent d81b297 commit 12bfb57

File tree

6 files changed

+44
-3
lines changed

6 files changed

+44
-3
lines changed

airflow/www/app.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@
3939
from airflow.www.extensions.init_jinja_globals import init_jinja_globals
4040
from airflow.www.extensions.init_manifest_files import configure_manifest_files
4141
from airflow.www.extensions.init_robots import init_robots
42-
from airflow.www.extensions.init_security import init_api_experimental_auth, init_xframe_protection
42+
from airflow.www.extensions.init_security import (
43+
init_api_experimental_auth,
44+
init_check_user_active,
45+
init_xframe_protection,
46+
)
4347
from airflow.www.extensions.init_session import init_airflow_session_interface
4448
from airflow.www.extensions.init_views import (
4549
init_api_connexion,
@@ -152,6 +156,7 @@ def create_app(config=None, testing=False):
152156
init_jinja_globals(flask_app)
153157
init_xframe_protection(flask_app)
154158
init_airflow_session_interface(flask_app)
159+
init_check_user_active(flask_app)
155160
return flask_app
156161

157162

airflow/www/extensions/init_security.py

+11
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
import logging
2020
from importlib import import_module
2121

22+
from flask import g, redirect, url_for
23+
from flask_login import logout_user
24+
2225
from airflow.configuration import conf
2326
from airflow.exceptions import AirflowConfigException, AirflowException
2427

@@ -60,3 +63,11 @@ def init_api_experimental_auth(app):
6063
except ImportError as err:
6164
log.critical("Cannot import %s for API authentication due to: %s", backend, err)
6265
raise AirflowException(err)
66+
67+
68+
def init_check_user_active(app):
69+
@app.before_request
70+
def check_user_active():
71+
if g.user is not None and not g.user.is_anonymous and not g.user.is_active:
72+
logout_user()
73+
return redirect(url_for(app.appbuilder.sm.auth_view.endpoint + ".login"))

tests/test_utils/decorators.py

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def no_op(*args, **kwargs):
4545
"init_xframe_protection",
4646
"init_airflow_session_interface",
4747
"init_appbuilder",
48+
"init_check_user_active",
4849
]
4950

5051
@functools.wraps(f)

tests/www/views/conftest.py

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def app(examples_dag_bag):
5858
"init_jinja_globals",
5959
"init_plugins",
6060
"init_airflow_session_interface",
61+
"init_check_user_active",
6162
]
6263
)
6364
def factory():

tests/www/views/test_session.py

+14
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,17 @@ def test_session_id_rotates(app, user_client):
8888
new_session_cookie = get_session_cookie(user_client)
8989
assert new_session_cookie is not None
9090
assert old_session_cookie.value != new_session_cookie.value
91+
92+
93+
def test_check_active_user(app, user_client):
94+
user = app.appbuilder.sm.find_user(username="test_user")
95+
user.active = False
96+
resp = user_client.get("/home")
97+
assert resp.status_code == 302
98+
assert "/login" in resp.headers.get("Location")
99+
100+
# And they were logged out
101+
user.active = True
102+
resp = user_client.get("/home")
103+
assert resp.status_code == 302
104+
assert "/login" in resp.headers.get("Location")

tests/www/views/test_views_base.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,18 @@
3030
from tests.test_utils.www import check_content_in_response, check_content_not_in_response
3131

3232

33-
def test_index(admin_client):
33+
def test_index_redirect(admin_client):
34+
resp = admin_client.get('/')
35+
assert resp.status_code == 302
36+
assert '/home' in resp.headers.get("Location")
37+
38+
resp = admin_client.get('/', follow_redirects=True)
39+
check_content_in_response('DAGs', resp)
40+
41+
42+
def test_homepage_query_count(admin_client):
3443
with assert_queries_count(16):
35-
resp = admin_client.get('/', follow_redirects=True)
44+
resp = admin_client.get('/home')
3645
check_content_in_response('DAGs', resp)
3746

3847

0 commit comments

Comments
 (0)