Skip to content

UIAlert returns AttributeError: 'NoneType' object has no attribute 'roles' when specifying AUTH_ROLE_PUBLIC #28746

Description

@vchiapaikeo

Apache Airflow version

2.5.0

What happened

When adding a role-based UIAlert following these docs, I received the below stacktrace:

Traceback (most recent call last):
  File "/home/airflow/.local/lib/python3.9/site-packages/flask/app.py", line 2525, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/airflow/.local/lib/python3.9/site-packages/flask/app.py", line 1822, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/airflow/.local/lib/python3.9/site-packages/flask/app.py", line 1820, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/airflow/.local/lib/python3.9/site-packages/flask/app.py", line 1796, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
  File "/home/airflow/.local/lib/python3.9/site-packages/airflow/www/auth.py", line 47, in decorated
    return func(*args, **kwargs)
  File "/home/airflow/.local/lib/python3.9/site-packages/airflow/www/views.py", line 780, in index
    dashboard_alerts = [
  File "/home/airflow/.local/lib/python3.9/site-packages/airflow/www/views.py", line 781, in <listcomp>
    fm for fm in settings.DASHBOARD_UIALERTS if fm.should_show(get_airflow_app().appbuilder.sm)
  File "/home/airflow/.local/lib/python3.9/site-packages/airflow/www/utils.py", line 820, in should_show
    user_roles = {r.name for r in securitymanager.current_user.roles}
AttributeError: 'NoneType' object has no attribute 'roles'

On further inspection, I realized this is happening because my webserver_config.py has this specification:

# Uncomment and set to desired role to enable access without authentication
AUTH_ROLE_PUBLIC = 'Viewer'

When we set AUTH_ROLE_PUBLIC to a role like Viewer, this line returns an exception because securitymanager.current_user is None.

Relevant code snippet:

    def should_show(self, securitymanager) -> bool:Open an interactive python shell in this frame
        """Determine if the user should see the message based on their role membership"""
        if self.roles:
            user_roles = {r.name for r in securitymanager.current_user.roles}
            if not user_roles.intersection(set(self.roles)):
                return False
        return True

What you think should happen instead

If we detect that the securitymanager.current_user is None, we should not attempt to get its roles attribute.

Instead, we can check to see if the AUTH_ROLE_PUBLIC is set in webserver_config.py which will tell us if a public role is being used. If it is, we can assume that because the current_user is None, the current_user's role is the public role.

In code, this might look like this:

    def should_show(self, securitymanager) -> bool:
        """Determine if the user should see the message based on their role membership"""
        if self.roles:
            user_roles = set()
            if hasattr(securitymanager.current_user, "roles"):
                user_roles = {r.name for r in securitymanager.current_user.roles}
            elif "AUTH_ROLE_PUBLIC" in securitymanager.appbuilder.get_app.config:
                # Give anonymous user public role
                user_roles = set([securitymanager.appbuilder.get_app.config["AUTH_ROLE_PUBLIC"]])
            if not user_roles.intersection(set(self.roles)):
                return False
        return True

Expected result on the webpage:

image

How to reproduce

Start breeze:

breeze --python 3.7 --backend postgres start-airflow  

After the webserver, triggerer, and scheduler are started, modify webserver_config.py to uncomment AUTH_ROLE_PUBLIC and add airflow_local_settings.py:

cd $AIRFLOW_HOME

# Uncomment AUTH_ROLE_PUBLIC
vi webserver_config.py

mkdir -p config

# Add sample airflow_local_settings.py below
vi config/airflow_local_settings.py
from airflow.www.utils import UIAlert

DASHBOARD_UIALERTS = [
    UIAlert("Role based alert", category="warning", roles=["Viewer"]),
]

Restart the webserver and navigate to airflow. You should see this page:

image

Operating System

Debian 11

Versions of Apache Airflow Providers

2.5.0

Deployment

Official Apache Airflow Helm Chart

Deployment details

Locally

Anything else

This problem only occurs if you add a role based UIAlert and are using AUTH_ROLE_PUBLIC

Are you willing to submit PR?

  • Yes I am willing to submit a PR!

Code of Conduct

Metadata

Metadata

Assignees

Labels

area:webserverWebserver related Issueskind:bugThis is a clearly a bug

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions