feat(imLoginFailureLog): 用户登录密码错误次数锁定与解锁能力(管理端)
- 安全策略登录限频由 JSON 文本改为结构化表单(次数/锁定分钟/窗口分钟),编辑校验同步扩展 - 失败日志新增解锁入口:/imLoginFailureLog/unlock 经 internal 通道调用 im-server 释放锁定 - 失败日志模型补充 accountHash 字段,解锁按钮按 risk_action=account_locked 展示 - 租户业务库初始化模板补充 im_login_lockouts 等表;新增解锁按钮菜单权限 SQL
This commit is contained in:
@@ -37,3 +37,6 @@ func (c *cImLoginFailureLog) BanUser(ctx context.Context, req *imloginfailurelog
|
||||
data, err := service.SysImLoginFailureLog().BanUser(ctx, &req.ImLoginFailureBanUserInp)
|
||||
return &imloginfailurelog.BanUserRes{ImUserCommandModel: data}, err
|
||||
}
|
||||
func (c *cImLoginFailureLog) Unlock(ctx context.Context, req *imloginfailurelog.UnlockReq) (*imloginfailurelog.UnlockRes, error) {
|
||||
return &imloginfailurelog.UnlockRes{}, service.SysImLoginFailureLog().Unlock(ctx, &req.ImLoginFailureUnlockInp)
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ func (c *cConfig) SecurityPolicy(ctx context.Context, req *api.SecurityPolicyReq
|
||||
}
|
||||
columns := dao.ImSecurityPolicy.Columns()
|
||||
record, err := imtenant.RegistryDB().Model(dao.ImSecurityPolicy.Table()).Safe().Ctx(ctx).
|
||||
Fields(columns.Id, columns.PolicyVersion, columns.GlobalFriendEnabled, "CAST("+columns.FriendDisabledPolicy+" AS CHAR) friend_disabled_policy", columns.MessageCurfewEnabled).
|
||||
Fields(columns.Id, columns.PolicyVersion, columns.GlobalFriendEnabled, columns.MessageCurfewEnabled, "CAST("+columns.LoginRateLimit+" AS CHAR) login_rate_limit", "CAST("+columns.FriendDisabledPolicy+" AS CHAR) friend_disabled_policy").
|
||||
Where(columns.TenantId, tenant.Id).Where(columns.PublishStatus, consts.ImSecurityPublishPublished).
|
||||
WhereNull(columns.DeletedAt).OrderDesc(columns.PolicyVersion).One()
|
||||
if err != nil {
|
||||
@@ -239,6 +239,22 @@ func (c *cConfig) SecurityPolicy(ctx context.Context, req *api.SecurityPolicyReq
|
||||
res.PolicyVersion = record[columns.PolicyVersion].Uint()
|
||||
res.GlobalFriendEnabled = record[columns.GlobalFriendEnabled].Int() == 1
|
||||
res.MessageCurfewEnabled = record[columns.MessageCurfewEnabled].Int() == 1
|
||||
if raw := strings.TrimSpace(record["login_rate_limit"].String()); raw != "" && raw != "null" {
|
||||
var limit struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
PasswordMaxAttempts int `json:"password_max_attempts"`
|
||||
LockSeconds int `json:"lock_seconds"`
|
||||
WindowSeconds int `json:"window_seconds"`
|
||||
}
|
||||
if json.Unmarshal([]byte(raw), &limit) == nil && limit.Enabled {
|
||||
res.LoginRateLimit = &api.SecurityLoginRateLimitRes{
|
||||
Enabled: true,
|
||||
PasswordMaxAttempts: limit.PasswordMaxAttempts,
|
||||
LockSeconds: limit.LockSeconds,
|
||||
WindowSeconds: limit.WindowSeconds,
|
||||
}
|
||||
}
|
||||
}
|
||||
if raw := strings.TrimSpace(record["friend_disabled_policy"].String()); raw != "" && raw != "null" {
|
||||
_ = json.Unmarshal([]byte(raw), &res.FriendDisabledPolicy)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user