Ejemplo n.º 1
0
def validate_adhoc_subquery(
    sql: str,
    database_id: int,
    default_schema: str,
) -> str:
    """
    Check if adhoc SQL contains sub-queries or nested sub-queries with table.

    If sub-queries are allowed, the adhoc SQL is modified to insert any applicable RLS
    predicates to it.

    :param sql: adhoc sql expression
    :raise SupersetSecurityException if sql contains sub-queries or
    nested sub-queries with table
    """
    # pylint: disable=import-outside-toplevel
    from superset import is_feature_enabled

    statements = []
    for statement in sqlparse.parse(sql):
        if has_table_query(statement):
            if not is_feature_enabled("ALLOW_ADHOC_SUBQUERY"):
                raise SupersetSecurityException(
                    SupersetError(
                        error_type=SupersetErrorType.
                        ADHOC_SUBQUERY_NOT_ALLOWED_ERROR,
                        message=_(
                            "Custom SQL fields cannot contain sub-queries."),
                        level=ErrorLevel.ERROR,
                    ))
            statement = insert_rls(statement, database_id, default_schema)
        statements.append(statement)

    return ";\n".join(str(statement) for statement in statements)
def test_has_table_query(sql: str, expected: bool) -> None:
    """
    Test if a given statement queries a table.

    This is used to prevent ad-hoc metrics from querying unauthorized tables, bypassing
    row-level security.
    """
    statement = sqlparse.parse(sql)[0]
    assert has_table_query(statement) == expected
Ejemplo n.º 3
0
def validate_adhoc_subquery(raw_sql: str) -> None:
    """
    Check if adhoc SQL contains sub-queries or nested sub-queries with table
    :param raw_sql: adhoc sql expression
    :raise SupersetSecurityException if sql contains sub-queries or
    nested sub-queries with table
    """
    # pylint: disable=import-outside-toplevel
    from superset import is_feature_enabled

    if is_feature_enabled("ALLOW_ADHOC_SUBQUERY"):
        return

    for statement in sqlparse.parse(raw_sql):
        if has_table_query(statement):
            raise SupersetSecurityException(
                SupersetError(
                    error_type=SupersetErrorType.
                    ADHOC_SUBQUERY_NOT_ALLOWED_ERROR,
                    message=_("Custom SQL fields cannot contain sub-queries."),
                    level=ErrorLevel.ERROR,
                ))
    return