fix: address review findings for observability PR
All checks were successful
Check / check (pull_request) Successful in 1m42s
All checks were successful
Check / check (pull_request) Successful in 1m42s
1. Security: Replace insecure extractRemoteIP() in audit service with middleware.RealIP() which validates trusted proxies before trusting X-Real-IP/X-Forwarded-For headers. Export RealIP from middleware. Update audit tests to verify anti-spoofing behavior. 2. Audit coverage: Add audit instrumentation to all 9 handlers that had dead action constants: HandleEnvVarSave, HandleLabelAdd, HandleLabelEdit, HandleLabelDelete, HandleVolumeAdd, HandleVolumeEdit, HandleVolumeDelete, HandlePortAdd, HandlePortDelete. 3. README: Fix API path from /api/audit to /api/v1/audit. 4. README: Fix duplicate numbering in DI order section (items 10-11 were listed twice, now correctly numbered 10-16).
This commit is contained in:
@@ -1023,6 +1023,10 @@ func (h *Handlers) HandleEnvVarSave() http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
h.auditLog(request, models.AuditActionEnvVarSave,
|
||||
models.AuditResourceEnvVar, application.ID,
|
||||
fmt.Sprintf("saved %d env vars", len(modelPairs)))
|
||||
|
||||
h.respondJSON(writer, request, map[string]bool{"ok": true}, http.StatusOK)
|
||||
}
|
||||
}
|
||||
@@ -1039,7 +1043,13 @@ func (h *Handlers) HandleLabelAdd() http.HandlerFunc {
|
||||
label.Key = key
|
||||
label.Value = value
|
||||
|
||||
return label.Save(ctx)
|
||||
err := label.Save(ctx)
|
||||
if err == nil {
|
||||
h.auditLog(request, models.AuditActionLabelAdd,
|
||||
models.AuditResourceLabel, application.ID, "added label: "+key)
|
||||
}
|
||||
|
||||
return err
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -1068,6 +1078,9 @@ func (h *Handlers) HandleLabelDelete() http.HandlerFunc {
|
||||
deleteErr := label.Delete(request.Context())
|
||||
if deleteErr != nil {
|
||||
h.log.Error("failed to delete label", "error", deleteErr)
|
||||
} else {
|
||||
h.auditLog(request, models.AuditActionLabelDelete,
|
||||
models.AuditResourceLabel, appID, "deleted label: "+label.Key)
|
||||
}
|
||||
|
||||
http.Redirect(writer, request, "/apps/"+appID, http.StatusSeeOther)
|
||||
@@ -1125,6 +1138,10 @@ func (h *Handlers) HandleVolumeAdd() http.HandlerFunc {
|
||||
saveErr := volume.Save(request.Context())
|
||||
if saveErr != nil {
|
||||
h.log.Error("failed to add volume", "error", saveErr)
|
||||
} else {
|
||||
h.auditLog(request, models.AuditActionVolumeAdd,
|
||||
models.AuditResourceVolume, application.ID,
|
||||
"added volume: "+hostPath+":"+containerPath)
|
||||
}
|
||||
|
||||
http.Redirect(writer, request, "/apps/"+application.ID, http.StatusSeeOther)
|
||||
@@ -1154,6 +1171,10 @@ func (h *Handlers) HandleVolumeDelete() http.HandlerFunc {
|
||||
deleteErr := volume.Delete(request.Context())
|
||||
if deleteErr != nil {
|
||||
h.log.Error("failed to delete volume", "error", deleteErr)
|
||||
} else {
|
||||
h.auditLog(request, models.AuditActionVolumeDelete,
|
||||
models.AuditResourceVolume, appID,
|
||||
"deleted volume: "+volume.HostPath+":"+volume.ContainerPath)
|
||||
}
|
||||
|
||||
http.Redirect(writer, request, "/apps/"+appID, http.StatusSeeOther)
|
||||
@@ -1203,6 +1224,10 @@ func (h *Handlers) HandlePortAdd() http.HandlerFunc {
|
||||
saveErr := port.Save(request.Context())
|
||||
if saveErr != nil {
|
||||
h.log.Error("failed to save port", "error", saveErr)
|
||||
} else {
|
||||
h.auditLog(request, models.AuditActionPortAdd,
|
||||
models.AuditResourcePort, application.ID,
|
||||
fmt.Sprintf("added port: %d:%d/%s", hostPort, containerPort, protocol))
|
||||
}
|
||||
|
||||
http.Redirect(writer, request, "/apps/"+application.ID, http.StatusSeeOther)
|
||||
@@ -1249,6 +1274,10 @@ func (h *Handlers) HandlePortDelete() http.HandlerFunc {
|
||||
deleteErr := port.Delete(request.Context())
|
||||
if deleteErr != nil {
|
||||
h.log.Error("failed to delete port", "error", deleteErr)
|
||||
} else {
|
||||
h.auditLog(request, models.AuditActionPortDelete,
|
||||
models.AuditResourcePort, appID,
|
||||
fmt.Sprintf("deleted port: %d:%d/%s", port.HostPort, port.ContainerPort, port.Protocol))
|
||||
}
|
||||
|
||||
http.Redirect(writer, request, "/apps/"+appID, http.StatusSeeOther)
|
||||
@@ -1324,6 +1353,9 @@ func (h *Handlers) HandleLabelEdit() http.HandlerFunc {
|
||||
saveErr := label.Save(request.Context())
|
||||
if saveErr != nil {
|
||||
h.log.Error("failed to update label", "error", saveErr)
|
||||
} else {
|
||||
h.auditLog(request, models.AuditActionLabelEdit,
|
||||
models.AuditResourceLabel, appID, "edited label: "+key)
|
||||
}
|
||||
|
||||
http.Redirect(writer, request, "/apps/"+appID, http.StatusSeeOther)
|
||||
@@ -1382,6 +1414,10 @@ func (h *Handlers) HandleVolumeEdit() http.HandlerFunc {
|
||||
saveErr := volume.Save(request.Context())
|
||||
if saveErr != nil {
|
||||
h.log.Error("failed to update volume", "error", saveErr)
|
||||
} else {
|
||||
h.auditLog(request, models.AuditActionVolumeEdit,
|
||||
models.AuditResourceVolume, appID,
|
||||
"edited volume: "+hostPath+":"+containerPath)
|
||||
}
|
||||
|
||||
http.Redirect(writer, request, "/apps/"+appID, http.StatusSeeOther)
|
||||
|
||||
Reference in New Issue
Block a user