From 0de298687c42c7c4be2c8f9277cc728c98b60d80 Mon Sep 17 00:00:00 2001 From: admin Date: Wed, 8 Apr 2026 14:49:27 +0200 Subject: [PATCH] api: add HTTP handlers and router for endpoints --- api/handler.go | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ api/router.go | 28 ++++++++++++++++++++++++ main.go | 46 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 api/handler.go create mode 100644 api/router.go diff --git a/api/handler.go b/api/handler.go new file mode 100644 index 0000000..0d5662b --- /dev/null +++ b/api/handler.go @@ -0,0 +1,58 @@ +package api + +import ( + "encoding/base64" + "fmt" + "io" + "net/http" + + "VerifactuMidAPI/internal/cert" + "VerifactuMidAPI/internal/config" + "VerifactuMidAPI/internal/crypto" +) + +type Handler struct { + cfg *config.Config + cert *cert.Storage + crypto *crypto.KeyPair +} + +func New(cfg *config.Config, certStorage *cert.Storage, keyPair *crypto.KeyPair) *Handler { + return &Handler{ + cfg: cfg, + cert: certStorage, + crypto: keyPair, + } +} + +func (h *Handler) GetPublicKey(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + http.Error(w, "method not allowed", http.StatusMethodNotAllowed) + return + } + + pubPEM, err := h.crypto.PublicKeyPEM() + if err != nil { + http.Error(w, "failed to get public key", http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(fmt.Sprintf(`{"public_key":"%s"}`, base64.StdEncoding.EncodeToString(pubPEM)))) +} + +func (h *Handler) RegisterCert(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "method not allowed", http.StatusMethodNotAllowed) + return + } + + body, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, "failed to read body", http.StatusBadRequest) + return + } + + w.Header().Set("Content-Type", "application/json") + w.Write(body) +} diff --git a/api/router.go b/api/router.go new file mode 100644 index 0000000..848e2db --- /dev/null +++ b/api/router.go @@ -0,0 +1,28 @@ +package api + +import ( + "net/http" +) + +func (h *Handler) RegisterRoutes(mux *http.ServeMux) { + mux.HandleFunc("/api/v1/auth/public-key", h.GetPublicKey) + mux.HandleFunc("/api/v1/auth/register", h.RegisterCert) + mux.HandleFunc("/api/v1/facturas", h.HandleFacturas) + mux.HandleFunc("/api/v1/facturas/anular", h.HandleFacturasAnular) + mux.HandleFunc("/api/v1/health", h.HealthCheck) +} + +func (h *Handler) HealthCheck(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(`{"status":"ok"}`)) +} + +func (h *Handler) HandleFacturas(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(`{"endpoint":"facturas","status":"not implemented"}`)) +} + +func (h *Handler) HandleFacturasAnular(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(`{"endpoint":"facturas/anular","status":"not implemented"}`)) +} diff --git a/main.go b/main.go index 38dd16d..1d95ff0 100644 --- a/main.go +++ b/main.go @@ -1,3 +1,47 @@ package main -func main() {} +import ( + "fmt" + "log" + "net/http" + "os" + + "VerifactuMidAPI/api" + "VerifactuMidAPI/internal/cert" + "VerifactuMidAPI/internal/config" + "VerifactuMidAPI/internal/crypto" +) + +func main() { + cfg, err := config.Load("config.yml") + if err != nil { + log.Fatalf("loading config: %v", err) + } + + certStorage := cert.NewStorage(cfg.Certificates.StoragePath) + if err := certStorage.Init(); err != nil { + log.Fatalf("initializing cert storage: %v", err) + } + + keyPair, err := crypto.LoadOrCreateKeyPair(cfg.Crypto.KeysPath) + if err != nil { + log.Fatalf("loading/creating key pair: %v", err) + } + + handler := api.New(cfg, certStorage, keyPair) + + mux := http.NewServeMux() + handler.RegisterRoutes(mux) + + addr := fmt.Sprintf(":%d", cfg.Server.Port) + log.Printf("Starting server on %s", addr) + if err := http.ListenAndServe(addr, mux); err != nil { + log.Fatalf("server error: %v", err) + } +} + +func init() { + if _, err := os.Stat("config.yml"); os.IsNotExist(err) { + log.Println("Warning: config.yml not found, using defaults") + } +}