mirror of
https://github.com/TeaOSLab/EdgeAPI.git
synced 2025-11-06 01:50:25 +08:00
[API节点]显示API节点运行日志 [用户]增加可用功能控制、AccessKey管理
This commit is contained in:
71
internal/db/models/sub_user_dao.go
Normal file
71
internal/db/models/sub_user_dao.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
const (
|
||||
SubUserStateEnabled = 1 // 已启用
|
||||
SubUserStateDisabled = 0 // 已禁用
|
||||
)
|
||||
|
||||
type SubUserDAO dbs.DAO
|
||||
|
||||
func NewSubUserDAO() *SubUserDAO {
|
||||
return dbs.NewDAO(&SubUserDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeSubUsers",
|
||||
Model: new(SubUser),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*SubUserDAO)
|
||||
}
|
||||
|
||||
var SharedSubUserDAO *SubUserDAO
|
||||
|
||||
func init() {
|
||||
dbs.OnReady(func() {
|
||||
SharedSubUserDAO = NewSubUserDAO()
|
||||
})
|
||||
}
|
||||
|
||||
// 启用条目
|
||||
func (this *SubUserDAO) EnableSubUser(id uint32) error {
|
||||
_, err := this.Query().
|
||||
Pk(id).
|
||||
Set("state", SubUserStateEnabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 禁用条目
|
||||
func (this *SubUserDAO) DisableSubUser(id uint32) error {
|
||||
_, err := this.Query().
|
||||
Pk(id).
|
||||
Set("state", SubUserStateDisabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 查找启用中的条目
|
||||
func (this *SubUserDAO) FindEnabledSubUser(id uint32) (*SubUser, error) {
|
||||
result, err := this.Query().
|
||||
Pk(id).
|
||||
Attr("state", SubUserStateEnabled).
|
||||
Find()
|
||||
if result == nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*SubUser), err
|
||||
}
|
||||
|
||||
// 根据主键查找名称
|
||||
func (this *SubUserDAO) FindSubUserName(id uint32) (string, error) {
|
||||
return this.Query().
|
||||
Pk(id).
|
||||
Result("name").
|
||||
FindStringCol("")
|
||||
}
|
||||
5
internal/db/models/sub_user_dao_test.go
Normal file
5
internal/db/models/sub_user_dao_test.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
26
internal/db/models/sub_user_model.go
Normal file
26
internal/db/models/sub_user_model.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package models
|
||||
|
||||
// 子用户
|
||||
type SubUser struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
UserId uint32 `field:"userId"` // 所属主用户ID
|
||||
IsOn uint8 `field:"isOn"` // 是否启用
|
||||
Name string `field:"name"` // 名称
|
||||
Username string `field:"username"` // 用户名
|
||||
Password string `field:"password"` // 密码
|
||||
State uint8 `field:"state"` // 状态
|
||||
}
|
||||
|
||||
type SubUserOperator struct {
|
||||
Id interface{} // ID
|
||||
UserId interface{} // 所属主用户ID
|
||||
IsOn interface{} // 是否启用
|
||||
Name interface{} // 名称
|
||||
Username interface{} // 用户名
|
||||
Password interface{} // 密码
|
||||
State interface{} // 状态
|
||||
}
|
||||
|
||||
func NewSubUserOperator() *SubUserOperator {
|
||||
return &SubUserOperator{}
|
||||
}
|
||||
1
internal/db/models/sub_user_model_ext.go
Normal file
1
internal/db/models/sub_user_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package models
|
||||
111
internal/db/models/user_access_key_dao.go
Normal file
111
internal/db/models/user_access_key_dao.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/rands"
|
||||
)
|
||||
|
||||
const (
|
||||
UserAccessKeyStateEnabled = 1 // 已启用
|
||||
UserAccessKeyStateDisabled = 0 // 已禁用
|
||||
)
|
||||
|
||||
type UserAccessKeyDAO dbs.DAO
|
||||
|
||||
func NewUserAccessKeyDAO() *UserAccessKeyDAO {
|
||||
return dbs.NewDAO(&UserAccessKeyDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeUserAccessKeys",
|
||||
Model: new(UserAccessKey),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*UserAccessKeyDAO)
|
||||
}
|
||||
|
||||
var SharedUserAccessKeyDAO *UserAccessKeyDAO
|
||||
|
||||
func init() {
|
||||
dbs.OnReady(func() {
|
||||
SharedUserAccessKeyDAO = NewUserAccessKeyDAO()
|
||||
})
|
||||
}
|
||||
|
||||
// 启用条目
|
||||
func (this *UserAccessKeyDAO) EnableUserAccessKey(id int64) error {
|
||||
_, err := this.Query().
|
||||
Pk(id).
|
||||
Set("state", UserAccessKeyStateEnabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 禁用条目
|
||||
func (this *UserAccessKeyDAO) DisableUserAccessKey(id int64) error {
|
||||
_, err := this.Query().
|
||||
Pk(id).
|
||||
Set("state", UserAccessKeyStateDisabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 查找启用中的条目
|
||||
func (this *UserAccessKeyDAO) FindEnabledUserAccessKey(id int64) (*UserAccessKey, error) {
|
||||
result, err := this.Query().
|
||||
Pk(id).
|
||||
Attr("state", UserAccessKeyStateEnabled).
|
||||
Find()
|
||||
if result == nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*UserAccessKey), err
|
||||
}
|
||||
|
||||
// 创建Key
|
||||
func (this *UserAccessKeyDAO) CreateAccessKey(userId int64, description string) (int64, error) {
|
||||
if userId <= 0 {
|
||||
return 0, errors.New("invalid userId")
|
||||
}
|
||||
op := NewUserAccessKeyOperator()
|
||||
op.UserId = userId
|
||||
op.Description = description
|
||||
op.UniqueId = rands.String(16)
|
||||
op.Secret = rands.String(32)
|
||||
op.IsOn = true
|
||||
op.State = UserAccessKeyStateEnabled
|
||||
return this.SaveInt64(op)
|
||||
}
|
||||
|
||||
// 查找用户所有的Key
|
||||
func (this *UserAccessKeyDAO) FindAllEnabledAccessKeys(userId int64) (result []*UserAccessKey, err error) {
|
||||
_, err = this.Query().
|
||||
State(UserAccessKeyStateEnabled).
|
||||
DescPk().
|
||||
Slice(&result).
|
||||
FindAll()
|
||||
return
|
||||
}
|
||||
|
||||
// 检查用户的AccessKey
|
||||
func (this *UserAccessKeyDAO) CheckUserAccessKey(userId int64, accessKeyId int64) (bool, error) {
|
||||
return this.Query().
|
||||
Pk(accessKeyId).
|
||||
State(UserAccessKeyStateEnabled).
|
||||
Attr("userId", userId).
|
||||
Exist()
|
||||
}
|
||||
|
||||
// 设置是否启用
|
||||
func (this *UserAccessKeyDAO) UpdateAccessKeyIsOn(accessKeyId int64, isOn bool) error {
|
||||
if accessKeyId <= 0 {
|
||||
return errors.New("invalid accessKeyId")
|
||||
}
|
||||
_, err := this.Query().
|
||||
Pk(accessKeyId).
|
||||
Set("isOn", isOn).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
5
internal/db/models/user_access_key_dao_test.go
Normal file
5
internal/db/models/user_access_key_dao_test.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
28
internal/db/models/user_access_key_model.go
Normal file
28
internal/db/models/user_access_key_model.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package models
|
||||
|
||||
// AccessKey
|
||||
type UserAccessKey struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
UserId uint32 `field:"userId"` // 用户ID
|
||||
SubUserId uint32 `field:"subUserId"` // 子用户ID
|
||||
IsOn uint8 `field:"isOn"` // 是否启用
|
||||
UniqueId string `field:"uniqueId"` // 唯一的Key
|
||||
Secret string `field:"secret"` // 密钥
|
||||
Description string `field:"description"` // 备注
|
||||
State uint8 `field:"state"` // 状态
|
||||
}
|
||||
|
||||
type UserAccessKeyOperator struct {
|
||||
Id interface{} // ID
|
||||
UserId interface{} // 用户ID
|
||||
SubUserId interface{} // 子用户ID
|
||||
IsOn interface{} // 是否启用
|
||||
UniqueId interface{} // 唯一的Key
|
||||
Secret interface{} // 密钥
|
||||
Description interface{} // 备注
|
||||
State interface{} // 状态
|
||||
}
|
||||
|
||||
func NewUserAccessKeyOperator() *UserAccessKeyOperator {
|
||||
return &UserAccessKeyOperator{}
|
||||
}
|
||||
1
internal/db/models/user_access_key_model_ext.go
Normal file
1
internal/db/models/user_access_key_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package models
|
||||
@@ -1,6 +1,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
@@ -229,3 +230,54 @@ func (this *UserDAO) FindUserClusterId(userId int64) (int64, error) {
|
||||
Result("clusterId").
|
||||
FindInt64Col(0)
|
||||
}
|
||||
|
||||
// 更新用户Features
|
||||
func (this *UserDAO) UpdateUserFeatures(userId int64, featuresJSON []byte) error {
|
||||
if userId <= 0 {
|
||||
return errors.New("invalid userId")
|
||||
}
|
||||
if len(featuresJSON) == 0 {
|
||||
featuresJSON = []byte("[]")
|
||||
}
|
||||
_, err := this.Query().
|
||||
Pk(userId).
|
||||
Set("features", featuresJSON).
|
||||
Update()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 查找用户Features
|
||||
func (this *UserDAO) FindUserFeatures(userId int64) ([]*UserFeature, error) {
|
||||
featuresJSON, err := this.Query().
|
||||
Pk(userId).
|
||||
Result("features").
|
||||
FindStringCol("")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(featuresJSON) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
featureCodes := []string{}
|
||||
err = json.Unmarshal([]byte(featuresJSON), &featureCodes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 检查是否还存在以及设置名称
|
||||
result := []*UserFeature{}
|
||||
if len(featureCodes) > 0 {
|
||||
for _, featureCode := range featureCodes {
|
||||
f := FindUserFeature(featureCode)
|
||||
if f != nil {
|
||||
result = append(result, &UserFeature{Name: f.Name, Code: f.Code, Description: f.Description})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
50
internal/db/models/user_features.go
Normal file
50
internal/db/models/user_features.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package models
|
||||
|
||||
import "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
|
||||
var (
|
||||
// 所有功能列表,注意千万不能在运行时进行修改
|
||||
allUserFeatures = []*UserFeature{
|
||||
{
|
||||
Name: "记录访问日志",
|
||||
Code: "server.accessLog",
|
||||
Description: "用户可以开启服务的访问日志",
|
||||
},
|
||||
{
|
||||
Name: "转发访问日志",
|
||||
Code: "server.accessLog.forward",
|
||||
Description: "用户可以配置访问日志转发到自定义的API",
|
||||
},
|
||||
{
|
||||
Name: "开启WAF",
|
||||
Code: "server.waf",
|
||||
Description: "用户可以开启WAF功能并可以设置黑白名单等",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// 用户功能
|
||||
type UserFeature struct {
|
||||
Name string `json:"name"`
|
||||
Code string `json:"code"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
func (this *UserFeature) ToPB() *pb.UserFeature {
|
||||
return &pb.UserFeature{Name: this.Name, Code: this.Code, Description: this.Description}
|
||||
}
|
||||
|
||||
// 所有功能列表
|
||||
func FindAllUserFeatures() []*UserFeature {
|
||||
return allUserFeatures
|
||||
}
|
||||
|
||||
// 查询单个功能
|
||||
func FindUserFeature(code string) *UserFeature {
|
||||
for _, feature := range allUserFeatures {
|
||||
if feature.Code == code {
|
||||
return feature
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -17,6 +17,7 @@ type User struct {
|
||||
State uint8 `field:"state"` // 状态
|
||||
Source string `field:"source"` // 来源
|
||||
ClusterId uint32 `field:"clusterId"` // 集群ID
|
||||
Features string `field:"features"` // 允许操作的特征
|
||||
}
|
||||
|
||||
type UserOperator struct {
|
||||
@@ -35,6 +36,7 @@ type UserOperator struct {
|
||||
State interface{} // 状态
|
||||
Source interface{} // 来源
|
||||
ClusterId interface{} // 集群ID
|
||||
Features interface{} // 允许操作的特征
|
||||
}
|
||||
|
||||
func NewUserOperator() *UserOperator {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/configs"
|
||||
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/rpc/services"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/setup"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
@@ -72,12 +73,12 @@ func (this *APINode) Start() {
|
||||
go NewNodeStatusExecutor().Listen()
|
||||
|
||||
// 监听RPC服务
|
||||
logs.Println("[API_NODE]starting rpc ...")
|
||||
remotelogs.Println("API_NODE", "starting RPC server ...")
|
||||
|
||||
// HTTP
|
||||
httpConfig, err := apiNode.DecodeHTTP()
|
||||
if err != nil {
|
||||
logs.Println("[API_NODE]decode http config: " + err.Error())
|
||||
remotelogs.Error("API_NODE", "decode http config: "+err.Error())
|
||||
return
|
||||
}
|
||||
isListening := false
|
||||
@@ -86,13 +87,13 @@ func (this *APINode) Start() {
|
||||
for _, addr := range listen.Addresses() {
|
||||
listener, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
logs.Println("[API_NODE]listening '" + addr + "' failed: " + err.Error())
|
||||
remotelogs.Error("API_NODE", "listening '"+addr+"' failed: "+err.Error())
|
||||
continue
|
||||
}
|
||||
go func() {
|
||||
err := this.listenRPC(listener, nil)
|
||||
if err != nil {
|
||||
logs.Println("[API_NODE]listening '" + addr + "' rpc: " + err.Error())
|
||||
remotelogs.Error("API_NODE", "listening '"+addr+"' rpc: "+err.Error())
|
||||
return
|
||||
}
|
||||
}()
|
||||
@@ -104,7 +105,7 @@ func (this *APINode) Start() {
|
||||
// HTTPS
|
||||
httpsConfig, err := apiNode.DecodeHTTPS()
|
||||
if err != nil {
|
||||
logs.Println("[API_NODE]decode https config: " + err.Error())
|
||||
remotelogs.Error("API_NODE", "decode https config: "+err.Error())
|
||||
return
|
||||
}
|
||||
if httpsConfig != nil &&
|
||||
@@ -122,7 +123,7 @@ func (this *APINode) Start() {
|
||||
for _, addr := range listen.Addresses() {
|
||||
listener, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
logs.Println("[API_NODE]listening '" + addr + "' failed: " + err.Error())
|
||||
remotelogs.Error("API_NODE", "listening '"+addr+"' failed: "+err.Error())
|
||||
continue
|
||||
}
|
||||
go func() {
|
||||
@@ -130,7 +131,7 @@ func (this *APINode) Start() {
|
||||
Certificates: certs,
|
||||
})
|
||||
if err != nil {
|
||||
logs.Println("[API_NODE]listening '" + addr + "' rpc: " + err.Error())
|
||||
remotelogs.Error("API_NODE", "listening '"+addr+"' rpc: "+err.Error())
|
||||
return
|
||||
}
|
||||
}()
|
||||
@@ -142,7 +143,7 @@ func (this *APINode) Start() {
|
||||
// HTTP接口
|
||||
|
||||
if !isListening {
|
||||
logs.Println("[API_NODE]the api node does have a listening address")
|
||||
remotelogs.Error("API_NODE", "the api node require at least one listening address")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -154,7 +155,7 @@ func (this *APINode) Start() {
|
||||
func (this *APINode) listenRPC(listener net.Listener, tlsConfig *tls.Config) error {
|
||||
var rpcServer *grpc.Server
|
||||
if tlsConfig == nil {
|
||||
logs.Println("[API_NODE]listening http://" + listener.Addr().String() + " ...")
|
||||
remotelogs.Println("API_NODE", "listening http://"+listener.Addr().String()+" ...")
|
||||
rpcServer = grpc.NewServer()
|
||||
} else {
|
||||
logs.Println("[API_NODE]listening https://" + listener.Addr().String() + " ...")
|
||||
@@ -212,6 +213,7 @@ func (this *APINode) listenRPC(listener net.Listener, tlsConfig *tls.Config) err
|
||||
pb.RegisterUserBillServiceServer(rpcServer, &services.UserBillService{})
|
||||
pb.RegisterUserNodeServiceServer(rpcServer, &services.UserNodeService{})
|
||||
pb.RegisterLoginServiceServer(rpcServer, &services.LoginService{})
|
||||
pb.RegisterUserAccessKeyServiceServer(rpcServer, &services.UserAccessKeyService{})
|
||||
err := rpcServer.Serve(listener)
|
||||
if err != nil {
|
||||
return errors.New("[API_NODE]start rpc failed: " + err.Error())
|
||||
@@ -252,11 +254,13 @@ func (this *APINode) autoUpgrade() error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// 不使用remotelogs(),因为此时还没有启动完成
|
||||
logs.Println("[API_NODE]upgrade database starting ...")
|
||||
err = setup.NewSQLExecutor(dbConfig).Run()
|
||||
if err != nil {
|
||||
return errors.New("execute sql failed: " + err.Error())
|
||||
}
|
||||
// 不使用remotelogs
|
||||
logs.Println("[API_NODE]upgrade database done")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package remotelogs
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/configs"
|
||||
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"time"
|
||||
@@ -15,7 +16,10 @@ func init() {
|
||||
ticker := time.NewTicker(60 * time.Second)
|
||||
go func() {
|
||||
for range ticker.C {
|
||||
// TODO
|
||||
err := uploadLogs()
|
||||
if err != nil {
|
||||
logs.Println("[LOG]" + err.Error())
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -24,7 +28,7 @@ func init() {
|
||||
func Println(tag string, description string) {
|
||||
logs.Println("[" + tag + "]" + description)
|
||||
|
||||
nodeConfig, _ := nodeconfigs.SharedNodeConfig()
|
||||
nodeConfig, _ := configs.SharedAPIConfig()
|
||||
if nodeConfig == nil {
|
||||
return
|
||||
}
|
||||
@@ -35,7 +39,7 @@ func Println(tag string, description string) {
|
||||
Tag: tag,
|
||||
Description: description,
|
||||
Level: "info",
|
||||
NodeId: nodeConfig.Id,
|
||||
NodeId: nodeConfig.NumberId(),
|
||||
CreatedAt: time.Now().Unix(),
|
||||
}:
|
||||
default:
|
||||
@@ -47,7 +51,7 @@ func Println(tag string, description string) {
|
||||
func Warn(tag string, description string) {
|
||||
logs.Println("[" + tag + "]" + description)
|
||||
|
||||
nodeConfig, _ := nodeconfigs.SharedNodeConfig()
|
||||
nodeConfig, _ := configs.SharedAPIConfig()
|
||||
if nodeConfig == nil {
|
||||
return
|
||||
}
|
||||
@@ -58,7 +62,7 @@ func Warn(tag string, description string) {
|
||||
Tag: tag,
|
||||
Description: description,
|
||||
Level: "warning",
|
||||
NodeId: nodeConfig.Id,
|
||||
NodeId: nodeConfig.NumberId(),
|
||||
CreatedAt: time.Now().Unix(),
|
||||
}:
|
||||
default:
|
||||
@@ -70,7 +74,7 @@ func Warn(tag string, description string) {
|
||||
func Error(tag string, description string) {
|
||||
logs.Println("[" + tag + "]" + description)
|
||||
|
||||
nodeConfig, _ := nodeconfigs.SharedNodeConfig()
|
||||
nodeConfig, _ := configs.SharedAPIConfig()
|
||||
if nodeConfig == nil {
|
||||
return
|
||||
}
|
||||
@@ -81,10 +85,28 @@ func Error(tag string, description string) {
|
||||
Tag: tag,
|
||||
Description: description,
|
||||
Level: "error",
|
||||
NodeId: nodeConfig.Id,
|
||||
NodeId: nodeConfig.NumberId(),
|
||||
CreatedAt: time.Now().Unix(),
|
||||
}:
|
||||
default:
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 上传日志
|
||||
func uploadLogs() error {
|
||||
Loop:
|
||||
for {
|
||||
select {
|
||||
case log := <-logChan:
|
||||
err := models.SharedNodeLogDAO.CreateLog(models.NodeRoleAPI, log.NodeId, log.Level, log.Tag, log.Description, log.CreatedAt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||
@@ -359,3 +360,61 @@ func (this *UserService) FindUserNodeClusterId(ctx context.Context, req *pb.Find
|
||||
}
|
||||
return &pb.FindUserNodeClusterIdResponse{NodeClusterId: clusterId}, nil
|
||||
}
|
||||
|
||||
// 设置用户能使用的功能
|
||||
func (this *UserService) UpdateUserFeatures(ctx context.Context, req *pb.UpdateUserFeaturesRequest) (*pb.RPCSuccess, error) {
|
||||
_, err := this.ValidateAdmin(ctx, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
featuresJSON, err := json.Marshal(req.FeatureCodes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = models.SharedUserDAO.UpdateUserFeatures(req.UserId, featuresJSON)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// 获取用户所有的功能列表
|
||||
func (this *UserService) FindUserFeatures(ctx context.Context, req *pb.FindUserFeaturesRequest) (*pb.FindUserFeaturesResponse, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, 0, req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if userId > 0 {
|
||||
if userId != req.UserId {
|
||||
return nil, this.PermissionError()
|
||||
}
|
||||
}
|
||||
|
||||
features, err := models.SharedUserDAO.FindUserFeatures(req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []*pb.UserFeature{}
|
||||
for _, feature := range features {
|
||||
result = append(result, feature.ToPB())
|
||||
}
|
||||
|
||||
return &pb.FindUserFeaturesResponse{Features: result}, nil
|
||||
}
|
||||
|
||||
// 获取所有的功能定义
|
||||
func (this *UserService) FindAllUserFeatureDefinitions(ctx context.Context, req *pb.FindAllUserFeatureDefinitionsRequest) (*pb.FindAllUserFeatureDefinitionsResponse, error) {
|
||||
_, err := this.ValidateAdmin(ctx, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
features := models.FindAllUserFeatures()
|
||||
result := []*pb.UserFeature{}
|
||||
for _, feature := range features {
|
||||
result = append(result, feature.ToPB())
|
||||
}
|
||||
return &pb.FindAllUserFeatureDefinitionsResponse{Features: result}, nil
|
||||
}
|
||||
|
||||
102
internal/rpc/services/service_user_access_key.go
Normal file
102
internal/rpc/services/service_user_access_key.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
)
|
||||
|
||||
// 用户AccessKey相关服务
|
||||
type UserAccessKeyService struct {
|
||||
BaseService
|
||||
}
|
||||
|
||||
// 创建AccessKey
|
||||
func (this *UserAccessKeyService) CreateUserAccessKey(ctx context.Context, req *pb.CreateUserAccessKeyRequest) (*pb.CreateUserAccessKeyResponse, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, 0, req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userAccessKeyId, err := models.SharedUserAccessKeyDAO.CreateAccessKey(req.UserId, req.Description)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.CreateUserAccessKeyResponse{UserAccessKeyId: userAccessKeyId}, nil
|
||||
}
|
||||
|
||||
// 查找所有的AccessKey
|
||||
func (this *UserAccessKeyService) FindAllEnabledUserAccessKeys(ctx context.Context, req *pb.FindAllEnabledUserAccessKeysRequest) (*pb.FindAllEnabledUserAccessKeysResponse, error) {
|
||||
_, _, err := this.ValidateAdminAndUser(ctx, 0, req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
accessKeys, err := models.SharedUserAccessKeyDAO.FindAllEnabledAccessKeys(req.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := []*pb.UserAccessKey{}
|
||||
for _, accessKey := range accessKeys {
|
||||
result = append(result, &pb.UserAccessKey{
|
||||
Id: int64(accessKey.Id),
|
||||
UserId: int64(accessKey.UserId),
|
||||
SubUserId: int64(accessKey.SubUserId),
|
||||
IsOn: accessKey.IsOn == 1,
|
||||
UniqueId: accessKey.UniqueId,
|
||||
Secret: accessKey.Secret,
|
||||
Description: accessKey.Description,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.FindAllEnabledUserAccessKeysResponse{UserAccessKeys: result}, nil
|
||||
}
|
||||
|
||||
// 删除AccessKey
|
||||
func (this *UserAccessKeyService) DeleteUserAccessKey(ctx context.Context, req *pb.DeleteUserAccessKeyRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if userId > 0 {
|
||||
ok, err := models.SharedUserAccessKeyDAO.CheckUserAccessKey(userId, req.UserAccessKeyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !ok {
|
||||
return nil, this.PermissionError()
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedUserAccessKeyDAO.DisableUserAccessKey(req.UserAccessKeyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
|
||||
// 设置是否启用AccessKey
|
||||
func (this *UserAccessKeyService) UpdateUserAccessKeyIsOn(ctx context.Context, req *pb.UpdateUserAccessKeyIsOnRequest) (*pb.RPCSuccess, error) {
|
||||
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if userId > 0 {
|
||||
ok, err := models.SharedUserAccessKeyDAO.CheckUserAccessKey(userId, req.UserAccessKeyId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !ok {
|
||||
return nil, this.PermissionError()
|
||||
}
|
||||
}
|
||||
|
||||
err = models.SharedUserAccessKeyDAO.UpdateAccessKeyIsOn(req.UserAccessKeyId, req.IsOn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return this.Success()
|
||||
}
|
||||
Reference in New Issue
Block a user