diff --git a/internal/db/models/sub_user_dao.go b/internal/db/models/sub_user_dao.go new file mode 100644 index 00000000..ba822c45 --- /dev/null +++ b/internal/db/models/sub_user_dao.go @@ -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("") +} diff --git a/internal/db/models/sub_user_dao_test.go b/internal/db/models/sub_user_dao_test.go new file mode 100644 index 00000000..97c24b56 --- /dev/null +++ b/internal/db/models/sub_user_dao_test.go @@ -0,0 +1,5 @@ +package models + +import ( + _ "github.com/go-sql-driver/mysql" +) diff --git a/internal/db/models/sub_user_model.go b/internal/db/models/sub_user_model.go new file mode 100644 index 00000000..05a9466b --- /dev/null +++ b/internal/db/models/sub_user_model.go @@ -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{} +} diff --git a/internal/db/models/sub_user_model_ext.go b/internal/db/models/sub_user_model_ext.go new file mode 100644 index 00000000..2640e7f9 --- /dev/null +++ b/internal/db/models/sub_user_model_ext.go @@ -0,0 +1 @@ +package models diff --git a/internal/db/models/user_access_key_dao.go b/internal/db/models/user_access_key_dao.go new file mode 100644 index 00000000..d840dbf5 --- /dev/null +++ b/internal/db/models/user_access_key_dao.go @@ -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 +} diff --git a/internal/db/models/user_access_key_dao_test.go b/internal/db/models/user_access_key_dao_test.go new file mode 100644 index 00000000..97c24b56 --- /dev/null +++ b/internal/db/models/user_access_key_dao_test.go @@ -0,0 +1,5 @@ +package models + +import ( + _ "github.com/go-sql-driver/mysql" +) diff --git a/internal/db/models/user_access_key_model.go b/internal/db/models/user_access_key_model.go new file mode 100644 index 00000000..1a324562 --- /dev/null +++ b/internal/db/models/user_access_key_model.go @@ -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{} +} diff --git a/internal/db/models/user_access_key_model_ext.go b/internal/db/models/user_access_key_model_ext.go new file mode 100644 index 00000000..2640e7f9 --- /dev/null +++ b/internal/db/models/user_access_key_model_ext.go @@ -0,0 +1 @@ +package models diff --git a/internal/db/models/user_dao.go b/internal/db/models/user_dao.go index aac41442..c7c180b5 100644 --- a/internal/db/models/user_dao.go +++ b/internal/db/models/user_dao.go @@ -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 +} diff --git a/internal/db/models/user_features.go b/internal/db/models/user_features.go new file mode 100644 index 00000000..779684dc --- /dev/null +++ b/internal/db/models/user_features.go @@ -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 +} diff --git a/internal/db/models/user_model.go b/internal/db/models/user_model.go index 6c01a4ab..8df5d524 100644 --- a/internal/db/models/user_model.go +++ b/internal/db/models/user_model.go @@ -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 { diff --git a/internal/nodes/api_node.go b/internal/nodes/api_node.go index 9799a9bd..b1cba71d 100644 --- a/internal/nodes/api_node.go +++ b/internal/nodes/api_node.go @@ -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 } diff --git a/internal/remotelogs/utils.go b/internal/remotelogs/utils.go index ee008431..96216266 100644 --- a/internal/remotelogs/utils.go +++ b/internal/remotelogs/utils.go @@ -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 +} diff --git a/internal/rpc/services/service_user.go b/internal/rpc/services/service_user.go index ac738e1f..1088465f 100644 --- a/internal/rpc/services/service_user.go +++ b/internal/rpc/services/service_user.go @@ -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 +} diff --git a/internal/rpc/services/service_user_access_key.go b/internal/rpc/services/service_user_access_key.go new file mode 100644 index 00000000..54cbdcd6 --- /dev/null +++ b/internal/rpc/services/service_user_access_key.go @@ -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() +}