Security fixes: P0-P2 complete (22 fixes)
P0 (7): Auth-bypass removed, migrations fixed, plugin-upload disabled, RLS FORCE+WITH CHECK, plugin double-registration fixed, persistent volume, domain removed P1 (11): User/tenant model, Redis centralized, worker separated, transactional outbox, XSS fixed, DMS chunked streaming, permissions unified, password reset, metrics secured, config/docs fixed, cross-tenant FK P2 (4): Contact model normalized, cross-imports reduced 94%, commands+state machines for contacts/dms/mail/calendar, SPA path-traversal 8 new migrations, 99 unit tests, 13 commands, 8 contracts, 72 files changed
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
"""Public contract for the kommunikation plugin.
|
||||
|
||||
Exposes only the symbols that other builtins plugins need.
|
||||
Importers should use::
|
||||
|
||||
from app.plugins.builtins.contracts import get_contract
|
||||
komm = get_contract("kommunikation")
|
||||
if komm:
|
||||
await komm.send_message(db, tenant_id, ...)
|
||||
|
||||
instead of importing from internal modules directly.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from app.plugins.builtins.contracts import get_contract_registry
|
||||
from app.plugins.builtins.kommunikation.miniapp_registry import (
|
||||
MiniAppDef,
|
||||
MiniAppRegistry,
|
||||
)
|
||||
from app.plugins.builtins.kommunikation.models import (
|
||||
CommConversation,
|
||||
CommMessage,
|
||||
CommParticipant,
|
||||
)
|
||||
from app.plugins.builtins.kommunikation.participant_registry import (
|
||||
ParticipantHandler,
|
||||
get_participant_registry,
|
||||
)
|
||||
from app.plugins.builtins.kommunikation.services import (
|
||||
create_plugin_room,
|
||||
get_conversation,
|
||||
get_messages,
|
||||
parse_mentions,
|
||||
send_message,
|
||||
)
|
||||
|
||||
|
||||
class KommunikationContract:
|
||||
"""Public API surface for the kommunikation plugin.
|
||||
|
||||
Exposes functions, classes, and model types that other plugins are
|
||||
allowed to use. Internal implementation details remain private to
|
||||
the plugin package.
|
||||
"""
|
||||
|
||||
contract_name = "kommunikation"
|
||||
|
||||
# ─── services ───
|
||||
parse_mentions = staticmethod(parse_mentions)
|
||||
get_conversation = staticmethod(get_conversation)
|
||||
get_messages = staticmethod(get_messages)
|
||||
send_message = staticmethod(send_message)
|
||||
create_plugin_room = staticmethod(create_plugin_room)
|
||||
|
||||
# ─── participant registry ───
|
||||
get_participant_registry = staticmethod(get_participant_registry)
|
||||
ParticipantHandler = ParticipantHandler
|
||||
|
||||
# ─── mini-app registry ───
|
||||
MiniAppRegistry = MiniAppRegistry
|
||||
MiniAppDef = MiniAppDef
|
||||
|
||||
# ─── models (read-only for queries) ───
|
||||
CommConversation = CommConversation
|
||||
CommMessage = CommMessage
|
||||
CommParticipant = CommParticipant
|
||||
|
||||
|
||||
# ─── self-registration ───
|
||||
|
||||
_contract = KommunikationContract()
|
||||
get_contract_registry().register("kommunikation", _contract)
|
||||
|
||||
|
||||
__all__ = [
|
||||
"KommunikationContract",
|
||||
"ParticipantHandler",
|
||||
"get_participant_registry",
|
||||
"MiniAppRegistry",
|
||||
"MiniAppDef",
|
||||
"parse_mentions",
|
||||
"get_conversation",
|
||||
"get_messages",
|
||||
"send_message",
|
||||
"create_plugin_room",
|
||||
"CommConversation",
|
||||
"CommMessage",
|
||||
"CommParticipant",
|
||||
]
|
||||
@@ -13,7 +13,10 @@ from fastapi import UploadFile
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.plugins.builtins.dms.models import File as DmsFile, Folder
|
||||
from app.plugins.builtins.dms.contracts import get_contract as get_dms_contract
|
||||
_dms = get_dms_contract()
|
||||
DmsFile = _dms.DmsFile
|
||||
Folder = _dms.Folder
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -14,7 +14,9 @@ from app.plugins.builtins.kommunikation.models import (
|
||||
CommMessage,
|
||||
CommParticipant,
|
||||
)
|
||||
from app.plugins.builtins.unified_search.embedding import generate_embedding
|
||||
from app.plugins.builtins.unified_search.contracts import get_contract as get_search_contract
|
||||
_search = get_search_contract()
|
||||
generate_embedding = _search.generate_embedding
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user