Merge remote-tracking branch 'origin/main' into multi-tenant

This commit is contained in:
TsMask
2025-01-11 12:00:19 +08:00
141 changed files with 1560 additions and 12496 deletions

535
lib/config/config.go Normal file
View File

@@ -0,0 +1,535 @@
package config
import (
"bufio"
"fmt"
"os"
"reflect"
"strings"
"be.ems/lib/global"
"be.ems/lib/log"
"gopkg.in/yaml.v3"
)
// Yaml struct of config
type YamlConfig struct {
Logger struct {
File string `yaml:"file"`
Level string `yaml:"level"`
Duration int `yaml:"duration"`
Count int `yaml:"count"`
} `yaml:"logger"`
Pprof struct {
Enabled bool `yaml:"enabled"`
Addr string `yaml:"addr"`
} `yaml:"pprof"`
// Rest []struct {
// IPv4 string `yaml:"ipv4"`
// IPv6 string `yaml:"ipv6"`
// Port uint16 `yaml:"port"`
// Scheme string `yaml:"scheme"`
// ClientAuthType int `yaml:"clientAuthType"`
// CaFile string `yaml:"caFile"`
// CertFile string `yaml:"certFile"`
// KeyFile string `yaml:"keyFile"`
// } `yaml:"rest"`
Rest []RestParam
WebServer struct {
Enabled bool `yaml:"enabled"`
RootDir string `yaml:"rootDir"`
Listen []struct {
Addr string `yaml:"addr"`
Scheme string `yaml:"scheme"`
ClientAuthType int `yaml:"clientAuthType"`
CaFile string `yaml:"caFile"`
CertFile string `yaml:"certFile"`
KeyFile string `yaml:"keyFile"`
} `yaml:"listen"`
} `yaml:"webServer"`
Database DbConfig `yaml:"database"`
OMC struct {
UriPrefix string `yaml:"uriPrefix"`
NeType string `yaml:"neType"`
NeId string `yaml:"neId"`
RmUID string `yaml:"rmUID"`
NeName string `yaml:"neName"`
Province string `yaml:"province"`
Vendor string `yaml:"vendor"`
Dn string `yaml:"dn"`
Chk2Ne bool `yaml:"chk2ne"`
Capability uint32 `yaml:"capability"`
Sn string `yaml:"sn"`
ExpiryDate string `yaml:"expiryDate"`
CheckSign bool `yaml:"checksign"`
RootDir string `yaml:"rootDir"`
BinDir string `yaml:"binDir"`
Backup string `yaml:"backup"`
Upload string `yaml:"upload"`
FrontUpload string `yaml:"frontUpload"`
FrontTraceDir string `yaml:"frontTraceDir"`
Software string `yaml:"software"`
License string `yaml:"license"`
GtpUri string `yaml:"gtpUri"`
CheckContentType bool `yaml:"checkContentType"`
TestMode bool `yaml:"testMode"`
RBACMode bool `yaml:"rbacMode"`
RunDir string `yaml:"runDir"`
CmdTimeout int `yaml:"cmdTimeout"`
} `yaml:"omc"`
Alarm AlarmConfig `yaml:"alarm"`
MML MMLParam `yaml:"mml"`
NE struct {
Addr string `yaml:"addr"`
Port uint16 `yaml:"port"`
User string `yaml:"user"`
EtcDir string `yaml:"etcdir"`
BinDir string `yaml:"bindir"`
OmcDir string `yaml:"omcdir"`
ScpDir string `yaml:"scpdir"`
LicenseDir string `yaml:"licensedir"`
EtcListIMS string `yaml:"etcListIMS"`
EtcListDefault string `yaml:"etcListDefault"`
DpkgOverwrite bool `yaml:"dpkgOverwrite"`
DpkgTimeout int `yaml:"dpkgTimeout"`
} `yaml:"ne"`
Auth struct {
Crypt string `yaml:"crypt"`
Token bool `yaml:"token"`
Expires uint32 `yaml:"expires"`
Session string `yaml:"session"`
PublicKey string `yaml:"publicKey"`
PrivateKey string `yaml:"privateKey"`
} `yaml:"auth"`
Params struct {
RmUIDMaxNum int `yaml:"rmuidmaxnum"`
AlarmIDMaxNum int `yaml:"alarmidmaxnum"`
PmIDMaxNum int `yaml:"pmidmaxnum"`
SubIDMaxNum int `yaml:"subidmaxnum"`
UriMaxLen int `yaml:"urimaxlen"`
RmUIDRegexp string `yaml:"rmuidregexp"`
} `yaml:"params"`
TestConfig struct {
Enabled bool `yaml:"enabled"`
File string `yaml:"file"`
} `yaml:"testConfig"`
}
type RestParam struct {
IPv4 string `yaml:"ipv4"`
IPv6 string `yaml:"ipv6"`
Port uint16 `yaml:"port"`
Scheme string `yaml:"scheme,omitempty" default:"http"`
ClientAuthType int `yaml:"clientAuthType"`
CaFile string `yaml:"caFile"`
CertFile string `yaml:"certFile"`
KeyFile string `yaml:"keyFile"`
}
type DbConfig struct {
Type string `yaml:"type"`
User string `yaml:"user"`
Password string `yaml:"password"`
Host string `yaml:"host"`
Port string `yaml:"port"`
Name string `yaml:"name"`
ConnParam string `yaml:"connParam,omitempty"`
Backup string `yaml:"backup"`
}
type AlarmConfig struct {
SplitEventAlarm bool `yaml:"splitEventAlarm"`
//ForwardAlarm bool `yaml:"forwardAlarm"`
EmailForward struct {
Enable bool `yaml:"enable" json:"enable"`
EmailList string `yaml:"emailList" json:"emailList"`
SMTP string `yaml:"smtp" json:"smtp"`
Port uint16 `yaml:"port" json:"port"`
User string `yaml:"user" json:"user"`
Password string `yaml:"password" json:"password"`
TLSSkipVerify bool `yaml:"tlsSkipVerify" json:"tlsSkipVerify"`
} `yaml:"alarmEmailForward"`
SMSCForward struct {
Enable bool `yaml:"enable" json:"enable"`
MobileList string `yaml:"mobileList" json:"mobileList"`
SMSCAddr string `yaml:"smscAddr" json:"smscAddr"`
SystemID string `yaml:"systemID" json:"systemID"`
Password string `yaml:"password" json:"password"`
SystemType string `yaml:"systemType" json:"systemType"`
DataCoding byte `yaml:"dataCoding" json:"dataCoding"`
ServiceNumber string `yaml:"serviceNumber" json:"serviceNumber"`
} `yaml:"alarmSMSForward"`
SMS struct {
ApiURL string `yaml:"apiURL"`
AccessKeyID string `yaml:"AccessKeyID"`
AccessKeySecret string `yaml:"accessKeySecret"`
SignName string `yaml:"signName"`
TemplateCode string `yaml:"templateCode"`
} `yaml:"smsForward"`
SMProxy string `yaml:"smProxy"`
}
type MMLParam struct {
Sleep int64 `yaml:"sleep"`
DeadLine int64 `yaml:"deadLine"`
SizeRow int16 `yaml:"sizeRow"`
SizeCol int16 `yaml:"sizeCol"`
BufferSize int `yaml:"bufferSize"`
MmlHome string `yaml:"mmlHome"`
}
type TestDatas struct {
UDM struct {
CapUsed uint32 `yaml:"capUsed"`
FeatureEnabled []string `yaml:"featureEnabled"`
} `yaml:"udm"`
AUSF struct {
CapUsed uint32 `yaml:"capUsed"`
FeatureEnabled []string `yaml:"featureEnabled"`
} `yaml:"ausf"`
AMF struct {
CapUsed uint32 `yaml:"capUsed"`
FeatureEnabled []string `yaml:"featureEnabled"`
} `yaml:"amf"`
SMF struct {
CapUsed uint32 `yaml:"capUsed"`
FeatureEnabled []string `yaml:"featureEnabled"`
} `yaml:"smf"`
UPF struct {
CapUsed uint32 `yaml:"capUsed"`
FeatureEnabled []string `yaml:"featureEnabled"`
} `yaml:"upf"`
}
type NeTestData struct {
CapUsed uint32 `yaml:"capUsed"`
FeatureEnabled []string `yaml:"featureEnabled"`
}
type TestDataMap struct {
NeTestDatas []map[string]NeTestData
}
var yamlConfig YamlConfig = NewYamlConfig()
type YamlConfigFile struct {
FilePath string `json:"filePath"`
ConfigLines YamlConfig `json:"configLines"`
OrignalLines []string `json:"orignalLines"`
}
var YamlConfigInfo YamlConfigFile = YamlConfigFile{
ConfigLines: NewYamlConfig(),
}
// set default value for yaml config
func NewYamlConfig() YamlConfig {
return YamlConfig{
Database: DbConfig{
Type: "mysql",
ConnParam: "charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=True&interpolateParams=True",
},
MML: MMLParam{
SizeRow: 200,
SizeCol: 120,
BufferSize: 65535,
},
Alarm: AlarmConfig{
SplitEventAlarm: true,
},
}
}
func ReadConfig(configFile string) {
YamlConfigInfo.FilePath = configFile
yamlFile, err := os.ReadFile(configFile)
if err != nil {
fmt.Println("Read yaml config file error:", err)
os.Exit(2)
}
// fmt.Println("yamlfile:", string(yamlFile))
err = yaml.Unmarshal(yamlFile, &YamlConfigInfo.ConfigLines)
if err != nil {
fmt.Println("Unmarshal error:", err)
os.Exit(3)
}
yamlConfig = YamlConfigInfo.ConfigLines
ReadOriginalConfig(configFile)
}
func ReadOriginalConfig(configFile string) {
// 读取原始YAML文件
inputFile, err := os.Open(configFile)
if err != nil {
fmt.Println("failed to open:", err)
os.Exit(3)
}
defer inputFile.Close()
scanner := bufio.NewScanner(inputFile)
for scanner.Scan() {
YamlConfigInfo.OrignalLines = append(YamlConfigInfo.OrignalLines, scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Println("failed to scanner:", err)
os.Exit(3)
}
}
func WriteOrignalConfig(configFile string, paramName string, paramData map[string]any) error {
lines := YamlConfigInfo.OrignalLines
for i, line := range lines {
if strings.Contains(line, paramName) {
for k, v := range paramData {
// find the first line nearby the paramName
for j := i + 1; j < len(lines); j++ {
if strings.Contains(lines[j], k+":") {
index := strings.Index(lines[j], k)
// Determine the type of v
switch v := v.(type) {
case string:
lines[j] = lines[j][:index] + fmt.Sprintf("%s: \"%s\"", k, v)
// case int:
// lines[j] = lines[j][:index] + fmt.Sprintf("%s: %d", k, v)
// case float64:
// lines[j] = lines[j][:index] + fmt.Sprintf("%s: %f", k, v)
case bool:
lines[j] = lines[j][:index] + fmt.Sprintf("%s: %t", k, v)
default:
lines[j] = lines[j][:index] + fmt.Sprintf("%s: %v", k, v)
}
break
}
}
}
break
}
}
// write back to yaml file
outputFile, err := os.Create(configFile)
if err != nil {
fmt.Println(err)
return err
}
defer outputFile.Close()
writer := bufio.NewWriter(outputFile)
for _, line := range YamlConfigInfo.OrignalLines {
writer.WriteString(line + "\n")
}
writer.Flush()
return nil
}
func WriteYamlConfig(newConfigData YamlConfig, configFile string) error {
// 将配置转换回YAML数据
newYamlData, err := yaml.Marshal(&newConfigData)
if err != nil {
log.Errorf("Failed to marshal YAML: %v", err)
return err
}
// 将新的YAML数据写入文件
err = os.WriteFile(configFile, newYamlData, 0644)
if err != nil {
log.Errorf("Failed to write YAML file: %v", err)
return err
}
return nil
}
var mapYaml map[string]interface{}
func ReadParamConfig(fileName string) *map[string]interface{} {
file, err := os.ReadFile(fileName)
if err != nil {
fmt.Println("Read yaml file error:", err)
}
mapYaml = make(map[string]interface{})
err = yaml.Unmarshal(file, &mapYaml)
if err != nil {
fmt.Printf("yaml.Unmarshal: %v when to struct", err)
}
// fmt.Println("mapYaml:", mapYaml)
return &mapYaml
}
func UpdateStructFromMap(s any, updates map[string]any) {
v := reflect.ValueOf(s).Elem()
t := v.Type()
for key, value := range updates {
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
if field.Tag.Get("json") == key {
structField := v.FieldByName(field.Name)
if structField.IsValid() && structField.CanSet() {
// Convert value to the appropriate type if necessary
convertedValue := reflect.ValueOf(value).Convert(structField.Type())
if structField.Type() == convertedValue.Type() {
structField.Set(convertedValue)
}
}
break
}
}
}
}
func GetYamlConfig() *YamlConfig {
return &YamlConfigInfo.ConfigLines
}
func GetAuthFromConfig() interface{} {
return yamlConfig.Auth
}
func GetExpiresFromConfig() uint32 {
return yamlConfig.Auth.Expires
}
func GetRmUIDFromConfig() string {
return yamlConfig.OMC.RmUID
}
func GetRmUIDRegexpFromConfig() string {
return yamlConfig.Params.RmUIDRegexp
}
func GetRmUIDMaxNumFromConfig() int {
return yamlConfig.Params.RmUIDMaxNum
}
func GetAlarmIDMaxNumFromConfig() int {
return yamlConfig.Params.AlarmIDMaxNum
}
func GetPmIDMaxNumFromConfig() int {
return yamlConfig.Params.PmIDMaxNum
}
func GetSubIDMaxNumFromConfig() int {
return yamlConfig.Params.SubIDMaxNum
}
func GetUriMaxLenFromConfig() int {
return yamlConfig.Params.UriMaxLen
}
func GetLogLevel() log.LogLevel {
var logLevel log.LogLevel
switch strings.ToLower(yamlConfig.Logger.Level) {
case "trace":
logLevel = log.LOG_TRACE
case "info":
logLevel = log.LOG_INFO
case "debug":
logLevel = log.LOG_DEBUG
case "warn":
logLevel = log.LOG_WARN
case "error":
logLevel = log.LOG_ERROR
case "fatal":
logLevel = log.LOG_FATAL
case "off":
logLevel = log.LOG_OFF
default:
logLevel = log.LOG_DEBUG
}
return logLevel
}
var (
DefaultUriPrefix string = "/api/rest"
UriPrefix string = "/omc/rest"
//TestDataUDM []map[string]interface{}
TDatas map[string]NeTestData
)
func ReadTestConfigYaml(pfile string) (ret error) {
file, err := os.ReadFile(pfile)
if err != nil {
return err
}
err = yaml.Unmarshal(file, &TDatas)
if err != nil {
fmt.Println("Failed to Unmarshal:", err)
return err
}
return nil
}
func GetDefaultUserAgent() string {
return "OMC-restagent/" + global.Version
}
func GetOMCHostUrl() string {
var omcip string = "127.0.0.1"
var rest RestParam = yamlConfig.Rest[0]
var port uint16 = rest.Port
if rest.IPv4 != "0.0.0.0" && rest.IPv4 != "" {
omcip = rest.IPv4
} else if rest.IPv6 != "::" && rest.IPv6 != "" {
omcip = "[" + rest.IPv6 + "]"
}
var scheme string = "http"
if rest.Scheme != "" {
scheme = rest.Scheme
}
return fmt.Sprintf("%s://%s:%d", scheme, omcip, port)
}
// const defaultConfigFile = "./etc/restconf.yaml"
// func init() {
// cfile := flag.String("c", defaultConfigFile, "config file")
// pv := flag.Bool("version", false, "print version")
// ph := flag.Bool("help", false, "print help")
// //global.BuildTime = "Wed May 31 18:24:04 CST 2023"
// //global.GoVer = "go version go1.15.7 linux/arm64"
// flag.Parse()
// if *pv {
// fmt.Printf("OMC restagent version: %s\n%s\n%s\n\n", global.Version, global.BuildTime, global.GoVer)
// os.Exit(0)
// }
// if *ph {
// flag.Usage()
// os.Exit(0)
// }
// // 使用viper读取配置
// conf.InitConfig(*cfile)
// ReadConfig(*cfile)
// if GetYamlConfig().OMC.UriPrefix != "" {
// UriPrefix = GetYamlConfig().OMC.UriPrefix
// }
// if GetYamlConfig().TestConfig.Enabled {
// ReadTestConfigYaml(GetYamlConfig().TestConfig.File)
// }
// }

