mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-23 16:36:23 +00:00
fix(slack): gate message files before metadata fetch
This commit is contained in:
parent
856b604b4a
commit
e1883df75e
2 changed files with 57 additions and 11 deletions
|
|
@ -3942,22 +3942,25 @@ class SlackAdapter(BasePlatformAdapter):
|
|||
# both as DM-style persistent conversations.
|
||||
is_one_to_one_dm = channel_type == "im"
|
||||
|
||||
# Early auth check: reject unauthorized users before any API calls
|
||||
# (thread context fetch, user name resolution, file downloads).
|
||||
# Pattern matches Telegram fix #54164 — gate at the adapter level
|
||||
# BEFORE event construction consumes resources.
|
||||
if user_id:
|
||||
# Reject unauthorized users before thread lookups, name resolution,
|
||||
# or file downloads. The final gateway runner auth check happens
|
||||
# after MessageEvent construction, so adapter-side media fetches need
|
||||
# the same auth chain up front.
|
||||
_runner = getattr(getattr(self, "_message_handler", None), "__self__", None)
|
||||
_auth_fn = getattr(_runner, "_is_user_authorized", None)
|
||||
if user_id and callable(_auth_fn):
|
||||
_source = self.build_source(
|
||||
chat_id=channel_id, chat_name="",
|
||||
chat_id=channel_id,
|
||||
chat_name="",
|
||||
chat_type="dm" if is_dm else "group",
|
||||
user_id=user_id, user_name="",
|
||||
user_id=user_id,
|
||||
user_name="",
|
||||
)
|
||||
_runner = getattr(getattr(self, "_message_handler", None), "__self__", None)
|
||||
_auth_fn = getattr(_runner, "_is_user_authorized", None)
|
||||
if callable(_auth_fn) and not _auth_fn(_source):
|
||||
if not _auth_fn(_source):
|
||||
logger.warning(
|
||||
"[Slack] Early reject of unauthorized user %s in channel %s",
|
||||
user_id, channel_id,
|
||||
user_id,
|
||||
channel_id,
|
||||
)
|
||||
return
|
||||
|
||||
|
|
|
|||
|
|
@ -1911,6 +1911,49 @@ class TestIncomingDocumentHandling:
|
|||
assert os.path.exists(msg_event.media_urls[0])
|
||||
assert msg_event.media_types == [SUPPORTED_VIDEO_TYPES[".mp4"]]
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_unauthorized_message_does_not_fetch_file_info(
|
||||
self,
|
||||
adapter,
|
||||
monkeypatch,
|
||||
):
|
||||
"""Global gateway auth must run before Slack file metadata fetches."""
|
||||
monkeypatch.delenv("SLACK_ALLOW_ALL_USERS", raising=False)
|
||||
monkeypatch.delenv("GATEWAY_ALLOW_ALL_USERS", raising=False)
|
||||
monkeypatch.delenv("SLACK_ALLOWED_USERS", raising=False)
|
||||
monkeypatch.setenv("GATEWAY_ALLOWED_USERS", "U_ALLOWED")
|
||||
|
||||
class Runner:
|
||||
def _is_user_authorized(self, source):
|
||||
return source.user_id == "U_ALLOWED"
|
||||
|
||||
async def handle(self, _event):
|
||||
raise AssertionError("gateway handler should not run")
|
||||
|
||||
adapter._message_handler = Runner().handle
|
||||
adapter._app.client.files_info = AsyncMock()
|
||||
|
||||
await adapter._handle_slack_message(
|
||||
{
|
||||
"type": "message",
|
||||
"channel": "D123",
|
||||
"channel_type": "im",
|
||||
"user": "U_INTRUDER",
|
||||
"text": "please read this",
|
||||
"ts": "1234567890.000001",
|
||||
"files": [
|
||||
{
|
||||
"id": "FSECRET",
|
||||
"mimetype": "text/plain",
|
||||
"name": "secret.txt",
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
adapter._app.client.files_info.assert_not_awaited()
|
||||
adapter.handle_message.assert_not_called()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_download_failure_is_surfaced_in_message_text(self, adapter):
|
||||
"""Attachment download failures (401/403/HTML-body/etc.) should be
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue