批量更新
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"server/models"
|
||||
"server/pkg/jwtutil"
|
||||
authsvc "server/services/auth"
|
||||
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
// PlatformAuthConfigController 统一认证 —— 租户登录策略配置(平台端管理)
|
||||
//
|
||||
// 可配置:登录验证码方式、密码强度、会话时长、同账号最大在线设备数(1号1机)
|
||||
// 以及超限策略(踢掉旧会话 / 拒绝新登录)等。
|
||||
type PlatformAuthConfigController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
func (c *PlatformAuthConfigController) serveJSON(data map[string]interface{}) {
|
||||
c.Data["json"] = data
|
||||
_ = c.ServeJSON()
|
||||
}
|
||||
|
||||
// Prepare 统一鉴权:仅平台管理员可配置
|
||||
func (c *PlatformAuthConfigController) Prepare() {
|
||||
authHeader := c.Ctx.Request.Header.Get("Authorization")
|
||||
if authHeader == "" {
|
||||
c.Ctx.Output.SetStatus(401)
|
||||
c.serveJSON(map[string]interface{}{"code": 401, "msg": "未登录"})
|
||||
c.StopRun()
|
||||
return
|
||||
}
|
||||
parts := strings.SplitN(authHeader, " ", 2)
|
||||
if len(parts) != 2 || parts[0] != "Bearer" {
|
||||
c.Ctx.Output.SetStatus(401)
|
||||
c.serveJSON(map[string]interface{}{"code": 401, "msg": "认证信息格式错误"})
|
||||
c.StopRun()
|
||||
return
|
||||
}
|
||||
claims, err := jwtutil.ParseToken(parts[1])
|
||||
if err != nil {
|
||||
c.Ctx.Output.SetStatus(401)
|
||||
c.serveJSON(map[string]interface{}{"code": 401, "msg": "登录已失效,请重新登录"})
|
||||
c.StopRun()
|
||||
return
|
||||
}
|
||||
if claims.UserType != "platform" {
|
||||
c.Ctx.Output.SetStatus(403)
|
||||
c.serveJSON(map[string]interface{}{"code": 403, "msg": "无权访问"})
|
||||
c.StopRun()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Detail 查询租户登录策略;未配置时返回系统默认值
|
||||
// GET /platform/authConfig/detail?tid=
|
||||
func (c *PlatformAuthConfigController) Detail() {
|
||||
tid, _ := c.GetInt64("tid", 0)
|
||||
if tid == 0 {
|
||||
c.serveJSON(map[string]interface{}{"code": 400, "msg": "tid 不能为空"})
|
||||
return
|
||||
}
|
||||
|
||||
var cfg models.AuthTenantAuthConfig
|
||||
err := models.Orm.QueryTable(new(models.AuthTenantAuthConfig)).
|
||||
Filter("tid", tid).One(&cfg)
|
||||
|
||||
if err != nil {
|
||||
// 未配置:返回默认值
|
||||
policy := authsvc.GetTenantSessionPolicy(uint64(tid))
|
||||
c.serveJSON(map[string]interface{}{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": map[string]interface{}{
|
||||
"tid": tid,
|
||||
"verify_type": "captcha",
|
||||
"open_verify": 1,
|
||||
"pwd_min_len": 8,
|
||||
"pwd_complexity": 0,
|
||||
"session_ttl": policy.SessionTTL,
|
||||
"max_session": policy.MaxSession,
|
||||
"kick_strategy": policy.KickStrategy,
|
||||
"mfa_required": 0,
|
||||
"ip_whitelist": "",
|
||||
"allow_third": "",
|
||||
"configured": false,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ipList := ""
|
||||
if cfg.IPWhitelist != nil {
|
||||
ipList = *cfg.IPWhitelist
|
||||
}
|
||||
allowThird := ""
|
||||
if cfg.AllowThird != nil {
|
||||
allowThird = *cfg.AllowThird
|
||||
}
|
||||
c.serveJSON(map[string]interface{}{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": map[string]interface{}{
|
||||
"tid": cfg.Tid,
|
||||
"verify_type": cfg.VerifyType,
|
||||
"open_verify": cfg.OpenVerify,
|
||||
"pwd_min_len": cfg.PwdMinLen,
|
||||
"pwd_complexity": cfg.PwdComplexity,
|
||||
"session_ttl": cfg.SessionTTL,
|
||||
"max_session": cfg.MaxSession,
|
||||
"kick_strategy": cfg.KickStrategy,
|
||||
"mfa_required": cfg.MfaRequired,
|
||||
"ip_whitelist": ipList,
|
||||
"allow_third": allowThird,
|
||||
"configured": true,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Save 保存租户登录策略(不存在则创建)
|
||||
// POST /platform/authConfig/save
|
||||
func (c *PlatformAuthConfigController) Save() {
|
||||
var p struct {
|
||||
Tid uint64 `json:"tid"`
|
||||
VerifyType string `json:"verify_type"`
|
||||
OpenVerify *int8 `json:"open_verify"`
|
||||
PwdMinLen int `json:"pwd_min_len"`
|
||||
PwdComplexity int8 `json:"pwd_complexity"`
|
||||
SessionTTL int `json:"session_ttl"`
|
||||
MaxSession int `json:"max_session"`
|
||||
KickStrategy int8 `json:"kick_strategy"`
|
||||
MfaRequired int8 `json:"mfa_required"`
|
||||
IPWhitelist string `json:"ip_whitelist"`
|
||||
AllowThird string `json:"allow_third"`
|
||||
}
|
||||
raw, _ := io.ReadAll(c.Ctx.Request.Body)
|
||||
if len(raw) > 0 {
|
||||
if err := json.Unmarshal(raw, &p); err != nil {
|
||||
c.serveJSON(map[string]interface{}{"code": 400, "msg": "参数错误"})
|
||||
return
|
||||
}
|
||||
}
|
||||
if p.Tid == 0 {
|
||||
c.serveJSON(map[string]interface{}{"code": 400, "msg": "tid 不能为空"})
|
||||
return
|
||||
}
|
||||
|
||||
// 校验 IP 白名单为合法 JSON 数组
|
||||
ip := strings.TrimSpace(p.IPWhitelist)
|
||||
if ip != "" {
|
||||
var arr []string
|
||||
if err := json.Unmarshal([]byte(ip), &arr); err != nil {
|
||||
c.serveJSON(map[string]interface{}{"code": 400, "msg": "IP白名单必须是 JSON 数组,如 [\"1.2.3.4\"]"})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
cfg := models.AuthTenantAuthConfig{
|
||||
Tid: p.Tid,
|
||||
VerifyType: defaultStrAuth2(p.VerifyType, "captcha"),
|
||||
OpenVerify: 1,
|
||||
PwdMinLen: p.PwdMinLen,
|
||||
PwdComplexity: p.PwdComplexity,
|
||||
SessionTTL: p.SessionTTL,
|
||||
MaxSession: p.MaxSession,
|
||||
KickStrategy: p.KickStrategy,
|
||||
MfaRequired: p.MfaRequired,
|
||||
}
|
||||
if p.OpenVerify != nil {
|
||||
cfg.OpenVerify = *p.OpenVerify
|
||||
}
|
||||
if cfg.PwdMinLen <= 0 {
|
||||
cfg.PwdMinLen = 8
|
||||
}
|
||||
if cfg.SessionTTL <= 0 {
|
||||
cfg.SessionTTL = authsvc.DefaultSessionTTL
|
||||
}
|
||||
if cfg.MaxSession <= 0 {
|
||||
cfg.MaxSession = authsvc.DefaultMaxSession
|
||||
}
|
||||
if cfg.KickStrategy != models.KickStrategyReject {
|
||||
cfg.KickStrategy = models.KickStrategyKickOld
|
||||
}
|
||||
if ip != "" {
|
||||
cfg.IPWhitelist = &ip
|
||||
}
|
||||
if v := strings.TrimSpace(p.AllowThird); v != "" {
|
||||
cfg.AllowThird = &v
|
||||
}
|
||||
|
||||
exist := models.Orm.QueryTable(new(models.AuthTenantAuthConfig)).Filter("tid", p.Tid).Exist()
|
||||
if exist {
|
||||
fields := []string{"verify_type", "open_verify", "pwd_min_len", "pwd_complexity",
|
||||
"session_ttl", "max_session", "kick_strategy", "mfa_required"}
|
||||
if cfg.IPWhitelist != nil {
|
||||
fields = append(fields, "ip_whitelist")
|
||||
}
|
||||
if cfg.AllowThird != nil {
|
||||
fields = append(fields, "allow_third")
|
||||
}
|
||||
if _, err := models.Orm.Update(&cfg, fields...); err != nil {
|
||||
c.serveJSON(map[string]interface{}{"code": 500, "msg": "保存失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if _, err := models.Orm.Insert(&cfg); err != nil {
|
||||
c.serveJSON(map[string]interface{}{"code": 500, "msg": "保存失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
}
|
||||
c.serveJSON(map[string]interface{}{"code": 200, "msg": "success"})
|
||||
}
|
||||
|
||||
// Reset 恢复默认值(删除自定义配置)
|
||||
// DELETE /platform/authConfig/reset/:tid
|
||||
func (c *PlatformAuthConfigController) Reset() {
|
||||
tid, err := strconv.ParseUint(c.Ctx.Input.Param(":tid"), 10, 64)
|
||||
if err != nil || tid == 0 {
|
||||
c.serveJSON(map[string]interface{}{"code": 400, "msg": "无效 tid"})
|
||||
return
|
||||
}
|
||||
if _, err := models.Orm.QueryTable(new(models.AuthTenantAuthConfig)).
|
||||
Filter("tid", tid).Delete(); err != nil {
|
||||
c.serveJSON(map[string]interface{}{"code": 500, "msg": "重置失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
c.serveJSON(map[string]interface{}{"code": 200, "msg": "已恢复默认"})
|
||||
}
|
||||
|
||||
func defaultStrAuth2(v, def string) string {
|
||||
if strings.TrimSpace(v) == "" {
|
||||
return def
|
||||
}
|
||||
return strings.TrimSpace(v)
|
||||
}
|
||||
Reference in New Issue
Block a user