Files
mnemosyne/mnemosyne/library/utils.py
Robert Helewka 16fb7ff4dc
All checks were successful
CVE Scan & Docker Build / security-scan (push) Successful in 51s
CVE Scan & Docker Build / build-and-push (push) Successful in 2m27s
docs: clarify Daedalus-Pallas integration auth model
Refine the phase-2 integration spec to reflect implementation details:

- Change `resolved_libraries` from `set[str]` to ordered `list[str]`
- Document `MCPToken.allowed_libraries` as JSONField (not M2M) since
  Library lives in Neo4j, not Django's ORM
- Clarify that `Library.workspace_id` is a content-routing attribute,
  not an authorization axis
- Describe retirement of the three-branch `_WORKSPACE_SCOPE_CLAUSE` in
  favor of a single `lib.uid IN $resolved_libraries` check
- Specify team JWT resolution via `TeamWorkspaceAssignment` DB join
- Note admin UI materializes full Library UID list explicitly
2026-05-10 11:59:44 -04:00

53 lines
1.7 KiB
Python

"""
Utility helpers for the library app.
"""
import logging
logger = logging.getLogger(__name__)
def neo4j_available():
"""
Check whether Neo4j is reachable.
Returns True if a simple Cypher query succeeds, False otherwise.
Used to guard views/tests that require Neo4j.
"""
try:
from neomodel import db
db.cypher_query("RETURN 1")
return True
except Exception:
return False
def all_library_uids() -> list[str]:
"""Return the UIDs of every ``Library`` node in Neo4j.
Used by trusted in-process callers — the Django admin HTML search
page, the ``/library/api/search/`` DRF endpoint (gated by Django
session auth) and the ``search`` management command — as the
``resolved_libraries`` argument to :class:`SearchRequest`. These
callers have already been authenticated/authorized at a coarser
layer (Django login / DRF session) and the unified auth middleware
(see ``mcp_server/auth.py``) is the one that resolves narrower
library sets for MCP bearer tokens.
Returns ``[]`` when Neo4j is unreachable. Callers that want the
unrestricted / "admin sees everything" semantics should feed this
result directly into ``SearchRequest.resolved_libraries``; callers
that want to distinguish "unrestricted" from "fail-closed empty"
must pass ``resolved_libraries=None`` for the former instead.
"""
if not neo4j_available():
return []
try:
from .models import Library
return [lib.uid for lib in Library.nodes.all() if lib.uid]
except Exception as exc: # pragma: no cover - Neo4j unreachable paths
logger.warning("Failed to enumerate library UIDs for search: %s", exc)
return []