feat(phases): implement webhooks (6.1), email (7.1), user preferences (7.2)
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled

- Phase 6.1: WebhookConfig model, CRUD router (/api/v1/webhooks, admin-only),
  dispatch_webhook() with HMAC signing; integrated into test validation,
  campaign completion, and MITRE sync job
- Phase 7.1: SMTP email service with send_test_validated_email,
  send_campaign_completed_email, send_new_mitre_techniques_email;
  notify_role_with_email() added to notification_service
- Phase 7.2: notification_preferences and jira_account_id on User model;
  PATCH /users/me/preferences endpoint; Alembic migrations b031phase6 and b032phase7

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kitos
2026-05-19 13:40:45 +02:00
parent d6df7fdc09
commit c1e06d4c0a
16 changed files with 590 additions and 2 deletions

View File

@@ -0,0 +1,19 @@
"""WebhookConfig model — outbound HTTP notification endpoints."""
import uuid
from datetime import datetime
from sqlalchemy import Column, String, Boolean, DateTime, Integer, Text, ForeignKey, func
from sqlalchemy.dialects.postgresql import UUID, JSONB
from app.database import Base
class WebhookConfig(Base):
__tablename__ = "webhook_configs"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
name = Column(String(200), nullable=False)
url = Column(Text, nullable=False)
secret = Column(String(256), nullable=True) # HMAC signature key
events = Column(JSONB, nullable=False, server_default="[]") # list of event types
is_active = Column(Boolean, default=True, nullable=False)
created_by = Column(UUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
last_triggered_at = Column(DateTime, nullable=True)
failure_count = Column(Integer, default=0, nullable=False)
created_at = Column(DateTime(timezone=True), server_default=func.now())