feat!: require explicit user on every tenant-data endpoint
Remove the implicit jpmschweitzer default tenant (DEFAULT_USER) from src/core/multi_tenancy.py and every endpoint and request model that inherited it (~40 endpoints across /query, /wiki, /vector, /graph, /ingest, /volatile, /documents, /stats, /rag). - Add validate_required_user() + RequiredUser pydantic type in multi_tenancy and a shared require_user FastAPI dependency (RequiredUserQuery) that rejects missing, empty, and whitespace-only users with 422, following the /maintenance/* pattern. - Wiki page create / smart-create / dossier request models now require user (no fallback in wiki_service). - /maintenance/cleanup/test-data derives the tenant from the page path instead of using the production tenant collection. - Wiki.js change listener skips changes when no tenant user can be derived from the notification email instead of defaulting to the production tenant. - Consolidation service internal helpers no longer default to the production tenant. - Tool catalog marks user as required with honest descriptions. - OpenAPI descriptions updated honestly; CHANGELOG notes that callers (tatlock, Scheduler ingest tasks) must now send explicit user. - Offline tests: 422 coverage for query/body endpoints, required-user validator tests; updated legacy tests that assumed a default tenant. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+20
-10
@@ -26,15 +26,20 @@ class TestWikiSmartCreateRequest:
|
||||
"""Tests for WikiSmartCreateRequest model validation."""
|
||||
|
||||
def test_minimal_request(self):
|
||||
"""Test request with only required field."""
|
||||
request = WikiSmartCreateRequest(topic="Docker containers")
|
||||
"""Test request with only required fields (topic AND user)."""
|
||||
request = WikiSmartCreateRequest(topic="Docker containers", user="llm_tester")
|
||||
assert request.topic == "Docker containers"
|
||||
assert request.path is None
|
||||
assert request.tags == []
|
||||
assert request.user is None
|
||||
assert request.user == "llm_tester"
|
||||
assert request.include_web_research is True
|
||||
assert request.include_wiki_search is True
|
||||
|
||||
def test_user_is_required(self):
|
||||
"""A request without an explicit user must be rejected."""
|
||||
with pytest.raises(ValueError):
|
||||
WikiSmartCreateRequest(topic="Docker containers")
|
||||
|
||||
def test_full_request(self):
|
||||
"""Test request with all fields."""
|
||||
request = WikiSmartCreateRequest(
|
||||
@@ -68,7 +73,8 @@ class TestWikiSmartCreateRequest:
|
||||
"""Test that path without leading slash gets one added."""
|
||||
request = WikiSmartCreateRequest(
|
||||
topic="Test",
|
||||
path="technology/test"
|
||||
path="technology/test",
|
||||
user="llm_tester"
|
||||
)
|
||||
assert request.path == "/technology/test"
|
||||
|
||||
@@ -76,7 +82,8 @@ class TestWikiSmartCreateRequest:
|
||||
"""Test that trailing slash is removed."""
|
||||
request = WikiSmartCreateRequest(
|
||||
topic="Test",
|
||||
path="/technology/test/"
|
||||
path="/technology/test/",
|
||||
user="llm_tester"
|
||||
)
|
||||
assert request.path == "/technology/test"
|
||||
|
||||
@@ -84,7 +91,8 @@ class TestWikiSmartCreateRequest:
|
||||
"""Test that duplicate tags are removed."""
|
||||
request = WikiSmartCreateRequest(
|
||||
topic="Test",
|
||||
tags=["devops", "devops", "containers", "devops"]
|
||||
tags=["devops", "devops", "containers", "devops"],
|
||||
user="llm_tester"
|
||||
)
|
||||
assert len(request.tags) == 2
|
||||
assert "devops" in request.tags
|
||||
@@ -94,7 +102,8 @@ class TestWikiSmartCreateRequest:
|
||||
"""Test that tag whitespace is cleaned."""
|
||||
request = WikiSmartCreateRequest(
|
||||
topic="Test",
|
||||
tags=[" devops ", "containers", " ", ""]
|
||||
tags=[" devops ", "containers", " ", ""],
|
||||
user="llm_tester"
|
||||
)
|
||||
assert "devops" in request.tags
|
||||
assert "containers" in request.tags
|
||||
@@ -536,7 +545,8 @@ class TestSmartCreateEndpoint:
|
||||
# For now, we test the model validation
|
||||
request = WikiSmartCreateRequest(
|
||||
topic="Test Topic",
|
||||
tags=["test"]
|
||||
tags=["test"],
|
||||
user="llm_tester"
|
||||
)
|
||||
assert request.topic == "Test Topic"
|
||||
|
||||
@@ -546,8 +556,8 @@ class TestSmartCreateEndpoint:
|
||||
WikiSmartCreateRequest(topic="")
|
||||
|
||||
def test_request_accepts_minimal_input(self):
|
||||
"""Test that only topic is required."""
|
||||
request = WikiSmartCreateRequest(topic="Minimal test")
|
||||
"""Test that topic and user are the only required fields."""
|
||||
request = WikiSmartCreateRequest(topic="Minimal test", user="llm_tester")
|
||||
assert request.topic == "Minimal test"
|
||||
assert request.include_web_research is True # default
|
||||
assert request.include_wiki_search is True # default
|
||||
|
||||
Reference in New Issue
Block a user