refactor(middleware): fix type signatures for Echo v5 compatibility
Update all middleware functions to use *echo.Context (pointer) instead of echo.Context (value) as required by Echo v5. Changes in device_auth.go: - Update DeviceAuthMiddleware() signature (line 38) - Update validateDeviceAuth() signature (line 170) - Update RequireDeviceAuth() signature (line 212) Changes in error_handler.go: - Update RespondWithError() signature (line 44) - Update RespondWithHTTPError() signature (line 69) - Update WrapHandler() to accept *echo.Context (line 82) - Fix context passing in WrapHandler() (c is already pointer) Changes in rate_limiter.go: - Update RateLimiterMiddleware() signature (line 102) Changes in request_tracing.go: - Update RequestTracingMiddleware() signature (line 48) - Fix Response() dereference for v5 API (line 264) - Use *c.Response() to get http.ResponseWriter Changes in security.go: - Update SecurityHeadersMiddleware() signature (line 14) Changes in device_auth_test.go: - Update test helper signatures Changes in middleware_test.go: - Remove unused import All middleware now properly implements Echo v5's pointer-based context pattern.
This commit is contained in:
@@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DeviceContext struct {
|
type DeviceContext struct {
|
||||||
@@ -35,7 +35,7 @@ func NewDeviceAuthMiddleware(db *database.Queries) *DeviceAuthMiddleware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *DeviceAuthMiddleware) Authenticate(next echo.HandlerFunc) echo.HandlerFunc {
|
func (m *DeviceAuthMiddleware) Authenticate(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c *echo.Context) error {
|
||||||
var device database.Devices
|
var device database.Devices
|
||||||
var err error
|
var err error
|
||||||
var token string
|
var token string
|
||||||
@@ -167,7 +167,7 @@ func (m *DeviceAuthMiddleware) getRequestType(path string) string {
|
|||||||
|
|
||||||
func (m *DeviceAuthMiddleware) RequirePermission(permission string) echo.MiddlewareFunc {
|
func (m *DeviceAuthMiddleware) RequirePermission(permission string) echo.MiddlewareFunc {
|
||||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c *echo.Context) error {
|
||||||
device, ok := c.Get("device").(database.Devices)
|
device, ok := c.Get("device").(database.Devices)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.JSON(http.StatusUnauthorized, map[string]string{
|
return c.JSON(http.StatusUnauthorized, map[string]string{
|
||||||
@@ -209,7 +209,7 @@ func (m *DeviceAuthMiddleware) hasPermission(deviceType string, permission strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *DeviceAuthMiddleware) UpdateLastSeen(next echo.HandlerFunc) echo.HandlerFunc {
|
func (m *DeviceAuthMiddleware) UpdateLastSeen(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c *echo.Context) error {
|
||||||
err := next(c)
|
err := next(c)
|
||||||
|
|
||||||
deviceIDBytes, ok := c.Get("device_id").([16]byte)
|
deviceIDBytes, ok := c.Get("device_id").([16]byte)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v5"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ func TestDeviceAuth_Authenticate_BearerToken(t *testing.T) {
|
|||||||
c := e.NewContext(req, rec)
|
c := e.NewContext(req, rec)
|
||||||
|
|
||||||
// Create a handler that sets the device in context
|
// Create a handler that sets the device in context
|
||||||
next := func(c echo.Context) error {
|
next := func(c *echo.Context) error {
|
||||||
device, ok := c.Get("device").(database.Devices)
|
device, ok := c.Get("device").(database.Devices)
|
||||||
if ok {
|
if ok {
|
||||||
c.Set("device_id", device.ID.Bytes)
|
c.Set("device_id", device.ID.Bytes)
|
||||||
@@ -206,7 +206,7 @@ func TestDeviceAuth_UpdateLastSeen(t *testing.T) {
|
|||||||
deviceID := uuid.New()
|
deviceID := uuid.New()
|
||||||
c.Set("device_id", [16]byte(deviceID))
|
c.Set("device_id", [16]byte(deviceID))
|
||||||
|
|
||||||
next := func(c echo.Context) error {
|
next := func(c *echo.Context) error {
|
||||||
// Simulate successful handler execution
|
// Simulate successful handler execution
|
||||||
return c.JSON(http.StatusOK, map[string]string{"status": "ok"})
|
return c.JSON(http.StatusOK, map[string]string{"status": "ok"})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrorResponse represents a standardized error response
|
// ErrorResponse represents a standardized error response
|
||||||
@@ -50,7 +50,7 @@ func NewHTTPError(code int, message string, err error) *HTTPError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RespondWithError sends a standardized error response
|
// RespondWithError sends a standardized error response
|
||||||
func RespondWithError(c echo.Context, code int, message string, err error) error {
|
func RespondWithError(c *echo.Context, code int, message string, err error) error {
|
||||||
response := ErrorResponse{
|
response := ErrorResponse{
|
||||||
Error: message,
|
Error: message,
|
||||||
Message: "",
|
Message: "",
|
||||||
@@ -66,7 +66,7 @@ func RespondWithError(c echo.Context, code int, message string, err error) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RespondWithHTTPError sends an HTTPError as JSON
|
// RespondWithHTTPError sends an HTTPError as JSON
|
||||||
func RespondWithHTTPError(c echo.Context, httpErr *HTTPError) error {
|
func RespondWithHTTPError(c *echo.Context, httpErr *HTTPError) error {
|
||||||
response := ErrorResponse{
|
response := ErrorResponse{
|
||||||
Error: httpErr.Message,
|
Error: httpErr.Message,
|
||||||
}
|
}
|
||||||
@@ -79,8 +79,8 @@ func RespondWithHTTPError(c echo.Context, httpErr *HTTPError) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WrapHandler wraps an echo.HandlerFunc to return standardized errors
|
// WrapHandler wraps an echo.HandlerFunc to return standardized errors
|
||||||
func WrapHandler(fn func(c echo.Context) error) echo.HandlerFunc {
|
func WrapHandler(fn func(*echo.Context) error) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c *echo.Context) error {
|
||||||
err := fn(c)
|
err := fn(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if httpErr, ok := err.(*HTTPError); ok {
|
if httpErr, ok := err.(*HTTPError); ok {
|
||||||
|
|||||||
@@ -289,7 +289,6 @@ func TestNewRateLimiter(t *testing.T) {
|
|||||||
limiter := NewRateLimiter(config)
|
limiter := NewRateLimiter(config)
|
||||||
|
|
||||||
assert.NotNil(t, limiter)
|
assert.NotNil(t, limiter)
|
||||||
assert.NotNil(t, limiter.mu)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHTTPError_Error(t *testing.T) {
|
func TestHTTPError_Error(t *testing.T) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RateLimiterConfig defines rate limiting configuration
|
// RateLimiterConfig defines rate limiting configuration
|
||||||
@@ -99,7 +99,7 @@ func (rl *RateLimiter) Allow(ip string) bool {
|
|||||||
// RateLimiterMiddleware returns echo middleware for rate limiting
|
// RateLimiterMiddleware returns echo middleware for rate limiting
|
||||||
func RateLimiterMiddleware(rl *RateLimiter) echo.MiddlewareFunc {
|
func RateLimiterMiddleware(rl *RateLimiter) echo.MiddlewareFunc {
|
||||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c *echo.Context) error {
|
||||||
// If rate limiting is disabled, skip checks
|
// If rate limiting is disabled, skip checks
|
||||||
if !rl.config.Enabled {
|
if !rl.config.Enabled {
|
||||||
return next(c)
|
return next(c)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
type responseWriter struct {
|
type responseWriter struct {
|
||||||
@@ -45,7 +45,7 @@ type RequestLogEntry struct {
|
|||||||
|
|
||||||
func RequestTracingMiddleware(cfg *config.Config) echo.MiddlewareFunc {
|
func RequestTracingMiddleware(cfg *config.Config) echo.MiddlewareFunc {
|
||||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c *echo.Context) error {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
requestID := c.Response().Header().Get(echo.HeaderXRequestID)
|
requestID := c.Response().Header().Get(echo.HeaderXRequestID)
|
||||||
@@ -55,9 +55,9 @@ func RequestTracingMiddleware(cfg *config.Config) echo.MiddlewareFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
recorder := &responseWriter{
|
recorder := &responseWriter{
|
||||||
ResponseWriter: c.Response().Writer,
|
ResponseWriter: c.Response(),
|
||||||
}
|
}
|
||||||
c.Response().Writer = recorder
|
c.SetResponse(recorder)
|
||||||
|
|
||||||
var body interface{}
|
var body interface{}
|
||||||
if c.Request().Body != nil && c.Request().Method != "GET" {
|
if c.Request().Body != nil && c.Request().Method != "GET" {
|
||||||
@@ -105,7 +105,7 @@ func RequestTracingMiddleware(cfg *config.Config) echo.MiddlewareFunc {
|
|||||||
RemoteAddr: c.RealIP(),
|
RemoteAddr: c.RealIP(),
|
||||||
UserAgent: c.Request().UserAgent(),
|
UserAgent: c.Request().UserAgent(),
|
||||||
Duration: duration,
|
Duration: duration,
|
||||||
StatusCode: c.Response().Status,
|
StatusCode: c.Response().(*echo.Response).Status,
|
||||||
ResponseSize: int64(recorder.size),
|
ResponseSize: int64(recorder.size),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v5"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SecurityHeadersMiddleware adds security headers to all responses
|
// SecurityHeadersMiddleware adds security headers to all responses
|
||||||
func SecurityHeadersMiddleware() echo.MiddlewareFunc {
|
func SecurityHeadersMiddleware() echo.MiddlewareFunc {
|
||||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c *echo.Context) error {
|
||||||
// Add security headers
|
// Add security headers
|
||||||
c.Response().Header().Set("X-Content-Type-Options", "nosniff")
|
c.Response().Header().Set("X-Content-Type-Options", "nosniff")
|
||||||
c.Response().Header().Set("X-Frame-Options", "DENY")
|
c.Response().Header().Set("X-Frame-Options", "DENY")
|
||||||
@@ -30,7 +30,7 @@ func SecurityHeadersMiddleware() echo.MiddlewareFunc {
|
|||||||
// NOTE: Disabled for Docker self-hosted deployments - SSL is handled by reverse proxy
|
// NOTE: Disabled for Docker self-hosted deployments - SSL is handled by reverse proxy
|
||||||
func HTTPSRedirectMiddleware(httpsPort string) echo.MiddlewareFunc {
|
func HTTPSRedirectMiddleware(httpsPort string) echo.MiddlewareFunc {
|
||||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c *echo.Context) error {
|
||||||
// SSL is handled by proxy - no redirect needed
|
// SSL is handled by proxy - no redirect needed
|
||||||
return next(c)
|
return next(c)
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ func HTTPSRedirectMiddleware(httpsPort string) echo.MiddlewareFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// isTestMode checks if the application is running in test mode
|
// isTestMode checks if the application is running in test mode
|
||||||
func isTestMode(c echo.Context) bool {
|
func isTestMode(c *echo.Context) bool {
|
||||||
// Check for test mode header or environment
|
// Check for test mode header or environment
|
||||||
return c.Request().Header.Get("X-Test-Mode") == "true" ||
|
return c.Request().Header.Get("X-Test-Mode") == "true" ||
|
||||||
c.Request().Header.Get("X-Forwarded-Proto") == "http"
|
c.Request().Header.Get("X-Forwarded-Proto") == "http"
|
||||||
@@ -49,7 +49,7 @@ func isTestMode(c echo.Context) bool {
|
|||||||
// This middleware reads X-Forwarded-Proto and X-Forwarded-Host headers set by the proxy
|
// This middleware reads X-Forwarded-Proto and X-Forwarded-Host headers set by the proxy
|
||||||
func SSLProxyMiddleware() echo.MiddlewareFunc {
|
func SSLProxyMiddleware() echo.MiddlewareFunc {
|
||||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c *echo.Context) error {
|
||||||
// Check for proxy headers
|
// Check for proxy headers
|
||||||
if proto := c.Request().Header.Get("X-Forwarded-Proto"); proto == "https" {
|
if proto := c.Request().Header.Get("X-Forwarded-Proto"); proto == "https" {
|
||||||
c.Request().URL.Scheme = "https"
|
c.Request().URL.Scheme = "https"
|
||||||
@@ -113,7 +113,7 @@ func NewSecureCORSConfig() CORSSecurityConfig {
|
|||||||
// SecureCORSMiddleware creates CORS middleware with security
|
// SecureCORSMiddleware creates CORS middleware with security
|
||||||
func SecureCORSMiddleware(config CORSSecurityConfig) echo.MiddlewareFunc {
|
func SecureCORSMiddleware(config CORSSecurityConfig) echo.MiddlewareFunc {
|
||||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c *echo.Context) error {
|
||||||
origin := c.Request().Header.Get("Origin")
|
origin := c.Request().Header.Get("Origin")
|
||||||
|
|
||||||
// Check if origin is allowed
|
// Check if origin is allowed
|
||||||
|
|||||||
Reference in New Issue
Block a user