111
lib/config/map.go Normal file
View File

@@ -0,0 +1,111 @@
package config
import (
"io/ioutil"
"log"
"gopkg.in/yaml.v3"
"be.ems/lib/global"
)
type Uri2Object struct {
Uri string `yaml:"uri"`
Object []Object `yaml:"object"`
}
type Object struct {
Name string `yaml:"name"`
Syntax string `yaml:"syntax"`
Oid string `yaml:"oid"`
}
var uri2Object []Uri2Object
func ReadMap(pfile string) (ret error) {
file, err := ioutil.ReadFile(pfile)
if err != nil {
log.Println(err)
return err
}
err = yaml.Unmarshal(file, &uri2Object)
if err != nil {
log.Println(err)
return err
}
/*
for _, v := range uri2Object {
log.Println(v)
}
*/
return nil
}
func GetOid(uri string, oids *[]string) *[]string {
for _, v := range uri2Object {
if uri == v.Uri {
for _, o := range v.Object {
*oids = append(*oids, o.Oid)
}
}
}
return oids
}
func GetOidByFileds(uri string, fields []string, oids *[]string) *[]string {
for _, v := range uri2Object {
if uri == v.Uri {
for _, o := range v.Object {
if global.IsContain(o.Name, fields) || len(fields) == 0 {
*oids = append(*oids, o.Oid)
}
}
}
}
return oids
}
type NameOid struct {
Name string
Oid string
}
type NameValue struct {
Name string
Value string
}
func GetDataOid(Uri string, nameOids *[]NameOid) *[]NameOid {
var nameOid NameOid
for _, v := range uri2Object {
if Uri == v.Uri {
for _, o := range v.Object {
nameOid.Name = o.Name
nameOid.Oid = o.Oid
*nameOids = append(*nameOids, nameOid)
}
}
}
return nameOids
}
func GetDataOidByFields(uri string, fields []string, nameOids *[]NameOid) *[]NameOid {
var nameOid NameOid
for _, v := range uri2Object {
if uri == v.Uri {
for _, o := range v.Object {
nameOid.Name = o.Name
nameOid.Oid = o.Oid
if len(fields) == 0 || global.IsContainP(nameOid.Name, &fields, len(fields)) {
*nameOids = append(*nameOids, nameOid)
}
}
}
}
return nameOids
}

