diff --git a/internal/db/models/authority_key_dao.go b/internal/db/models/authority/authority_key_dao.go similarity index 98% rename from internal/db/models/authority_key_dao.go rename to internal/db/models/authority/authority_key_dao.go index 5d9b6760..17193fd6 100644 --- a/internal/db/models/authority_key_dao.go +++ b/internal/db/models/authority/authority_key_dao.go @@ -1,4 +1,4 @@ -package models +package authority import ( "encoding/json" diff --git a/internal/db/models/authority_key_dao_test.go b/internal/db/models/authority/authority_key_dao_test.go similarity index 95% rename from internal/db/models/authority_key_dao_test.go rename to internal/db/models/authority/authority_key_dao_test.go index 2af39bae..6d6cfebf 100644 --- a/internal/db/models/authority_key_dao_test.go +++ b/internal/db/models/authority/authority_key_dao_test.go @@ -1,4 +1,4 @@ -package models +package authority import ( _ "github.com/go-sql-driver/mysql" diff --git a/internal/db/models/authority_key_model.go b/internal/db/models/authority/authority_key_model.go similarity index 97% rename from internal/db/models/authority_key_model.go rename to internal/db/models/authority/authority_key_model.go index ce014a78..ce03abe7 100644 --- a/internal/db/models/authority_key_model.go +++ b/internal/db/models/authority/authority_key_model.go @@ -1,4 +1,4 @@ -package models +package authority // AuthorityKey 企业版认证信息 type AuthorityKey struct { diff --git a/internal/db/models/authority/authority_key_model_ext.go b/internal/db/models/authority/authority_key_model_ext.go new file mode 100644 index 00000000..c59e5b8b --- /dev/null +++ b/internal/db/models/authority/authority_key_model_ext.go @@ -0,0 +1 @@ +package authority diff --git a/internal/db/models/authority/authority_node_dao.go b/internal/db/models/authority/authority_node_dao.go new file mode 100644 index 00000000..608b2917 --- /dev/null +++ b/internal/db/models/authority/authority_node_dao.go @@ -0,0 +1,198 @@ +package authority + +import ( + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "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" + "github.com/iwind/TeaGo/types" +) + +const ( + AuthorityNodeStateEnabled = 1 // 已启用 + AuthorityNodeStateDisabled = 0 // 已禁用 +) + +type AuthorityNodeDAO dbs.DAO + +func NewAuthorityNodeDAO() *AuthorityNodeDAO { + return dbs.NewDAO(&AuthorityNodeDAO{ + DAOObject: dbs.DAOObject{ + DB: Tea.Env, + Table: "edgeAuthorityNodes", + Model: new(AuthorityNode), + PkName: "id", + }, + }).(*AuthorityNodeDAO) +} + +var SharedAuthorityNodeDAO *AuthorityNodeDAO + +func init() { + dbs.OnReady(func() { + SharedAuthorityNodeDAO = NewAuthorityNodeDAO() + }) +} + +// EnableAuthorityNode 启用条目 +func (this *AuthorityNodeDAO) EnableAuthorityNode(tx *dbs.Tx, id int64) error { + _, err := this.Query(tx). + Pk(id). + Set("state", AuthorityNodeStateEnabled). + Update() + return err +} + +// DisableAuthorityNode 禁用条目 +func (this *AuthorityNodeDAO) DisableAuthorityNode(tx *dbs.Tx, id int64) error { + _, err := this.Query(tx). + Pk(id). + Set("state", AuthorityNodeStateDisabled). + Update() + return err +} + +// FindEnabledAuthorityNode 查找启用中的条目 +func (this *AuthorityNodeDAO) FindEnabledAuthorityNode(tx *dbs.Tx, id int64) (*AuthorityNode, error) { + result, err := this.Query(tx). + Pk(id). + Attr("state", AuthorityNodeStateEnabled). + Find() + if result == nil { + return nil, err + } + return result.(*AuthorityNode), err +} + +// FindAuthorityNodeName 根据主键查找名称 +func (this *AuthorityNodeDAO) FindAuthorityNodeName(tx *dbs.Tx, id int64) (string, error) { + return this.Query(tx). + Pk(id). + Result("name"). + FindStringCol("") +} + +// FindAllEnabledAuthorityNodes 列出所有可用认证节点 +func (this *AuthorityNodeDAO) FindAllEnabledAuthorityNodes(tx *dbs.Tx) (result []*AuthorityNode, err error) { + _, err = this.Query(tx). + State(AuthorityNodeStateEnabled). + Desc("order"). + AscPk(). + Slice(&result). + FindAll() + return +} + +// CountAllEnabledAuthorityNodes 计算认证节点数量 +func (this *AuthorityNodeDAO) CountAllEnabledAuthorityNodes(tx *dbs.Tx) (int64, error) { + return this.Query(tx). + State(AuthorityNodeStateEnabled). + Count() +} + +// ListEnabledAuthorityNodes 列出单页的认证节点 +func (this *AuthorityNodeDAO) ListEnabledAuthorityNodes(tx *dbs.Tx, offset int64, size int64) (result []*AuthorityNode, err error) { + _, err = this.Query(tx). + State(AuthorityNodeStateEnabled). + Offset(offset). + Limit(size). + Desc("order"). + DescPk(). + Slice(&result). + FindAll() + return +} + +// CreateAuthorityNode 创建认证节点 +func (this *AuthorityNodeDAO) CreateAuthorityNode(tx *dbs.Tx, name string, description string, isOn bool) (nodeId int64, err error) { + uniqueId, err := this.GenUniqueId(tx) + if err != nil { + return 0, err + } + secret := rands.String(32) + err = models.NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, models.NodeRoleAuthority) + if err != nil { + return + } + + op := NewAuthorityNodeOperator() + op.IsOn = isOn + op.UniqueId = uniqueId + op.Secret = secret + op.Name = name + op.Description = description + op.State = AuthorityNodeStateEnabled + err = this.Save(tx, op) + if err != nil { + return + } + + return types.Int64(op.Id), nil +} + +// UpdateAuthorityNode 修改认证节点 +func (this *AuthorityNodeDAO) UpdateAuthorityNode(tx *dbs.Tx, nodeId int64, name string, description string, isOn bool) error { + if nodeId <= 0 { + return errors.New("invalid nodeId") + } + + op := NewAuthorityNodeOperator() + op.Id = nodeId + op.Name = name + op.Description = description + op.IsOn = isOn + err := this.Save(tx, op) + return err +} + +// FindEnabledAuthorityNodeWithUniqueId 根据唯一ID获取节点信息 +func (this *AuthorityNodeDAO) FindEnabledAuthorityNodeWithUniqueId(tx *dbs.Tx, uniqueId string) (*AuthorityNode, error) { + result, err := this.Query(tx). + Attr("uniqueId", uniqueId). + Attr("state", AuthorityNodeStateEnabled). + Find() + if result == nil { + return nil, err + } + return result.(*AuthorityNode), err +} + +// FindEnabledAuthorityNodeIdWithUniqueId 根据唯一ID获取节点ID +func (this *AuthorityNodeDAO) FindEnabledAuthorityNodeIdWithUniqueId(tx *dbs.Tx, uniqueId string) (int64, error) { + return this.Query(tx). + Attr("uniqueId", uniqueId). + Attr("state", AuthorityNodeStateEnabled). + ResultPk(). + FindInt64Col(0) +} + +// GenUniqueId 生成唯一ID +func (this *AuthorityNodeDAO) GenUniqueId(tx *dbs.Tx) (string, error) { + for { + uniqueId := rands.HexString(32) + ok, err := this.Query(tx). + Attr("uniqueId", uniqueId). + Exist() + if err != nil { + return "", err + } + if ok { + continue + } + return uniqueId, nil + } +} + +// UpdateNodeStatus 更改节点状态 +func (this *AuthorityNodeDAO) UpdateNodeStatus(tx *dbs.Tx, nodeId int64, statusJSON []byte) error { + if statusJSON == nil { + return nil + } + _, err := this.Query(tx). + Pk(nodeId). + Set("status", string(statusJSON)). + Update() + return err +} diff --git a/internal/db/models/authority/authority_node_dao_test.go b/internal/db/models/authority/authority_node_dao_test.go new file mode 100644 index 00000000..9ec176c0 --- /dev/null +++ b/internal/db/models/authority/authority_node_dao_test.go @@ -0,0 +1,6 @@ +package authority + +import ( + _ "github.com/go-sql-driver/mysql" + _ "github.com/iwind/TeaGo/bootstrap" +) diff --git a/internal/db/models/authority/authority_node_model.go b/internal/db/models/authority/authority_node_model.go new file mode 100644 index 00000000..ea06f163 --- /dev/null +++ b/internal/db/models/authority/authority_node_model.go @@ -0,0 +1,36 @@ +package authority + +// AuthorityNode 监控节点 +type AuthorityNode struct { + Id uint32 `field:"id"` // ID + IsOn uint8 `field:"isOn"` // 是否启用 + UniqueId string `field:"uniqueId"` // 唯一ID + Secret string `field:"secret"` // 密钥 + Name string `field:"name"` // 名称 + Description string `field:"description"` // 描述 + Order uint32 `field:"order"` // 排序 + State uint8 `field:"state"` // 状态 + CreatedAt uint64 `field:"createdAt"` // 创建时间 + AdminId uint32 `field:"adminId"` // 管理员ID + Weight uint32 `field:"weight"` // 权重 + Status string `field:"status"` // 运行状态 +} + +type AuthorityNodeOperator struct { + Id interface{} // ID + IsOn interface{} // 是否启用 + UniqueId interface{} // 唯一ID + Secret interface{} // 密钥 + Name interface{} // 名称 + Description interface{} // 描述 + Order interface{} // 排序 + State interface{} // 状态 + CreatedAt interface{} // 创建时间 + AdminId interface{} // 管理员ID + Weight interface{} // 权重 + Status interface{} // 运行状态 +} + +func NewAuthorityNodeOperator() *AuthorityNodeOperator { + return &AuthorityNodeOperator{} +} diff --git a/internal/db/models/authority/authority_node_model_ext.go b/internal/db/models/authority/authority_node_model_ext.go new file mode 100644 index 00000000..c59e5b8b --- /dev/null +++ b/internal/db/models/authority/authority_node_model_ext.go @@ -0,0 +1 @@ +package authority diff --git a/internal/db/models/authority_key_model_ext.go b/internal/db/models/authority_key_model_ext.go deleted file mode 100644 index 2640e7f9..00000000 --- a/internal/db/models/authority_key_model_ext.go +++ /dev/null @@ -1 +0,0 @@ -package models diff --git a/internal/db/models/monitor_node_dao.go b/internal/db/models/monitor_node_dao.go index 694e6675..be4b07d6 100644 --- a/internal/db/models/monitor_node_dao.go +++ b/internal/db/models/monitor_node_dao.go @@ -1,15 +1,12 @@ package models import ( - "encoding/json" "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/maps" "github.com/iwind/TeaGo/rands" "github.com/iwind/TeaGo/types" - "strconv" ) const ( @@ -38,7 +35,7 @@ func init() { }) } -// 启用条目 +// EnableMonitorNode 启用条目 func (this *MonitorNodeDAO) EnableMonitorNode(tx *dbs.Tx, id int64) error { _, err := this.Query(tx). Pk(id). @@ -47,7 +44,7 @@ func (this *MonitorNodeDAO) EnableMonitorNode(tx *dbs.Tx, id int64) error { return err } -// 禁用条目 +// DisableMonitorNode 禁用条目 func (this *MonitorNodeDAO) DisableMonitorNode(tx *dbs.Tx, id int64) error { _, err := this.Query(tx). Pk(id). @@ -56,7 +53,7 @@ func (this *MonitorNodeDAO) DisableMonitorNode(tx *dbs.Tx, id int64) error { return err } -// 查找启用中的条目 +// FindEnabledMonitorNode 查找启用中的条目 func (this *MonitorNodeDAO) FindEnabledMonitorNode(tx *dbs.Tx, id int64) (*MonitorNode, error) { result, err := this.Query(tx). Pk(id). @@ -68,7 +65,7 @@ func (this *MonitorNodeDAO) FindEnabledMonitorNode(tx *dbs.Tx, id int64) (*Monit return result.(*MonitorNode), err } -// 根据主键查找名称 +// FindMonitorNodeName 根据主键查找名称 func (this *MonitorNodeDAO) FindMonitorNodeName(tx *dbs.Tx, id int64) (string, error) { return this.Query(tx). Pk(id). @@ -76,7 +73,7 @@ func (this *MonitorNodeDAO) FindMonitorNodeName(tx *dbs.Tx, id int64) (string, e FindStringCol("") } -// 列出所有可用监控节点 +// FindAllEnabledMonitorNodes 列出所有可用监控节点 func (this *MonitorNodeDAO) FindAllEnabledMonitorNodes(tx *dbs.Tx) (result []*MonitorNode, err error) { _, err = this.Query(tx). State(MonitorNodeStateEnabled). @@ -87,14 +84,14 @@ func (this *MonitorNodeDAO) FindAllEnabledMonitorNodes(tx *dbs.Tx) (result []*Mo return } -// 计算监控节点数量 +// CountAllEnabledMonitorNodes 计算监控节点数量 func (this *MonitorNodeDAO) CountAllEnabledMonitorNodes(tx *dbs.Tx) (int64, error) { return this.Query(tx). State(MonitorNodeStateEnabled). Count() } -// 列出单页的监控节点 +// ListEnabledMonitorNodes 列出单页的监控节点 func (this *MonitorNodeDAO) ListEnabledMonitorNodes(tx *dbs.Tx, offset int64, size int64) (result []*MonitorNode, err error) { _, err = this.Query(tx). State(MonitorNodeStateEnabled). @@ -107,34 +104,7 @@ func (this *MonitorNodeDAO) ListEnabledMonitorNodes(tx *dbs.Tx, offset int64, si return } -// 根据主机名和端口获取ID -func (this *MonitorNodeDAO) FindEnabledMonitorNodeIdWithAddr(tx *dbs.Tx, protocol string, host string, port int) (int64, error) { - addr := maps.Map{ - "protocol": protocol, - "host": host, - "portRange": strconv.Itoa(port), - } - addrJSON, err := json.Marshal(addr) - if err != nil { - return 0, err - } - - one, err := this.Query(tx). - State(MonitorNodeStateEnabled). - Where("JSON_CONTAINS(accessAddrs, :addr)"). - Param("addr", string(addrJSON)). - ResultPk(). - Find() - if err != nil { - return 0, err - } - if one == nil { - return 0, nil - } - return int64(one.(*MonitorNode).Id), nil -} - -// 创建监控节点 +// CreateMonitorNode 创建监控节点 func (this *MonitorNodeDAO) CreateMonitorNode(tx *dbs.Tx, name string, description string, isOn bool) (nodeId int64, err error) { uniqueId, err := this.GenUniqueId(tx) if err != nil { @@ -161,7 +131,7 @@ func (this *MonitorNodeDAO) CreateMonitorNode(tx *dbs.Tx, name string, descripti return types.Int64(op.Id), nil } -// 修改监控节点 +// UpdateMonitorNode 修改监控节点 func (this *MonitorNodeDAO) UpdateMonitorNode(tx *dbs.Tx, nodeId int64, name string, description string, isOn bool) error { if nodeId <= 0 { return errors.New("invalid nodeId") @@ -176,7 +146,7 @@ func (this *MonitorNodeDAO) UpdateMonitorNode(tx *dbs.Tx, nodeId int64, name str return err } -// 根据唯一ID获取节点信息 +// FindEnabledMonitorNodeWithUniqueId 根据唯一ID获取节点信息 func (this *MonitorNodeDAO) FindEnabledMonitorNodeWithUniqueId(tx *dbs.Tx, uniqueId string) (*MonitorNode, error) { result, err := this.Query(tx). Attr("uniqueId", uniqueId). @@ -188,7 +158,7 @@ func (this *MonitorNodeDAO) FindEnabledMonitorNodeWithUniqueId(tx *dbs.Tx, uniqu return result.(*MonitorNode), err } -// 根据唯一ID获取节点ID +// FindEnabledMonitorNodeIdWithUniqueId 根据唯一ID获取节点ID func (this *MonitorNodeDAO) FindEnabledMonitorNodeIdWithUniqueId(tx *dbs.Tx, uniqueId string) (int64, error) { return this.Query(tx). Attr("uniqueId", uniqueId). @@ -197,7 +167,7 @@ func (this *MonitorNodeDAO) FindEnabledMonitorNodeIdWithUniqueId(tx *dbs.Tx, uni FindInt64Col(0) } -// 生成唯一ID +// GenUniqueId 生成唯一ID func (this *MonitorNodeDAO) GenUniqueId(tx *dbs.Tx) (string, error) { for { uniqueId := rands.HexString(32) @@ -214,7 +184,7 @@ func (this *MonitorNodeDAO) GenUniqueId(tx *dbs.Tx) (string, error) { } } -// 更改节点状态 +// UpdateNodeStatus 更改节点状态 func (this *MonitorNodeDAO) UpdateNodeStatus(tx *dbs.Tx, nodeId int64, statusJSON []byte) error { if statusJSON == nil { return nil diff --git a/internal/db/models/node_roles.go b/internal/db/models/node_roles.go index 22860244..50f0d37b 100644 --- a/internal/db/models/node_roles.go +++ b/internal/db/models/node_roles.go @@ -3,14 +3,15 @@ package models type NodeRole = string const ( - NodeRoleAdmin NodeRole = "admin" - NodeRoleUser NodeRole = "user" - NodeRoleProvider NodeRole = "provider" - NodeRoleAPI NodeRole = "api" - NodeRoleDatabase NodeRole = "database" - NodeRoleLog NodeRole = "log" - NodeRoleDNS NodeRole = "dns" - NodeRoleMonitor NodeRole = "monitor" - NodeRoleNode NodeRole = "node" - NodeRoleCluster NodeRole = "cluster" + NodeRoleAdmin NodeRole = "admin" + NodeRoleUser NodeRole = "user" + NodeRoleProvider NodeRole = "provider" + NodeRoleAPI NodeRole = "api" + NodeRoleDatabase NodeRole = "database" + NodeRoleLog NodeRole = "log" + NodeRoleDNS NodeRole = "dns" + NodeRoleMonitor NodeRole = "monitor" + NodeRoleNode NodeRole = "node" + NodeRoleCluster NodeRole = "cluster" + NodeRoleAuthority NodeRole = "authority" ) diff --git a/internal/nodes/api_node.go b/internal/nodes/api_node.go index 72fd11f6..85afdb1f 100644 --- a/internal/nodes/api_node.go +++ b/internal/nodes/api_node.go @@ -254,6 +254,7 @@ func (this *APINode) listenRPC(listener net.Listener, tlsConfig *tls.Config) err pb.RegisterNodeClusterFirewallActionServiceServer(rpcServer, &services.NodeClusterFirewallActionService{}) pb.RegisterMonitorNodeServiceServer(rpcServer, &services.MonitorNodeService{}) pb.RegisterAuthorityKeyServiceServer(rpcServer, &services.AuthorityKeyService{}) + pb.RegisterAuthorityNodeServiceServer(rpcServer, &services.AuthorityNodeService{}) err := rpcServer.Serve(listener) if err != nil { return errors.New("[API_NODE]start rpc failed: " + err.Error()) diff --git a/internal/rpc/services/service_authority_key.go b/internal/rpc/services/service_authority_key.go index 95ed0d39..9d77645f 100644 --- a/internal/rpc/services/service_authority_key.go +++ b/internal/rpc/services/service_authority_key.go @@ -5,7 +5,7 @@ package services import ( "context" "encoding/json" - "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/TeaOSLab/EdgeAPI/internal/db/models/authority" rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" ) @@ -22,7 +22,7 @@ func (this *AuthorityKeyService) UpdateAuthorityKey(ctx context.Context, req *pb return nil, err } var tx = this.NullTx() - err = models.SharedAuthorityKeyDAO.UpdateKey(tx, req.Value, req.DayFrom, req.DayTo, req.Hostname, req.MacAddresses) + err = authority.SharedAuthorityKeyDAO.UpdateKey(tx, req.Value, req.DayFrom, req.DayTo, req.Hostname, req.MacAddresses) if err != nil { return nil, err } @@ -36,7 +36,7 @@ func (this *AuthorityKeyService) ReadAuthorityKey(ctx context.Context, req *pb.R return nil, err } var tx = this.NullTx() - key, err := models.SharedAuthorityKeyDAO.ReadKey(tx) + key, err := authority.SharedAuthorityKeyDAO.ReadKey(tx) if err != nil { return nil, err } @@ -68,7 +68,7 @@ func (this *AuthorityKeyService) ResetAuthorityKey(ctx context.Context, req *pb. if err != nil { return nil, err } - err = models.SharedAuthorityKeyDAO.ResetKey(nil) + err = authority.SharedAuthorityKeyDAO.ResetKey(nil) if err != nil { return nil, err } diff --git a/internal/rpc/services/service_authority_node.go b/internal/rpc/services/service_authority_node.go new file mode 100644 index 00000000..50db68a6 --- /dev/null +++ b/internal/rpc/services/service_authority_node.go @@ -0,0 +1,233 @@ +package services + +import ( + "context" + "github.com/TeaOSLab/EdgeAPI/internal/db/models/authority" + "github.com/TeaOSLab/EdgeAPI/internal/errors" + rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "google.golang.org/grpc/metadata" +) + +type AuthorityNodeService struct { + BaseService +} + +// CreateAuthorityNode 创建认证节点 +func (this *AuthorityNodeService) CreateAuthorityNode(ctx context.Context, req *pb.CreateAuthorityNodeRequest) (*pb.CreateAuthorityNodeResponse, error) { + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + tx := this.NullTx() + + nodeId, err := authority.SharedAuthorityNodeDAO.CreateAuthorityNode(tx, req.Name, req.Description, req.IsOn) + if err != nil { + return nil, err + } + + return &pb.CreateAuthorityNodeResponse{NodeId: nodeId}, nil +} + +// UpdateAuthorityNode 修改认证节点 +func (this *AuthorityNodeService) UpdateAuthorityNode(ctx context.Context, req *pb.UpdateAuthorityNodeRequest) (*pb.RPCSuccess, error) { + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + tx := this.NullTx() + + err = authority.SharedAuthorityNodeDAO.UpdateAuthorityNode(tx, req.NodeId, req.Name, req.Description, req.IsOn) + if err != nil { + return nil, err + } + + return this.Success() +} + +// DeleteAuthorityNode 删除认证节点 +func (this *AuthorityNodeService) DeleteAuthorityNode(ctx context.Context, req *pb.DeleteAuthorityNodeRequest) (*pb.RPCSuccess, error) { + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + tx := this.NullTx() + + err = authority.SharedAuthorityNodeDAO.DisableAuthorityNode(tx, req.NodeId) + if err != nil { + return nil, err + } + + return this.Success() +} + +// FindAllEnabledAuthorityNodes 列出所有可用认证节点 +func (this *AuthorityNodeService) FindAllEnabledAuthorityNodes(ctx context.Context, req *pb.FindAllEnabledAuthorityNodesRequest) (*pb.FindAllEnabledAuthorityNodesResponse, error) { + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + tx := this.NullTx() + + nodes, err := authority.SharedAuthorityNodeDAO.FindAllEnabledAuthorityNodes(tx) + if err != nil { + return nil, err + } + + result := []*pb.AuthorityNode{} + for _, node := range nodes { + result = append(result, &pb.AuthorityNode{ + Id: int64(node.Id), + IsOn: node.IsOn == 1, + UniqueId: node.UniqueId, + Secret: node.Secret, + Name: node.Name, + Description: node.Description, + }) + } + + return &pb.FindAllEnabledAuthorityNodesResponse{Nodes: result}, nil +} + +// CountAllEnabledAuthorityNodes 计算认证节点数量 +func (this *AuthorityNodeService) CountAllEnabledAuthorityNodes(ctx context.Context, req *pb.CountAllEnabledAuthorityNodesRequest) (*pb.RPCCountResponse, error) { + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + tx := this.NullTx() + + count, err := authority.SharedAuthorityNodeDAO.CountAllEnabledAuthorityNodes(tx) + if err != nil { + return nil, err + } + + return this.SuccessCount(count) +} + +// ListEnabledAuthorityNodes 列出单页的认证节点 +func (this *AuthorityNodeService) ListEnabledAuthorityNodes(ctx context.Context, req *pb.ListEnabledAuthorityNodesRequest) (*pb.ListEnabledAuthorityNodesResponse, error) { + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + tx := this.NullTx() + + nodes, err := authority.SharedAuthorityNodeDAO.ListEnabledAuthorityNodes(tx, req.Offset, req.Size) + if err != nil { + return nil, err + } + + result := []*pb.AuthorityNode{} + for _, node := range nodes { + result = append(result, &pb.AuthorityNode{ + Id: int64(node.Id), + IsOn: node.IsOn == 1, + UniqueId: node.UniqueId, + Secret: node.Secret, + Name: node.Name, + Description: node.Description, + StatusJSON: []byte(node.Status), + }) + } + + return &pb.ListEnabledAuthorityNodesResponse{Nodes: result}, nil +} + +// FindEnabledAuthorityNode 根据ID查找节点 +func (this *AuthorityNodeService) FindEnabledAuthorityNode(ctx context.Context, req *pb.FindEnabledAuthorityNodeRequest) (*pb.FindEnabledAuthorityNodeResponse, error) { + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + tx := this.NullTx() + + node, err := authority.SharedAuthorityNodeDAO.FindEnabledAuthorityNode(tx, req.NodeId) + if err != nil { + return nil, err + } + + if node == nil { + return &pb.FindEnabledAuthorityNodeResponse{Node: nil}, nil + } + + result := &pb.AuthorityNode{ + Id: int64(node.Id), + IsOn: node.IsOn == 1, + UniqueId: node.UniqueId, + Secret: node.Secret, + Name: node.Name, + Description: node.Description, + } + return &pb.FindEnabledAuthorityNodeResponse{Node: result}, nil +} + +// FindCurrentAuthorityNode 获取当前认证节点的版本 +func (this *AuthorityNodeService) FindCurrentAuthorityNode(ctx context.Context, req *pb.FindCurrentAuthorityNodeRequest) (*pb.FindCurrentAuthorityNodeResponse, error) { + _, err := this.ValidateAuthority(ctx) + if err != nil { + return nil, err + } + + tx := this.NullTx() + + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + return nil, errors.New("context: need 'nodeId'") + } + nodeIds := md.Get("nodeid") + if len(nodeIds) == 0 { + return nil, errors.New("invalid 'nodeId'") + } + nodeId := nodeIds[0] + node, err := authority.SharedAuthorityNodeDAO.FindEnabledAuthorityNodeWithUniqueId(tx, nodeId) + if err != nil { + return nil, err + } + + if node == nil { + return &pb.FindCurrentAuthorityNodeResponse{Node: nil}, nil + } + + result := &pb.AuthorityNode{ + Id: int64(node.Id), + IsOn: node.IsOn == 1, + UniqueId: node.UniqueId, + Secret: node.Secret, + Name: node.Name, + Description: node.Description, + } + return &pb.FindCurrentAuthorityNodeResponse{Node: result}, nil +} + +// UpdateAuthorityNodeStatus 更新节点状态 +func (this *AuthorityNodeService) UpdateAuthorityNodeStatus(ctx context.Context, req *pb.UpdateAuthorityNodeStatusRequest) (*pb.RPCSuccess, error) { + // 校验节点 + _, nodeId, err := this.ValidateNodeId(ctx, rpcutils.UserTypeAuthority) + if err != nil { + return nil, err + } + + if req.NodeId > 0 { + nodeId = req.NodeId + } + + if nodeId <= 0 { + return nil, errors.New("'nodeId' should be greater than 0") + } + + tx := this.NullTx() + + err = authority.SharedAuthorityNodeDAO.UpdateNodeStatus(tx, nodeId, req.StatusJSON) + if err != nil { + return nil, err + } + return this.Success() +} diff --git a/internal/rpc/services/service_base.go b/internal/rpc/services/service_base.go index 141c7b8f..9c3a386f 100644 --- a/internal/rpc/services/service_base.go +++ b/internal/rpc/services/service_base.go @@ -21,7 +21,7 @@ import ( type BaseService struct { } -// 校验管理员 +// ValidateAdmin 校验管理员 func (this *BaseService) ValidateAdmin(ctx context.Context, reqAdminId int64) (adminId int64, err error) { _, reqUserId, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) if err != nil { @@ -33,7 +33,7 @@ func (this *BaseService) ValidateAdmin(ctx context.Context, reqAdminId int64) (a return reqUserId, nil } -// 校验管理员和用户 +// ValidateAdminAndUser 校验管理员和用户 func (this *BaseService) ValidateAdminAndUser(ctx context.Context, requireAdminId int64, requireUserId int64) (adminId int64, userId int64, err error) { reqUserType, reqUserId, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser) if err != nil { @@ -70,25 +70,31 @@ func (this *BaseService) ValidateAdminAndUser(ctx context.Context, requireAdminI return } -// 校验边缘节点 +// ValidateNode 校验边缘节点 func (this *BaseService) ValidateNode(ctx context.Context) (nodeId int64, err error) { _, nodeId, err = rpcutils.ValidateRequest(ctx, rpcutils.UserTypeNode) return } -// 校验用户节点 +// ValidateUser 校验用户节点 func (this *BaseService) ValidateUser(ctx context.Context) (userId int64, err error) { _, userId, err = rpcutils.ValidateRequest(ctx, rpcutils.UserTypeUser) return } -// 校验监控节点 +// ValidateMonitor 校验监控节点 func (this *BaseService) ValidateMonitor(ctx context.Context) (nodeId int64, err error) { _, nodeId, err = rpcutils.ValidateRequest(ctx, rpcutils.UserTypeMonitor) return } -// 获取节点ID +// ValidateAuthority 校验认证节点 +func (this *BaseService) ValidateAuthority(ctx context.Context) (nodeId int64, err error) { + _, nodeId, err = rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAuthority) + return +} + +// ValidateNodeId 获取节点ID func (this *BaseService) ValidateNodeId(ctx context.Context, roles ...rpcutils.UserType) (role rpcutils.UserType, nodeIntId int64, err error) { if ctx == nil { err = errors.New("context should not be nil") @@ -185,27 +191,27 @@ func (this *BaseService) ValidateNodeId(ctx context.Context, roles ...rpcutils.U return } -// 返回成功 +// Success 返回成功 func (this *BaseService) Success() (*pb.RPCSuccess, error) { return &pb.RPCSuccess{}, nil } -// 返回数字 +// SuccessCount 返回数字 func (this *BaseService) SuccessCount(count int64) (*pb.RPCCountResponse, error) { return &pb.RPCCountResponse{Count: count}, nil } -// 返回权限错误 +// PermissionError 返回权限错误 func (this *BaseService) PermissionError() error { return errors.New("Permission Denied") } -// 空的数据库事务 +// NullTx 空的数据库事务 func (this *BaseService) NullTx() *dbs.Tx { return nil } -// 获取当前的数据库 +// RunTx 在当前数据中执行一个事务 func (this *BaseService) RunTx(callback func(tx *dbs.Tx) error) error { db, err := dbs.Default() if err != nil {