Improve security

This commit is contained in:
2026-03-07 15:34:23 +00:00
parent add685a326
commit 611de57bf8
31 changed files with 3617 additions and 58 deletions

View File

@@ -16,6 +16,7 @@ from core.commands.registry import get as get_handler
from core.commands.registry import register
from core.messaging.reply_sync import is_mirrored_origin
from core.models import CommandAction, CommandChannelBinding, CommandProfile, Message
from core.security.command_policy import CommandSecurityContext, evaluate_command_policy
from core.tasks.chat_defaults import ensure_default_source_for_chat
from core.util import logs
@@ -318,12 +319,21 @@ def _matches_trigger(profile: CommandProfile, text: str) -> bool:
async def process_inbound_message(ctx: CommandContext) -> list[CommandResult]:
ensure_handlers_registered()
trigger_message = await sync_to_async(
lambda: Message.objects.filter(id=ctx.message_id).first()
lambda: Message.objects.select_related("user", "session", "session__identifier")
.filter(id=ctx.message_id)
.first()
)()
if trigger_message is None:
return []
if is_mirrored_origin(trigger_message.message_meta):
return []
effective_service, effective_channel = _effective_bootstrap_scope(ctx, trigger_message)
security_context = CommandSecurityContext(
service=effective_service,
channel_identifier=effective_channel,
message_meta=dict(getattr(trigger_message, "message_meta", {}) or {}),
payload=dict(ctx.payload or {}),
)
await sync_to_async(_auto_setup_profile_bindings_for_first_command)(
ctx,
trigger_message,
@@ -334,6 +344,25 @@ async def process_inbound_message(ctx: CommandContext) -> list[CommandResult]:
for profile in profiles:
if not _matches_trigger(profile, ctx.message_text):
continue
decision = await sync_to_async(evaluate_command_policy)(
user=trigger_message.user,
scope_key=f"command.{profile.slug}",
context=security_context,
)
if not decision.allowed:
results.append(
CommandResult(
ok=False,
status="skipped",
error=f"policy_denied:{decision.code}",
payload={
"profile": profile.slug,
"scope": f"command.{profile.slug}",
"reason": decision.reason,
},
)
)
continue
if profile.reply_required and trigger_message.reply_to_id is None:
if (
profile.slug == "bp"