fix: Event-bus workflow trigger, RBAC on all routes, search provider, events, cron jobs
Critical fixes:
- Event Bus → Workflow auto-trigger: wildcard subscription starts workflows on matching events
- Kommunikation routes: require_permission on all 30+ endpoints (comm:read/write/delete/manage)
- Permissions routes: require_permission('permissions:admin') on all management endpoints
- CompanySearchProvider registered in auto_register_providers()
Medium fixes:
- system_notif events: 10 event_bus.publish() calls added (lead.created, contact.created/updated,
task.created/overdue, mail.received, user.created, workflow.completed, notification.created, backup.*)
- Cron jobs: backup_check (daily), search_index_check (daily), workflow_timeout (5min) registered
- AI tool permission: call_crm_api now requires 'ai:write' permission
- New file: automation/jobs.py with backup_check and search_index_check functions
This commit is contained in:
@@ -11,7 +11,7 @@ from fastapi import APIRouter, Depends, HTTPException, Query, UploadFile, File,
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.core.db import get_db
|
||||
from app.deps import get_current_user
|
||||
from app.deps import get_current_user, require_permission
|
||||
from app.plugins.builtins.kommunikation.rbac import CommRBAC
|
||||
from app.plugins.builtins.kommunikation.schemas import (
|
||||
ConversationCreate,
|
||||
@@ -200,7 +200,7 @@ async def unmute_conv(
|
||||
|
||||
# ─── Participants ───
|
||||
|
||||
@router.post("/conversations/{conversation_id}/participants")
|
||||
@router.post("/conversations/{conversation_id}/participants", dependencies=[Depends(require_permission("comm:manage"))])
|
||||
async def add_participant_endpoint(
|
||||
conversation_id: str,
|
||||
body: ParticipantAdd,
|
||||
@@ -218,7 +218,7 @@ async def add_participant_endpoint(
|
||||
return result
|
||||
|
||||
|
||||
@router.delete("/conversations/{conversation_id}/participants/{participant_id}")
|
||||
@router.delete("/conversations/{conversation_id}/participants/{participant_id}", dependencies=[Depends(require_permission("comm:manage"))])
|
||||
async def remove_participant_endpoint(
|
||||
conversation_id: str,
|
||||
participant_id: str,
|
||||
@@ -238,7 +238,7 @@ async def remove_participant_endpoint(
|
||||
return {"success": True}
|
||||
|
||||
|
||||
@router.patch("/conversations/{conversation_id}/participants/{participant_id}")
|
||||
@router.patch("/conversations/{conversation_id}/participants/{participant_id}", dependencies=[Depends(require_permission("comm:manage"))])
|
||||
async def change_participant_role(
|
||||
conversation_id: str,
|
||||
participant_id: str,
|
||||
@@ -259,7 +259,7 @@ async def change_participant_role(
|
||||
|
||||
# ─── Messages ───
|
||||
|
||||
@router.get("/conversations/{conversation_id}/messages")
|
||||
@router.get("/conversations/{conversation_id}/messages", dependencies=[Depends(require_permission("comm:read"))])
|
||||
async def get_conv_messages(
|
||||
conversation_id: str,
|
||||
page: int = Query(1, ge=1),
|
||||
@@ -278,7 +278,7 @@ async def get_conv_messages(
|
||||
return await get_messages(db, tenant_id, conv_id, page, page_size, before_id)
|
||||
|
||||
|
||||
@router.post("/conversations/{conversation_id}/messages")
|
||||
@router.post("/conversations/{conversation_id}/messages", dependencies=[Depends(require_permission("comm:write"))])
|
||||
async def send_conv_message(
|
||||
conversation_id: str,
|
||||
body: MessageCreate,
|
||||
@@ -303,7 +303,7 @@ async def send_conv_message(
|
||||
)
|
||||
|
||||
|
||||
@router.patch("/messages/{message_id}")
|
||||
@router.patch("/messages/{message_id}", dependencies=[Depends(require_permission("comm:write"))])
|
||||
async def update_msg(
|
||||
message_id: str,
|
||||
body: MessageUpdate,
|
||||
@@ -322,7 +322,7 @@ async def update_msg(
|
||||
return {"success": True}
|
||||
|
||||
|
||||
@router.delete("/messages/{message_id}")
|
||||
@router.delete("/messages/{message_id}", dependencies=[Depends(require_permission("comm:delete"))])
|
||||
async def delete_msg(
|
||||
message_id: str,
|
||||
current_user: dict = Depends(get_current_user),
|
||||
@@ -338,7 +338,7 @@ async def delete_msg(
|
||||
|
||||
# ─── Attachments ───
|
||||
|
||||
@router.post("/messages/{message_id}/attachments")
|
||||
@router.post("/messages/{message_id}/attachments", dependencies=[Depends(require_permission("comm:write"))])
|
||||
async def upload_attachment(
|
||||
message_id: str,
|
||||
file: UploadFile = File(...),
|
||||
@@ -364,7 +364,7 @@ async def upload_attachment(
|
||||
|
||||
# ─── Reactions ───
|
||||
|
||||
@router.post("/messages/{message_id}/reactions")
|
||||
@router.post("/messages/{message_id}/reactions", dependencies=[Depends(require_permission("comm:write"))])
|
||||
async def add_msg_reaction(
|
||||
message_id: str,
|
||||
body: ReactionCreate,
|
||||
@@ -381,7 +381,7 @@ async def add_msg_reaction(
|
||||
return result
|
||||
|
||||
|
||||
@router.delete("/messages/{message_id}/reactions/{emoji}")
|
||||
@router.delete("/messages/{message_id}/reactions/{emoji}", dependencies=[Depends(require_permission("comm:write"))])
|
||||
async def remove_msg_reaction(
|
||||
message_id: str,
|
||||
emoji: str,
|
||||
@@ -399,7 +399,7 @@ async def remove_msg_reaction(
|
||||
|
||||
# ─── Read State ───
|
||||
|
||||
@router.post("/conversations/{conversation_id}/read")
|
||||
@router.post("/conversations/{conversation_id}/read", dependencies=[Depends(require_permission("comm:write"))])
|
||||
async def mark_conv_read(
|
||||
conversation_id: str,
|
||||
body: ReadStateUpdate,
|
||||
@@ -416,7 +416,7 @@ async def mark_conv_read(
|
||||
|
||||
# ─── Mini-Apps ───
|
||||
|
||||
@router.get("/miniapps")
|
||||
@router.get("/miniapps", dependencies=[Depends(require_permission("comm:read"))])
|
||||
async def list_miniapps(
|
||||
current_user: dict = Depends(get_current_user),
|
||||
):
|
||||
@@ -429,7 +429,7 @@ async def list_miniapps(
|
||||
return {"items": registry.list_apps()}
|
||||
|
||||
|
||||
@router.post("/conversations/{conversation_id}/miniapps")
|
||||
@router.post("/conversations/{conversation_id}/miniapps", dependencies=[Depends(require_permission("comm:write"))])
|
||||
async def start_miniapp(
|
||||
conversation_id: str,
|
||||
body: MiniAppStartRequest,
|
||||
@@ -455,7 +455,7 @@ async def start_miniapp(
|
||||
|
||||
# ─── Content Types ───
|
||||
|
||||
@router.get("/block-types")
|
||||
@router.get("/block-types", dependencies=[Depends(require_permission("comm:read"))])
|
||||
async def get_block_types():
|
||||
"""List all known content block types."""
|
||||
return {"items": list_block_types()}
|
||||
|
||||
Reference in New Issue
Block a user