package handlers import ( "net/http" "time" "github.com/gin-gonic/gin" ) // SecurityHandler handles security-related HTTP requests type SecurityHandler struct{} // NewSecurityHandler creates a new security handler func NewSecurityHandler() *SecurityHandler { return &SecurityHandler{} } // FraudAlert represents a fraud alert type FraudAlert struct { ID string `json:"id"` Type string `json:"type"` Severity string `json:"severity"` ProfileID string `json:"profile_id"` Description string `json:"description"` RiskScore float64 `json:"risk_score"` Evidence []string `json:"evidence"` IPAddress string `json:"ip_address"` Timestamp time.Time `json:"timestamp"` Status string `json:"status"` ActionsTaken []string `json:"actions_taken"` Metadata map[string]any `json:"metadata"` } // FraudMetrics represents fraud detection metrics type FraudMetrics struct { Period string `json:"period"` TotalAlerts int64 `json:"total_alerts"` ResolvedAlerts int64 `json:"resolved_alerts"` FalsePositives int64 `json:"false_positives"` ResolutionRate float64 `json:"resolution_rate_pct"` FalsePositiveRate float64 `json:"false_positive_rate_pct"` ByType map[string]int64 `json:"by_type"` BySeverity map[string]int64 `json:"by_severity"` GeneratedAt time.Time `json:"generated_at"` } // AnalyzeTransaction analyzes a transaction for fraud func (h *SecurityHandler) AnalyzeTransaction(c *gin.Context) { var req map[string]any if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } profileID, _ := req["profile_id"].(string) ipAddress, _ := req["ip_address"].(string) // Simulated fraud analysis riskScore := 25.0 // Low risk by default // Check for suspicious patterns if amount, ok := req["amount"].(float64); ok && amount > 1000 { riskScore += 20 } alert := FraudAlert{ ID: "alert-" + time.Now().Format("20060102150405"), Type: "transaction_analysis", Severity: getSeverityFromScore(riskScore), ProfileID: profileID, Description: "Transaction analyzed for fraud indicators", RiskScore: riskScore, Evidence: []string{ "Transaction amount within normal range", "IP address matches historical pattern", "Device fingerprint recognized", }, IPAddress: ipAddress, Timestamp: time.Now(), Status: "analyzed", ActionsTaken: []string{"Logged for monitoring"}, Metadata: req, } c.JSON(http.StatusOK, alert) } // GetFraudAlerts returns fraud alerts with filtering func (h *SecurityHandler) GetFraudAlerts(c *gin.Context) { var filter struct { Type string `json:"type"` Severity string `json:"severity"` Status string `json:"status"` Limit int `json:"limit"` } c.ShouldBindJSON(&filter) if filter.Limit == 0 || filter.Limit > 100 { filter.Limit = 50 } // Simulated alerts alerts := []FraudAlert{ { ID: "alert-001", Type: "account_takeover", Severity: "high", ProfileID: "profile-123", Description: "Multiple failed login attempts from new IP", RiskScore: 85.0, Evidence: []string{"10 failed logins", "New IP address", "Different country"}, IPAddress: "192.168.1.100", Timestamp: time.Now().Add(-2 * time.Hour), Status: "new", }, { ID: "alert-002", Type: "payment_fraud", Severity: "medium", ProfileID: "profile-456", Description: "Unusual payment pattern detected", RiskScore: 55.0, Evidence: []string{"Large transaction", "New payment method"}, IPAddress: "10.0.0.50", Timestamp: time.Now().Add(-5 * time.Hour), Status: "investigating", }, { ID: "alert-003", Type: "sim_swap", Severity: "critical", ProfileID: "profile-789", Description: "SIM swap attempt detected", RiskScore: 95.0, Evidence: []string{"SIM change request", "No prior notification", "High-value account"}, IPAddress: "172.16.0.25", Timestamp: time.Now().Add(-30 * time.Minute), Status: "blocked", }, } // Filter alerts filtered := make([]FraudAlert, 0) for _, alert := range alerts { if filter.Type != "" && alert.Type != filter.Type { continue } if filter.Severity != "" && alert.Severity != filter.Severity { continue } if filter.Status != "" && alert.Status != filter.Status { continue } filtered = append(filtered, alert) if len(filtered) >= filter.Limit { break } } c.JSON(http.StatusOK, filtered) } // UpdateAlertStatus updates a fraud alert status func (h *SecurityHandler) UpdateAlertStatus(c *gin.Context) { alertID := c.Param("id") var req struct { Status string `json:"status" binding:"required"` Actions []string `json:"actions"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{ "id": alertID, "status": req.Status, "actions_taken": req.Actions, "updated_at": time.Now(), }) } // GetFraudMetrics returns fraud detection metrics func (h *SecurityHandler) GetFraudMetrics(c *gin.Context) { period := c.DefaultQuery("period", "monthly") metrics := FraudMetrics{ Period: period, TotalAlerts: 1250, ResolvedAlerts: 1100, FalsePositives: 125, ResolutionRate: 88.0, FalsePositiveRate: 10.0, ByType: map[string]int64{ "account_takeover": 350, "subscription_fraud": 200, "payment_fraud": 400, "usage_anomaly": 200, "sim_swap": 100, }, BySeverity: map[string]int64{ "low": 400, "medium": 500, "high": 250, "critical": 100, }, GeneratedAt: time.Now(), } c.JSON(http.StatusOK, metrics) } // GetFraudPatterns returns detected fraud patterns func (h *SecurityHandler) GetFraudPatterns(c *gin.Context) { patterns := []map[string]any{ { "id": "pattern-1", "name": "Velocity Attack", "description": "Multiple rapid transactions from same source", "frequency": "high", "indicators": []string{"High transaction rate", "Same IP", "Different accounts"}, "mitigation": "Rate limiting, IP blocking", }, { "id": "pattern-2", "name": "Account Enumeration", "description": "Systematic probing of account existence", "frequency": "medium", "indicators": []string{"Sequential account checks", "Automated requests"}, "mitigation": "CAPTCHA, rate limiting", }, { "id": "pattern-3", "name": "SIM Swap Attack", "description": "Unauthorized SIM card replacement", "frequency": "low", "indicators": []string{"Sudden SIM change", "No customer contact", "High-value target"}, "mitigation": "Multi-factor verification, cooling period", }, } c.JSON(http.StatusOK, gin.H{"patterns": patterns}) } // VerifySIMSwap verifies a SIM swap request func (h *SecurityHandler) VerifySIMSwap(c *gin.Context) { var req struct { ProfileID string `json:"profile_id" binding:"required"` MSISDN string `json:"msisdn" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // Simulated SIM swap verification c.JSON(http.StatusOK, gin.H{ "profile_id": req.ProfileID, "msisdn": req.MSISDN, "verified": true, "risk_score": 15.0, "risk_level": "low", "last_sim_swap": time.Now().AddDate(-1, 0, 0).Format("2006-01-02"), "checks_passed": []string{ "Identity verified", "No recent SIM changes", "Account in good standing", }, }) } // GetSIMSwapHistory returns SIM swap history for a profile func (h *SecurityHandler) GetSIMSwapHistory(c *gin.Context) { profileID := c.Param("profile_id") history := []map[string]any{ { "id": "swap-001", "profile_id": profileID, "old_iccid": "8901234567890123456", "new_iccid": "8901234567890123457", "timestamp": time.Now().AddDate(-1, 0, 0), "reason": "Device upgrade", "verified": true, "status": "completed", }, { "id": "swap-002", "profile_id": profileID, "old_iccid": "8901234567890123455", "new_iccid": "8901234567890123456", "timestamp": time.Now().AddDate(-2, 0, 0), "reason": "Lost device", "verified": true, "status": "completed", }, } c.JSON(http.StatusOK, gin.H{"history": history}) } func getSeverityFromScore(score float64) string { switch { case score >= 80: return "critical" case score >= 60: return "high" case score >= 40: return "medium" default: return "low" } }