View File

@@ -1,36 +0,0 @@
package conf
import (
"fmt"
"github.com/spf13/viper"
)
var v *viper.Viper
// 配置文件读取
func InitConfig(configFile string) {
v = viper.New()
// 设置配置文件路径
v.SetConfigFile(configFile)
// 读取配置文件
err := v.ReadInConfig()
if err != nil {
fmt.Printf("failure to read configuration file: %v \n", err)
return
}
}
// Get 获取配置信息
//
// Get("server.port")
func Get(key string) any {
return v.Get(key)
}
// AllSettings 全部配置信息
func AllSettings() map[string]interface{} {
return v.AllSettings()
}

View File

@@ -1,26 +0,0 @@
package vo
import (
"be.ems/lib/dborm"
)
// LoginUser 登录用户身份权限信息对象
type LoginUser struct {
// UserID 用户ID
UserID string `json:"userId"`
// UserName 用户名
UserName string `json:"userName"`
// LoginTime 登录时间时间戳
LoginTime int64 `json:"loginTime"`
// ExpireTime 过期时间时间戳
ExpireTime int64 `json:"expireTime"`
// Permissions 权限列表
Permissions []string `json:"permissions"`
// User 用户信息
User dborm.User `json:"user"`
}

View File

@@ -1,72 +0,0 @@
package result
const CODE_ERROR = 0
const MSG_ERROR = "error"
const CODE_SUCCESS = 1
const MSG_SUCCESS = "success"
// CodeMsg 响应结果
func CodeMsg(code int, msg string) map[string]any {
args := make(map[string]any)
args["code"] = code
args["msg"] = msg
return args
}
// 响应成功结果 map[string]any{}
func Ok(v map[string]any) map[string]any {
args := make(map[string]any)
args["code"] = CODE_SUCCESS
args["msg"] = MSG_SUCCESS
// v合并到args
for key, value := range v {
args[key] = value
}
return args
}
// 响应成功结果信息
func OkMsg(msg string) map[string]any {
args := make(map[string]any)
args["code"] = CODE_SUCCESS
args["msg"] = msg
return args
}
// 响应成功结果数据
func OkData(data any) map[string]any {
args := make(map[string]any)
args["code"] = CODE_SUCCESS
args["msg"] = MSG_SUCCESS
args["data"] = data
return args
}
// 响应失败结果 map[string]any{}
func Err(v map[string]any) map[string]any {
args := make(map[string]any)
args["code"] = CODE_ERROR
args["msg"] = MSG_ERROR
// v合并到args
for key, value := range v {
args[key] = value
}
return args
}
// 响应失败结果信息
func ErrMsg(msg string) map[string]any {
args := make(map[string]any)
args["code"] = CODE_ERROR
args["msg"] = msg
return args
}
// 响应失败结果数据
func ErrData(data any) map[string]any {
args := make(map[string]any)
args["code"] = CODE_ERROR
args["msg"] = MSG_ERROR
args["data"] = data
return args
}

