Files
invoke-ai--invokeai/tests/app/routers/test_session_queue_sanitization.py
wehub-resource-sync cddb07a176
docs / deploy (push) Has been cancelled
docs / changes (push) Has been cancelled
docs / check-and-build (push) Has been cancelled
build container image / cpu (push) Has been cancelled
build container image / cuda (push) Has been cancelled
build container image / rocm (push) Has been cancelled
frontend checks / frontend-checks (push) Has been cancelled
frontend tests / frontend-tests (push) Has been cancelled
lfs checks / lfs-check (push) Has been cancelled
python checks / python-checks (push) Has been cancelled
python tests / py3.12: macos-default (push) Has been cancelled
python tests / py3.11: windows-cpu (push) Has been cancelled
python tests / py3.12: windows-cpu (push) Has been cancelled
python tests / py3.11: linux-cpu (push) Has been cancelled
typegen checks / typegen-checks (push) Has been cancelled
uv lock checks / uv-lock-checks (push) Has been cancelled
openapi checks / openapi-checks (push) Has been cancelled
python tests / py3.11: macos-default (push) Has been cancelled
python tests / py3.12: linux-cpu (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:22:06 +08:00

192 lines
6.8 KiB
Python

"""Tests for session queue item sanitization in multiuser mode."""
from datetime import datetime
import pytest
from invokeai.app.api.routers.session_queue import sanitize_queue_item_for_user
from invokeai.app.invocations.baseinvocation import BaseInvocation, BaseInvocationOutput, invocation, invocation_output
from invokeai.app.invocations.fields import InputField, OutputField
from invokeai.app.services.session_queue.session_queue_common import NodeFieldValue, SessionQueueItem
from invokeai.app.services.shared.graph import Graph, GraphExecutionState
from invokeai.app.services.shared.invocation_context import InvocationContext
# Define a minimal test invocation for the test
@invocation_output("test_sanitization_output")
class TestSanitizationInvocationOutput(BaseInvocationOutput):
value: str = OutputField(default="")
@invocation("test_sanitization", version="1.0.0")
class TestSanitizationInvocation(BaseInvocation):
test_field: str = InputField(default="")
def invoke(self, context: InvocationContext) -> TestSanitizationInvocationOutput:
return TestSanitizationInvocationOutput(value=self.test_field)
@pytest.fixture
def sample_session_queue_item() -> SessionQueueItem:
"""Create a sample queue item with full data for testing."""
graph = Graph()
# Add a simple node to the graph
graph.add_node(TestSanitizationInvocation(id="test_node", test_field="test value"))
session = GraphExecutionState(id="test_session", graph=graph)
# Create timestamps for the queue item
now = datetime.now()
return SessionQueueItem(
item_id=1,
status="pending",
batch_id="batch_123",
session_id="session_123",
queue_id="default",
user_id="user_123",
user_display_name="Test User",
user_email="test@example.com",
field_values=[
NodeFieldValue(node_path="test_node", field_name="test_field", value="sensitive prompt data"),
],
session=session,
workflow=None,
workflow_call_id="workflow-call-1",
parent_item_id=99,
parent_session_id="parent-session-1",
root_item_id=1,
workflow_call_depth=2,
created_at=now,
updated_at=now,
started_at=None,
completed_at=None,
)
def test_sanitize_queue_item_for_admin(sample_session_queue_item):
"""Test that admins can see all data regardless of user_id."""
result = sanitize_queue_item_for_user(
queue_item=sample_session_queue_item,
current_user_id="different_user",
is_admin=True,
)
# Admin should see everything
assert result.field_values is not None
assert len(result.field_values) == 1
assert result.session.graph.nodes is not None
assert len(result.session.graph.nodes) == 1
def test_sanitize_queue_item_for_owner(sample_session_queue_item):
"""Test that queue item owners can see their own data."""
result = sanitize_queue_item_for_user(
queue_item=sample_session_queue_item,
current_user_id="user_123", # Same as queue item user_id
is_admin=False,
)
# Owner should see everything
assert result.field_values is not None
assert len(result.field_values) == 1
assert result.session.graph.nodes is not None
assert len(result.session.graph.nodes) == 1
def test_sanitize_queue_item_for_different_user(sample_session_queue_item):
"""Test that non-admin users cannot see other users' sensitive data."""
result = sanitize_queue_item_for_user(
queue_item=sample_session_queue_item,
current_user_id="different_user",
is_admin=False,
)
# Non-admin viewing another user's item should have sanitized data
assert result.field_values is None
assert result.workflow is None
# Session should be replaced with empty/redacted graph
assert result.session.graph.nodes is not None
assert len(result.session.graph.nodes) == 0
assert result.session.id == "redacted"
# Identity and batch fields should be redacted
assert result.user_id == "redacted"
assert result.batch_id == "redacted"
assert result.session_id == "redacted"
assert result.user_display_name is None
assert result.user_email is None
assert result.origin is None
assert result.destination is None
assert result.error_type is None
assert result.error_message is None
assert result.error_traceback is None
def test_sanitize_preserves_non_sensitive_fields(sample_session_queue_item):
"""Test that sanitization preserves non-sensitive fields."""
result = sanitize_queue_item_for_user(
queue_item=sample_session_queue_item,
current_user_id="different_user",
is_admin=False,
)
# Non-sensitive fields should be preserved
assert result.item_id == 1
assert result.status == "pending"
assert result.queue_id == "default"
assert result.created_at is not None
assert result.updated_at is not None
# Sensitive fields should be redacted for non-owner non-admin
assert result.batch_id == "redacted"
assert result.session_id == "redacted"
assert result.user_id == "redacted"
assert result.user_display_name is None
assert result.user_email is None
def test_sanitize_redacts_workflow_call_metadata_for_different_user(sample_session_queue_item):
result = sanitize_queue_item_for_user(
queue_item=sample_session_queue_item,
current_user_id="different_user",
is_admin=False,
)
assert result.workflow_call_id is None
assert result.parent_item_id is None
assert result.parent_session_id is None
assert result.root_item_id is None
assert result.workflow_call_depth is None
def test_sanitize_system_user_item_for_non_admin(sample_session_queue_item):
"""Test that non-admin users cannot see sensitive data from System user's queue items."""
# Simulate a legacy System user queue item
system_item = sample_session_queue_item.model_copy(update={"user_id": "system"})
result = sanitize_queue_item_for_user(
queue_item=system_item,
current_user_id="non_admin_user",
is_admin=False,
)
# System user's sensitive fields should be sanitized for non-admin users
assert result.field_values is None
assert result.workflow is None
assert len(result.session.graph.nodes) == 0
def test_sanitize_system_user_item_for_admin(sample_session_queue_item):
"""Test that admin users can see full data from System user's queue items."""
system_item = sample_session_queue_item.model_copy(update={"user_id": "system"})
result = sanitize_queue_item_for_user(
queue_item=system_item,
current_user_id="admin_user",
is_admin=True,
)
# Admin should see everything including System user's data
assert result.field_values is not None
assert len(result.field_values) == 1
assert len(result.session.graph.nodes) == 1