Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions gateway/platforms/feishu.py
Original file line number Diff line number Diff line change
Expand Up @@ -2039,14 +2039,22 @@ def _on_drive_comment_event(self, data: Any) -> None:
logging, and reaction. Scheduling follows the same
``run_coroutine_threadsafe`` pattern used by ``_on_message_event``.
"""
from gateway.platforms.feishu_comment import handle_drive_comment_event
from gateway.platforms.feishu_comment import (
CommentContext,
handle_drive_comment_event,
)

loop = self._loop
if not self._loop_accepts_callbacks(loop):
logger.warning("[Feishu] Dropping drive comment event before adapter loop is ready")
return
# Build the handler's dependency bundle here so the handler signature
# stays independent of the concrete ``FeishuAdapter`` type. All
# ``_client`` / ``_session_store`` reads are localized to
# ``CommentContext.from_adapter``.
ctx = CommentContext.from_adapter(self, self_open_id=self._bot_open_id)
future = asyncio.run_coroutine_threadsafe(
handle_drive_comment_event(self._client, data, self_open_id=self._bot_open_id),
handle_drive_comment_event(ctx, data),
loop,
)
future.add_done_callback(self._log_background_failure)
Expand Down
1,089 changes: 945 additions & 144 deletions gateway/platforms/feishu_comment.py

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions gateway/platforms/feishu_comment_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

import json
import logging
import os
import stat
import time
from dataclasses import dataclass, field
from pathlib import Path
Expand Down Expand Up @@ -237,6 +239,19 @@ def _save_pairing(data: dict) -> None:
tmp = PAIRING_FILE.with_suffix(".tmp")
with open(tmp, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
# Restrict to owner-only rw BEFORE rename so there's never a window
# where the final file exists with the default umask permissions.
# The pairing file lists the open_ids allow-listed to @-mention the
# bot on documents — leaking it hands an attacker a targeting list.
try:
os.chmod(tmp, stat.S_IRUSR | stat.S_IWUSR)
except OSError as e:
# Best-effort: on filesystems / platforms where chmod is a no-op
# (e.g. certain Windows setups), log and continue. Don't block
# the write — correctness beats ideal permissions.
logger.warning(
"[Feishu-Rules] chmod 0600 on pairing tmp file failed: %s", e,
)
tmp.replace(PAIRING_FILE)
# Invalidate cache so next load picks up change
_pairing_cache._mtime = 0.0
Expand Down
Loading
Loading