View File

@@ -11,8 +11,6 @@ import (
"strings"
"be.ems/lib/log"
"be.ems/lib/oauth"
"be.ems/src/modules/system/model"
_ "github.com/go-sql-driver/mysql"
"xorm.io/xorm"
@@ -29,7 +27,7 @@ type Menu struct {
Title string `json:"title"`
Icon string `json:"icon"`
Href string `json:"href"`
ParentId int `json:"parent_id`
ParentId int `json:"parent_id"`
Remark int `json:"remark"`
}
@@ -149,7 +147,7 @@ func ConstructInsertSQL(tableName string, insertData interface{}) (string, []str
for c, v := range r.(map[string]interface{}) {
log.Tracef("c: %v v: %v", c, v)
if cl == "" {
cl = fmt.Sprintf("%s", c)
cl = fmt.Sprint(c)
} else {
cl = fmt.Sprintf("%s, %s", cl, c)
}
@@ -510,33 +508,6 @@ const (
MeasureTaskStatusDeleted = "Deleted"
)
type MTask struct {
Id int `json:"id" xorm:"pk 'id' autoincr"`
NeSet struct {
NEs []string `json:"nes"`
} `json:"neSet" xorm:"ne_set"`
KpiSet struct {
Code string `json:"Code"`
KPIs []string `json:"KPIs`
} `json:"kpiSet" xorm:"kpi_set"`
StartTime string `json:"startTime" xorm:"start_time"`
EndTime string `json:"endTime" xorm:"end_time"`
Periods []struct {
Start string `json:"start"`
End string `json:"end"`
} `json:"Periods" xorm:"periods`
Schedule struct {
Type string `json:"type"`
Days []int `json:"days"`
} `json:"schedule" xorm:"schedule"`
GranulOption string `json:"granulOption" xorm:"granul_option"`
Status string `json:"status" xorm:"status"`
CreateTime string `json:"createTime" xorm:"create_time"`
UpdateTime string `json:"updateTime" xorm:"update_time"`
DeleteTime string `json:"deleteTime xorm:"delete_time"`
}
type ScheduleJ struct {
Type string `json:"Type"`
Days []int `json:"Days"`
@@ -665,40 +636,6 @@ func XormUpdateTableByWhere(whereCondition string, tableName string, tbInfo inte
return affected, nil
}
type User struct {
Id int `json:"id" xorm:"pk 'id' autoincr"`
AccountId string `json:"accountId"`
Name string `json:"name" xorm:"name"`
Sn string `json:"sn"`
Gender string `json:"gender"`
Description string `json:"description"`
TelephoneNumber string `json:"telephoneNumber" xorm:"telephone_number"`
Mobile string `json:"mobile"`
Email string `json:"email" xorm:"email"`
StartTime string `json:"startTime" xorm:"start_time"`
EndTime string `json:"endTime" xorm:"end_time"`
IdCardNumber string `json:"idCardNumber"`
EmployeeNumber string `json:"employeeNumber"`
Organize string `json:"organize"`
EmployeeType string `json:"employeeType"`
SupporterCorpName string `json:"supporterCorpName"`
RealName string `json:"realName" xorm:"real_name"`
Password string `json:"password" xorm:"password"`
PasswordSha512 string `json:"passwordSha512"`
ChangePasswordFlag int `json:"changePasswordFlag"`
PasswordExpiration string `json:"passwordExpiration"`
Status string `json:"status"`
UserExpiration string `json:"userExpiration"`
GroupName string `json:"groupId" xorm:"group_name"`
Profile string `json:"profile" xorm:"profile"`
Phone string `json:"phone" xorm:"phone"`
CreateTime string `json:"createTime" xorm:"create_time"`
UpdateTime string `json:"updateTime" xorm:"update_time"`
// 角色对象组
Roles []model.SysRole `json:"roles" xorm:"-"`
}
// 记录密码登录错误次数
func pwdErrCountAdd(accountId, profileStr string, reset bool) int {
if profileStr == "" {
@@ -803,117 +740,6 @@ func pwdErrCountAdd(accountId, profileStr string, reset bool) int {
return count
}
func XormCheckLoginUser(name, password, cryptArgo string) (bool, *User, error) {
log.Info("XormCheckLoginUser processing... ")
user := new(User)
// has, err := xEngine.Table("user").Where("name='%s' and password=PASSWORD('%s')", name, password).Get(user)
switch cryptArgo {
case "mysql":
has, err := xEngine.SQL("select * from user where account_id=? and password=PASSWORD(?)", name, password).Exist()
if err != nil || has == false {
log.Error("Failed to check user from database:", err)
return false, nil, err
}
case "md5":
has, err := xEngine.
SQL("select * from user where account_id=? and password=MD5(?)", name, password).Exist()
if err != nil || has == false {
log.Error("Failed to check user from database:", err)
return false, nil, err
}
case "bcrypt":
has, err := xEngine.Table("user").Where("account_id=?", name).Get(user)
if err != nil || !has {
log.Error("Failed to get user from database:", err)
return false, nil, err
}
if oauth.BcryptCompare(user.Password, password) != nil {
err := errors.New("Incorrect user name or password")
log.Error(err)
// 记录错误
errCoutn := pwdErrCountAdd(user.AccountId, user.Profile, false)
if errCoutn > 3 {
// 登录失败次数过多请30分钟后重试
return false, nil, errors.New("Login failed too many times, please retry after 30 minutes")
}
return false, nil, err
}
// 重置错误次数
pwdErrCountAdd(user.AccountId, user.Profile, true)
default:
errMsg := "Incorrect crypt algoritmo"
log.Error("crypt:%s", errMsg)
return false, nil, errors.New(errMsg)
}
// enum('Active','Closed','Locked','Pending')
errMsg := ""
switch user.Status {
case "Closed":
errMsg = "Account disabled" // 账户已禁用
case "Locked":
errMsg = "Account locked" // 账户已锁定
case "Pending":
// errMsg = "账户已挂起"
_, err := xEngine.Exec("UPDATE user SET status = 'Active' WHERE account_id = ?", user.AccountId)
if err != nil {
return false, nil, err
}
}
if errMsg != "" {
log.Error("user Status:%s", errMsg)
return false, nil, errors.New(errMsg)
}
// 密码到期时间
if user.PasswordExpiration != "" {
arr := strings.Split(user.PasswordExpiration, " ")
if len(arr) > 0 {
t, err := time.Parse("2006-01-02", arr[0])
if err != nil {
return false, nil, err
}
if t.Before(time.Now()) {
errMsg := "Password expiration time" // 密码到期时间
// 读取配置信息
result, err := XormGetConfig("Security", "pwdStrong")
if err != nil {
return false, nil, err
}
data := make(map[string]any)
err = json.Unmarshal([]byte(result["value_json"].(string)), &data)
if err != nil {
log.Error("json Unmarshal:%s", errMsg)
return false, nil, err
}
errMsg = data["outTimeMsg"].(string)
log.Error("PasswordExpiration:%s", errMsg)
return false, nil, errors.New(errMsg)
}
}
}
// 用户到期时间
if user.UserExpiration != "" {
arr := strings.Split(user.UserExpiration, " ")
if len(arr) > 0 {
t, err := time.Parse("2006-01-02", arr[0])
if err != nil {
return false, nil, err
}
if t.Before(time.Now()) {
errMsg := "User account expiration" // 用户账户到期
log.Error("UserExpiration:%s", errMsg)
return false, nil, errors.New(errMsg)
}
}
}
return true, user, nil
}
func XormIsExistUser(accid string) (bool, error) {
log.Info("XormIsExistUser processing... ")
@@ -1000,22 +826,22 @@ func XormInsertSession(name, host, token string, expires uint32, sessionFlag str
if err != nil {
return affected, err
}
if exist == true {
affected, err = xSession.Table("session").Where("account_id = ? and host = ?", name, host).Update(session)
if exist {
affected, _ = xSession.Table("session").Where("account_id = ? and host = ?", name, host).Update(session)
} else {
affected, err = xSession.InsertOne(session)
affected, _ = xSession.InsertOne(session)
}
} else { // single session for a user
exist, err := xEngine.Table("session").Where("status = 'online' and account_id = ?", name).Exist()
if err != nil {
return affected, err
}
if exist == true {
if exist {
// todo...
err := errors.New("user is logged in")
return -1, err
} else {
affected, err = xSession.InsertOne(session)
affected, _ = xSession.InsertOne(session)
}
}
xSession.Commit()

View File

@@ -291,12 +291,6 @@ func init() {
Register("POST", dbrest.UriDbStop, dbrest.DbStop, nil)
Register("POST", dbrest.CustomUriDbStop, dbrest.DbStop, nil)
// 系统备份
Register("POST", dbrest.UriDbBackup, dbrest.DbBackup, nil)
Register("POST", dbrest.CustomUriDbBackup, dbrest.DbBackup, nil)
Register("POST", dbrest.UriConfBackup, dbrest.ConfBackup, nil)
Register("POST", dbrest.CustomUriConfBackup, dbrest.ConfBackup, nil)
// 日志表备份
Register("POST", lm.ExtBackupDataUri, lm.ExtDatabaseBackupData, nil)
Register("POST", lm.CustomExtBackupDataUri, lm.ExtDatabaseBackupData, nil)

View File

@@ -329,7 +329,7 @@ func uploadSizeLimit(buf *bytes.Buffer, part *multipart.Part, maxLimit int64, li
}
maxLimit -= n
if maxLimit < 0 {
return fmt.Errorf(limitError)
return fmt.Errorf("%s", limitError)
}
return nil
}

View File

@@ -16,11 +16,11 @@ import (
"strconv"
"strings"
"be.ems/lib/config"
"be.ems/lib/dborm"
"be.ems/lib/global"
"be.ems/lib/log"
"be.ems/lib/oauth"
"be.ems/restagent/config"
"github.com/gorilla/mux"
)
@@ -560,23 +560,10 @@ func CheckExtValidRequest(w http.ResponseWriter, r *http.Request) (string, error
return token, nil
}
func ResponseStatusOK200Login(w http.ResponseWriter, token string, user *dborm.User) {
func ResponseStatusOK200Login(w http.ResponseWriter, token string) {
var oAuthResponse SucceedOAuthResponse
oAuthResponse.AccessToken = token
oAuthResponse.Expires = strconv.Itoa((int)(config.GetExpiresFromConfig()))
oAuthResponse.ChangePasswordFlag = user.ChangePasswordFlag
oAuthResponse.GroupName = user.GroupName
ResponseWithJson(w, http.StatusOK, oAuthResponse)
}
func ResponseStatusOK200LoginWhitRP(w http.ResponseWriter, token string, user *dborm.User, roles, perms []string) {
var oAuthResponse SucceedOAuthResponse
oAuthResponse.AccessToken = token
oAuthResponse.Expires = strconv.Itoa((int)(config.GetExpiresFromConfig()))
oAuthResponse.ChangePasswordFlag = user.ChangePasswordFlag
oAuthResponse.GroupName = user.GroupName
oAuthResponse.Roles = roles
oAuthResponse.Perms = perms
ResponseWithJson(w, http.StatusOK, oAuthResponse)
}

View File

@@ -11,9 +11,9 @@ import (
"sync"
"time"
"be.ems/lib/config"
"be.ems/lib/log"
"be.ems/lib/oauth"
"be.ems/restagent/config"
)
// SessionMgr session manager