feat: intégration TikTak #197-200 + scoped tokens, webhooks filtrés, listes mtime/size ; fix e2e-server BUG-112
This commit is contained in:
@@ -117,6 +117,29 @@ class ToolRateLimitError(ToolError):
|
||||
self.retry_after = retry_after
|
||||
|
||||
|
||||
#: Tools a ``files``-scoped API token (#199, synchro TikTak) may invoke :
|
||||
#: vault file read/write surface only — no external calls (git/web), no
|
||||
#: notifications, no scheduler, no cross-vault analysis beyond file content.
|
||||
FILES_SCOPE_TOOLS: frozenset[str] = frozenset({
|
||||
# Lecture / recherche de fichiers
|
||||
"list_vaults", "list_directory", "list_all_files",
|
||||
"read_file", "read_file_raw", "get_backlinks",
|
||||
"get_graph", "search_fulltext", "search_advanced", "search_paths",
|
||||
"list_tags", "suggest_tags", "list_recent",
|
||||
"list_backups", "diff_backup", "restore_backup",
|
||||
"find_duplicates",
|
||||
# Mutations de fichiers
|
||||
"create_file", "create_directory", "edit_file", "append_to_file",
|
||||
"rename_file", "rename_directory", "move_path", "replace_in_files",
|
||||
"delete_file", "delete_directory", "merge_duplicate_notes",
|
||||
# Tableurs & documents (création/édition de fichiers du vault)
|
||||
"create_xlsx", "create_docx", "create_csv", "create_pdf",
|
||||
"list_xlsx_sheets", "xlsx_to_markdown", "search_workbook",
|
||||
"analyze_range", "update_xlsx_cells", "append_xlsx_rows",
|
||||
"edit_xlsx_structure",
|
||||
})
|
||||
|
||||
|
||||
@dataclass
|
||||
class ToolContext:
|
||||
"""Carries the caller identity and execution options for a tool call.
|
||||
@@ -190,6 +213,32 @@ class ToolContext:
|
||||
details={"vault": vault},
|
||||
)
|
||||
|
||||
def require_tool_allowed(self, tool: str) -> None:
|
||||
"""Raise :class:`ToolPermissionError` when the caller's token scope
|
||||
forbids *tool* (#199).
|
||||
|
||||
A ``files``-scoped token is confined to :data:`FILES_SCOPE_TOOLS`
|
||||
(vault file surface). Full-scope and scopeless callers (session
|
||||
tokens, pre-#199 API keys) are unaffected ; an unknown scope fails
|
||||
closed.
|
||||
"""
|
||||
token_scope = self.user.get("_token_scope") or "full"
|
||||
if token_scope == "full":
|
||||
return
|
||||
if token_scope == "files":
|
||||
if tool not in FILES_SCOPE_TOOLS:
|
||||
raise ToolPermissionError(
|
||||
f"Token à portée limitée : outil '{tool}' hors périmètre 'files'",
|
||||
code="token_scope_denied",
|
||||
details={"tool": tool, "scope": "files"},
|
||||
)
|
||||
return
|
||||
raise ToolPermissionError(
|
||||
"Token à portée inconnue : appel refusé",
|
||||
code="token_scope_denied",
|
||||
details={"tool": tool},
|
||||
)
|
||||
|
||||
|
||||
def resolve_safe_path(vault_root: Path, relative_path: str | None) -> Path:
|
||||
"""Resolve a vault-relative path, rejecting traversal outside the vault.
|
||||
|
||||
Reference in New Issue
Block a user