| package middleware |
|
|
| import ( |
| "context" |
| "net/http" |
|
|
| "github.com/Wei-Shaw/sub2api/internal/pkg/ctxkey" |
| "github.com/Wei-Shaw/sub2api/internal/pkg/googleapi" |
| "github.com/Wei-Shaw/sub2api/internal/service" |
| "github.com/gin-gonic/gin" |
| ) |
|
|
| |
| type ContextKey string |
|
|
| const ( |
| |
| ContextKeyUser ContextKey = "user" |
| |
| ContextKeyUserRole ContextKey = "user_role" |
| |
| ContextKeyAPIKey ContextKey = "api_key" |
| |
| ContextKeySubscription ContextKey = "subscription" |
| |
| ContextKeyForcePlatform ContextKey = "force_platform" |
| ) |
|
|
| |
| |
| func ForcePlatform(platform string) gin.HandlerFunc { |
| return func(c *gin.Context) { |
| |
| ctx := context.WithValue(c.Request.Context(), ctxkey.ForcePlatform, platform) |
| c.Request = c.Request.WithContext(ctx) |
| |
| c.Set(string(ContextKeyForcePlatform), platform) |
| c.Next() |
| } |
| } |
|
|
| |
| func HasForcePlatform(c *gin.Context) bool { |
| _, exists := c.Get(string(ContextKeyForcePlatform)) |
| return exists |
| } |
|
|
| |
| func GetForcePlatformFromContext(c *gin.Context) (string, bool) { |
| value, exists := c.Get(string(ContextKeyForcePlatform)) |
| if !exists { |
| return "", false |
| } |
| platform, ok := value.(string) |
| return platform, ok |
| } |
|
|
| |
| type ErrorResponse struct { |
| Code string `json:"code"` |
| Message string `json:"message"` |
| } |
|
|
| |
| func NewErrorResponse(code, message string) ErrorResponse { |
| return ErrorResponse{ |
| Code: code, |
| Message: message, |
| } |
| } |
|
|
| |
| func AbortWithError(c *gin.Context, statusCode int, code, message string) { |
| c.JSON(statusCode, NewErrorResponse(code, message)) |
| c.Abort() |
| } |
|
|
| |
| |
| |
|
|
| |
| type GatewayErrorWriter func(c *gin.Context, status int, message string) |
|
|
| |
| func AnthropicErrorWriter(c *gin.Context, status int, message string) { |
| c.JSON(status, gin.H{ |
| "type": "error", |
| "error": gin.H{"type": "permission_error", "message": message}, |
| }) |
| } |
|
|
| |
| func GoogleErrorWriter(c *gin.Context, status int, message string) { |
| c.JSON(status, gin.H{ |
| "error": gin.H{ |
| "code": status, |
| "message": message, |
| "status": googleapi.HTTPStatusToGoogleStatus(status), |
| }, |
| }) |
| } |
|
|
| |
| |
| func RequireGroupAssignment(settingService *service.SettingService, writeError GatewayErrorWriter) gin.HandlerFunc { |
| return func(c *gin.Context) { |
| apiKey, ok := GetAPIKeyFromContext(c) |
| if !ok || apiKey.GroupID != nil { |
| c.Next() |
| return |
| } |
| |
| if settingService.IsUngroupedKeySchedulingAllowed(c.Request.Context()) { |
| c.Next() |
| return |
| } |
| writeError(c, http.StatusForbidden, "API Key is not assigned to any group and cannot be used. Please contact the administrator to assign it to a group.") |
| c.Abort() |
| } |
| } |
|
|