[API节点]显示API节点运行日志 [用户]增加可用功能控制、AccessKey管理

This commit is contained in:
刘祥超
2020-12-30 22:01:01 +08:00
parent 4147e0d8bc
commit f905bb7066
15 changed files with 556 additions and 17 deletions

View 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("")
}

View File

@@ -0,0 +1,5 @@
package models
import (
_ "github.com/go-sql-driver/mysql"
)

View 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{}
}

View File

@@ -0,0 +1 @@
package models

View 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
}

View File

@@ -0,0 +1,5 @@
package models
import (
_ "github.com/go-sql-driver/mysql"
)

View 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{}
}

View File

@@ -0,0 +1 @@
package models

View File

@@ -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
}

View 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
}

View File

@@ -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 {