feat: implement security agent service with webhook integration and error handling
This commit is contained in:
parent
3676637de3
commit
4b14eaf21b
|
|
@ -0,0 +1,6 @@
|
||||||
|
import { InjectionToken } from '@angular/core';
|
||||||
|
|
||||||
|
export const SECURITY_AGENT_WEBHOOK_URL = new InjectionToken<string>('SECURITY_AGENT_WEBHOOK_URL', {
|
||||||
|
providedIn: 'root',
|
||||||
|
factory: () => 'https://n8n.bryan-bano.com/webhook/security-agent'
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
export type SimulationMode = 'PURPLE_TEAM' | 'EASM' | 'SOAR';
|
||||||
|
export type SecurityVerdict = 'SAFE' | 'ATTENTION_REQUIRED' | 'CRITICAL_THREAT';
|
||||||
|
|
||||||
|
export interface SecurityAgentParameters {
|
||||||
|
readonly auto_isolate?: boolean;
|
||||||
|
readonly scan_depth?: 'quick' | 'full';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SecurityAgentRequest {
|
||||||
|
readonly mode: SimulationMode;
|
||||||
|
readonly target: string;
|
||||||
|
readonly requested_by: string;
|
||||||
|
readonly parameters?: SecurityAgentParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SecurityExecutionSummary {
|
||||||
|
readonly risk_score: number;
|
||||||
|
readonly verdict: SecurityVerdict;
|
||||||
|
readonly mitre_techniques: string[];
|
||||||
|
readonly containment_executed: boolean;
|
||||||
|
readonly mitigation_time_ms: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SecurityEvidence {
|
||||||
|
readonly sha256_hash: string;
|
||||||
|
readonly report_url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SecurityAgentResponse {
|
||||||
|
readonly success: boolean;
|
||||||
|
readonly execution_id: string;
|
||||||
|
readonly simulation_id: string;
|
||||||
|
readonly timestamp: string;
|
||||||
|
readonly mode: SimulationMode;
|
||||||
|
readonly target: string;
|
||||||
|
readonly summary: SecurityExecutionSummary;
|
||||||
|
readonly evidence: SecurityEvidence;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { SecurityAgentRequest, SecurityAgentResponse } from '../models/security.model';
|
||||||
|
|
||||||
|
export abstract class SecurityAgentPort {
|
||||||
|
abstract triggerSimulation(payload: SecurityAgentRequest): Observable<SecurityAgentResponse>;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export * from '../domain/models/security.model';
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { Injectable, inject } from '@angular/core';
|
||||||
|
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
||||||
|
import { Observable, throwError } from 'rxjs';
|
||||||
|
import { catchError } from 'rxjs/operators';
|
||||||
|
import { SecurityAgentRequest, SecurityAgentResponse } from '../domain/models/security.model';
|
||||||
|
import { SecurityAgentPort } from '../domain/ports/security-agent.port';
|
||||||
|
import { SECURITY_AGENT_WEBHOOK_URL } from '../core/tokens/security-agent-config.token';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class SecurityAgentService implements SecurityAgentPort {
|
||||||
|
private readonly http = inject(HttpClient);
|
||||||
|
private readonly webhookUrl = inject(SECURITY_AGENT_WEBHOOK_URL);
|
||||||
|
|
||||||
|
triggerSimulation(payload: SecurityAgentRequest): Observable<SecurityAgentResponse> {
|
||||||
|
return this.http.post<SecurityAgentResponse>(this.webhookUrl, payload).pipe(
|
||||||
|
catchError((error: HttpErrorResponse) => this.handleError(error))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleError(error: HttpErrorResponse): Observable<never> {
|
||||||
|
let errorMessage = 'Ocurrió un error inesperado al conectar con el orquestador n8n.';
|
||||||
|
if (error.status === 429) {
|
||||||
|
errorMessage = 'Límite de tasa excedido (Rate Limit: máx 10 peticiones cada 5 min).';
|
||||||
|
} else if (error.status === 400) {
|
||||||
|
errorMessage = error.error?.message || 'Payload o parámetros inválidos.';
|
||||||
|
} else if (error.status === 0) {
|
||||||
|
errorMessage = 'Error de red o conexión rechazada con el servidor n8n.';
|
||||||
|
} else if (error.status >= 500) {
|
||||||
|
errorMessage = error.error?.message || `Error interno del orquestador n8n (HTTP ${error.status}).`;
|
||||||
|
}
|
||||||
|
return throwError(() => new Error(errorMessage));
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue