chore: clean .gitignore cache

This commit is contained in:
GitHub Actions
2026-01-26 19:21:33 +00:00
parent 1b1b3a70b1
commit e5f0fec5db
1483 changed files with 0 additions and 472793 deletions

View File

@@ -1,163 +0,0 @@
package server
import (
"context"
"fmt"
"net"
"net/http"
"time"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"github.com/Wikid82/charon/backend/internal/api/handlers"
"github.com/Wikid82/charon/backend/internal/config"
"github.com/Wikid82/charon/backend/internal/logger"
)
// EmergencyServer provides a minimal HTTP server for emergency operations.
// This server runs on a separate port with minimal security for failsafe access.
//
// Security Philosophy:
// - Separate port bypasses Caddy/CrowdSec/WAF entirely
// - Optional Basic Auth (configurable via env)
// - Should ONLY be accessible via VPN/SSH tunnel
// - Default bind to localhost (127.0.0.1) for safety
//
// Use Cases:
// - Layer 7 reverse proxy blocking requests (CrowdSec bouncer at Caddy)
// - Caddy itself is down or misconfigured
// - Emergency access when main application port is unreachable
type EmergencyServer struct {
server *http.Server
listener net.Listener
db *gorm.DB
cfg config.EmergencyConfig
}
// NewEmergencyServer creates a new emergency server instance
func NewEmergencyServer(db *gorm.DB, cfg config.EmergencyConfig) *EmergencyServer {
return &EmergencyServer{
db: db,
cfg: cfg,
}
}
// Start initializes and starts the emergency server
func (s *EmergencyServer) Start() error {
if !s.cfg.Enabled {
logger.Log().Info("Emergency server disabled (CHARON_EMERGENCY_SERVER_ENABLED=false)")
return nil
}
// Security warning if no authentication configured
if s.cfg.BasicAuthUsername == "" || s.cfg.BasicAuthPassword == "" {
logger.Log().Warn("⚠️ SECURITY WARNING: Emergency server has NO authentication configured")
logger.Log().Warn("⚠️ Ensure port is accessible ONLY via VPN/SSH tunnel")
logger.Log().Warn("⚠️ Set CHARON_EMERGENCY_USERNAME and CHARON_EMERGENCY_PASSWORD")
}
// Configure Gin for minimal logging (not production mode to preserve logs)
router := gin.New()
// Middleware 1: Recovery (panic handler)
router.Use(gin.Recovery())
// Middleware 2: Simple request logging (minimal)
router.Use(func(c *gin.Context) {
start := time.Now()
path := c.Request.URL.Path
method := c.Request.Method
c.Next()
latency := time.Since(start).Milliseconds()
status := c.Writer.Status()
logger.Log().WithFields(map[string]interface{}{
"server": "emergency",
"method": method,
"path": path,
"status": status,
"latency": fmt.Sprintf("%dms", latency),
"ip": c.ClientIP(),
}).Info("Emergency server request")
})
// Middleware 3: Basic Auth (if configured)
if s.cfg.BasicAuthUsername != "" && s.cfg.BasicAuthPassword != "" {
accounts := gin.Accounts{
s.cfg.BasicAuthUsername: s.cfg.BasicAuthPassword,
}
router.Use(gin.BasicAuth(accounts))
logger.Log().WithField("username", s.cfg.BasicAuthUsername).Info("Emergency server Basic Auth enabled")
}
// Emergency endpoints only
emergencyHandler := handlers.NewEmergencyHandler(s.db)
// POST /emergency/security-reset - Disable all security modules
router.POST("/emergency/security-reset", emergencyHandler.SecurityReset)
// GET /health - Health check endpoint
router.GET("/health", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "ok",
"server": "emergency",
"time": time.Now().UTC().Format(time.RFC3339),
})
})
// Create HTTP server with sensible timeouts
s.server = &http.Server{
Handler: router,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
IdleTimeout: 30 * time.Second,
}
// Create listener (this allows us to get the actual port when using :0 for testing)
listener, err := net.Listen("tcp", s.cfg.BindAddress)
if err != nil {
return fmt.Errorf("failed to create listener: %w", err)
}
s.listener = listener
// Start server in goroutine
go func() {
logger.Log().WithFields(map[string]interface{}{
"address": listener.Addr().String(),
"auth": s.cfg.BasicAuthUsername != "",
"endpoint": "/emergency/security-reset",
}).Info("Starting emergency server (Tier 2 break glass)")
if err := s.server.Serve(listener); err != nil && err != http.ErrServerClosed {
logger.Log().WithError(err).Error("Emergency server failed")
}
}()
return nil
}
// Stop gracefully shuts down the emergency server
func (s *EmergencyServer) Stop(ctx context.Context) error {
if s.server == nil {
return nil
}
logger.Log().Info("Stopping emergency server")
if err := s.server.Shutdown(ctx); err != nil {
return fmt.Errorf("emergency server shutdown: %w", err)
}
logger.Log().Info("Emergency server stopped")
return nil
}
// GetAddr returns the actual bind address (useful for tests with :0)
func (s *EmergencyServer) GetAddr() string {
if s.listener == nil {
return ""
}
return s.listener.Addr().String()
}