Skip to main content

mkt_ksa_geo_sec/api/
alerts.rs

1/******************************************************************************************
2     📍 منصة تحليل الأمان الجغرافي MKT KSA – تطوير منصور بن خالد
3* 📄 رخصة Apache 2.0 – يسمح بالاستخدام والتعديل بشرط النسبة وعدم تقديم ضمانات.
4* MKT KSA Geolocation Security – Developed by Mansour Bin Khalid (KSA 🇸🇦)
5* Licensed under Apache 2.0 – https://www.apache.org/licenses/LICENSE-2.0
6* © 2025 All rights reserved.
7
8     اسم الملف: alerts.rs
9    المسار: src/api/alerts.rs
10
11    وظيفة الملف:
12    هذا الملف مسؤول عن جميع العمليات المتعلقة بتنبيهات الأمان عبر واجهة برمجة التطبيقات (API).
13    يوفر نقطة نهاية (Endpoint) لإطلاق التنبيهات الأمنية من الأنظمة الخارجية أو واجهات المستخدم.
14    عند استقبال طلب تنبيه، يتحقق من صلاحية المستخدم عبر JWT، ثم يبني نموذج التنبيه ويوقعه رقمياً (توقيع وهمي حالياً)،
15    ويعيد استجابة JSON تحتوي على حالة العملية وبيانات التنبيه.
16    الملف مصمم ليكون نقطة مركزية لإدارة التنبيهات الأمنية، ويمكن ربطه مستقبلاً بقاعدة البيانات أو أنظمة إشعار خارجية.
17
18    File name: alerts.rs
19    Path: src/api/alerts.rs
20
21    File purpose:
22    This file is responsible for all operations related to security alerts via the API.
23    It provides an endpoint for triggering security alerts from external systems or user interfaces.
24    Upon receiving an alert request, it verifies user authorization via JWT, constructs and (dummy) signs the alert model,
25    and returns a JSON response with the operation status and alert data.
26    The file is designed as a central point for managing security alerts, and can be integrated with a database or external notification systems in the future.
27******************************************************************************************/
28use crate::api::api_error;
29use crate::api::authorize_request;
30use crate::api::ok_json_with_trace;
31use crate::api::parse_json_payload;
32use crate::api::BearerToken;
33use crate::db::crud;
34use crate::db::models::SecurityAlert;
35use crate::AppState;
36use actix_web::http::StatusCode;
37use actix_web::{post, web, HttpRequest, Responder};
38use serde::Deserialize;
39use serde_json::json;
40use uuid::Uuid;
41
42/// نموذج الطلب لإطلاق التنبيه (يحدد الكيانات ونوع التنبيه والتفاصيل)
43/// Request model for triggering an alert (specifies entities, alert type, and details)
44#[derive(Deserialize)]
45pub struct AlertTriggerRequest {
46    pub entity_id: Uuid, // معرف الكيان المرتبط بالتنبيه (مثلاً مستخدم أو جهاز)
47    // The entity ID related to the alert (e.g., user or device)
48    pub entity_type: String, // نوع الكيان (مستخدم، جهاز، خدمة...)
49    // Type of entity (user, device, service, etc.)
50    pub alert_type: String, // نوع التنبيه (اختراق، محاولة دخول، إلخ)
51    // Alert type (breach, login attempt, etc.)
52    pub severity: String, // درجة الخطورة (عالي، متوسط، منخفض)
53    // Severity level (high, medium, low)
54    pub details: serde_json::Value, // تفاصيل إضافية (JSON)
55                                    // Additional details (JSON)
56}
57
58/// نقطة نهاية لإطلاق التنبيه الأمني عبر POST /alerts/trigger
59#[post("/alerts/trigger")]
60pub async fn trigger_alert(
61    app_data: web::Data<AppState>,
62    req: HttpRequest,
63    bearer: BearerToken,
64    payload_bytes: web::Bytes,
65) -> impl Responder {
66    if let Err(resp) = authorize_request(&app_data, &req, &bearer, &payload_bytes).await {
67        return resp;
68    }
69
70    let payload: AlertTriggerRequest = match parse_json_payload(&payload_bytes) {
71        Ok(v) => v,
72        Err(resp) => return resp,
73    };
74
75    // --- بناء نموذج التنبيه ---
76    // Build the alert model
77    let alert = SecurityAlert {
78        id: Uuid::new_v4(),
79        user_id: payload.entity_id, // معرف الكيان المرتبط
80        // Related entity ID
81        alert_type: payload.alert_type.clone(), // نوع التنبيه
82        // Alert type
83        alert_data: json!({
84            "entity_type": payload.entity_type,
85            "severity": payload.severity,
86            "details": payload.details,
87        }), // تفاصيل إضافية
88        // Additional details
89        created_at: chrono::Utc::now().naive_utc(), // وقت الإنشاء
90                                                    // Creation time
91    };
92
93    app_data.alert_memory.push(alert.alert_type.clone()).await;
94    if let Some(pool) = &app_data.db_pool {
95        if crud::create_security_alert(pool, &alert).await.is_err() {
96            return api_error(
97                StatusCode::INTERNAL_SERVER_ERROR,
98                "ALERT_PERSISTENCE_FAILED",
99                "Failed to persist alert",
100            );
101        }
102    }
103    // --- إرجاع استجابة JSON موحدة ---
104    // Return a unified JSON response
105    ok_json_with_trace(
106        &req,
107        json!({
108            "status": "alert_triggered",
109            "alert": alert
110        }),
111    )
112}