Increase security and reformat
This commit is contained in:
@@ -4,7 +4,7 @@ from typing import Iterable
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from core.models import Message, User
|
||||
from core.models import Message
|
||||
from core.presence import AvailabilitySignal, record_inferred_signal
|
||||
from core.presence.inference import now_ms
|
||||
|
||||
@@ -19,7 +19,9 @@ class Command(BaseCommand):
|
||||
parser.add_argument("--user-id", default="")
|
||||
parser.add_argument("--dry-run", action="store_true", default=False)
|
||||
|
||||
def _iter_messages(self, *, days: int, limit: int, service: str, user_id: str) -> Iterable[Message]:
|
||||
def _iter_messages(
|
||||
self, *, days: int, limit: int, service: str, user_id: str
|
||||
) -> Iterable[Message]:
|
||||
cutoff_ts = now_ms() - (max(1, int(days)) * 24 * 60 * 60 * 1000)
|
||||
qs = Message.objects.filter(ts__gte=cutoff_ts).select_related(
|
||||
"user", "session", "session__identifier", "session__identifier__person"
|
||||
@@ -40,7 +42,9 @@ class Command(BaseCommand):
|
||||
created = 0
|
||||
scanned = 0
|
||||
|
||||
for msg in self._iter_messages(days=days, limit=limit, service=service_filter, user_id=user_filter):
|
||||
for msg in self._iter_messages(
|
||||
days=days, limit=limit, service=service_filter, user_id=user_filter
|
||||
):
|
||||
scanned += 1
|
||||
identifier = getattr(getattr(msg, "session", None), "identifier", None)
|
||||
person = getattr(identifier, "person", None)
|
||||
@@ -48,12 +52,18 @@ class Command(BaseCommand):
|
||||
if not identifier or not person or not user:
|
||||
continue
|
||||
|
||||
service = str(getattr(msg, "source_service", "") or identifier.service or "").strip().lower()
|
||||
service = (
|
||||
str(getattr(msg, "source_service", "") or identifier.service or "")
|
||||
.strip()
|
||||
.lower()
|
||||
)
|
||||
if not service:
|
||||
continue
|
||||
|
||||
base_ts = int(getattr(msg, "ts", 0) or 0)
|
||||
message_author = str(getattr(msg, "custom_author", "") or "").strip().upper()
|
||||
message_author = (
|
||||
str(getattr(msg, "custom_author", "") or "").strip().upper()
|
||||
)
|
||||
outgoing = message_author in {"USER", "BOT"}
|
||||
|
||||
candidates = []
|
||||
@@ -84,7 +94,9 @@ class Command(BaseCommand):
|
||||
"origin": "backfill_contact_availability",
|
||||
"message_id": str(msg.id),
|
||||
"inferred_from": "read_receipt",
|
||||
"read_by": str(getattr(msg, "read_by_identifier", "") or ""),
|
||||
"read_by": str(
|
||||
getattr(msg, "read_by_identifier", "") or ""
|
||||
),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -7,7 +7,12 @@ from asgiref.sync import async_to_sync
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from core.clients.transport import send_message_raw
|
||||
from core.models import CodexPermissionRequest, CodexRun, ExternalSyncEvent, TaskProviderConfig
|
||||
from core.models import (
|
||||
CodexPermissionRequest,
|
||||
CodexRun,
|
||||
ExternalSyncEvent,
|
||||
TaskProviderConfig,
|
||||
)
|
||||
from core.tasks.providers import get_provider
|
||||
from core.util import logs
|
||||
|
||||
@@ -15,7 +20,9 @@ log = logs.get_logger("codex_worker")
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Process queued external sync events for worker-backed providers (codex_cli)."
|
||||
help = (
|
||||
"Process queued external sync events for worker-backed providers (codex_cli)."
|
||||
)
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument("--once", action="store_true", default=False)
|
||||
@@ -73,7 +80,9 @@ class Command(BaseCommand):
|
||||
payload = dict(event.payload or {})
|
||||
action = str(payload.get("action") or "append_update").strip().lower()
|
||||
provider_payload = dict(payload.get("provider_payload") or payload)
|
||||
run_id = str(provider_payload.get("codex_run_id") or payload.get("codex_run_id") or "").strip()
|
||||
run_id = str(
|
||||
provider_payload.get("codex_run_id") or payload.get("codex_run_id") or ""
|
||||
).strip()
|
||||
codex_run = None
|
||||
if run_id:
|
||||
codex_run = CodexRun.objects.filter(id=run_id, user=event.user).first()
|
||||
@@ -104,9 +113,13 @@ class Command(BaseCommand):
|
||||
result_payload = dict(result.payload or {})
|
||||
requires_approval = bool(result_payload.get("requires_approval"))
|
||||
if requires_approval:
|
||||
approval_key = str(result_payload.get("approval_key") or uuid.uuid4().hex[:12]).strip()
|
||||
approval_key = str(
|
||||
result_payload.get("approval_key") or uuid.uuid4().hex[:12]
|
||||
).strip()
|
||||
permission_request = dict(result_payload.get("permission_request") or {})
|
||||
summary = str(result_payload.get("summary") or permission_request.get("summary") or "").strip()
|
||||
summary = str(
|
||||
result_payload.get("summary") or permission_request.get("summary") or ""
|
||||
).strip()
|
||||
requested_permissions = permission_request.get("requested_permissions")
|
||||
if not isinstance(requested_permissions, (list, dict)):
|
||||
requested_permissions = permission_request or {}
|
||||
@@ -121,28 +134,42 @@ class Command(BaseCommand):
|
||||
codex_run.status = "waiting_approval"
|
||||
codex_run.result_payload = dict(result_payload)
|
||||
codex_run.error = ""
|
||||
codex_run.save(update_fields=["status", "result_payload", "error", "updated_at"])
|
||||
codex_run.save(
|
||||
update_fields=["status", "result_payload", "error", "updated_at"]
|
||||
)
|
||||
CodexPermissionRequest.objects.update_or_create(
|
||||
approval_key=approval_key,
|
||||
defaults={
|
||||
"user": event.user,
|
||||
"codex_run": codex_run if codex_run is not None else CodexRun.objects.create(
|
||||
user=event.user,
|
||||
task=event.task,
|
||||
derived_task_event=event.task_event,
|
||||
source_service=str(provider_payload.get("source_service") or ""),
|
||||
source_channel=str(provider_payload.get("source_channel") or ""),
|
||||
external_chat_id=str(provider_payload.get("external_chat_id") or ""),
|
||||
status="waiting_approval",
|
||||
request_payload=dict(payload or {}),
|
||||
result_payload=dict(result_payload),
|
||||
error="",
|
||||
"codex_run": (
|
||||
codex_run
|
||||
if codex_run is not None
|
||||
else CodexRun.objects.create(
|
||||
user=event.user,
|
||||
task=event.task,
|
||||
derived_task_event=event.task_event,
|
||||
source_service=str(
|
||||
provider_payload.get("source_service") or ""
|
||||
),
|
||||
source_channel=str(
|
||||
provider_payload.get("source_channel") or ""
|
||||
),
|
||||
external_chat_id=str(
|
||||
provider_payload.get("external_chat_id") or ""
|
||||
),
|
||||
status="waiting_approval",
|
||||
request_payload=dict(payload or {}),
|
||||
result_payload=dict(result_payload),
|
||||
error="",
|
||||
)
|
||||
),
|
||||
"external_sync_event": event,
|
||||
"summary": summary,
|
||||
"requested_permissions": requested_permissions if isinstance(requested_permissions, dict) else {
|
||||
"items": list(requested_permissions or [])
|
||||
},
|
||||
"requested_permissions": (
|
||||
requested_permissions
|
||||
if isinstance(requested_permissions, dict)
|
||||
else {"items": list(requested_permissions or [])}
|
||||
),
|
||||
"resume_payload": dict(resume_payload or {}),
|
||||
"status": "pending",
|
||||
"resolved_at": None,
|
||||
@@ -150,9 +177,17 @@ class Command(BaseCommand):
|
||||
"resolution_note": "",
|
||||
},
|
||||
)
|
||||
approver_service = str((cfg.settings or {}).get("approver_service") or "").strip().lower()
|
||||
approver_identifier = str((cfg.settings or {}).get("approver_identifier") or "").strip()
|
||||
requested_text = result_payload.get("permission_request") or result_payload.get("requested_permissions") or {}
|
||||
approver_service = (
|
||||
str((cfg.settings or {}).get("approver_service") or "").strip().lower()
|
||||
)
|
||||
approver_identifier = str(
|
||||
(cfg.settings or {}).get("approver_identifier") or ""
|
||||
).strip()
|
||||
requested_text = (
|
||||
result_payload.get("permission_request")
|
||||
or result_payload.get("requested_permissions")
|
||||
or {}
|
||||
)
|
||||
if approver_service and approver_identifier:
|
||||
try:
|
||||
async_to_sync(send_message_raw)(
|
||||
@@ -168,10 +203,17 @@ class Command(BaseCommand):
|
||||
metadata={"origin_tag": f"codex-approval:{approval_key}"},
|
||||
)
|
||||
except Exception:
|
||||
log.exception("failed to notify approver channel for approval_key=%s", approval_key)
|
||||
log.exception(
|
||||
"failed to notify approver channel for approval_key=%s",
|
||||
approval_key,
|
||||
)
|
||||
else:
|
||||
source_service = str(provider_payload.get("source_service") or "").strip().lower()
|
||||
source_channel = str(provider_payload.get("source_channel") or "").strip()
|
||||
source_service = (
|
||||
str(provider_payload.get("source_service") or "").strip().lower()
|
||||
)
|
||||
source_channel = str(
|
||||
provider_payload.get("source_channel") or ""
|
||||
).strip()
|
||||
if source_service and source_channel:
|
||||
try:
|
||||
async_to_sync(send_message_raw)(
|
||||
@@ -185,7 +227,9 @@ class Command(BaseCommand):
|
||||
metadata={"origin_tag": "codex-approval-missing-target"},
|
||||
)
|
||||
except Exception:
|
||||
log.exception("failed to notify source channel for missing approver target")
|
||||
log.exception(
|
||||
"failed to notify source channel for missing approver target"
|
||||
)
|
||||
return
|
||||
|
||||
event.status = "ok" if result.ok else "failed"
|
||||
@@ -201,18 +245,24 @@ class Command(BaseCommand):
|
||||
approval_key = str(provider_payload.get("approval_key") or "").strip()
|
||||
if mode == "approval_response" and approval_key:
|
||||
req = (
|
||||
CodexPermissionRequest.objects.select_related("external_sync_event", "codex_run")
|
||||
CodexPermissionRequest.objects.select_related(
|
||||
"external_sync_event", "codex_run"
|
||||
)
|
||||
.filter(user=event.user, approval_key=approval_key)
|
||||
.first()
|
||||
)
|
||||
if req and req.external_sync_event_id:
|
||||
if result.ok:
|
||||
ExternalSyncEvent.objects.filter(id=req.external_sync_event_id).update(
|
||||
ExternalSyncEvent.objects.filter(
|
||||
id=req.external_sync_event_id
|
||||
).update(
|
||||
status="ok",
|
||||
error="",
|
||||
)
|
||||
elif str(event.error or "").strip() == "approval_denied":
|
||||
ExternalSyncEvent.objects.filter(id=req.external_sync_event_id).update(
|
||||
ExternalSyncEvent.objects.filter(
|
||||
id=req.external_sync_event_id
|
||||
).update(
|
||||
status="failed",
|
||||
error="approval_denied",
|
||||
)
|
||||
@@ -220,9 +270,16 @@ class Command(BaseCommand):
|
||||
codex_run.status = "ok" if result.ok else "failed"
|
||||
codex_run.error = str(result.error or "")
|
||||
codex_run.result_payload = result_payload
|
||||
codex_run.save(update_fields=["status", "error", "result_payload", "updated_at"])
|
||||
codex_run.save(
|
||||
update_fields=["status", "error", "result_payload", "updated_at"]
|
||||
)
|
||||
|
||||
if result.ok and result.external_key and event.task_id and not str(event.task.external_key or "").strip():
|
||||
if (
|
||||
result.ok
|
||||
and result.external_key
|
||||
and event.task_id
|
||||
and not str(event.task.external_key or "").strip()
|
||||
):
|
||||
event.task.external_key = str(result.external_key)
|
||||
event.task.save(update_fields=["external_key"])
|
||||
|
||||
@@ -250,7 +307,11 @@ class Command(BaseCommand):
|
||||
continue
|
||||
|
||||
for row_id in claimed_ids:
|
||||
event = ExternalSyncEvent.objects.filter(id=row_id).select_related("task", "user").first()
|
||||
event = (
|
||||
ExternalSyncEvent.objects.filter(id=row_id)
|
||||
.select_related("task", "user")
|
||||
.first()
|
||||
)
|
||||
if event is None:
|
||||
continue
|
||||
try:
|
||||
|
||||
@@ -85,7 +85,9 @@ class Command(BaseCommand):
|
||||
compared = shadow_compare_session(session, detail_limit=detail_limit)
|
||||
aggregate["sessions_scanned"] += 1
|
||||
aggregate["db_message_count"] += int(compared.get("db_message_count") or 0)
|
||||
aggregate["projected_message_count"] += int(compared.get("projected_message_count") or 0)
|
||||
aggregate["projected_message_count"] += int(
|
||||
compared.get("projected_message_count") or 0
|
||||
)
|
||||
aggregate["mismatch_total"] += int(compared.get("mismatch_total") or 0)
|
||||
for key in aggregate["counters"].keys():
|
||||
aggregate["counters"][key] += int(
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from core.models import ContactAvailabilityEvent, ContactAvailabilitySpan, Message
|
||||
from core.presence import AvailabilitySignal, record_native_signal
|
||||
from core.presence.inference import now_ms
|
||||
|
||||
|
||||
_SOURCE_ORDER = {
|
||||
"message_in": 10,
|
||||
"message_out": 20,
|
||||
@@ -51,9 +48,14 @@ class Command(BaseCommand):
|
||||
if not identifier or not person or not user:
|
||||
continue
|
||||
|
||||
service = str(
|
||||
getattr(msg, "source_service", "") or getattr(identifier, "service", "")
|
||||
).strip().lower()
|
||||
service = (
|
||||
str(
|
||||
getattr(msg, "source_service", "")
|
||||
or getattr(identifier, "service", "")
|
||||
)
|
||||
.strip()
|
||||
.lower()
|
||||
)
|
||||
if not service:
|
||||
continue
|
||||
|
||||
@@ -95,12 +97,16 @@ class Command(BaseCommand):
|
||||
"origin": "recalculate_contact_availability",
|
||||
"message_id": str(msg.id),
|
||||
"inferred_from": "read_receipt",
|
||||
"read_by": str(getattr(msg, "read_by_identifier", "") or ""),
|
||||
"read_by": str(
|
||||
getattr(msg, "read_by_identifier", "") or ""
|
||||
),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
reactions = list((getattr(msg, "receipt_payload", {}) or {}).get("reactions") or [])
|
||||
reactions = list(
|
||||
(getattr(msg, "receipt_payload", {}) or {}).get("reactions") or []
|
||||
)
|
||||
for reaction in reactions:
|
||||
item = dict(reaction or {})
|
||||
if bool(item.get("removed")):
|
||||
@@ -124,7 +130,9 @@ class Command(BaseCommand):
|
||||
"inferred_from": "reaction",
|
||||
"emoji": str(item.get("emoji") or ""),
|
||||
"actor": str(item.get("actor") or ""),
|
||||
"source_service": str(item.get("source_service") or service),
|
||||
"source_service": str(
|
||||
item.get("source_service") or service
|
||||
),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -67,7 +67,9 @@ def _compute_payload(rows, identifier_values):
|
||||
pending_out_ts = None
|
||||
first_ts = int(rows[0]["ts"] or 0)
|
||||
last_ts = int(rows[-1]["ts"] or 0)
|
||||
latest_service = str(rows[-1].get("session__identifier__service") or "").strip().lower()
|
||||
latest_service = (
|
||||
str(rows[-1].get("session__identifier__service") or "").strip().lower()
|
||||
)
|
||||
|
||||
for row in rows:
|
||||
ts = int(row.get("ts") or 0)
|
||||
@@ -162,18 +164,18 @@ def _compute_payload(rows, identifier_values):
|
||||
payload = {
|
||||
"source_event_ts": last_ts,
|
||||
"stability_state": stability_state,
|
||||
"stability_score": float(stability_score_value)
|
||||
if stability_score_value is not None
|
||||
else None,
|
||||
"stability_score": (
|
||||
float(stability_score_value) if stability_score_value is not None else None
|
||||
),
|
||||
"stability_confidence": round(confidence, 3),
|
||||
"stability_sample_messages": message_count,
|
||||
"stability_sample_days": sample_days,
|
||||
"commitment_inbound_score": float(commitment_in_value)
|
||||
if commitment_in_value is not None
|
||||
else None,
|
||||
"commitment_outbound_score": float(commitment_out_value)
|
||||
if commitment_out_value is not None
|
||||
else None,
|
||||
"commitment_inbound_score": (
|
||||
float(commitment_in_value) if commitment_in_value is not None else None
|
||||
),
|
||||
"commitment_outbound_score": (
|
||||
float(commitment_out_value) if commitment_out_value is not None else None
|
||||
),
|
||||
"commitment_confidence": round(confidence, 3),
|
||||
"inbound_messages": inbound_count,
|
||||
"outbound_messages": outbound_count,
|
||||
@@ -232,15 +234,17 @@ class Command(BaseCommand):
|
||||
dry_run = bool(options.get("dry_run"))
|
||||
reset = not bool(options.get("no_reset"))
|
||||
compact_enabled = not bool(options.get("skip_compact"))
|
||||
today_start = dj_timezone.now().astimezone(timezone.utc).replace(
|
||||
hour=0,
|
||||
minute=0,
|
||||
second=0,
|
||||
microsecond=0,
|
||||
)
|
||||
cutoff_ts = int(
|
||||
(today_start.timestamp() * 1000) - (days * 24 * 60 * 60 * 1000)
|
||||
today_start = (
|
||||
dj_timezone.now()
|
||||
.astimezone(timezone.utc)
|
||||
.replace(
|
||||
hour=0,
|
||||
minute=0,
|
||||
second=0,
|
||||
microsecond=0,
|
||||
)
|
||||
)
|
||||
cutoff_ts = int((today_start.timestamp() * 1000) - (days * 24 * 60 * 60 * 1000))
|
||||
|
||||
people_qs = Person.objects.all()
|
||||
if user_id:
|
||||
@@ -256,14 +260,18 @@ class Command(BaseCommand):
|
||||
compacted_deleted = 0
|
||||
|
||||
for person in people:
|
||||
identifiers_qs = PersonIdentifier.objects.filter(user=person.user, person=person)
|
||||
identifiers_qs = PersonIdentifier.objects.filter(
|
||||
user=person.user, person=person
|
||||
)
|
||||
if service:
|
||||
identifiers_qs = identifiers_qs.filter(service=service)
|
||||
identifiers = list(identifiers_qs)
|
||||
if not identifiers:
|
||||
continue
|
||||
identifier_values = {
|
||||
str(row.identifier or "").strip() for row in identifiers if row.identifier
|
||||
str(row.identifier or "").strip()
|
||||
for row in identifiers
|
||||
if row.identifier
|
||||
}
|
||||
if not identifier_values:
|
||||
continue
|
||||
@@ -350,7 +358,9 @@ class Command(BaseCommand):
|
||||
snapshots_created += 1
|
||||
if dry_run:
|
||||
continue
|
||||
WorkspaceMetricSnapshot.objects.create(conversation=conversation, **payload)
|
||||
WorkspaceMetricSnapshot.objects.create(
|
||||
conversation=conversation, **payload
|
||||
)
|
||||
existing_signatures.add(signature)
|
||||
|
||||
if not latest_payload:
|
||||
@@ -368,7 +378,9 @@ class Command(BaseCommand):
|
||||
"updated_at": dj_timezone.now().isoformat(),
|
||||
}
|
||||
if not dry_run:
|
||||
conversation.platform_type = latest_service or conversation.platform_type
|
||||
conversation.platform_type = (
|
||||
latest_service or conversation.platform_type
|
||||
)
|
||||
conversation.last_event_ts = latest_payload.get("source_event_ts")
|
||||
conversation.stability_state = str(
|
||||
latest_payload.get("stability_state")
|
||||
@@ -416,7 +428,9 @@ class Command(BaseCommand):
|
||||
)
|
||||
if compact_enabled:
|
||||
snapshot_rows = list(
|
||||
WorkspaceMetricSnapshot.objects.filter(conversation=conversation)
|
||||
WorkspaceMetricSnapshot.objects.filter(
|
||||
conversation=conversation
|
||||
)
|
||||
.order_by("computed_at", "id")
|
||||
.values("id", "computed_at", "source_event_ts")
|
||||
)
|
||||
@@ -428,7 +442,9 @@ class Command(BaseCommand):
|
||||
)
|
||||
if keep_ids:
|
||||
compacted_deleted += (
|
||||
WorkspaceMetricSnapshot.objects.filter(conversation=conversation)
|
||||
WorkspaceMetricSnapshot.objects.filter(
|
||||
conversation=conversation
|
||||
)
|
||||
.exclude(id__in=list(keep_ids))
|
||||
.delete()[0]
|
||||
)
|
||||
|
||||
@@ -4,4 +4,6 @@ from core.management.commands.codex_worker import Command as LegacyCodexWorkerCo
|
||||
|
||||
|
||||
class Command(LegacyCodexWorkerCommand):
|
||||
help = "Process queued task-sync events for worker-backed providers (Codex + Claude)."
|
||||
help = (
|
||||
"Process queued task-sync events for worker-backed providers (Codex + Claude)."
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user