Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
so-operation-api
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
smart-operation
so-operation-api
Commits
6b5aa92c
Commit
6b5aa92c
authored
Jul 05, 2023
by
李科
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/dev' into dev
parents
106dd7f4
3cb81b59
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
684 additions
and
2 deletions
+684
-2
src/bean/entity/system_preference_config.go
src/bean/entity/system_preference_config.go
+37
-0
src/bean/vo/response/system_user.go
src/bean/vo/response/system_user.go
+37
-0
src/common/client/redis.go
src/common/client/redis.go
+24
-0
src/common/conf/options.go
src/common/conf/options.go
+2
-1
src/controller/system_preference.go
src/controller/system_preference.go
+143
-0
src/main.go
src/main.go
+2
-1
src/pkg/beagle/license/license.go
src/pkg/beagle/license/license.go
+137
-0
src/router/router.go
src/router/router.go
+2
-0
src/router/systempreferencerouter.go
src/router/systempreferencerouter.go
+35
-0
src/service/login.go
src/service/login.go
+70
-0
src/service/system_preference.go
src/service/system_preference.go
+195
-0
No files found.
src/bean/entity/system_preference_config.go
0 → 100644
View file @
6b5aa92c
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'"`
}
src/bean/vo/response/system_user.go
View file @
6b5aa92c
...
...
@@ -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"`
// 所属组织
}
src/common/client/redis.go
View file @
6b5aa92c
...
...
@@ -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
()
}
src/common/conf/options.go
View file @
6b5aa92c
...
...
@@ -31,7 +31,8 @@ type Config struct {
MinioSecretKey
string
MinioBucket
string
//TempDirPrefix string
PrometheusHost
string
PrometheusHost
string
AccessRuleModeKey
string
}
const
(
...
...
src/controller/system_preference.go
0 → 100644
View file @
6b5aa92c
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
)
}
}
src/main.go
View file @
6b5aa92c
...
...
@@ -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"
,
}
}
...
...
src/pkg/beagle/license/license.go
0 → 100644
View file @
6b5aa92c
/**
* @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
}
src/router/router.go
View file @
6b5aa92c
...
...
@@ -45,6 +45,8 @@ func Load(r *gin.Engine, middleware ...gin.HandlerFunc) {
InitSystemMenuRouter
(
r
)
// 初始化字典相关路由(r)
initDictRoute
(
r
)
// 首选项配置相关路由
InitPreferenceConfigRouter
(
r
)
// 初始化指标配置路由
InitMetricConfigRouter
(
r
)
// 初始化预警规则配置路由
...
...
src/router/systempreferencerouter.go
0 → 100644
View file @
6b5aa92c
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) // 修改规则状态
//}
}
src/service/login.go
View file @
6b5aa92c
...
...
@@ -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
}
src/service/system_preference.go
0 → 100644
View file @
6b5aa92c
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
)
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment