Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions controller/custom_oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ func GetUserOAuthBindingsByAdmin(c *gin.Context) {
}

myRole := c.GetInt("role")
if myRole <= targetUser.Role && myRole != common.RoleRootUser {
if !canManageTargetRole(myRole, targetUser.Role) {
common.ApiErrorMsg(c, "no permission")
return
}
Expand Down Expand Up @@ -560,7 +560,7 @@ func UnbindCustomOAuthByAdmin(c *gin.Context) {
}

myRole := c.GetInt("role")
if myRole <= targetUser.Role && myRole != common.RoleRootUser {
if !canManageTargetRole(myRole, targetUser.Role) {
common.ApiErrorMsg(c, "no permission")
return
}
Expand Down
5 changes: 5 additions & 0 deletions controller/passkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,11 @@ func AdminResetPasskey(c *gin.Context) {
common.ApiError(c, err)
return
}
myRole := c.GetInt("role")
if !canManageTargetRole(myRole, user.Role) {
common.ApiErrorMsg(c, "no permission")
return
}

if _, err := model.GetPasskeyByUserID(user.Id); err != nil {
if errors.Is(err, model.ErrPasskeyNotFound) {
Expand Down
6 changes: 3 additions & 3 deletions controller/task_video.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,13 @@ func updateVideoSingleTask(ctx context.Context, adaptor channel.TaskAdaptor, cha
return fmt.Errorf("readAll failed for task %s: %w", taskId, err)
}

logger.LogDebug(ctx, fmt.Sprintf("UpdateVideoSingleTask response: %s", string(responseBody)))
logger.LogDebug(ctx, "UpdateVideoSingleTask response: %s", responseBody)

taskResult := &relaycommon.TaskInfo{}
// try parse as New API response format
var responseItems dto.TaskResponse[model.Task]
if err = common.Unmarshal(responseBody, &responseItems); err == nil && responseItems.IsSuccess() {
logger.LogDebug(ctx, fmt.Sprintf("UpdateVideoSingleTask parsed as new api response format: %+v", responseItems))
logger.LogDebug(ctx, "UpdateVideoSingleTask parsed as new api response format: %+v", responseItems)
t := responseItems.Data
taskResult.TaskID = t.TaskID
taskResult.Status = string(t.Status)
Expand All @@ -116,7 +116,7 @@ func updateVideoSingleTask(ctx context.Context, adaptor channel.TaskAdaptor, cha
task.Data = redactVideoResponseBody(responseBody)
}

logger.LogDebug(ctx, fmt.Sprintf("UpdateVideoSingleTask taskResult: %+v", taskResult))
logger.LogDebug(ctx, "UpdateVideoSingleTask taskResult: %+v", taskResult)

now := time.Now().Unix()
if taskResult.Status == "" {
Expand Down
2 changes: 1 addition & 1 deletion controller/twofa.go
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ func AdminDisable2FA(c *gin.Context) {
}

myRole := c.GetInt("role")
if myRole <= targetUser.Role && myRole != common.RoleRootUser {
if !canManageTargetRole(myRole, targetUser.Role) {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "无权操作同级或更高级用户的2FA设置",
Expand Down
14 changes: 9 additions & 5 deletions controller/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ func SearchUsers(c *gin.Context) {
return
}

func canManageTargetRole(myRole int, targetRole int) bool {
return myRole == common.RoleRootUser || myRole > targetRole
}

func GetUser(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
Expand All @@ -276,7 +280,7 @@ func GetUser(c *gin.Context) {
return
}
myRole := c.GetInt("role")
if myRole <= user.Role && myRole != common.RoleRootUser {
if !canManageTargetRole(myRole, user.Role) {
common.ApiErrorI18n(c, i18n.MsgUserNoPermissionSameLevel)
return
}
Expand Down Expand Up @@ -567,11 +571,11 @@ func UpdateUser(c *gin.Context) {
return
}
myRole := c.GetInt("role")
if myRole <= originUser.Role && myRole != common.RoleRootUser {
if !canManageTargetRole(myRole, originUser.Role) {
common.ApiErrorI18n(c, i18n.MsgUserNoPermissionHigherLevel)
return
}
if myRole <= updatedUser.Role && myRole != common.RoleRootUser {
if !canManageTargetRole(myRole, updatedUser.Role) {
common.ApiErrorI18n(c, i18n.MsgUserCannotCreateHigherLevel)
return
}
Expand Down Expand Up @@ -610,7 +614,7 @@ func AdminClearUserBinding(c *gin.Context) {
}

myRole := c.GetInt("role")
if myRole <= user.Role && myRole != common.RoleRootUser {
if !canManageTargetRole(myRole, user.Role) {
common.ApiErrorI18n(c, i18n.MsgUserNoPermissionSameLevel)
return
}
Expand Down Expand Up @@ -872,7 +876,7 @@ func ManageUser(c *gin.Context) {
return
}
myRole := c.GetInt("role")
if myRole <= user.Role && myRole != common.RoleRootUser {
if !canManageTargetRole(myRole, user.Role) {
common.ApiErrorI18n(c, i18n.MsgUserNoPermissionHigherLevel)
return
}
Expand Down
13 changes: 9 additions & 4 deletions logger/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,11 @@ func LogDebug(ctx context.Context, msg string, args ...any) {
}

func logHelper(ctx context.Context, level string, msg string) {
id := ctx.Value(common.RequestIdKey)
if id == nil {
id = "SYSTEM"
var id any = "SYSTEM"
if ctx != nil {
if requestID := ctx.Value(common.RequestIdKey); requestID != nil {
id = requestID
}
}
now := time.Now()
common.LogWriterMu.RLock()
Expand Down Expand Up @@ -172,10 +174,13 @@ func FormatQuota(quota int) string {

// LogJson 仅供测试使用 only for test
func LogJson(ctx context.Context, msg string, obj any) {
if !common.DebugEnabled {
return
}
jsonStr, err := common.Marshal(obj)
if err != nil {
LogError(ctx, fmt.Sprintf("json marshal failed: %s", err.Error()))
return
}
LogDebug(ctx, fmt.Sprintf("%s | %s", msg, string(jsonStr)))
LogDebug(ctx, "%s | %s", msg, jsonStr)
}
4 changes: 2 additions & 2 deletions model/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/constant"
"github.com/QuantumNous/new-api/dto"
"github.com/QuantumNous/new-api/logger"
"github.com/QuantumNous/new-api/types"

"github.com/samber/lo"
Expand Down Expand Up @@ -250,10 +251,9 @@ func (channel *Channel) GetNextEnabledKey() (string, int, *types.NewAPIError) {
if err != nil {
return "", 0, types.NewError(err, types.ErrorCodeGetChannelFailed, types.ErrOptionWithSkipRetry())
}
//println("before polling index:", channel.ChannelInfo.MultiKeyPollingIndex)
defer func() {
if common.DebugEnabled {
println(fmt.Sprintf("channel %d polling index: %d", channel.Id, channel.ChannelInfo.MultiKeyPollingIndex))
logger.LogDebug(nil, "channel %d polling index: %d", channel.Id, channel.ChannelInfo.MultiKeyPollingIndex)
}
if !common.MemoryCacheEnabled {
_ = channel.SaveChannelInfo()
Expand Down
12 changes: 8 additions & 4 deletions model/channel_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/constant"
"github.com/QuantumNous/new-api/logger"
"github.com/QuantumNous/new-api/setting/ratio_setting"
)

Expand Down Expand Up @@ -257,9 +258,12 @@ func CacheUpdateChannel(channel *Channel) {
return
}

println("CacheUpdateChannel:", channel.Id, channel.Name, channel.Status, channel.ChannelInfo.MultiKeyPollingIndex)

println("before:", channelsIDM[channel.Id].ChannelInfo.MultiKeyPollingIndex)
if channelsIDM == nil {
channelsIDM = make(map[int]*Channel)
}
if oldChannel, ok := channelsIDM[channel.Id]; ok {
logger.LogDebug(nil, "CacheUpdateChannel before: id=%d, name=%s, status=%d, polling_index=%d", channel.Id, channel.Name, channel.Status, oldChannel.ChannelInfo.MultiKeyPollingIndex)
}
channelsIDM[channel.Id] = channel
println("after :", channelsIDM[channel.Id].ChannelInfo.MultiKeyPollingIndex)
logger.LogDebug(nil, "CacheUpdateChannel after: id=%d, name=%s, status=%d, polling_index=%d", channel.Id, channel.Name, channel.Status, channel.ChannelInfo.MultiKeyPollingIndex)
}
4 changes: 2 additions & 2 deletions model/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ type User struct {
OidcId string `json:"oidc_id" gorm:"column:oidc_id;index"`
WeChatId string `json:"wechat_id" gorm:"column:wechat_id;index"`
TelegramId string `json:"telegram_id" gorm:"column:telegram_id;index"`
VerificationCode string `json:"verification_code" gorm:"-:all"` // this field is only for Email verification, don't save it to database!
AccessToken *string `json:"access_token" gorm:"type:char(32);column:access_token;uniqueIndex"` // this token is for system management
VerificationCode string `json:"verification_code" gorm:"-:all"` // this field is only for Email verification, don't save it to database!
AccessToken *string `json:"-" gorm:"type:char(32);column:access_token;uniqueIndex"` // this token is for system management
Quota int `json:"quota" gorm:"type:int;default:0"`
UsedQuota int `json:"used_quota" gorm:"type:int;default:0;column:used_quota"` // used quota
RequestCount int `json:"request_count" gorm:"type:int;default:0;"` // request number
Expand Down
7 changes: 3 additions & 4 deletions relay/channel/ali/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ func asyncTaskWait(c *gin.Context, info *relaycommon.RelayInfo, taskID string) (
time.Sleep(time.Duration(5) * time.Second)

for {
logger.LogDebug(c, fmt.Sprintf("asyncTaskWait step %d/%d, wait %d seconds", step, maxStep, waitSeconds))
logger.LogDebug(c, "asyncTaskWait step %d/%d, wait %d seconds", step, maxStep, waitSeconds)
step++
rsp, err, body := updateTask(info, taskID)
responseBody = body
Expand Down Expand Up @@ -320,11 +320,10 @@ func aliImageHandler(a *Adaptor, c *gin.Context, resp *http.Response, info *rela
}
}

//logger.LogDebug(c, "ali_async_task_result: "+string(originRespBody))
if a.IsSyncImageModel {
logger.LogDebug(c, "ali_sync_image_result: "+string(originRespBody))
logger.LogDebug(c, "ali_sync_image_result: %s", originRespBody)
} else {
logger.LogDebug(c, "ali_async_image_result: "+string(originRespBody))
logger.LogDebug(c, "ali_async_image_result: %s", originRespBody)
}

imageResponses := responseAli2OpenAIImage(c, aliResponse, originRespBody, info, responseFormat)
Expand Down
40 changes: 10 additions & 30 deletions relay/channel/api_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,7 @@ func DoApiRequest(a Adaptor, c *gin.Context, info *common.RelayInfo, requestBody
if err != nil {
return nil, fmt.Errorf("get request url failed: %w", err)
}
if common2.DebugEnabled {
println("fullRequestURL:", fullRequestURL)
}
logger.LogDebug(c, "fullRequestURL: %s", fullRequestURL)
req, err := http.NewRequest(c.Request.Method, fullRequestURL, requestBody)
if err != nil {
return nil, fmt.Errorf("new request failed: %w", err)
Expand Down Expand Up @@ -323,9 +321,7 @@ func DoFormRequest(a Adaptor, c *gin.Context, info *common.RelayInfo, requestBod
if err != nil {
return nil, fmt.Errorf("get request url failed: %w", err)
}
if common2.DebugEnabled {
println("fullRequestURL:", fullRequestURL)
}
logger.LogDebug(c, "fullRequestURL: %s", fullRequestURL)
req, err := http.NewRequest(c.Request.Method, fullRequestURL, requestBody)
if err != nil {
return nil, fmt.Errorf("new request failed: %w", err)
Expand Down Expand Up @@ -388,13 +384,9 @@ func startPingKeepAlive(c *gin.Context, pingInterval time.Duration) context.Canc
defer func() {
// 增加panic恢复处理
if r := recover(); r != nil {
if common2.DebugEnabled {
println("SSE ping goroutine panic recovered:", fmt.Sprintf("%v", r))
}
}
if common2.DebugEnabled {
println("SSE ping goroutine stopped.")
logger.LogDebug(c, "SSE ping goroutine panic recovered: %v", r)
}
logger.LogDebug(c, "SSE ping goroutine stopped")
}()

if pingInterval <= 0 {
Expand All @@ -405,15 +397,11 @@ func startPingKeepAlive(c *gin.Context, pingInterval time.Duration) context.Canc
// 确保在任何情况下都清理ticker
defer func() {
ticker.Stop()
if common2.DebugEnabled {
println("SSE ping ticker stopped")
}
logger.LogDebug(c, "SSE ping ticker stopped")
}()

var pingMutex sync.Mutex
if common2.DebugEnabled {
println("SSE ping goroutine started")
}
logger.LogDebug(c, "SSE ping goroutine started")

// 增加超时控制,防止goroutine长时间运行
maxPingDuration := 120 * time.Minute // 最大ping持续时间
Expand All @@ -425,9 +413,7 @@ func startPingKeepAlive(c *gin.Context, pingInterval time.Duration) context.Canc
// 发送 ping 数据
case <-ticker.C:
if err := sendPingData(c, &pingMutex); err != nil {
if common2.DebugEnabled {
println("SSE ping error, stopping goroutine:", err.Error())
}
logger.LogDebug(c, "SSE ping error, stopping goroutine: %s", err.Error())
return
}
// 收到退出信号
Expand All @@ -438,9 +424,7 @@ func startPingKeepAlive(c *gin.Context, pingInterval time.Duration) context.Canc
return
// 超时保护,防止goroutine无限运行
case <-pingTimeout.C:
if common2.DebugEnabled {
println("SSE ping goroutine timeout, stopping")
}
logger.LogDebug(c, "SSE ping goroutine timeout, stopping")
return
}
}
Expand All @@ -463,9 +447,7 @@ func sendPingData(c *gin.Context, mutex *sync.Mutex) error {
return
}

if common2.DebugEnabled {
println("SSE ping data sent.")
}
logger.LogDebug(c, "SSE ping data sent")
done <- nil
}()

Expand Down Expand Up @@ -507,9 +489,7 @@ func doRequest(c *gin.Context, req *http.Request, info *common.RelayInfo) (*http
defer func() {
if stopPinger != nil {
stopPinger()
if common2.DebugEnabled {
println("SSE ping goroutine stopped by defer")
}
logger.LogDebug(c, "SSE ping goroutine stopped by defer")
}
}()
}
Expand Down
4 changes: 1 addition & 3 deletions relay/channel/claude/relay-claude.go
Original file line number Diff line number Diff line change
Expand Up @@ -949,9 +949,7 @@ func ClaudeHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayI
if err != nil {
return nil, types.NewError(err, types.ErrorCodeBadResponseBody)
}
if common.DebugEnabled {
println("responseBody: ", string(responseBody))
}
logger.LogDebug(c, "responseBody: %s", responseBody)
handleErr := HandleClaudeResponseData(c, info, claudeInfo, resp, responseBody)
if handleErr != nil {
return nil, handleErr
Expand Down
8 changes: 2 additions & 6 deletions relay/channel/gemini/relay-gemini-native.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ func GeminiTextGenerationHandler(c *gin.Context, info *relaycommon.RelayInfo, re
return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}

if common.DebugEnabled {
println(string(responseBody))
}
logger.LogDebug(c, "Gemini native response body: %s", responseBody)

// 解析为 Gemini 原生响应格式
var geminiResponse dto.GeminiChatResponse
Expand Down Expand Up @@ -57,9 +55,7 @@ func NativeGeminiEmbeddingHandler(c *gin.Context, resp *http.Response, info *rel
return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}

if common.DebugEnabled {
println(string(responseBody))
}
logger.LogDebug(c, "Gemini native embedding response body: %s", responseBody)

usage := service.ResponseText2Usage(c, "", info.UpstreamModelName, info.GetEstimatePromptTokens())

Expand Down
6 changes: 2 additions & 4 deletions relay/channel/gemini/relay-gemini.go
Original file line number Diff line number Diff line change
Expand Up @@ -1362,7 +1362,7 @@ func GeminiChatStreamHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *
}
}

logger.LogDebug(c, fmt.Sprintf("info.SendResponseCount = %d", info.SendResponseCount))
logger.LogDebug(c, "info.SendResponseCount = %d", info.SendResponseCount)
if info.SendResponseCount == 0 {
// send first response
emptyResponse := helper.GenerateStartEmptyResponse(id, createAt, info.UpstreamModelName, nil)
Expand Down Expand Up @@ -1422,9 +1422,7 @@ func GeminiChatHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.R
return nil, types.NewOpenAIError(err, types.ErrorCodeBadResponseBody, http.StatusInternalServerError)
}
service.CloseResponseBodyGracefully(resp)
if common.DebugEnabled {
println(string(responseBody))
}
logger.LogDebug(c, "Gemini response body: %s", responseBody)
var geminiResponse dto.GeminiChatResponse
err = common.Unmarshal(responseBody, &geminiResponse)
if err != nil {
Expand Down
Loading