Commit 6b5aa92c authored by 李科's avatar 李科

Merge remote-tracking branch 'origin/dev' into dev

parents 106dd7f4 3cb81b59
package entity
type SystemPreferenceConfig struct {
Id int64 `json:"id" xorm:"pk autoincr" vd:"$>0;msg:'请输入配置id'"` //id
// 授权配置
SystemVersion string `json:"system_version"` //系统版本号
SystemUser string `json:"system_user" vd:"len($)>0;msg:'请输入使用用户'"` //系统User
License string `json:"license" vd:"len($)>0;msg:'请输入license'"` //系统license
LicenseInformDay int `json:"license_inform_day"` //license剩余有效期提醒
LicenseDeadDate string `json:"license_dead_date"` //license截至有效期
// 登录页配置
Logo string `json:"logo"` //logo
BgImage string `json:"bg_image"` //背景图
BottomTitle string `json:"bottom_title"` //底部所有权内容
Icp string `json:"icp"` //ICP备案
IcpUrl string `json:"icp_url"` //ICP备案跳转链接
Police string `json:"police"` //公安网备案
PoliceUrl string `json:"police_url"` //公安网跳转链接
LegalNotice string `json:"legal_notice"` //法律声明
PrivacyPolicy string `json:"privacy_policy"` //隐私政策
// 安全配置
MinPwdLevel int `json:"min_pwd_level" vd:"$>0;msg:'请选择最低密码强度'"` //最低密码强度1弱2中3强
ForceUpdateState int `json:"force_update_state"` //是否强制修改0否1是
PwdValidity int `json:"pwd_validity" vd:"$ >= 0;msg:'请输入密码有效期'"` //密码有效期
SessionValidity int `json:"session_validity" vd:"$ >= 10 && $ <= 30;msg:'会话有效期范围在(10~30分钟),请重新输入'"` //会话有效期
AccessRuleState int `json:"access_rule_state" vd:"$== 0 || $==1;msg:'请选择系统访问规则模式'"` //访问规则模式0关闭1开启
// 登录配置
LoginConfigState int `json:"login_config_state" vd:"$== 0 || $==1;msg:'请选择是否启用登录配置'"` //是否启用登录配置0否1是
LoginLimitTime int `json:"login_limit_time"` //登录受限时间
LoginPwdError int `json:"login_pwd_error"` //密码错误次数
LoginLockTime int `json:"login_lock_time"` //自动锁定时间
}
type LicenseInfo struct {
License string `json:"license" vd:"len($)>0;msg:'请输入license'"`
}
......@@ -53,3 +53,40 @@ type SystemUserListRes struct {
CreatedTime jsontime.Time `json:"created_time" ` // 创建时间
SystemId string `json:"system_id"` // 系统账号id
}
type CheckLicense struct {
SystemOptionsId int64 `json:"systemOptionsId"`
SystemVersion string `json:"systemVersion"`
SystemUser string `json:"systemUser"`
License string `json:"license"`
DeadDate string `json:"deadDate"`
CanUpdLicense int8 `json:"canUpdLicense"`
IsExpired int8 `json:"isExpired"`
}
type LicenseInformAccess struct {
CanUpdLicense int8 `json:"canUpdLicense"`
}
// 获取具有审批权限的角色
type ApprovalAuthorityRole struct {
Id int64 `json:"id"`
RoleId string `json:"role_id"` // 角色id(uuid)
RoleName string `json:"role_name"` // 角色名称
}
// 获取具有审批权限的组织
type ApprovalAuthorityOrg struct {
Id int64 `json:"id"`
OrganizationId string `json:"organization_id"` // 组织id(uuid)
OrganizationName string `json:"organization_name"` // 组织名称
}
// 获取具有审批权限的用户
type ApprovalAuthorityUser struct {
Id int64 `json:"id"`
SystemId string `json:"system_id" xorm:"system_id"` // 系统账号id
RoleId string `json:"role_id"` // 角色id(uuid)
DataPurview int `json:"data_purview"` // 数据权限:1-仅自己,2-本组织所有,3-全平台所有
OrganizationId string `json:"organization_id" xorm:"organization_id"` // 所属组织
}
......@@ -17,6 +17,11 @@ import (
"go.uber.org/zap"
)
const (
RULEKEY = "so-lock-rule"
LOCKKEY = "so-lock"
)
type Redis struct {
Conn *redis.Client
Prefix string
......@@ -97,3 +102,22 @@ func (r Redis) Expire(key string, expiration time.Duration) (bool, error) {
key = fmt.Sprintf("%s-%s", strings.ToUpper(r.Prefix), strings.ToUpper(key))
return r.Conn.Expire(strings.ToUpper(key), expiration).Result()
}
func (r Redis) Exist(key string) (int64, error) {
key = fmt.Sprintf("%s-%s", strings.ToUpper(r.Prefix), strings.ToUpper(key))
return r.Conn.Exists(strings.ToUpper(key)).Result()
}
func (r Redis) Keys(pattern string) ([]string, error) {
pattern = fmt.Sprintf("%s-%s", strings.ToUpper(r.Prefix), strings.ToUpper(pattern))
return r.Conn.Keys(strings.ToUpper(pattern)).Result()
}
func (r Redis) DelList(keys []string) error {
fmt.Println("删除key为:", keys)
for k, v := range keys {
keys[k] = strings.ToUpper(fmt.Sprintf("%s-%s", strings.ToUpper(r.Prefix), strings.ToUpper(v)))
}
bmd := r.Conn.Del(keys...)
return bmd.Err()
}
......@@ -31,7 +31,8 @@ type Config struct {
MinioSecretKey string
MinioBucket string
//TempDirPrefix string
PrometheusHost string
PrometheusHost string
AccessRuleModeKey string
}
const (
......
package controller
import (
"errors"
vd "github.com/bytedance/go-tagexpr/validator"
"github.com/gin-gonic/gin"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/service"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
)
// 获取系统首选项信息
func GetSystemOptions(c *gin.Context) {
svc := service.SystemOptionsSvc{}
if systemOptions, err := svc.GetSystemOptions(); err != nil {
SendJsonResponse(c, err, nil)
} else {
SendJsonResponse(c, nil, systemOptions)
}
}
// 设置授权信息
func SetLicenseOptions(c *gin.Context) {
var licenseOpts entity.SystemPreferenceConfig
if err := c.ShouldBindJSON(&licenseOpts); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
return
}
if err := util.ValidateSimple(licenseOpts, "Id"); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
return
}
svc := service.SystemOptionsSvc{}
if err := svc.SetLicenseOptions(licenseOpts); err != nil {
SendJsonResponse(c, err, nil)
} else {
SendJsonResponse(c, resp.OK, nil)
}
}
// 设置登陆页信息
func SetLoginPageOptions(c *gin.Context) {
var licenseOpts entity.SystemPreferenceConfig
if err := c.ShouldBindJSON(&licenseOpts); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
return
}
if err := util.ValidateSimple(licenseOpts, "Id"); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
return
}
svc := service.SystemOptionsSvc{}
if err := svc.SetLoginPageOptions(licenseOpts); err != nil {
SendJsonResponse(c, err, nil)
} else {
SendJsonResponse(c, resp.OK, nil)
}
}
// 设置安全选项
func SetSafeOptions(c *gin.Context) {
var safeOpts entity.SystemPreferenceConfig
if err := c.ShouldBindJSON(&safeOpts); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
return
}
if err := util.ValidateSimple(safeOpts, "id", "force_update_state", "min_pwd_level", "session_validity", "pwd_validity", "access_rule_state"); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
return
}
svc := service.SystemOptionsSvc{}
if err := svc.SetSafeOptions(safeOpts); err != nil {
SendJsonResponse(c, err, nil)
} else {
SendJsonResponse(c, resp.OK, nil)
}
}
// 设置登录配置
func SetLoginOptions(c *gin.Context) {
var loginOpts entity.SystemPreferenceConfig
if err := c.ShouldBindJSON(&loginOpts); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
return
}
if err := util.ValidateSimple(loginOpts, "id", "login_config_state"); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
return
}
if loginOpts.LoginConfigState == 1 {
if loginOpts.LoginLimitTime == 0 || loginOpts.LoginPwdError == 0 || loginOpts.LoginLockTime == 0 {
SendJsonResponse(c, resp.InvalidParam.WithError(errors.New("登录受限参数不能为空")), nil)
return
}
}
svc := service.SystemOptionsSvc{}
if err := svc.SetLoginOptions(loginOpts); err != nil {
SendJsonResponse(c, err, nil)
} else {
SendJsonResponse(c, resp.OK, nil)
}
}
// 校验license是否过期
func CheckLicense(c *gin.Context) {
value, _ := c.Get("user_info")
user := value.(entity.SystemUserInfo)
svc := service.SystemOptionsSvc{}
if data, err := svc.CheckLicense(user); err != nil {
SendJsonResponse(c, err, nil)
} else {
SendJsonResponse(c, nil, data)
}
}
// 一键还原受限
func ReStartConfig(c *gin.Context) {
svc := service.SystemOptionsSvc{}
if data, err := svc.DeleteLockUser(); err != nil {
SendJsonResponse(c, err, nil)
} else {
SendJsonResponse(c, resp.OK, data)
}
}
func GetLicenseInfo(c *gin.Context) {
license := entity.LicenseInfo{}
if err := c.ShouldBindJSON(&license); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), nil)
return
}
if err := vd.Validate(license); err != nil {
SendJsonResponse(c, resp.InvalidParam.WithError(err), "")
return
}
svc := service.SystemOptionsSvc{}
if data, err := svc.GetLicenseInfo(license); err != nil {
SendJsonResponse(c, err, nil)
} else {
SendJsonResponse(c, resp.OK, data)
}
}
......@@ -71,7 +71,8 @@ func initConfig() {
MinioSecretKey: util.SetEnvStr("MINIO_SECRET_KEY", "H76cPmwvH7vJ"), // Minio Secret
MinioBucket: util.SetEnvStr("MINIO_BUCKET", "so-operation"), // Minio Bucket
//TempDirPrefix: util.SetEnvStr("TEMP_DIR_PREFIX", "/app/xlsx/"), //模板目录前缀
PrometheusHost: util.SetEnvStr("PROMETHEUS_HOST", "https://prometheus.wodcloud.com"), // Prometheus Host
PrometheusHost: util.SetEnvStr("PROMETHEUS_HOST", "https://prometheus.wodcloud.com"), // Prometheus Host
AccessRuleModeKey: "accessRuleMode",
}
}
......
/**
* @Author chenghao
* @Date 2021/12/7
**/
package license
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
)
type License struct {
ClusterID string `json:"clusterId"`
ClusterNode int `json:"clusterNode"`
TaskName string `json:"taskName"`
CustomerName string `json:"customerName"`
Version string `json:"version"`
DeadDate string `json:"deadDate"` // 授权码到期时间
StartDate string `json:"startDate"` // 授权码开始时间
ValidDate int `json:"validDate"` //有效期:单位月
}
func GetAesString(key interface{}) (res string, err error) {
jsonStr, _ := json.Marshal(key)
return EnPwdCode(jsonStr)
}
/*
*
高级加密标准(Adevanced Encryption Standard ,AES)
16,24,32位字符串的话,分别对应AES-128,AES-192,AES-256 加密方法
key不能泄露
*/
var PwdKey = []byte("BIGDATE@*#VCLOUDCLICENSE")
// PKCS7 填充模式
func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
//Repeat()函数的功能是把切片[]byte{byte(padding)}复制padding个,然后合并成新的字节切片返回
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
// 填充的反向操作,删除填充字符串
func PKCS7UnPadding(origData []byte) ([]byte, error) {
//获取数据长度
length := len(origData)
if length == 0 {
return nil, errors.New("加密字符串错误!")
} else {
//获取填充字符串长度
unpadding := int(origData[length-1])
//截取切片,删除填充字节,并且返回明文
return origData[:(length - unpadding)], nil
}
}
// 实现加密
func AesEcrypt(origData []byte, key []byte) ([]byte, error) {
//创建加密算法实例
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
//获取块的大小
blockSize := block.BlockSize()
//对数据进行填充,让数据长度满足需求
origData = PKCS7Padding(origData, blockSize)
//采用AES加密方法中CBC加密模式
blocMode := cipher.NewCBCEncrypter(block, key[:blockSize])
crypted := make([]byte, len(origData))
//执行加密
blocMode.CryptBlocks(crypted, origData)
return crypted, nil
}
// 实现解密
func AesDeCrypt(cypted []byte, key []byte) ([]byte, error) {
//创建加密算法实例
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
//获取块大小
blockSize := block.BlockSize()
//创建加密客户端实例
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
origData := make([]byte, len(cypted))
//这个函数也可以用来解密
blockMode.CryptBlocks(origData, cypted)
//去除填充字符串
origData, err = PKCS7UnPadding(origData)
if err != nil {
return nil, err
}
return origData, err
}
// 加密base64
func EnPwdCode(pwd []byte) (string, error) {
result, err := AesEcrypt(pwd, PwdKey)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(result), err
}
// 解密
func DePwdCode(pwd string) ([]byte, error) {
//解密base64字符串
pwdByte, err := base64.StdEncoding.DecodeString(pwd)
if err != nil {
return nil, err
}
//执行AES解密
return AesDeCrypt(pwdByte, PwdKey)
}
// DecodeLicense 解密授权码
func DecodeLicense(secretKey string) (licenseInfo *License, err error) {
codeBytes, err := DePwdCode(secretKey)
if err != nil {
return nil, errors.New("授权码有误")
}
fmt.Println(string(codeBytes))
err = json.Unmarshal(codeBytes, &licenseInfo)
if err != nil {
return nil, errors.New("秘钥解析失败")
}
return
}
......@@ -45,6 +45,8 @@ func Load(r *gin.Engine, middleware ...gin.HandlerFunc) {
InitSystemMenuRouter(r)
// 初始化字典相关路由(r)
initDictRoute(r)
// 首选项配置相关路由
InitPreferenceConfigRouter(r)
// 初始化指标配置路由
InitMetricConfigRouter(r)
// 初始化预警规则配置路由
......
package router
import (
"fmt"
"github.com/gin-gonic/gin"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/controller"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header"
)
// 初始化配置管理路由
func InitPreferenceConfigRouter(e *gin.Engine) {
sys := e.Group(fmt.Sprintf("%s/sysOptions", conf.Options.Prefix), header.SetContext)
{
sys.GET("", controller.GetSystemOptions) // 获取系统首选项信息
sys.POST("licenseOpts", controller.SetLicenseOptions) // 设置授权信息
sys.POST("loginPageOpts", controller.SetLoginPageOptions) // 设置授权信息
sys.POST("safeOpts", controller.SetSafeOptions) // 设置安全选项
sys.POST("loginOpts", controller.SetLoginOptions) // 设置登录选项
sys.GET("checkLicense", controller.CheckLicense) // 校验license是否有效
sys.POST("reStartConfig", controller.ReStartConfig) // 一键还原受限
sys.POST("getLicenseInfo", controller.GetLicenseInfo) // 获取license信息
}
//rule := v5.Group("/accessRule", header.SetUserToContext)
//{
// rule.POST("addAccessRule", controller.AddAccessRule, log.AddLogMiddleware("访问规则管理", "/addAccessRule", constant.OpTypeIntMap[constant.Add])) // 新增访问规则
// rule.PUT("updateAccessRule", controller.UpdateAccessRule, log.AddLogMiddleware("访问规则管理", "/updateAccessRule", constant.OpTypeIntMap[constant.Edit])) // 编辑访问规则
// rule.DELETE("delAccessRule", controller.DelAccessRule, log.AddLogMiddleware("访问规则管理", "/delAccessRule", constant.OpTypeIntMap[constant.AllDelete])) // 删除访问规则
// rule.GET("listAccessRule", controller.ListAccessRule, log.AddLogMiddleware("访问规则管理", "/listAccessRule", constant.OpTypeIntMap[constant.Find])) // 查询访问规则列表
// rule.GET("listRuleUser", controller.ListRuleUser) // 查询用户详情列表
// rule.PUT("updateState", controller.UpdateState) // 修改规则状态
//}
}
......@@ -239,3 +239,73 @@ func (u *UserSvc) VerifyCaptcha(id, value string) (err error) {
}
return
}
// 用户锁定(此逻辑包含锁定规则以及锁定key)
func (u *UserSvc) UserLock(systemId, pwd string, config *entity.SystemPreferenceConfig) (err error) {
r, err := client.GetRedisClient()
if err != nil {
return resp.RedisConnectError.ErrorDetail(err)
}
startLockKey := fmt.Sprintf("%s-%s", client.RULEKEY, systemId)
lockSystemKey := fmt.Sprintf("%s-%s", client.LOCKKEY, systemId)
errorNum, err := r.Get(startLockKey)
if err != nil && err != redis.Nil {
conf.Logger.Error("获取密码插入次数失败", zap.Error(err))
return resp.RedisExecError.ErrorDetail(err)
} else if errorNum == "" {
if err := r.Set(startLockKey, 0, time.Duration(config.LoginLimitTime)*time.Hour); err != nil {
conf.Logger.Error("密码插入次数插入redis失败", zap.Error(err))
return resp.RedisExecError.ErrorDetail(err)
}
} else if cast.ToInt(errorNum) >= config.LoginPwdError {
// 错误上限, 自动锁定
has, err := r.Exist(lockSystemKey)
if err != nil {
return err
}
if has == 1 {
// 获取锁定规则过期时间
ttl, err := r.Ttl(startLockKey)
if err != nil {
conf.Logger.Error("获取锁定规则过期时间失败", zap.Error(err))
return resp.RedisExecError.ErrorDetail(err)
}
return resp.FAIL.ErrorDetail(fmt.Errorf("您已经%s次输错密码,账号已锁定,请在%s分后重试!", errorNum, ttl/60))
}
// 如果不存在过期时间key,则代表锁定时间已过期,删除锁定规则,重新进行新的锁定规则
err = r.Del(startLockKey)
if err != nil {
conf.Logger.Error("删除锁定规则文件失败", zap.Error(err))
return resp.RedisExecError.ErrorDetail(err)
}
}
// 判断是否输错密码
h := md5.New()
_, err = h.Write([]byte(strings.ToUpper(systemId + "-" + u.PassWord)))
if err != nil {
conf.Logger.Error("加密错误", zap.Error(err))
return err
}
upperMd5Pass := strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
if upperMd5Pass != pwd {
incr, err := r.Incr(startLockKey)
if err != nil {
conf.Logger.Error("写入错误次数失败", zap.Error(err))
return err
}
conf.Logger.Info("当前错误次数为", zap.Int64("incr", incr))
if int(incr) >= config.LoginPwdError {
err = r.Set(lockSystemKey, 0, time.Duration(config.LoginLockTime)*time.Minute)
if err != nil {
return err
}
}
return fmt.Errorf("请正确输入密码,连续%d次输错密码,账号将被锁定,还可重试%d次", incr, config.LoginPwdError-cast.ToInt(incr))
}
// 密码正确 删除 锁定文件
if err := r.Del(startLockKey); err != nil {
conf.Logger.Error("删除锁定文件错误", zap.Error(err))
return err
}
return nil
}
package service
import (
"errors"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/license"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/util"
"time"
"go.uber.org/zap"
)
type SystemOptionsSvc struct {
}
// 获取系统首选项
func (so *SystemOptionsSvc) GetSystemOptions() (config *entity.SystemPreferenceConfig, err error) {
db, err := client.GetDbClient()
if err != nil {
return nil, resp.DbConnectError.WithError(err)
}
var systemOpts entity.SystemPreferenceConfig
if _, err := db.Table("system_preference_config").Get(&systemOpts); err != nil {
conf.Logger.Error("获取系统首选项配置失败", zap.Error(err))
return nil, resp.DbSelectError.WithError(err)
}
return &systemOpts, nil
}
func (so *SystemOptionsSvc) SetLicenseOptions(licenseOpts entity.SystemPreferenceConfig) error {
if err := util.ValidateSimple(licenseOpts, "Id"); err != nil {
return resp.InvalidParam.WithError(err)
}
// 验证license信息
if licenseInfo, err := license.DecodeLicense(licenseOpts.License); err != nil {
conf.Logger.Error("license err", zap.Error(err))
return resp.InvalidParam.WithError(err)
} else {
conf.Logger.Info("license解析信息:", zap.Any("license", licenseInfo))
if licenseInfo.CustomerName != licenseOpts.SystemUser {
return resp.InvalidParam.WithError(err)
}
if len(licenseInfo.DeadDate) != 11 {
deadDate, _ := time.Parse("2006-01-02", licenseInfo.DeadDate)
// It is shorthand for t.Sub(time.Now()).
if time.Until(deadDate) <= 0 {
return resp.InvalidParam.WithError(errors.New("license 已过期"))
}
licenseOpts.LicenseDeadDate = licenseInfo.DeadDate
}
}
db, err := client.GetDbClient()
if err != nil {
return resp.DbConnectError.ErrorDetail(err)
}
if _, err := db.Table("system_preference_config").Where("id = ?", licenseOpts.Id).Cols("system_version", "system_user", "license", "license_dead_date", "license_inform_day").Update(licenseOpts); err != nil {
conf.Logger.Error("dberr", zap.Error(err))
return resp.DbUpdateError.ErrorDetail(err)
}
return nil
}
// 设置登录页
func (so *SystemOptionsSvc) SetLoginPageOptions(safeOpts entity.SystemPreferenceConfig) error {
// 获取数据库连接
db, err := client.GetDbClient()
if err != nil {
return resp.DbConnectError.ErrorDetail(err)
}
_, err = db.Table("system_preference_config").Where("id = ?", safeOpts.Id).
Cols("logo", "bg_image", "bottom_title", "icp", "icp_url", "police", "police_url", "legal_notice", "privacy_policy").
Update(safeOpts)
if err != nil {
conf.Logger.Error("设置登录页信息失败!", zap.Error(err))
return resp.DbUpdateError.ErrorDetail(err)
}
return nil
}
// 设置安全信息
func (so *SystemOptionsSvc) SetSafeOptions(safeOpts entity.SystemPreferenceConfig) error {
rCon, err := client.GetRedisClient()
if err != nil {
return resp.RedisConnectError.ErrorDetail(err)
}
// 获取数据库连接
db, err := client.GetDbClient()
if err != nil {
return resp.DbConnectError.ErrorDetail(err)
}
_, err = db.Table("system_preference_config").Where("id = ?", safeOpts.Id).
Cols("min_pwd_level", "force_update_state", "pwd_validity", "session_validity", "access_rule_state").
Update(safeOpts)
if err != nil {
conf.Logger.Error("设置安全信息失败!", zap.Error(err))
return resp.DbUpdateError.ErrorDetail(err)
}
go func() {
rCon.Del(conf.Options.AccessRuleModeKey)
}()
return nil
}
// 设置登录配置
func (so *SystemOptionsSvc) SetLoginOptions(loginOpts entity.SystemPreferenceConfig) error {
// 获取数据库连接
db, err := client.GetDbClient()
if err != nil {
return resp.DbConnectError.ErrorDetail(err)
}
_, err = db.Table("system_preference_config").
Cols("login_config_state", "login_limit_time", "login_pwd_error", "login_lock_time").
Where("id = ?", loginOpts.Id).Update(loginOpts)
if err != nil {
conf.Logger.Error("更新登录配置信息失败", zap.Error(err))
return resp.DbUpdateError.ErrorDetail(err)
}
// 若有账号在锁定当中,管理员将该配置设置为失效,则所有锁定的账号解锁
go func() {
if loginOpts.LoginConfigState == 0 {
so.DeleteLockUser()
}
}()
return nil
}
// 校验License是否过期
func (so *SystemOptionsSvc) CheckLicense(user entity.SystemUserInfo) (*response.CheckLicense, error) {
systemOptions, e := so.GetSystemOptions()
if e != nil {
return nil, e
}
var checkLicense = response.CheckLicense{
SystemOptionsId: systemOptions.Id,
SystemVersion: systemOptions.SystemVersion,
SystemUser: systemOptions.SystemUser,
License: systemOptions.License,
CanUpdLicense: 2,
IsExpired: 3,
DeadDate: systemOptions.LicenseDeadDate,
}
//if user.SystemId == util.AdminSystemUser {
// checkLicense.CanUpdLicense = 1
//}
if len(checkLicense.DeadDate) == 10 {
deadDate, _ := time.Parse("2006-01-02", checkLicense.DeadDate)
// It is shorthand for t.Sub(time.Now()).
leftDays := time.Until(deadDate).Hours() / 24
if leftDays <= 0 {
checkLicense.IsExpired = 1
} else if int(leftDays) <= systemOptions.LicenseInformDay {
checkLicense.IsExpired = 2
}
}
return &checkLicense, nil
}
// 所有锁定的账号解锁
func (so *SystemOptionsSvc) DeleteLockUser() (data interface{}, err error) {
rCon, err := client.GetRedisClient()
if err != nil {
return nil, resp.RedisConnectError.ErrorDetail(err)
}
ruleKeys, err := rCon.Keys(client.RULEKEY)
if err != nil {
conf.Logger.Error("查询锁定规则key序列失败")
return nil, resp.RedisExecError.ErrorDetail(err)
}
lockKeys, err := rCon.Keys(client.LOCKKEY)
if err != nil {
conf.Logger.Error("查询锁定key序列失败")
return nil, resp.RedisExecError.ErrorDetail(err)
}
lockKeys = append(lockKeys, ruleKeys...)
if len(lockKeys) == 0 {
return "无账号锁定", nil
}
err = rCon.DelList(lockKeys)
if err != nil {
conf.Logger.Error("批量删除锁定key失败")
return "", resp.RedisExecError.ErrorDetail(err)
}
return "", nil
}
func (so *SystemOptionsSvc) GetLicenseInfo(str entity.LicenseInfo) (data interface{}, err error) {
return license.DecodeLicense(str.License)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment