Initial commit: breakpilot-compliance - Compliance SDK Platform
Services: Admin-Compliance, Backend-Compliance, AI-Compliance-SDK, Consent-SDK, Developer-Portal, PCA-Platform, DSMS Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
// Package api provides HTTP handlers for the Security Scanner
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/breakpilot/compliance-sdk/services/security-scanner/internal/scanner"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// ScanRequest represents a scan request
|
||||
type ScanRequest struct {
|
||||
Tools []string `json:"tools"`
|
||||
TargetPath string `json:"target_path"`
|
||||
ExcludePaths []string `json:"exclude_paths"`
|
||||
}
|
||||
|
||||
// StartScan starts a new security scan
|
||||
func StartScan(manager *scanner.Manager) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
var req ScanRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
tools := req.Tools
|
||||
if len(tools) == 0 {
|
||||
tools = manager.AvailableTools()
|
||||
}
|
||||
|
||||
scan := manager.StartScan(tools, req.TargetPath)
|
||||
|
||||
c.JSON(http.StatusAccepted, gin.H{
|
||||
"scan_id": scan.ID,
|
||||
"status": scan.Status,
|
||||
"tools": scan.Tools,
|
||||
"started_at": scan.StartedAt,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// GetScanStatus returns the status of a scan
|
||||
func GetScanStatus(manager *scanner.Manager) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
scanID := c.Param("scanId")
|
||||
scan := manager.GetScan(scanID)
|
||||
|
||||
if scan == nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Scan not found"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"scan_id": scan.ID,
|
||||
"status": scan.Status,
|
||||
"started_at": scan.StartedAt,
|
||||
"completed_at": scan.CompletedAt,
|
||||
"summary": scan.Summary,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// GetScanResults returns the results of a scan
|
||||
func GetScanResults(manager *scanner.Manager) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
scanID := c.Param("scanId")
|
||||
scan := manager.GetScan(scanID)
|
||||
|
||||
if scan == nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Scan not found"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, scan)
|
||||
}
|
||||
}
|
||||
|
||||
// GetFindings returns all findings
|
||||
func GetFindings(manager *scanner.Manager) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
findings := manager.GetAllFindings()
|
||||
|
||||
severity := c.Query("severity")
|
||||
tool := c.Query("tool")
|
||||
status := c.Query("status")
|
||||
|
||||
// Filter findings
|
||||
filtered := []scanner.Finding{}
|
||||
for _, f := range findings {
|
||||
if severity != "" && f.Severity != severity {
|
||||
continue
|
||||
}
|
||||
if tool != "" && f.Tool != tool {
|
||||
continue
|
||||
}
|
||||
if status != "" && f.Status != status {
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, f)
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"findings": filtered,
|
||||
"total": len(filtered),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// GetFinding returns a specific finding
|
||||
func GetFinding(manager *scanner.Manager) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
findingID := c.Param("findingId")
|
||||
findings := manager.GetAllFindings()
|
||||
|
||||
for _, f := range findings {
|
||||
if f.ID == findingID {
|
||||
c.JSON(http.StatusOK, f)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Finding not found"})
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateFindingStatus updates the status of a finding
|
||||
func UpdateFindingStatus(manager *scanner.Manager) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
findingID := c.Param("findingId")
|
||||
|
||||
var req struct {
|
||||
Status string `json:"status" binding:"required"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if manager.UpdateFindingStatus(findingID, req.Status) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"id": findingID,
|
||||
"status": req.Status,
|
||||
})
|
||||
} else {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Finding not found"})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateSBOM generates a Software Bill of Materials
|
||||
func GenerateSBOM(manager *scanner.Manager) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
var req struct {
|
||||
TargetPath string `json:"target_path"`
|
||||
}
|
||||
c.ShouldBindJSON(&req)
|
||||
|
||||
sbom := manager.GenerateSBOM(req.TargetPath)
|
||||
|
||||
c.JSON(http.StatusOK, sbom)
|
||||
}
|
||||
}
|
||||
|
||||
// GetSBOM returns an SBOM by ID
|
||||
func GetSBOM(manager *scanner.Manager) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
// In production, retrieve from storage
|
||||
sbom := manager.GenerateSBOM("")
|
||||
c.JSON(http.StatusOK, sbom)
|
||||
}
|
||||
}
|
||||
|
||||
// ExportSBOM exports an SBOM in the specified format
|
||||
func ExportSBOM(manager *scanner.Manager) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
format := c.Param("format")
|
||||
|
||||
sbom := manager.GenerateSBOM("")
|
||||
sbom.Format = format
|
||||
|
||||
var contentType string
|
||||
switch format {
|
||||
case "cyclonedx":
|
||||
contentType = "application/vnd.cyclonedx+json"
|
||||
case "spdx":
|
||||
contentType = "application/spdx+json"
|
||||
default:
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Unsupported format"})
|
||||
return
|
||||
}
|
||||
|
||||
c.Header("Content-Type", contentType)
|
||||
c.Header("Content-Disposition", "attachment; filename=sbom."+format+".json")
|
||||
c.JSON(http.StatusOK, sbom)
|
||||
}
|
||||
}
|
||||
|
||||
// GetRecommendations returns security recommendations
|
||||
func GetRecommendations(manager *scanner.Manager) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
recs := manager.GetRecommendations()
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"recommendations": recs,
|
||||
"total": len(recs),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// GetToolsStatus returns the status of all tools
|
||||
func GetToolsStatus(manager *scanner.Manager) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
tools := manager.GetTools()
|
||||
c.JSON(http.StatusOK, gin.H{"tools": tools})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user