修复事务拒绝响应与单库会话续期互相等待
Some checks are pending
Security Checks / security (push) Waiting to run

This commit is contained in:
smail 2026-09-25 23:07:54 +08:00
parent 66555994df
commit 9a60bd74eb
2 changed files with 11 additions and 0 deletions

View File

@ -130,20 +130,24 @@ func ModifyPassword(ctx *context.Context, w http.ResponseWriter, req *http.Reque
affected, err := tx.Where("id = ? and password = ? and session_version = ? and security_version = ? and disabled = 0", ctx.UserID, currentUser.Password, currentUser.SessionVersion, currentUser.SecurityVersion).Cols("password", "session_version", "security_version", "must_change_password", "password_changed_at").Update(&user)
if err != nil {
log.WithContext(ctx).WithError(err).Error("update password failed")
_ = tx.Rollback()
response.NewErrorResponse(response.ServerError, i18n.GetText(ctx.Lang, "unknowError"), "").FPrint(w)
return
}
if affected != 1 {
_ = tx.Rollback()
log.WithContext(ctx).Warn("password changed concurrently")
response.NewErrorResponse(response.ParamsError, i18n.GetText(ctx.Lang, "unknowError"), "").FPrint(w)
return
}
if err := credentialService.RevokeAllWithSession(tx, ctx.UserID); err != nil {
_ = tx.Rollback()
log.WithContext(ctx).WithError(err).Error("revoke credentials after password change failed")
response.NewErrorResponse(response.ServerError, i18n.GetText(ctx.Lang, "unknowError"), "").FPrint(w)
return
}
if err := tx.Commit(); err != nil {
_ = tx.Rollback()
log.WithContext(ctx).WithError(err).Error("commit password change failed")
response.NewErrorResponse(response.ServerError, i18n.GetText(ctx.Lang, "unknowError"), "").FPrint(w)
return

View File

@ -423,6 +423,7 @@ func EditUser(ctx *context.Context, w http.ResponseWriter, req *http.Request) {
}()
updateColumns := []string{"name", "disabled", "role", "is_admin"}
if err := accountgroup.CheckWrite(tx, writeGuard); err != nil {
_ = tx.Rollback()
writeAccountGroupError(w, err)
return
}
@ -435,15 +436,18 @@ func EditUser(ctx *context.Context, w http.ResponseWriter, req *http.Request) {
update := tx.ID(user.ID).Where("session_version = ? AND security_version = ?", originalSessionVersion, originalSecurityVersion).Cols(updateColumns...)
accountgroup.ApplyScope(update, ctx.UserID, ctx.EffectiveRole())
if num, err := update.Update(&user); err != nil {
_ = tx.Rollback()
log.WithContext(ctx).WithError(err).Error("update user failed")
response.NewErrorResponse(response.ServerError, "更新用户失败", "").FPrint(w)
return
} else if num == 0 {
_ = tx.Rollback()
response.NewErrorResponse(response.ServerError, "没有可更新的数据", "").FPrint(w)
return
}
if reqData.Password != "" {
if err := credentialService.RevokeAllWithSession(tx, user.ID); err != nil {
_ = tx.Rollback()
log.WithContext(ctx).WithError(err).Error("revoke target credentials failed")
response.NewErrorResponse(response.ServerError, "撤销目标用户安全凭据失败", "").FPrint(w)
return
@ -452,15 +456,18 @@ func EditUser(ctx *context.Context, w http.ResponseWriter, req *http.Request) {
if user.EffectiveRole() != access.RoleAdmin {
count, err := tx.Where("user_id = ?", user.ID).Count(&models.AccountGroupMember{})
if err != nil {
_ = tx.Rollback()
writeAccountGroupError(w, err)
return
}
if count > 1 {
_ = tx.Rollback()
writeSecurityError(w, response.ParamsError, "请先将账号调整为一个分组,再更改为普通用户")
return
}
}
if err := tx.Commit(); err != nil {
_ = tx.Rollback()
log.WithContext(ctx).WithError(err).Error("commit user update failed")
response.NewErrorResponse(response.ServerError, "更新用户失败", "").FPrint(w)
return