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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ data/
findings.md
progress.md
task_plan.md
token_estimator_test.go
18 changes: 12 additions & 6 deletions controller/channel-test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ func testChannel(channel *model.Channel, testModel string, endpointType string,
}
}
cache.WriteContext(c)
c.Set("id", 1)

//c.Request.Header.Set("Authorization", "Bearer "+channel.Key)
c.Request.Header.Set("Content-Type", "application/json")
Expand Down Expand Up @@ -274,7 +275,7 @@ func testChannel(channel *model.Channel, testModel string, endpointType string,
return testResult{
context: c,
localErr: err,
newAPIError: types.NewError(err, types.ErrorCodeModelPriceError),
newAPIError: types.NewError(err, types.ErrorCodeModelPriceError, types.ErrOptionWithStatusCode(http.StatusBadRequest)),
}
}

Expand Down Expand Up @@ -756,11 +757,15 @@ func TestChannel(c *gin.Context) {
tik := time.Now()
result := testChannel(channel, testModel, endpointType, isStream)
if result.localErr != nil {
c.JSON(http.StatusOK, gin.H{
resp := gin.H{
"success": false,
"message": result.localErr.Error(),
"time": 0.0,
})
}
if result.newAPIError != nil {
resp["error_code"] = result.newAPIError.GetErrorCode()
}
c.JSON(http.StatusOK, resp)
return
}
tok := time.Now()
Expand All @@ -769,9 +774,10 @@ func TestChannel(c *gin.Context) {
consumedTime := float64(milliseconds) / 1000.0
if result.newAPIError != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": result.newAPIError.Error(),
"time": consumedTime,
"success": false,
"message": result.newAPIError.Error(),
"time": consumedTime,
"error_code": result.newAPIError.GetErrorCode(),
})
return
}
Expand Down
2 changes: 1 addition & 1 deletion controller/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func Relay(c *gin.Context, relayFormat types.RelayFormat) {

priceData, err := helper.ModelPriceHelper(c, relayInfo, tokens, meta)
if err != nil {
newAPIError = types.NewError(err, types.ErrorCodeModelPriceError)
newAPIError = types.NewError(err, types.ErrorCodeModelPriceError, types.ErrOptionWithStatusCode(http.StatusBadRequest))
return
}

Expand Down
59 changes: 52 additions & 7 deletions controller/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,15 @@ func Login(c *gin.Context) {
}
err = user.ValidateAndFill()
if err != nil {
c.JSON(http.StatusOK, gin.H{
"message": err.Error(),
"success": false,
})
switch {
case errors.Is(err, model.ErrDatabase):
common.SysLog(fmt.Sprintf("Login database error for user %s: %v", username, err))
common.ApiErrorI18n(c, i18n.MsgDatabaseError)
case errors.Is(err, model.ErrUserEmptyCredentials):
common.ApiErrorI18n(c, i18n.MsgInvalidParams)
default:
common.ApiErrorI18n(c, i18n.MsgUserUsernameOrPasswordError)
}
return
}

Expand Down Expand Up @@ -572,9 +577,6 @@ func UpdateUser(c *gin.Context) {
common.ApiError(c, err)
return
}
if originUser.Quota != updatedUser.Quota {
model.RecordLog(originUser.Id, model.LogTypeManage, fmt.Sprintf("管理员将用户额度从 %s修改为 %s", logger.LogQuota(originUser.Quota), logger.LogQuota(updatedUser.Quota)))
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "",
Expand Down Expand Up @@ -841,6 +843,8 @@ func CreateUser(c *gin.Context) {
type ManageRequest struct {
Id int `json:"id"`
Action string `json:"action"`
Value int `json:"value"`
Mode string `json:"mode"`
}

// ManageUser Only admin user can do this
Expand Down Expand Up @@ -907,6 +911,47 @@ func ManageUser(c *gin.Context) {
return
}
user.Role = common.RoleCommonUser
case "add_quota":
switch req.Mode {
case "add":
if req.Value <= 0 {
common.ApiErrorI18n(c, i18n.MsgUserQuotaChangeZero)
return
}
if err := model.IncreaseUserQuota(user.Id, req.Value, true); err != nil {
common.ApiError(c, err)
return
}
model.RecordLog(user.Id, model.LogTypeManage,
fmt.Sprintf("管理员增加用户额度 %s", logger.LogQuota(req.Value)))
case "subtract":
if req.Value <= 0 {
common.ApiErrorI18n(c, i18n.MsgUserQuotaChangeZero)
return
}
if err := model.DecreaseUserQuota(user.Id, req.Value, true); err != nil {
common.ApiError(c, err)
return
}
model.RecordLog(user.Id, model.LogTypeManage,
fmt.Sprintf("管理员减少用户额度 %s", logger.LogQuota(req.Value)))
case "override":
oldQuota := user.Quota
if err := model.DB.Model(&model.User{}).Where("id = ?", user.Id).Update("quota", req.Value).Error; err != nil {
common.ApiError(c, err)
return
}
model.RecordLog(user.Id, model.LogTypeManage,
fmt.Sprintf("管理员覆盖用户额度从 %s 为 %s", logger.LogQuota(oldQuota), logger.LogQuota(req.Value)))
default:
common.ApiErrorI18n(c, i18n.MsgInvalidParams)
return
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "",
})
return
}

if err := user.Update(false); err != nil {
Expand Down
13 changes: 13 additions & 0 deletions i18n/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ const (
MsgBatchTooMany = "common.batch_too_many"
)

// Auth middleware messages
const (
MsgAuthNotLoggedIn = "auth.not_logged_in"
MsgAuthAccessTokenInvalid = "auth.access_token_invalid"
MsgAuthUserInfoInvalid = "auth.user_info_invalid"
MsgAuthUserIdNotProvided = "auth.user_id_not_provided"
MsgAuthUserIdFormatError = "auth.user_id_format_error"
MsgAuthUserIdMismatch = "auth.user_id_mismatch"
MsgAuthUserBanned = "auth.user_banned"
MsgAuthInsufficientPrivilege = "auth.insufficient_privilege"
)

// Token related messages
const (
MsgTokenNameTooLong = "token.name_too_long"
Expand Down Expand Up @@ -101,6 +113,7 @@ const (
MsgUserTelegramIdEmpty = "user.telegram_id_empty"
MsgUserTelegramNotBound = "user.telegram_not_bound"
MsgUserLinuxDOIdEmpty = "user.linux_do_id_empty"
MsgUserQuotaChangeZero = "user.quota_change_zero"
)

// Quota related messages
Expand Down
13 changes: 12 additions & 1 deletion i18n/locales/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Common messages
common.invalid_params: "Invalid parameters"
common.database_error: "Database error, please try again later"
common.database_error: "Database error, please contact the administrator"
common.retry_later: "Please try again later"
common.generate_failed: "Generation failed"
common.not_found: "Not found"
Expand All @@ -23,6 +23,16 @@ common.already_exists: "Already exists"
common.name_cannot_be_empty: "Name cannot be empty"
common.batch_too_many: "Too many items in batch request, maximum is {{.Max}}"

# Auth middleware messages
auth.not_logged_in: "Unauthorized, not logged in and no access token provided"
auth.access_token_invalid: "Unauthorized, invalid access token"
auth.user_info_invalid: "Unauthorized, invalid user info"
auth.user_id_not_provided: "Unauthorized, New-Api-User header not provided"
auth.user_id_format_error: "Unauthorized, New-Api-User header format error"
auth.user_id_mismatch: "Unauthorized, New-Api-User does not match logged in user"
auth.user_banned: "User has been banned"
auth.insufficient_privilege: "Unauthorized, insufficient privileges"

# Token messages
token.name_too_long: "Token name is too long"
token.quota_negative: "Quota value cannot be negative"
Expand Down Expand Up @@ -91,6 +101,7 @@ user.wechat_id_empty: "WeChat ID is empty!"
user.telegram_id_empty: "Telegram ID is empty!"
user.telegram_not_bound: "This Telegram account is not bound"
user.linux_do_id_empty: "Linux DO ID is empty!"
user.quota_change_zero: "Quota change amount cannot be zero"

# Quota messages
quota.negative: "Quota cannot be negative!"
Expand Down
13 changes: 12 additions & 1 deletion i18n/locales/zh-CN.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# Common messages
common.invalid_params: "无效的参数"
common.database_error: "数据库错误,请稍后重试"
common.database_error: "数据库出错,请联系管理员"
common.retry_later: "请稍后重试"
common.generate_failed: "生成失败"
common.not_found: "未找到"
Expand All @@ -24,6 +24,16 @@ common.already_exists: "已存在"
common.name_cannot_be_empty: "名称不能为空"
common.batch_too_many: "批量请求数量过多,最多 {{.Max}} 条"

# Auth middleware messages
auth.not_logged_in: "无权进行此操作,未登录且未提供 access token"
auth.access_token_invalid: "无权进行此操作,access token 无效"
auth.user_info_invalid: "无权进行此操作,用户信息无效"
auth.user_id_not_provided: "无权进行此操作,未提供 New-Api-User"
auth.user_id_format_error: "无权进行此操作,New-Api-User 格式错误"
auth.user_id_mismatch: "无权进行此操作,New-Api-User 与登录用户不匹配"
auth.user_banned: "用户已被封禁"
auth.insufficient_privilege: "无权进行此操作,权限不足"

# Token messages
token.name_too_long: "令牌名称过长"
token.quota_negative: "额度值不能为负数"
Expand Down Expand Up @@ -92,6 +102,7 @@ user.wechat_id_empty: "WeChat id 为空!"
user.telegram_id_empty: "Telegram id 为空!"
user.telegram_not_bound: "该 Telegram 账户未绑定"
user.linux_do_id_empty: "Linux DO id 为空!"
user.quota_change_zero: "额度变更量不能为0"

# Quota messages
quota.negative: "额度不能为负数!"
Expand Down
13 changes: 12 additions & 1 deletion i18n/locales/zh-TW.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# Common messages
common.invalid_params: "無效的參數"
common.database_error: "資料庫錯誤,請稍後重試"
common.database_error: "資料庫出錯,請聯繫管理員"
common.retry_later: "請稍後重試"
common.generate_failed: "生成失敗"
common.not_found: "未找到"
Expand All @@ -24,6 +24,16 @@ common.already_exists: "已存在"
common.name_cannot_be_empty: "名稱不能為空"
common.batch_too_many: "批次請求數量過多,最多 {{.Max}} 條"

# Auth middleware messages
auth.not_logged_in: "無權進行此操作,未登入且未提供 access token"
auth.access_token_invalid: "無權進行此操作,access token 無效"
auth.user_info_invalid: "無權進行此操作,使用者資訊無效"
auth.user_id_not_provided: "無權進行此操作,未提供 New-Api-User"
auth.user_id_format_error: "無權進行此操作,New-Api-User 格式錯誤"
auth.user_id_mismatch: "無權進行此操作,New-Api-User 與登入使用者不匹配"
auth.user_banned: "使用者已被封禁"
auth.insufficient_privilege: "無權進行此操作,權限不足"

# Token messages
token.name_too_long: "令牌名稱過長"
token.quota_negative: "額度值不能為負數"
Expand Down Expand Up @@ -92,6 +102,7 @@ user.wechat_id_empty: "WeChat id 為空!"
user.telegram_id_empty: "Telegram id 為空!"
user.telegram_not_bound: "該 Telegram 帳號未綁定"
user.linux_do_id_empty: "Linux DO id 為空!"
user.quota_change_zero: "額度變更量不能為0"

# Quota messages
quota.negative: "額度不能為負數!"
Expand Down
Loading