feat(aria): add Svelte SPA frontend and threat events API
CD - Develop / build-and-deploy (push) Failing after 54s
CD - Develop / build-and-deploy (push) Failing after 54s
- frontend/: full aria.bcos.dev SPA (port 5187) with Dashboard, Threat Events, and IOC Management views; Phase 2-3 nav items disabled as placeholders - ThreatEventController: GET /api/aria/events (paginated, severity/device filter) and GET /api/aria/stats (total/critical/high/activeIoc counts) - Deployed to bcos.dev: hiveiq-aria-frontend container + aria.bcos.dev NPM proxy Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package com.hiveops.aria.controller;
|
||||
|
||||
import com.hiveops.aria.entity.ThreatEvent;
|
||||
import com.hiveops.aria.repository.ThreatEventRepository;
|
||||
import com.hiveops.aria.repository.ThreatIocRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/aria")
|
||||
@RequiredArgsConstructor
|
||||
public class ThreatEventController {
|
||||
|
||||
private final ThreatEventRepository eventRepository;
|
||||
private final ThreatIocRepository iocRepository;
|
||||
|
||||
@GetMapping("/events")
|
||||
@PreAuthorize("hasAnyRole('MSP_ADMIN','BCOS_ADMIN')")
|
||||
public Page<ThreatEvent> getEvents(
|
||||
@RequestParam(required = false) ThreatEvent.ThreatSeverity severity,
|
||||
@RequestParam(required = false) String deviceAgentId,
|
||||
@RequestParam(defaultValue = "0") int page,
|
||||
@RequestParam(defaultValue = "50") int size) {
|
||||
|
||||
PageRequest pageable = PageRequest.of(page, size, Sort.by("detectedAt").descending());
|
||||
|
||||
if (severity != null) {
|
||||
return eventRepository.findBySeverityOrderByDetectedAtDesc(severity, pageable);
|
||||
}
|
||||
if (deviceAgentId != null && !deviceAgentId.isBlank()) {
|
||||
return eventRepository.findByDeviceAgentIdOrderByDetectedAtDesc(deviceAgentId, pageable);
|
||||
}
|
||||
return eventRepository.findAllByOrderByDetectedAtDesc(pageable);
|
||||
}
|
||||
|
||||
@GetMapping("/stats")
|
||||
@PreAuthorize("hasAnyRole('MSP_ADMIN','BCOS_ADMIN')")
|
||||
public ResponseEntity<Map<String, Object>> getStats() {
|
||||
Instant since24h = Instant.now().minus(24, ChronoUnit.HOURS);
|
||||
Instant since7d = Instant.now().minus(7, ChronoUnit.DAYS);
|
||||
|
||||
long totalEvents = eventRepository.count();
|
||||
long critical24h = eventRepository.findBySeverityOrderByDetectedAtDesc(
|
||||
ThreatEvent.ThreatSeverity.CRITICAL,
|
||||
PageRequest.of(0, Integer.MAX_VALUE)).getTotalElements();
|
||||
long high24h = eventRepository.findBySeverityOrderByDetectedAtDesc(
|
||||
ThreatEvent.ThreatSeverity.HIGH,
|
||||
PageRequest.of(0, Integer.MAX_VALUE)).getTotalElements();
|
||||
long activeIocs = iocRepository.findByActiveTrue().size();
|
||||
|
||||
return ResponseEntity.ok(Map.of(
|
||||
"totalEvents", totalEvents,
|
||||
"criticalCount", critical24h,
|
||||
"highCount", high24h,
|
||||
"activeIocCount", activeIocs
|
||||
));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user