Fix all integrations

This commit is contained in:
2026-03-08 22:08:55 +00:00
parent bca4d6898f
commit acedc01e83
58 changed files with 4120 additions and 960 deletions

View File

@@ -40,6 +40,14 @@ from core.models import (
WorkspaceConversation,
WorkspaceMetricSnapshot,
)
from core.security.capabilities import (
CAPABILITY_SCOPES,
)
from core.security.capabilities import GLOBAL_SCOPE_KEY as COMMAND_GLOBAL_SCOPE_KEY
from core.security.capabilities import GROUP_LABELS as CAPABILITY_GROUP_LABELS
from core.security.capabilities import (
scope_record,
)
from core.transports.capabilities import capability_snapshot
from core.views.manage.permissions import SuperUserRequiredMixin
@@ -528,7 +536,7 @@ class SecurityPage(LoginRequiredMixin, View):
template_name = "pages/security.html"
page_mode = "encryption"
GLOBAL_SCOPE_KEY = "global.override"
GLOBAL_SCOPE_KEY = COMMAND_GLOBAL_SCOPE_KEY
# Allowed Services list used by both Global Scope Override and local scopes.
# Keep this in sync with the UI text on the Security page.
POLICY_SERVICES = ["xmpp", "whatsapp", "signal", "instagram", "web"]
@@ -541,47 +549,7 @@ class SecurityPage(LoginRequiredMixin, View):
"require_omemo",
"require_trusted_fingerprint",
)
POLICY_SCOPES = [
(
"gateway.tasks",
"Gateway .tasks commands",
"Handles .tasks list/show/complete/undo over gateway channels.",
),
(
"gateway.approval",
"Gateway approval commands",
"Handles .approval/.codex/.claude approve/deny over gateway channels.",
),
(
"gateway.totp",
"Gateway TOTP enrollment",
"Controls TOTP enrollment/status commands over gateway channels.",
),
(
"tasks.submit",
"Task submissions from chat",
"Controls automatic task creation from inbound messages.",
),
(
"tasks.commands",
"Task command verbs (.task/.undo/.epic)",
"Controls explicit task command verbs.",
),
(
"command.bp",
"Business plan command",
"Controls Business Plan command execution.",
),
("command.codex", "Codex command", "Controls Codex command execution."),
("command.claude", "Claude command", "Controls Claude command execution."),
]
POLICY_GROUP_LABELS = {
"gateway": "Gateway",
"tasks": "Tasks",
"command": "Commands",
"agentic": "Agentic",
"other": "Other",
}
POLICY_GROUP_LABELS = CAPABILITY_GROUP_LABELS
def _show_encryption(self) -> bool:
return str(getattr(self, "page_mode", "encryption")).strip().lower() in {
@@ -774,8 +742,10 @@ class SecurityPage(LoginRequiredMixin, View):
)
}
payload = []
for scope_key, label, description in self.POLICY_SCOPES:
key = str(scope_key or "").strip().lower()
for scope in CAPABILITY_SCOPES:
if not bool(scope.configurable):
continue
key = str(scope.key or "").strip().lower()
item = rows.get(key)
raw_allowed_services = [
str(value or "").strip().lower()
@@ -797,8 +767,8 @@ class SecurityPage(LoginRequiredMixin, View):
payload.append(
{
"scope_key": key,
"label": label,
"description": description,
"label": scope.label,
"description": scope.description,
"enabled": self._apply_global_override(
bool(getattr(item, "enabled", True)),
global_overrides["scope_enabled"],
@@ -827,38 +797,20 @@ class SecurityPage(LoginRequiredMixin, View):
return payload
def _scope_group_key(self, scope_key: str) -> str:
key = str(scope_key or "").strip().lower()
if key in {"tasks.commands", "gateway.tasks"}:
return "tasks"
if key in {"command.codex", "command.claude"}:
return "agentic"
if key.startswith("gateway."):
return "command"
if key.startswith("tasks."):
if key == "tasks.submit":
return "tasks"
return "command"
if key.startswith("command."):
return "command"
if ".commands" in key:
return "command"
if ".approval" in key:
return "command"
if ".totp" in key:
return "command"
if ".task" in key:
return "tasks"
return "other"
row = scope_record(scope_key)
return row.group if row is not None else "other"
def _grouped_scope_rows(self, request):
rows = self._scope_rows(request)
grouped: dict[str, list[dict]] = {key: [] for key in self.POLICY_GROUP_LABELS}
grouped: dict[str, list[dict]] = {
key: [] for key in self.POLICY_GROUP_LABELS.keys()
}
for row in rows:
group_key = self._scope_group_key(row.get("scope_key"))
grouped.setdefault(group_key, [])
grouped[group_key].append(row)
payload = []
for group_key in ("tasks", "command", "agentic", "other"):
for group_key in ("gateway", "tasks", "command", "agentic", "other"):
items = grouped.get(group_key) or []
if not items:
continue
@@ -875,6 +827,10 @@ class SecurityPage(LoginRequiredMixin, View):
row = self._security_settings(request)
if str(request.POST.get("encryption_settings_submit") or "").strip() == "1":
row.require_omemo = _to_bool(request.POST.get("require_omemo"), False)
row.encrypt_component_messages_with_omemo = _to_bool(
request.POST.get("encrypt_component_messages_with_omemo"),
True,
)
row.encrypt_contact_messages_with_omemo = _to_bool(
request.POST.get("encrypt_contact_messages_with_omemo"),
False,
@@ -882,6 +838,7 @@ class SecurityPage(LoginRequiredMixin, View):
row.save(
update_fields=[
"require_omemo",
"encrypt_component_messages_with_omemo",
"encrypt_contact_messages_with_omemo",
"updated_at",
]