P1 fixes: outbox no_handlers, HTML sanitization, WebSocket plugin check, fail-closed plugin gate, plugin admin-only

This commit is contained in:
Agent Zero
2026-07-29 12:33:46 +02:00
parent 8539a6402c
commit 8dacb739bd
5 changed files with 42 additions and 14 deletions
+9 -9
View File
@@ -18,7 +18,7 @@ from pydantic import BaseModel
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.db import get_db
from app.deps import require_permission
from app.deps import require_permission, require_admin
from app.plugins.base import BasePlugin
from app.plugins.manifest import PluginManifest
from app.plugins.migration_runner import MigrationValidationError
@@ -143,7 +143,7 @@ async def update_plugin_config(
name: str,
body: PluginConfigUpdate,
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(require_permission("plugins:configure")),
current_user: dict = Depends(require_admin),
):
"""Update the configuration for a specific plugin.
@@ -171,7 +171,7 @@ async def update_plugin_config(
async def install_plugin(
name: str,
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(require_permission("plugins:configure")),
current_user: dict = Depends(require_admin),
):
"""Install a plugin by name. Runs migrations and creates DB record.
@@ -204,7 +204,7 @@ async def install_plugin(
async def activate_plugin(
name: str,
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(require_permission("plugins:configure")),
current_user: dict = Depends(require_admin),
):
"""Activate a plugin by name. Registers event listeners and routes.
@@ -237,7 +237,7 @@ async def activate_plugin(
async def deactivate_plugin(
name: str,
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(require_permission("plugins:configure")),
current_user: dict = Depends(require_admin),
):
"""Deactivate a plugin by name. Unregisters event listeners and routes.
@@ -267,7 +267,7 @@ async def uninstall_plugin(
name: str,
remove_data: bool = Query(False),
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(require_permission("plugins:configure")),
current_user: dict = Depends(require_admin),
):
"""Uninstall a plugin by name. Deactivates, drops tables, removes DB record.
@@ -477,7 +477,7 @@ def _install_plugin_from_dir(
async def upload_plugin(
file: UploadFile = File(...),
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(require_permission("plugins:configure")),
current_user: dict = Depends(require_admin),
):
"""Upload and install a plugin from a ZIP file.
@@ -494,7 +494,7 @@ async def upload_plugin(
async def install_plugin_from_url(
body: PluginUrlInstall,
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(require_permission("plugins:configure")),
current_user: dict = Depends(require_admin),
):
"""Install a plugin from a URL (downloads ZIP and installs).
@@ -522,7 +522,7 @@ class MarketplaceInstall(BaseModel):
async def install_from_marketplace(
body: MarketplaceInstall,
db: AsyncSession = Depends(get_db),
current_user: dict = Depends(require_permission("plugins:configure")),
current_user: dict = Depends(require_admin),
):
"""Install a plugin from the marketplace.