feat: sync deployed v1.0.0-rc.38-custom.42
Sync production source including routing, billing, Astra detection and public uptime. Update custom build instructions and license packaging.
This commit is contained in:
1 parent
aa6c3f50f4
commit
ceddfd3d6b
828 files changed
+122253
-13702
No files matched your search
+45
-19
@@ -361,20 +361,7 @@ func TokenAuthReadOnly() func(c *gin.Context) {
|
||||
func TokenAuth() func(c *gin.Context) {
|
||||
return func(c *gin.Context) {
|
||||
// 先检测是否为ws
|
||||
if c.Request.Header.Get("Sec-WebSocket-Protocol") != "" {
|
||||
// Sec-WebSocket-Protocol: realtime, openai-insecure-api-key.sk-xxx, openai-beta.realtime-v1
|
||||
// read sk from Sec-WebSocket-Protocol
|
||||
key := c.Request.Header.Get("Sec-WebSocket-Protocol")
|
||||
parts := strings.SplitSeq(key, ",")
|
||||
for part := range parts {
|
||||
part = strings.TrimSpace(part)
|
||||
if strings.HasPrefix(part, "openai-insecure-api-key") {
|
||||
key = strings.TrimPrefix(part, "openai-insecure-api-key.")
|
||||
break
|
||||
}
|
||||
}
|
||||
c.Request.Header.Set("Authorization", "Bearer "+key)
|
||||
}
|
||||
applyWebSocketSubprotocolAuthorization(c.Request.Header)
|
||||
// 检查path包含/v1/messages 或 /v1/models
|
||||
if strings.Contains(c.Request.URL.Path, "/v1/messages") || strings.Contains(c.Request.URL.Path, "/v1/models") {
|
||||
anthropicKey := c.Request.Header.Get("x-api-key")
|
||||
@@ -467,7 +454,7 @@ func TokenAuth() func(c *gin.Context) {
|
||||
|
||||
userGroup := userCache.Group
|
||||
tokenGroup := token.Group
|
||||
if tokenGroup != "" {
|
||||
if tokenGroup != "" && token.RoutingPolicy == "" {
|
||||
// check common.UserUsableGroups[userGroup]
|
||||
if _, ok := service.GetUserUsableGroups(userGroup)[tokenGroup]; !ok {
|
||||
abortWithOpenAiMessage(c, http.StatusForbidden, fmt.Sprintf("无权访问 %s 分组", tokenGroup))
|
||||
@@ -486,12 +473,39 @@ func TokenAuth() func(c *gin.Context) {
|
||||
|
||||
err = SetupContextForToken(c, token, parts...)
|
||||
if err != nil {
|
||||
if !c.IsAborted() {
|
||||
abortWithOpenAiMessage(c, http.StatusForbidden, "Invalid token routing policy")
|
||||
}
|
||||
return
|
||||
}
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func applyWebSocketSubprotocolAuthorization(header http.Header) bool {
|
||||
key, ok := apiKeyFromWebSocketSubprotocol(strings.Join(header.Values("Sec-WebSocket-Protocol"), ","))
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
header.Set("Authorization", "Bearer "+key)
|
||||
return true
|
||||
}
|
||||
|
||||
func apiKeyFromWebSocketSubprotocol(protocols string) (string, bool) {
|
||||
if protocols == "" {
|
||||
return "", false
|
||||
}
|
||||
const insecureAPIKeyPrefix = "openai-insecure-api-key."
|
||||
for part := range strings.SplitSeq(protocols, ",") {
|
||||
part = strings.TrimSpace(part)
|
||||
if strings.HasPrefix(part, insecureAPIKeyPrefix) {
|
||||
key := strings.TrimPrefix(part, insecureAPIKeyPrefix)
|
||||
return key, key != ""
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func SetupContextForToken(c *gin.Context, token *model.Token, parts ...string) error {
|
||||
if token == nil {
|
||||
return fmt.Errorf("token is nil")
|
||||
@@ -511,15 +525,27 @@ func SetupContextForToken(c *gin.Context, token *model.Token, parts ...string) e
|
||||
c.Set("token_model_limit_enabled", false)
|
||||
}
|
||||
common.SetContextKey(c, constant.ContextKeyTokenGroup, token.Group)
|
||||
common.SetContextKey(c, constant.ContextKeyTokenAstraAutoSwitch, token.AstraAutoSwitch && token.AstraDetectionEnabled)
|
||||
common.SetContextKey(c, constant.ContextKeyTokenAstraDetectionDisabled, !token.AstraDetectionEnabled)
|
||||
common.SetContextKey(c, constant.ContextKeyTokenCrossGroupRetry, token.CrossGroupRetry)
|
||||
if policy, err := token.GetRoutingPolicy(); err != nil {
|
||||
return err
|
||||
} else if policy != nil {
|
||||
c.Set(model.TokenRoutingContextKey, policy)
|
||||
common.SetContextKey(c, constant.ContextKeyTokenCrossGroupRetry, true)
|
||||
}
|
||||
if token.AutoGroups != "" {
|
||||
autoGroups, err := token.GetAutoGroups()
|
||||
groupPool, err := token.GetGroupPool()
|
||||
if err != nil {
|
||||
common.SysError(fmt.Sprintf("failed to parse auto groups for token %d: %v", token.Id, err))
|
||||
autoGroups = []string{}
|
||||
common.SetContextKey(c, constant.ContextKeyTokenAutoGroups, autoGroups)
|
||||
} else if len(autoGroups) > 0 {
|
||||
common.SetContextKey(c, constant.ContextKeyTokenAutoGroups, []string{})
|
||||
} else if len(groupPool) > 0 {
|
||||
autoGroups := make([]string, 0, len(groupPool))
|
||||
for _, entry := range groupPool {
|
||||
autoGroups = append(autoGroups, entry.Group)
|
||||
}
|
||||
common.SetContextKey(c, constant.ContextKeyTokenAutoGroups, autoGroups)
|
||||
common.SetContextKey(c, constant.ContextKeyTokenGroupPool, groupPool)
|
||||
}
|
||||
}
|
||||
if len(parts) > 1 {
|
||||
|
||||
Reference in new issue
Block a user