Skip to content

Embedding fails because GuestUser is never active #36598

@charlymarchiaro

Description

@charlymarchiaro

Bug description

When dashboards are embedded, api calls to the following endpoints fail with Forbidden (403) error.

  • api/v1/dashboard/{id_or_slug}
  • api/v1/dashboard/{id_or_slug}/charts
  • api/v1/dashboard/{id_or_slug}/datasets

After discarding all the typical misconfiguration errors, I noticed that the issue seems to originate in the fact that the GuestUser instance's property is_active always returns False.

Even when the GuestUser class has an active attribute always set to True:

# guest_token.py
# --------------------------------------------------

class GuestUser(AnonymousUserMixin):
    """
    Used as the "anonymous" user in case of guest authentication (embedded)
    """

    is_guest_user = True
>>  active = True

    @property
    def is_authenticated(self) -> bool:
        """
        This is set to true because guest users should be considered authenticated,
        at least in most places. The treatment of this flag is kind of inconsistent.
        """
        return True

    @property
    def is_anonymous(self) -> bool:
        """
        This is set to false because lots of code assumes that
        if user.is_anonymous, then role = Public
        But guest users need to have their own role independent of Public.
        """
        return False

    def __init__(self, token: GuestToken, roles: list[Role]):
        user = token["user"]
        self.guest_token = token
        self.username = user.get("username", "guest_user")
        self.first_name = user.get("first_name", "Guest")
        self.last_name = user.get("last_name", "User")
        self.roles = roles
        self.groups: list[Group] = []  # Guest users don't belong to any groups
        self.resources = token["resources"]
        self.rls = token.get("rls_rules", [])

The problem is that it inherits the is_active property from AnonymousUserMixin, which is always set to False:

# flask_login.mixins.py
# --------------------------------------------------

class AnonymousUserMixin:
    """
    This is the default object for representing an anonymous user.
    """

    @property
    def is_authenticated(self):
        return False

>>  @property
>>  def is_active(self):
>>      return False

    @property
    def is_anonymous(self):
        return True

    def get_id(self):
        return

After overriding the inherited is_active logic so that it returns True, the dashboards are embedded correctly.

Screenshots/recordings

No response

Superset version

master / latest-dev

Python version

3.11

Node version

18 or greater

Browser

Chrome

Additional context

No response

Checklist

  • I have searched Superset docs and Slack and didn't find a solution to my problem.
  • I have searched the GitHub issue tracker and didn't find a similar bug report.
  • I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions