package router import ( "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/recover" "github.com/rs/zerolog" "github.com/gosec/gsc-ops-api/internal/handler" "github.com/gosec/gsc-ops-api/internal/middleware" ) // Config holds all handler dependencies for route registration type Config struct { Logger zerolog.Logger APIKeys []string // APIKeyValidate backs the static APIKeys list with a dynamic, self-managed // key store so new consumers can be added at runtime without a rebuild. APIKeyValidate middleware.APIKeyValidator APIKeysAdmin *handler.APIKeyHandler Health *handler.HealthHandler LDAPUsers *handler.LDAPUserHandler LDAPGroups *handler.LDAPGroupHandler LDAPEntities *handler.LDAPEntityHandler DNSZones *handler.DNSZoneHandler DNSRecords *handler.DNSRecordHandler DBTenants *handler.DBTenantHandler DBUsers *handler.DBUserHandler Certs *handler.CertHandler PGP *handler.PGPHandler CardDAV *handler.CardDAVHandler PBX *handler.PBXHandler VoiceAgent *handler.VoiceAgentHandler PersonalAgent *handler.PersonalAgentHandler Persona *handler.PersonaHandler } // Setup registers all routes on the Fiber app func Setup(app *fiber.App, cfg *Config) { // Global middleware app.Use(recover.New()) app.Use(middleware.RequestID()) app.Use(middleware.Logging(cfg.Logger)) app.Use(middleware.JWTExtract()) // Health endpoints (no API key required) app.Get("/health", cfg.Health.Liveness) app.Get("/ready", cfg.Health.Readiness) // API v1 routes: authenticate (static keys + dynamic key store), then // enforce per-key scopes. Static keys carry the wildcard scope and bypass. api := app.Group("/api/v1", middleware.APIKeyWithValidator(cfg.APIKeys, cfg.APIKeyValidate), middleware.ScopeEnforce(), ) // Dynamic API-key management (bootstrapped by any existing valid key) if cfg.APIKeysAdmin != nil { apiKeys := api.Group("/admin/api-keys") apiKeys.Get("/", cfg.APIKeysAdmin.List) apiKeys.Post("/", cfg.APIKeysAdmin.Create) apiKeys.Delete("/:id", cfg.APIKeysAdmin.Revoke) } // LDAP Users ldapUsers := api.Group("/ldap/users") ldapUsers.Get("/", cfg.LDAPUsers.List) ldapUsers.Get("/:uid", cfg.LDAPUsers.Get) ldapUsers.Post("/", cfg.LDAPUsers.Create) ldapUsers.Put("/:uid", cfg.LDAPUsers.Update) ldapUsers.Delete("/:uid", cfg.LDAPUsers.Delete) ldapUsers.Post("/:uid/password", cfg.LDAPUsers.ResetPassword) ldapUsers.Get("/:uid/groups", cfg.LDAPUsers.ListGroups) ldapUsers.Get("/:uid/services", cfg.LDAPUsers.ListServices) ldapUsers.Get("/:uid/services/:domain", cfg.LDAPUsers.GetService) // LDAP Groups ldapGroups := api.Group("/ldap/groups") ldapGroups.Get("/", cfg.LDAPGroups.List) ldapGroups.Get("/:cn", cfg.LDAPGroups.Get) ldapGroups.Post("/", cfg.LDAPGroups.Create) ldapGroups.Put("/:cn", cfg.LDAPGroups.Update) ldapGroups.Delete("/:cn", cfg.LDAPGroups.Delete) ldapGroups.Get("/:cn/members", cfg.LDAPGroups.ListMembers) ldapGroups.Post("/:cn/members", cfg.LDAPGroups.AddMembers) ldapGroups.Delete("/:cn/members/:uid", cfg.LDAPGroups.RemoveMember) // LDAP Entities (generic CRUD) ldapEntities := api.Group("/ldap/entities") ldapEntities.Get("/", cfg.LDAPEntities.ListTypes) ldapEntities.Get("/:type", cfg.LDAPEntities.List) ldapEntities.Post("/:type", cfg.LDAPEntities.Create) ldapEntities.Get("/:type/:rdn", cfg.LDAPEntities.Get) ldapEntities.Put("/:type/:rdn", cfg.LDAPEntities.Update) ldapEntities.Delete("/:type/:rdn", cfg.LDAPEntities.Delete) // DNS Zones dnsZones := api.Group("/dns/zones") dnsZones.Get("/", cfg.DNSZones.List) dnsZones.Get("/:zoneId", cfg.DNSZones.Get) dnsZones.Post("/", cfg.DNSZones.Create) dnsZones.Put("/:zoneId", cfg.DNSZones.Update) dnsZones.Delete("/:zoneId", cfg.DNSZones.Delete) dnsZones.Post("/:zoneId/notify", cfg.DNSZones.Notify) // DNS Records dnsZones.Get("/:zoneId/records", cfg.DNSRecords.List) dnsZones.Post("/:zoneId/records", cfg.DNSRecords.Create) dnsZones.Put("/:zoneId/records", cfg.DNSRecords.Replace) dnsZones.Delete("/:zoneId/records", cfg.DNSRecords.Delete) // DNS Domains (orchestrated) dnsDomains := api.Group("/dns/domains") dnsDomains.Post("/setup", cfg.DNSRecords.DomainSetup) dnsDomains.Post("/verify", cfg.DNSRecords.DomainVerify) // DB Tenants dbTenants := api.Group("/db/tenants") dbTenants.Get("/", cfg.DBTenants.List) dbTenants.Get("/:id", cfg.DBTenants.Get) dbTenants.Post("/", cfg.DBTenants.Create) dbTenants.Put("/:id", cfg.DBTenants.Update) dbTenants.Delete("/:id", cfg.DBTenants.Delete) // DB Users dbUsers := api.Group("/db/users") dbUsers.Get("/", cfg.DBUsers.List) dbUsers.Get("/:id", cfg.DBUsers.Get) dbUsers.Post("/", cfg.DBUsers.Create) dbUsers.Put("/:id", cfg.DBUsers.Update) dbUsers.Delete("/:id", cfg.DBUsers.Delete) // Certificates certs := api.Group("/certs") certs.Get("/", cfg.Certs.List) certs.Get("/:serialNumber", cfg.Certs.Get) certs.Post("/request", cfg.Certs.Request) certs.Post("/:serialNumber/renew", cfg.Certs.Renew) certs.Post("/:serialNumber/revoke", cfg.Certs.Revoke) // PGP Keys pgp := api.Group("/pgp/keys") pgp.Get("/", cfg.PGP.Search) pgp.Get("/:keyId", cfg.PGP.Get) pgp.Post("/", cfg.PGP.Upload) pgp.Delete("/:keyId", cfg.PGP.Delete) // PBX if cfg.PBX != nil { pbxTrunks := api.Group("/pbx/trunks") pbxTrunks.Get("/", cfg.PBX.ListTrunks) pbxTrunks.Post("/", cfg.PBX.CreateTrunk) pbxTrunks.Get("/:id", cfg.PBX.GetTrunk) pbxTrunks.Put("/:id", cfg.PBX.UpdateTrunk) pbxTrunks.Delete("/:id", cfg.PBX.DeleteTrunk) pbxTrunks.Post("/:id/activate", cfg.PBX.ActivateTrunk) pbxTrunks.Post("/:id/deactivate", cfg.PBX.DeactivateTrunk) pbxTrunks.Get("/:id/dids", cfg.PBX.ListTrunkDIDs) pbxTrunks.Post("/:id/dids", cfg.PBX.CreateTrunkDID) pbxTrunks.Delete("/:id/dids/:didId", cfg.PBX.DeleteTrunkDID) pbxExts := api.Group("/pbx/extensions") pbxExts.Get("/", cfg.PBX.ListExtensions) pbxExts.Post("/", cfg.PBX.CreateExtension) pbxExts.Get("/:id", cfg.PBX.GetExtension) pbxExts.Put("/:id", cfg.PBX.UpdateExtension) pbxExts.Delete("/:id", cfg.PBX.DeleteExtension) pbxInbound := api.Group("/pbx/inbound-routes") pbxInbound.Get("/", cfg.PBX.ListInboundRoutes) pbxInbound.Post("/", cfg.PBX.CreateInboundRoute) pbxInbound.Get("/:id", cfg.PBX.GetInboundRoute) pbxInbound.Put("/:id", cfg.PBX.UpdateInboundRoute) pbxInbound.Delete("/:id", cfg.PBX.DeleteInboundRoute) pbxOutbound := api.Group("/pbx/outbound-routes") pbxOutbound.Get("/", cfg.PBX.ListOutboundRoutes) pbxOutbound.Post("/", cfg.PBX.CreateOutboundRoute) pbxOutbound.Get("/:id", cfg.PBX.GetOutboundRoute) pbxOutbound.Put("/:id", cfg.PBX.UpdateOutboundRoute) pbxOutbound.Delete("/:id", cfg.PBX.DeleteOutboundRoute) api.Get("/pbx/status", cfg.PBX.Status) api.Post("/pbx/reload", cfg.PBX.Reload) } // Voice Agents if cfg.VoiceAgent != nil { voiceAgents := api.Group("/voice-agents") voiceAgents.Get("/", cfg.VoiceAgent.ListConfigs) voiceAgents.Post("/", cfg.VoiceAgent.CreateConfig) voiceAgents.Get("/sessions/:sessionId", cfg.VoiceAgent.GetSession) voiceAgents.Get("/:id", cfg.VoiceAgent.GetConfig) voiceAgents.Put("/:id", cfg.VoiceAgent.UpdateConfig) voiceAgents.Delete("/:id", cfg.VoiceAgent.DeleteConfig) voiceAgents.Get("/:id/sessions", cfg.VoiceAgent.ListSessions) } // Personal Agents (user agent configs) if cfg.PersonalAgent != nil { agents := api.Group("/agents") agents.Get("/me", cfg.PersonalAgent.GetMyConfig) agents.Put("/me", cfg.PersonalAgent.UpsertMyConfig) agents.Delete("/me", cfg.PersonalAgent.DeleteMyConfig) } // Personas if cfg.Persona != nil { personas := api.Group("/personas") personas.Get("/", cfg.Persona.ListPersonas) personas.Post("/", cfg.Persona.CreatePersona) personas.Get("/:id", cfg.Persona.GetPersona) personas.Put("/:id", cfg.Persona.UpdatePersona) personas.Delete("/:id", cfg.Persona.DeletePersona) personas.Get("/:id/self-model", cfg.Persona.GetSelfModel) personas.Get("/:id/experiences", cfg.Persona.GetExperiences) personas.Get("/:id/evaluations/:sessionId", cfg.Persona.GetEvaluations) personas.Get("/:id/moral-pattern/:sessionId", cfg.Persona.GetMoralPattern) } // CardDAV if cfg.CardDAV != nil { cardDAVPrincipals := api.Group("/carddav/principals") cardDAVPrincipals.Get("/", cfg.CardDAV.ListPrincipals) cardDAVPrincipals.Get("/:username", cfg.CardDAV.GetPrincipal) cardDAVPrincipals.Post("/", cfg.CardDAV.CreatePrincipal) cardDAVPrincipals.Delete("/:username", cfg.CardDAV.DeletePrincipal) cardDAVBooks := api.Group("/carddav/addressbooks") cardDAVBooks.Get("/", cfg.CardDAV.ListAddressBooks) cardDAVBooks.Get("/:id", cfg.CardDAV.GetAddressBook) cardDAVBooks.Post("/", cfg.CardDAV.CreateAddressBook) cardDAVBooks.Put("/:id", cfg.CardDAV.UpdateAddressBook) cardDAVBooks.Delete("/:id", cfg.CardDAV.DeleteAddressBook) cardDAVBooks.Get("/:id/contacts", cfg.CardDAV.ListContacts) cardDAVBooks.Get("/:id/contacts/:uri", cfg.CardDAV.GetContact) cardDAVBooks.Post("/:id/contacts", cfg.CardDAV.CreateContact) cardDAVBooks.Put("/:id/contacts/:uri", cfg.CardDAV.UpdateContact) cardDAVBooks.Delete("/:id/contacts/:uri", cfg.CardDAV.DeleteContact) } }