283 lines
10 KiB
Go
283 lines
10 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"time"
|
|
|
|
"kra/internal/conf"
|
|
"kra/internal/service/dto"
|
|
|
|
"google.golang.org/protobuf/encoding/protojson"
|
|
"google.golang.org/protobuf/proto"
|
|
"google.golang.org/protobuf/types/known/durationpb"
|
|
)
|
|
|
|
func (s *SystemConfigService) PersistConfig(ctx context.Context) error {
|
|
return s.uc.PersistConfig(ctx)
|
|
}
|
|
|
|
func (s *SystemConfigService) PersistAdminConfig(ctx context.Context, value *conf.AdminBackend) error {
|
|
raw, err := protojson.MarshalOptions{UseProtoNames: true}.Marshal(value)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return s.uc.PersistAdminConfig(ctx, raw)
|
|
}
|
|
|
|
func (s *SystemConfigService) ReloadConfig(ctx context.Context) error { return s.uc.ReloadConfig(ctx) }
|
|
|
|
func (s *SystemConfigService) DiskMountPoints() []string {
|
|
config := s.runtime.Admin()
|
|
if config == nil {
|
|
return nil
|
|
}
|
|
points := make([]string, 0, len(config.DiskList))
|
|
for _, item := range config.DiskList {
|
|
if item != nil && item.MountPoint != "" {
|
|
points = append(points, item.MountPoint)
|
|
}
|
|
}
|
|
return points
|
|
}
|
|
|
|
func (s *SystemConfigService) SystemConfig() map[string]any {
|
|
admin := map[string]any{"routerPrefix": ""}
|
|
email := map[string]any{}
|
|
config := s.runtime.Admin()
|
|
if config == nil {
|
|
return map[string]any{"config": map[string]any{"admin": admin, "email": email, "data": map[string]any{}}}
|
|
}
|
|
admin["routerPrefix"] = config.RouterPrefix
|
|
if config.System != nil {
|
|
admin["system"] = map[string]any{"useRedis": config.System.UseRedis, "useMultipoint": config.System.UseMultipoint, "useStrictAuth": config.System.UseStrictAuth, "disableAutoMigrate": config.System.DisableAutoMigrate, "useMongo": config.System.UseMongo}
|
|
}
|
|
if config.Jwt != nil {
|
|
admin["jwt"] = map[string]any{"signingKey": "******", "expiresTime": config.Jwt.ExpiresTime.AsDuration().String(), "bufferTime": config.Jwt.BufferTime.AsDuration().String(), "issuer": config.Jwt.Issuer}
|
|
}
|
|
if config.Captcha != nil {
|
|
admin["captcha"] = map[string]any{"keyLong": config.Captcha.KeyLong, "imgWidth": config.Captcha.ImgWidth, "imgHeight": config.Captcha.ImgHeight, "storeExpiration": config.Captcha.StoreExpiration.AsDuration().String()}
|
|
}
|
|
if config.Local != nil {
|
|
admin["local"] = map[string]any{"storePath": config.Local.StorePath, "pathPrefix": config.Local.PathPrefix}
|
|
}
|
|
if config.Media != nil {
|
|
admin["media"] = map[string]any{"sessionTtl": config.Media.SessionTtl, "maxFileSize": config.Media.MaxFileSize}
|
|
}
|
|
if config.Email != nil {
|
|
email = map[string]any{"to": config.Email.To, "from": config.Email.From, "host": config.Email.Host, "secret": "******", "nickname": config.Email.Nickname, "port": config.Email.Port, "is-ssl": config.Email.IsSsl, "is-loginauth": config.Email.IsLoginAuth}
|
|
}
|
|
if config.Storage != nil {
|
|
storage := proto.Clone(config.Storage).(*conf.AdminBackend_Storage)
|
|
maskStorageSecrets(storage)
|
|
admin["storage"] = storage
|
|
}
|
|
if config.Zap != nil {
|
|
admin["zap"] = config.Zap
|
|
}
|
|
if config.Cors != nil {
|
|
admin["cors"] = config.Cors
|
|
}
|
|
if config.App != nil {
|
|
admin["app"] = config.App
|
|
}
|
|
data := s.runtime.Data()
|
|
if data != nil {
|
|
if data.Database != nil {
|
|
data.Database.Password = "******"
|
|
}
|
|
if data.Redis != nil {
|
|
data.Redis.Password = "******"
|
|
}
|
|
if data.Mongo != nil {
|
|
data.Mongo.Password = "******"
|
|
}
|
|
for _, database := range data.DatabaseList {
|
|
if database != nil {
|
|
database.Password = "******"
|
|
}
|
|
}
|
|
for _, redis := range data.RedisList {
|
|
if redis != nil {
|
|
redis.Password = "******"
|
|
}
|
|
}
|
|
}
|
|
dataMap := map[string]any{}
|
|
if raw, err := (protojson.MarshalOptions{UseProtoNames: true}).Marshal(data); err == nil {
|
|
_ = json.Unmarshal(raw, &dataMap)
|
|
}
|
|
return map[string]any{"config": map[string]any{"admin": admin, "email": email, "data": dataMap}}
|
|
}
|
|
|
|
func (s *SystemConfigService) SaveSystemConfig(ctx context.Context, req *dto.SetSystemConfigRequest) error {
|
|
config := s.runtime.Admin()
|
|
if config == nil {
|
|
return nil
|
|
}
|
|
next := proto.Clone(config).(*conf.AdminBackend)
|
|
data := s.runtime.Data()
|
|
next.RouterPrefix = req.Config.Admin.RouterPrefix
|
|
if next.System == nil {
|
|
next.System = &conf.AdminBackend_System{}
|
|
}
|
|
next.System.UseRedis = req.Config.Admin.System.UseRedis
|
|
next.System.UseMultipoint = req.Config.Admin.System.UseMultipoint
|
|
next.System.UseStrictAuth = req.Config.Admin.System.UseStrictAuth
|
|
next.System.DisableAutoMigrate = req.Config.Admin.System.DisableAutoMigrate
|
|
next.System.UseMongo = req.Config.Admin.System.UseMongo
|
|
if req.Config.Admin.Zap != nil {
|
|
next.Zap = req.Config.Admin.Zap
|
|
}
|
|
if req.Config.Admin.Cors != nil {
|
|
next.Cors = req.Config.Admin.Cors
|
|
}
|
|
if req.Config.Admin.App != nil {
|
|
next.App = req.Config.Admin.App
|
|
}
|
|
if next.Jwt != nil {
|
|
if req.Config.Admin.JWT.SigningKey != "" && req.Config.Admin.JWT.SigningKey != "******" {
|
|
next.Jwt.SigningKey = req.Config.Admin.JWT.SigningKey
|
|
}
|
|
if req.Config.Admin.JWT.Issuer != "" {
|
|
next.Jwt.Issuer = req.Config.Admin.JWT.Issuer
|
|
}
|
|
if value, err := time.ParseDuration(req.Config.Admin.JWT.ExpiresTime); err == nil && value > 0 {
|
|
next.Jwt.ExpiresTime = durationpb.New(value)
|
|
}
|
|
if value, err := time.ParseDuration(req.Config.Admin.JWT.BufferTime); err == nil && value >= 0 {
|
|
next.Jwt.BufferTime = durationpb.New(value)
|
|
}
|
|
}
|
|
if next.Captcha != nil {
|
|
if req.Config.Admin.Captcha.KeyLong > 0 {
|
|
next.Captcha.KeyLong = req.Config.Admin.Captcha.KeyLong
|
|
}
|
|
if req.Config.Admin.Captcha.ImgWidth > 0 {
|
|
next.Captcha.ImgWidth = req.Config.Admin.Captcha.ImgWidth
|
|
}
|
|
if req.Config.Admin.Captcha.ImgHeight > 0 {
|
|
next.Captcha.ImgHeight = req.Config.Admin.Captcha.ImgHeight
|
|
}
|
|
if value, err := time.ParseDuration(req.Config.Admin.Captcha.StoreExpiration); err == nil && value > 0 {
|
|
next.Captcha.StoreExpiration = durationpb.New(value)
|
|
}
|
|
}
|
|
if next.Local != nil {
|
|
if req.Config.Admin.Local.StorePath != "" {
|
|
next.Local.StorePath = req.Config.Admin.Local.StorePath
|
|
}
|
|
if req.Config.Admin.Local.PathPrefix != "" {
|
|
next.Local.PathPrefix = req.Config.Admin.Local.PathPrefix
|
|
}
|
|
}
|
|
if next.Media != nil {
|
|
if req.Config.Admin.Media.SessionTTL > 0 {
|
|
next.Media.SessionTtl = req.Config.Admin.Media.SessionTTL
|
|
}
|
|
next.Media.MaxFileSize = req.Config.Admin.Media.MaxFileSize
|
|
}
|
|
if req.Config.Admin.Storage != nil {
|
|
preserveStorageSecrets(req.Config.Admin.Storage, next.Storage)
|
|
next.Storage = req.Config.Admin.Storage
|
|
}
|
|
if next.Email != nil && req.Config.Email != nil {
|
|
next.Email.To, next.Email.From, next.Email.Host = req.Config.Email.To, req.Config.Email.From, req.Config.Email.Host
|
|
next.Email.Nickname, next.Email.Port = req.Config.Email.Nickname, req.Config.Email.Port
|
|
next.Email.IsSsl, next.Email.IsLoginAuth = req.Config.Email.IsSSL, req.Config.Email.IsLoginAuth
|
|
if req.Config.Email.Secret != "" && req.Config.Email.Secret != "******" {
|
|
next.Email.Secret = req.Config.Email.Secret
|
|
}
|
|
}
|
|
if req.Config.Data != nil {
|
|
if data == nil {
|
|
data = &conf.Data{}
|
|
}
|
|
if value := req.Config.Data.Database; value != nil {
|
|
password := value.Password
|
|
if data.Database != nil && (password == "" || password == "******") {
|
|
password = data.Database.Password
|
|
}
|
|
data.Database = &conf.Data_Database{Driver: value.Driver, Source: value.Source, Host: value.Host, Port: value.Port, User: value.User, Password: password, Name: value.Name, Config: value.Config, Path: value.Path, Prefix: value.Prefix, Engine: value.Engine, LogMode: value.LogMode, MaxIdleConns: value.MaxIdleConns, MaxOpenConns: value.MaxOpenConns, ConnMaxLifetime: value.ConnMaxLifetime, Singular: value.Singular}
|
|
}
|
|
if value := req.Config.Data.Redis; value != nil {
|
|
password := value.Password
|
|
if data.Redis != nil && (password == "" || password == "******") {
|
|
password = data.Redis.Password
|
|
}
|
|
redis := &conf.Data_Redis{Network: value.Network, Addr: value.Addr, Name: value.Name, Password: password, Db: value.DB, UseCluster: value.UseCluster, ClusterAddrs: value.ClusterAddrs}
|
|
if duration, parseErr := time.ParseDuration(value.ReadTimeout); parseErr == nil && duration >= 0 {
|
|
redis.ReadTimeout = durationpb.New(duration)
|
|
}
|
|
if duration, parseErr := time.ParseDuration(value.WriteTimeout); parseErr == nil && duration >= 0 {
|
|
redis.WriteTimeout = durationpb.New(duration)
|
|
}
|
|
data.Redis = redis
|
|
}
|
|
if req.Config.Data.DatabaseList != nil {
|
|
for i, item := range req.Config.Data.DatabaseList {
|
|
if item != nil && (item.Password == "" || item.Password == "******") && i < len(data.DatabaseList) && data.DatabaseList[i] != nil {
|
|
item.Password = data.DatabaseList[i].Password
|
|
}
|
|
}
|
|
data.DatabaseList = req.Config.Data.DatabaseList
|
|
}
|
|
if req.Config.Data.RedisList != nil {
|
|
for i, item := range req.Config.Data.RedisList {
|
|
if item != nil && (item.Password == "" || item.Password == "******") && i < len(data.RedisList) && data.RedisList[i] != nil {
|
|
item.Password = data.RedisList[i].Password
|
|
}
|
|
}
|
|
data.RedisList = req.Config.Data.RedisList
|
|
}
|
|
if req.Config.Data.Mongo != nil {
|
|
if data.Mongo != nil && (req.Config.Data.Mongo.Password == "" || req.Config.Data.Mongo.Password == "******") {
|
|
req.Config.Data.Mongo.Password = data.Mongo.Password
|
|
}
|
|
data.Mongo = req.Config.Data.Mongo
|
|
}
|
|
}
|
|
dataRaw, err := protojson.MarshalOptions{UseProtoNames: true}.Marshal(data)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
adminRaw, err := protojson.MarshalOptions{UseProtoNames: true}.Marshal(next)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return s.uc.PersistRuntimeConfig(ctx, dataRaw, adminRaw)
|
|
}
|
|
|
|
func objectStores(storage *conf.AdminBackend_Storage) []*conf.AdminBackend_ObjectStore {
|
|
if storage == nil {
|
|
return nil
|
|
}
|
|
return []*conf.AdminBackend_ObjectStore{storage.AliyunOss, storage.HuaweiObs, storage.TencentCos, storage.AwsS3, storage.CloudflareR2, storage.Minio}
|
|
}
|
|
|
|
func maskStorageSecrets(storage *conf.AdminBackend_Storage) {
|
|
if storage.Qiniu != nil {
|
|
storage.Qiniu.SecretKey = "******"
|
|
}
|
|
for _, item := range objectStores(storage) {
|
|
if item != nil {
|
|
item.SecretKey = "******"
|
|
}
|
|
}
|
|
}
|
|
|
|
func preserveStorageSecrets(next, current *conf.AdminBackend_Storage) {
|
|
if next == nil || current == nil {
|
|
return
|
|
}
|
|
if next.Qiniu != nil && current.Qiniu != nil && (next.Qiniu.SecretKey == "" || next.Qiniu.SecretKey == "******") {
|
|
next.Qiniu.SecretKey = current.Qiniu.SecretKey
|
|
}
|
|
nextItems, currentItems := objectStores(next), objectStores(current)
|
|
for i := range nextItems {
|
|
if nextItems[i] != nil && currentItems[i] != nil && (nextItems[i].SecretKey == "" || nextItems[i].SecretKey == "******") {
|
|
nextItems[i].SecretKey = currentItems[i].SecretKey
|
|
}
|
|
}
|
|
}
|