refatoração de segurança e logs
This commit is contained in:
parent
6873b87a85
commit
663a8d5bf2
12 changed files with 362 additions and 37 deletions
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
|
@ -20,8 +21,13 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
// Load .env if present (convenience for local dev). Environment variables
|
||||
// explicitly set in the OS take precedence.
|
||||
// Logger estruturado (stdout). Mantemos log.Printf apenas para logs muito
|
||||
// iniciais/críticos e para compatibilidade; o restante deve usar slog.
|
||||
logger := elinps.LoggerPadrao()
|
||||
slog.SetDefault(logger)
|
||||
|
||||
// Carrega .env se existir (conveniência para dev local).
|
||||
// Variáveis definidas no SO têm precedência.
|
||||
_ = godotenv.Load()
|
||||
|
||||
cfg := mustLoadConfig()
|
||||
|
|
@ -35,7 +41,7 @@ func main() {
|
|||
}
|
||||
defer pool.Close()
|
||||
|
||||
// Ensures required extensions exist.
|
||||
// Garante extensões necessárias.
|
||||
if err := db.EnsurePgcrypto(ctx, pool); err != nil {
|
||||
log.Fatalf("ensure pgcrypto: %v", err)
|
||||
}
|
||||
|
|
@ -44,23 +50,24 @@ func main() {
|
|||
r.Use(middleware.RequestID)
|
||||
r.Use(middleware.RealIP)
|
||||
r.Use(middleware.Recoverer)
|
||||
r.Use(elinps.MiddlewareLogRequisicao(logger))
|
||||
r.Use(middleware.Timeout(15 * time.Second))
|
||||
r.Use(middleware.Compress(5))
|
||||
|
||||
// CORS wildcard + preflight
|
||||
// CORS liberado + preflight.
|
||||
r.Use(elinps.CORSMiddleware())
|
||||
|
||||
// Basic limits
|
||||
// Limites básicos.
|
||||
r.Use(elinps.MaxBodyBytesMiddleware(64 * 1024))
|
||||
|
||||
// Health
|
||||
// Health.
|
||||
r.Get("/healthz", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })
|
||||
|
||||
// Home: renderiza README.md
|
||||
// Público (sem senha), para facilitar documentação do serviço.
|
||||
r.Get("/", elinps.NewReadmePage("README.md").ServeHTTP)
|
||||
|
||||
// Static widget
|
||||
// Widget estático.
|
||||
fileServer := http.FileServer(http.Dir("web/static"))
|
||||
// Versão do widget para controle de cache.
|
||||
//
|
||||
|
|
@ -87,12 +94,12 @@ func main() {
|
|||
})
|
||||
r.Handle("/*", http.StripPrefix("/static/", fileServer))
|
||||
})
|
||||
// Convenience: allow /teste.html
|
||||
// Conveniência: permitir /teste.html
|
||||
r.Get("/teste.html", func(w http.ResponseWriter, r *http.Request) {
|
||||
http.ServeFile(w, r, "web/static/teste.html")
|
||||
})
|
||||
|
||||
// NPS routes
|
||||
// Rotas NPS.
|
||||
h := elinps.NewHandlers(pool)
|
||||
r.Route("/api/e-li.nps", func(r chi.Router) {
|
||||
r.Post("/pedido", h.PostPedido)
|
||||
|
|
@ -103,7 +110,7 @@ func main() {
|
|||
r.Get("/{produto}/{id}/form", h.GetForm)
|
||||
})
|
||||
|
||||
// Painel (dashboard)
|
||||
// Painel.
|
||||
// Protegido por SENHA_PAINEL.
|
||||
// Se SENHA_PAINEL estiver vazia, o painel fica desabilitado.
|
||||
painel := elinps.NewPainelHandlers(pool, cfg.SenhaPainel)
|
||||
|
|
@ -116,7 +123,7 @@ func main() {
|
|||
}
|
||||
|
||||
go func() {
|
||||
log.Printf("listening on %s", cfg.Addr)
|
||||
logger.Info("servidor_iniciado", "addr", cfg.Addr)
|
||||
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
log.Fatalf("listen: %v", err)
|
||||
}
|
||||
|
|
@ -126,9 +133,9 @@ func main() {
|
|||
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
if err := srv.Shutdown(shutdownCtx); err != nil {
|
||||
log.Printf("shutdown: %v", err)
|
||||
logger.Error("erro_no_shutdown", "err", err)
|
||||
}
|
||||
log.Printf("bye")
|
||||
logger.Info("servidor_finalizado")
|
||||
}
|
||||
|
||||
type config struct {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue