73a82e6175
Upgrades the routing engine to support tag, token limit, multimodal, reasoning, and tool calling conditions. Adds unit tests for the new routing features.
87 lines
2.2 KiB
Go
87 lines
2.2 KiB
Go
package middleware
|
|
|
|
import (
|
|
"log"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"gophergate/internal/db"
|
|
"gophergate/internal/models"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func AuthMiddleware(database *db.DB, requireAuth bool) gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
authHeader := c.GetHeader("Authorization")
|
|
if authHeader == "" {
|
|
// Fallback to checking "Authentication" header in case the client library used the wrong name
|
|
authHeader = c.GetHeader("Authentication")
|
|
}
|
|
|
|
if authHeader == "" {
|
|
if requireAuth {
|
|
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
|
|
"error": gin.H{
|
|
"message": "Missing Authorization or Authentication header.",
|
|
"type": "invalid_request_error",
|
|
"param": nil,
|
|
"code": "401",
|
|
},
|
|
})
|
|
return
|
|
}
|
|
c.Next()
|
|
return
|
|
}
|
|
|
|
token := strings.TrimPrefix(authHeader, "Bearer ")
|
|
if token == authHeader { // No "Bearer " prefix
|
|
if requireAuth {
|
|
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
|
|
"error": gin.H{
|
|
"message": "Invalid authorization header format. Bearer token required.",
|
|
"type": "invalid_request_error",
|
|
"param": nil,
|
|
"code": "401",
|
|
},
|
|
})
|
|
return
|
|
}
|
|
c.Next()
|
|
return
|
|
}
|
|
|
|
// Try to resolve client from database with a read-only SELECT
|
|
var clientID string
|
|
err := database.Get(&clientID, "SELECT client_id FROM client_tokens WHERE token = ? AND is_active = 1", token)
|
|
|
|
if err == nil {
|
|
c.Set("auth", models.AuthInfo{
|
|
Token: token,
|
|
ClientID: clientID,
|
|
})
|
|
|
|
// Update last_used_at asynchronously so that database locks or write delays
|
|
// do not block or fail the client's request authentication.
|
|
go func(t string) {
|
|
if _, updateErr := database.Exec("UPDATE client_tokens SET last_used_at = CURRENT_TIMESTAMP WHERE token = ?", t); updateErr != nil {
|
|
log.Printf("Warning: failed to update client token last_used_at: %v", updateErr)
|
|
}
|
|
}(token)
|
|
|
|
c.Next()
|
|
} else {
|
|
log.Printf("Token not found, inactive or error in DB: %s (err: %v)", token, err)
|
|
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
|
|
"error": gin.H{
|
|
"message": "Invalid or inactive client token.",
|
|
"type": "invalid_request_error",
|
|
"param": nil,
|
|
"code": "401",
|
|
},
|
|
})
|
|
}
|
|
}
|
|
}
|