mirror of
https://github.com/apache/superset.git
synced 2026-04-11 12:26:05 +00:00
95 lines
4.0 KiB
Python
95 lines
4.0 KiB
Python
# 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 typing import List, Optional, Tuple, TYPE_CHECKING, Union
|
|
|
|
from flask import current_app, g
|
|
|
|
from superset.tasks.exceptions import ExecutorNotFoundError
|
|
from superset.tasks.types import ExecutorType
|
|
|
|
if TYPE_CHECKING:
|
|
from superset.models.dashboard import Dashboard
|
|
from superset.models.slice import Slice
|
|
from superset.reports.models import ReportSchedule
|
|
|
|
|
|
# pylint: disable=too-many-branches
|
|
def get_executor(
|
|
executor_types: List[ExecutorType],
|
|
model: Union[Dashboard, ReportSchedule, Slice],
|
|
current_user: Optional[str] = None,
|
|
) -> Tuple[ExecutorType, str]:
|
|
"""
|
|
Extract the user that should be used to execute a scheduled task. Certain executor
|
|
types extract the user from the underlying object (e.g. CREATOR), the constant
|
|
Selenium user (SELENIUM), or the user that initiated the request.
|
|
|
|
:param executor_types: The requested executor type in descending order. When the
|
|
first user is found it is returned.
|
|
:param model: The underlying object
|
|
:param current_user: The username of the user that initiated the task. For
|
|
thumbnails this is the user that requested the thumbnail, while for alerts
|
|
and reports this is None (=initiated by Celery).
|
|
:return: User to execute the report as
|
|
:raises ScheduledTaskExecutorNotFoundError: If no users were found in after
|
|
iterating through all entries in `executor_types`
|
|
"""
|
|
owners = model.owners
|
|
owner_dict = {owner.id: owner for owner in owners}
|
|
for executor_type in executor_types:
|
|
if executor_type == ExecutorType.SELENIUM:
|
|
return executor_type, current_app.config["THUMBNAIL_SELENIUM_USER"]
|
|
if executor_type == ExecutorType.CURRENT_USER and current_user:
|
|
return executor_type, current_user
|
|
if executor_type == ExecutorType.CREATOR_OWNER:
|
|
if (user := model.created_by) and (owner := owner_dict.get(user.id)):
|
|
return executor_type, owner.username
|
|
if executor_type == ExecutorType.CREATOR:
|
|
if user := model.created_by:
|
|
return executor_type, user.username
|
|
if executor_type == ExecutorType.MODIFIER_OWNER:
|
|
if (user := model.changed_by) and (owner := owner_dict.get(user.id)):
|
|
return executor_type, owner.username
|
|
if executor_type == ExecutorType.MODIFIER:
|
|
if user := model.changed_by:
|
|
return executor_type, user.username
|
|
if executor_type == ExecutorType.OWNER:
|
|
owners = model.owners
|
|
if len(owners) == 1:
|
|
return executor_type, owners[0].username
|
|
if len(owners) > 1:
|
|
if modifier := model.changed_by:
|
|
if modifier and (user := owner_dict.get(modifier.id)):
|
|
return executor_type, user.username
|
|
if creator := model.created_by:
|
|
if creator and (user := owner_dict.get(creator.id)):
|
|
return executor_type, user.username
|
|
return executor_type, owners[0].username
|
|
|
|
raise ExecutorNotFoundError()
|
|
|
|
|
|
def get_current_user() -> Optional[str]:
|
|
user = g.user if hasattr(g, "user") and g.user else None
|
|
if user and not user.is_anonymous:
|
|
return user.username
|
|
|
|
return None
|