package main import ( "context" "encoding/json" "fmt" "log" "net/http" "strconv" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "github.com/jackc/pgx/v5/pgxpool" "github.com/lab/security-governance-core/internal/audit" "github.com/lab/security-governance-core/internal/config" "github.com/lab/security-governance-core/internal/db" ) type application struct { config *config.Config queries *db.Queries auditLogger *audit.Logger } func main() { cfg := config.Load() pool, err := pgxpool.New(context.Background(), cfg.DatabaseURL) if err != nil { log.Fatalf("Unable to connect to database: %v\n", err) } defer pool.Close() queries := db.New(pool) app := &application{ config: cfg, queries: queries, auditLogger: audit.NewLogger(queries), } r := chi.NewRouter() r.Use(middleware.Logger) r.Use(middleware.Recoverer) r.Get("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Security Governance Core")) }) r.Post("/security-profiles", app.createSecurityProfileHandler) r.Post("/policies", app.createPolicyHandler) r.Get("/findings", app.getFindingsHandler) r.Get("/audit-logs", app.getAuditLogsHandler) log.Printf("Starting server on port %s", cfg.Port) if err := http.ListenAndServe(fmt.Sprintf(":%s", cfg.Port), r); err != nil { log.Fatalf("Could not start server: %s\n", err) } } func (app *application) createSecurityProfileHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) } func (app *application) createPolicyHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) } func (app *application) getFindingsHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) } func (app *application) getAuditLogsHandler(w http.ResponseWriter, r *http.Request) { limit, _ := strconv.Atoi(r.URL.Query().Get("limit")) offset, _ := strconv.Atoi(r.URL.Query().Get("offset")) if limit <= 0 { limit = 10 } if offset < 0 { offset = 0 } // For demonstration, we'll use a hardcoded actor ID. In a real app, this would come from a JWT token. actorID := "user-123" app.auditLogger.Log(r.Context(), actorID, "list_audit_logs", "audit_log", "", nil) logs, err := app.queries.ListAuditLogs(r.Context(), db.ListAuditLogsParams{ Limit: int32(limit), Offset: int32(offset), }) if err != nil { http.Error(w, "Failed to retrieve audit logs", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(logs) }