mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-10 08:32:09 +00:00
fix(discord): propagate role_authorized flag so DISCORD_ALLOWED_ROLES works end-to-end
DISCORD_ALLOWED_ROLES was checked by the Discord adapter (_is_allowed_user) but gateway._is_user_authorized only read DISCORD_ALLOWED_USERS, so role-authorized users were rejected with "Unauthorized user" at the gateway layer despite passing the adapter gate. - Add role_authorized: bool = False to SessionSource - Add role_authorized param to build_source (base.py) - Compute _role_authorized in on_message when user passes via role not user ID - Thread _role_authorized through _handle_message -> build_source - Check source.role_authorized early in _is_user_authorized (run.py) Fixes #33952
This commit is contained in:
parent
5a4297a11a
commit
e5580f43c2
4 changed files with 13 additions and 2 deletions
|
|
@ -207,6 +207,11 @@ class GatewayAuthorizationMixin:
|
|||
if platform_allow_all_var and os.getenv(platform_allow_all_var, "").lower() in {"true", "1", "yes"}:
|
||||
return True
|
||||
|
||||
# Adapter-verified role auth: the Discord adapter already confirmed the
|
||||
# user holds a role in DISCORD_ALLOWED_ROLES before dispatching the message.
|
||||
if getattr(source, "role_authorized", False):
|
||||
return True
|
||||
|
||||
if getattr(source, "is_bot", False):
|
||||
allow_bots_var = platform_allow_bots_map.get(source.platform)
|
||||
if allow_bots_var and os.getenv(allow_bots_var, "none").lower().strip() in {"mentions", "all"}:
|
||||
|
|
|
|||
|
|
@ -4651,6 +4651,7 @@ class BasePlatformAdapter(ABC):
|
|||
guild_id: Optional[str] = None,
|
||||
parent_chat_id: Optional[str] = None,
|
||||
message_id: Optional[str] = None,
|
||||
role_authorized: bool = False,
|
||||
) -> SessionSource:
|
||||
"""Helper to build a SessionSource for this platform."""
|
||||
# Normalize empty topic to None
|
||||
|
|
@ -4671,6 +4672,7 @@ class BasePlatformAdapter(ABC):
|
|||
guild_id=str(guild_id) if guild_id else None,
|
||||
parent_chat_id=str(parent_chat_id) if parent_chat_id else None,
|
||||
message_id=str(message_id) if message_id else None,
|
||||
role_authorized=role_authorized,
|
||||
)
|
||||
|
||||
@abstractmethod
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ class SessionSource:
|
|||
guild_id: Optional[str] = None # Discord guild / Slack workspace / Matrix server scope
|
||||
parent_chat_id: Optional[str] = None # Parent channel when chat_id refers to a thread
|
||||
message_id: Optional[str] = None # ID of the triggering message (for pin/reply/react)
|
||||
role_authorized: bool = False # True when adapter granted access via role (not user ID)
|
||||
|
||||
@property
|
||||
def description(self) -> str:
|
||||
|
|
|
|||
|
|
@ -794,6 +794,7 @@ class DiscordAdapter(BasePlatformAdapter):
|
|||
# Must run BEFORE the user allowlist check so that bots
|
||||
# permitted by DISCORD_ALLOW_BOTS are not rejected for
|
||||
# not being in DISCORD_ALLOWED_USERS (fixes #4466).
|
||||
_role_authorized = False
|
||||
if getattr(message.author, "bot", False):
|
||||
allow_bots = os.getenv("DISCORD_ALLOW_BOTS", "none").lower().strip()
|
||||
if allow_bots == "none":
|
||||
|
|
@ -817,6 +818,7 @@ class DiscordAdapter(BasePlatformAdapter):
|
|||
is_dm=_is_dm,
|
||||
):
|
||||
return
|
||||
_role_authorized = bool(getattr(self, "_allowed_role_ids", set()))
|
||||
|
||||
# Multi-agent filtering: if the message mentions specific bots
|
||||
# but NOT this bot, the sender is talking to another agent —
|
||||
|
|
@ -858,7 +860,7 @@ class DiscordAdapter(BasePlatformAdapter):
|
|||
if "*" not in _free_channels and not (_channel_ids & _free_channels):
|
||||
return
|
||||
|
||||
await self._handle_message(message)
|
||||
await self._handle_message(message, role_authorized=_role_authorized)
|
||||
|
||||
@self._client.event
|
||||
async def on_voice_state_update(member, before, after):
|
||||
|
|
@ -4726,7 +4728,7 @@ class DiscordAdapter(BasePlatformAdapter):
|
|||
raise Exception(f"HTTP {resp.status}")
|
||||
return await resp.read()
|
||||
|
||||
async def _handle_message(self, message: DiscordMessage) -> None:
|
||||
async def _handle_message(self, message: DiscordMessage, role_authorized: bool = False) -> None:
|
||||
"""Handle incoming Discord messages."""
|
||||
# In server channels (not DMs), require the bot to be @mentioned
|
||||
# UNLESS the channel is in the free-response list or the message is
|
||||
|
|
@ -4910,6 +4912,7 @@ class DiscordAdapter(BasePlatformAdapter):
|
|||
guild_id=str(guild.id) if guild else None,
|
||||
parent_chat_id=parent_channel_id,
|
||||
message_id=str(message.id),
|
||||
role_authorized=role_authorized,
|
||||
)
|
||||
|
||||
# Build media URLs -- download image attachments to local cache so the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue