This commit is contained in:
hero920103 committed 2026-10-19 01:13:17 +08:00
1 parent 5718a00e31
commit 1850ac640e
226 files changed
+37772 -12071

No files matched your search

+59 -61
View File
@@ -9,7 +9,7 @@ import (
"strings"
"server/models"
"server/pkg/jwtutil"
"server/pkg/identity"
"server/pkg/passwordutil"
"server/services"
authsvc "server/services/auth"
@@ -133,47 +133,26 @@ func toBackendUserInfoDTO(u models.SystemTenantUser) backendUserInfoDTO {
}
}
// getJWTUidTid 取当前登录者标识:
// - uid:令牌里的 user_id,即认证中心 identity_id
// - tid:令牌里的 tenant_id
// requireBackendIdentity 解析并校验 backend 端登录态;失败时已写好响应,调用方必须立即 return。
//
// 键名历史上有两套写法(uid/tid 与 userId/tenantId),这里都兼容;
// 中间件在 warn/off 模式下可能没有注入,故再兜底自行解析 Authorization 头,
// 否则会静默拿到 0(曾导致按 identity_id 直查老表、显示到别人的资料)。
func (c *BackendAdminUserController) getJWTUidTid() (uint64, uint64) {
var uid uint64
var tid uint64
data := c.Ctx.Input.Data()
for _, key := range []string{"uid", "userId"} {
if v, ok := data[key].(uint64); ok && v > 0 {
uid = v
break
}
// 取代原 getJWTUidTid:那版从中间件注入的 ctx data 里取 uid/tid,
// 既不判端、取不到时又静默返回 0,而 0 会让「按企业过滤」退化成全局查询——
// 平台或小程序的令牌即可枚举、编辑别家企业的用户。
// 现在 uid/tid 只来自令牌,且必须是 backend 端且已绑定企业。
func (c *BackendAdminUserController) requireBackendIdentity() (uint64, uint64, bool) {
claims, err := identity.Claims(c.Ctx.Request.Header.Get("Authorization"), identity.EndBackend)
if err != nil {
code := identity.Status(err)
c.Data["json"] = map[string]interface{}{"code": code, "msg": err.Error()}
_ = c.ServeJSON()
return 0, 0, false
}
for _, key := range []string{"tid", "tenantId"} {
if v, ok := data[key].(uint64); ok && v > 0 {
tid = v
break
}
if claims.TenantId <= 0 {
c.Data["json"] = map[string]interface{}{"code": 403, "msg": "登录态未绑定企业"}
_ = c.ServeJSON()
return 0, 0, false
}
if uid == 0 || tid == 0 {
auth := c.Ctx.Request.Header.Get("Authorization")
if parts := strings.SplitN(auth, " ", 2); len(parts) == 2 && parts[0] == "Bearer" {
if claims, err := jwtutil.ParseToken(parts[1]); err == nil {
if uid == 0 {
uid = uint64(claims.UserID)
}
if tid == 0 {
tid = uint64(claims.TenantId)
}
}
}
}
return uid, tid
return uint64(claims.UserID), uint64(claims.TenantId), true
}
func (c *BackendAdminUserController) parseTenantUserPayload() (backendTenantUserPayload, bool) {
@@ -246,20 +225,21 @@ func findBackendTenantUser(idOrUid uint64, jwtTid uint64, byID bool) (*models.Sy
// GetAllUsers 获取当前租户后台用户列表
// GET /backend/getAllUsers
func (c *BackendAdminUserController) GetAllUsers() {
_, jwtTid := c.getJWTUidTid()
_, jwtTid, ok := c.requireBackendIdentity()
if !ok {
return
}
keyword := strings.TrimSpace(c.GetString("keyword"))
tid, _ := c.GetUint64("tid")
if jwtTid > 0 {
tid = jwtTid
// 用户列表只按登录态隔离:?tid= 不再生效(此前不传 tid 会直接返回全部企业的用户)
tid := jwtTid
if tid == 0 {
c.Data["json"] = map[string]interface{}{"code": 403, "msg": "登录态未绑定企业"}
_ = c.ServeJSON()
return
}
cond := orm.NewCondition().And("delete_time__isnull", true)
if tid > 0 {
cond = cond.And("tid", tid)
}
cond := orm.NewCondition().And("delete_time__isnull", true).And("tid", tid)
if keyword != "" {
kwCond := orm.NewCondition().
@@ -303,7 +283,10 @@ func (c *BackendAdminUserController) GetTenantUsers() {
tidStr := c.Ctx.Input.Param(":tid")
tid, _ := strconv.ParseUint(tidStr, 10, 64)
_, jwtTid := c.getJWTUidTid()
_, jwtTid, ok := c.requireBackendIdentity()
if !ok {
return
}
if jwtTid > 0 {
tid = jwtTid
}
@@ -348,7 +331,10 @@ func (c *BackendAdminUserController) GetTenantUsers() {
// by=id:前端明确传主键(用户管理页),只按主键查询;
// 缺省时兼容 identity_id / 老 uid(个人中心等场景)。
func (c *BackendAdminUserController) GetUserInfo() {
jwtUid, jwtTid := c.getJWTUidTid()
jwtUid, jwtTid, ok := c.requireBackendIdentity()
if !ok {
return
}
idStr := c.Ctx.Input.Param(":id")
id, _ := strconv.ParseUint(idStr, 10, 64)
@@ -388,7 +374,10 @@ func (c *BackendAdminUserController) AddUser() {
return
}
_, jwtTid := c.getJWTUidTid()
_, jwtTid, ok := c.requireBackendIdentity()
if !ok {
return
}
if jwtTid > 0 {
p.Tid = jwtTid
}
@@ -423,22 +412,22 @@ func (c *BackendAdminUserController) AddUser() {
_ = c.ServeJSON()
return
}
identity, err := authsvc.GetIdentityByID(p.IdentityID)
if err != nil || identity == nil {
ident, err := authsvc.GetIdentityByID(p.IdentityID)
if err != nil || ident == nil {
c.Data["json"] = map[string]interface{}{"code": 404, "msg": "认证身份不存在"}
_ = c.ServeJSON()
return
}
if !authsvc.VerifyIdentityPassword(identity, strings.TrimSpace(p.VerifyPassword)) {
if !authsvc.VerifyIdentityPassword(ident, strings.TrimSpace(p.VerifyPassword)) {
c.Data["json"] = map[string]interface{}{"code": 401, "msg": "密码不正确,无法确认是同一账号"}
_ = c.ServeJSON()
return
}
// uid 统一为 identity_id,与已全量迁移的业务表口径一致
p.Uid = identity.ID
p.Uid = ident.ID
// 老表镜像身份层现有密码哈希(登录仍以认证中心为准)
if identity.PasswordHash != nil && *identity.PasswordHash != "" {
h := *identity.PasswordHash
if ident.PasswordHash != nil && *ident.PasswordHash != "" {
h := *ident.PasswordHash
p.Password = &h
} else {
// 身份层无密码(历史数据),仅镜像到老表,不影响统一认证
@@ -594,7 +583,10 @@ func (c *BackendAdminUserController) EditUser() {
return
}
_, jwtTid := c.getJWTUidTid()
_, jwtTid, ok := c.requireBackendIdentity()
if !ok {
return
}
row, err := findBackendTenantUser(id, jwtTid, c.GetString("by") == "id")
if err != nil || row == nil {
@@ -719,7 +711,10 @@ func (c *BackendAdminUserController) DeleteUser() {
return
}
_, jwtTid := c.getJWTUidTid()
_, jwtTid, ok := c.requireBackendIdentity()
if !ok {
return
}
row, err := findBackendTenantUser(id, jwtTid, c.GetString("by") == "id")
if err != nil || row == nil {
@@ -765,7 +760,10 @@ func (c *BackendAdminUserController) ChangePassword() {
return
}
_, jwtTid := c.getJWTUidTid()
_, jwtTid, ok := c.requireBackendIdentity()
if !ok {
return
}
row, err := findBackendTenantUser(p.ID, jwtTid, p.By == "id")
if err != nil || row == nil {