mirror of
https://github.com/APIParkLab/APIPark.git
synced 2026-06-14 20:41:15 +08:00
Consumer MCP completed
This commit is contained in:
@@ -33,7 +33,8 @@ type IAuthorizationModule interface {
|
||||
// Info 获取项目鉴权详情
|
||||
Info(ctx context.Context, appId string, aid string) (*application_authorization_dto.Authorization, error)
|
||||
|
||||
CheckAPIKeyAuthorization(ctx context.Context, serviceId string, apikey string) (bool, error)
|
||||
CheckAPIKeyAuthorizationByService(ctx context.Context, serviceId string, apikey string) (bool, error)
|
||||
CheckAPIKeyAuthorizationByApp(ctx context.Context, appId string, apikey string) (bool, error)
|
||||
|
||||
//ExportAll(ctx context.Context) ([]*application_authorization_dto.ExportAuthorization, error)
|
||||
}
|
||||
|
||||
@@ -44,7 +44,27 @@ type imlAuthorizationModule struct {
|
||||
transaction store.ITransaction `autowired:""`
|
||||
}
|
||||
|
||||
func (i *imlAuthorizationModule) CheckAPIKeyAuthorization(ctx context.Context, serviceId string, apikey string) (bool, error) {
|
||||
func (i *imlAuthorizationModule) CheckAPIKeyAuthorizationByApp(ctx context.Context, appId string, apikey string) (bool, error) {
|
||||
authorizations, err := i.authorizationService.ListByApp(ctx, appId)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
for _, a := range authorizations {
|
||||
if a.Type != "apikey" {
|
||||
continue
|
||||
}
|
||||
cfg := make(map[string]interface{})
|
||||
if a.Config != "" {
|
||||
json.Unmarshal([]byte(a.Config), &cfg)
|
||||
}
|
||||
if cfg["apikey"] == apikey {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (i *imlAuthorizationModule) CheckAPIKeyAuthorizationByService(ctx context.Context, serviceId string, apikey string) (bool, error) {
|
||||
list, err := i.subscribeService.ListBySubscribeStatus(ctx, serviceId, subscribe.ApplyStatusSubscribe)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
||||
+77
-105
@@ -46,18 +46,43 @@ type imlMcpModule struct {
|
||||
releaseService release.IReleaseService `autowired:""`
|
||||
}
|
||||
|
||||
func (i *imlMcpModule) subscribeServiceIds(ctx context.Context, appId string) ([]string, error) {
|
||||
subscribes, err := i.subscriberService.SubscriptionsByApplication(ctx, appId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get subscriber error: %w,app id is %s", err, appId)
|
||||
}
|
||||
serviceIds := utils.SliceToSlice(subscribes, func(s *subscribe.Subscribe) string {
|
||||
return s.Service
|
||||
}, func(s *subscribe.Subscribe) bool {
|
||||
return s.ApplyStatus == subscribe.ApplyStatusSubscribe
|
||||
})
|
||||
if len(serviceIds) == 0 {
|
||||
return nil, fmt.Errorf("no subscriber found,app id is %s", appId)
|
||||
}
|
||||
return serviceIds, nil
|
||||
}
|
||||
|
||||
func (i *imlMcpModule) Services(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
|
||||
keyword, _ := req.GetArguments()["keyword"].(string)
|
||||
list, err := i.serviceService.Search(ctx, keyword, map[string]interface{}{
|
||||
appId := utils.Label(ctx, "app")
|
||||
condition := map[string]interface{}{
|
||||
"as_server": true,
|
||||
}, "update_at desc")
|
||||
}
|
||||
if appId != "" {
|
||||
serviceIds, err := i.subscribeServiceIds(ctx, appId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get subscriber service ids error: %w,app id is %s", err, appId)
|
||||
}
|
||||
condition["uuid"] = serviceIds
|
||||
}
|
||||
|
||||
list, err := i.serviceService.Search(ctx, keyword, condition, "update_at desc")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("search service error: %w", err)
|
||||
}
|
||||
if len(list) == 0 {
|
||||
list, err = i.serviceService.Search(ctx, "", map[string]interface{}{
|
||||
"as_server": true,
|
||||
}, "update_at desc")
|
||||
list, err = i.serviceService.Search(ctx, "", condition, "update_at desc")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("search service error: %w", err)
|
||||
}
|
||||
@@ -115,120 +140,61 @@ func (i *imlMcpModule) Services(ctx context.Context, req mcp.CallToolRequest) (*
|
||||
|
||||
}
|
||||
|
||||
//func (i *imlMcpModule) Apps(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
// keyword := req.GetArguments()["keyword"].(string)
|
||||
// condition := make(map[string]interface{})
|
||||
// condition["as_app"] = true
|
||||
// list, err := i.serviceService.Search(ctx, keyword, condition, "update_at desc")
|
||||
// if err != nil {
|
||||
// return nil, fmt.Errorf("search service error: %w", err)
|
||||
// }
|
||||
// if len(list) == 0 {
|
||||
// list, err = i.serviceService.Search(ctx, "", condition, "update_at desc")
|
||||
// if err != nil {
|
||||
// return nil, fmt.Errorf("search service error: %w", err)
|
||||
// }
|
||||
// }
|
||||
// data, _ := json.Marshal(utils.SliceToSlice(list, func(s *service.Service) *mcp_dto.App {
|
||||
// return &mcp_dto.App{
|
||||
// Id: s.Id,
|
||||
// Name: s.Name,
|
||||
// Description: s.Name,
|
||||
// CreateTime: s.CreateTime,
|
||||
// UpdateTime: s.UpdateTime,
|
||||
// }
|
||||
// }))
|
||||
// return mcp.NewToolResultText(string(data)), nil
|
||||
//}
|
||||
|
||||
func (i *imlMcpModule) APIs(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
serviceId, _ := req.GetArguments()["service"].(string)
|
||||
serviceIds := make([]string, 0, 1)
|
||||
if serviceId == "" {
|
||||
serviceIds = append(serviceIds, serviceId)
|
||||
return nil, fmt.Errorf("service id is empty")
|
||||
}
|
||||
serviceList, err := i.serviceService.ServiceList(ctx)
|
||||
s, err := i.serviceService.Get(ctx, serviceId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get service list error: %w", err)
|
||||
return nil, fmt.Errorf("get service error: %w,service id is %s", err, serviceId)
|
||||
}
|
||||
appId := utils.Label(ctx, "app")
|
||||
if appId != "" {
|
||||
subscribers, err := i.subscriberService.ListByApplication(ctx, serviceId, appId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get subscriber error: %w,app id is %s", err, appId)
|
||||
}
|
||||
if len(subscribers) < 1 || subscribers[0].ApplyStatus != subscribe.ApplyStatusSubscribe {
|
||||
return nil, fmt.Errorf("no subscriber found,app id is %s", appId)
|
||||
}
|
||||
}
|
||||
result := make([]*mcp_dto.ServiceAPI, 0, len(serviceList))
|
||||
|
||||
for _, s := range serviceList {
|
||||
serviceRelease, err := i.releaseService.GetRunning(ctx, s.Id)
|
||||
if err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fmt.Errorf("get service release error: %w,service id is %s", err, s.Id)
|
||||
}
|
||||
continue
|
||||
serviceRelease, err := i.releaseService.GetRunning(ctx, serviceId)
|
||||
if err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fmt.Errorf("get service release error: %w,service id is %s", err, s.Id)
|
||||
}
|
||||
_, _, apiDocRelease, _, _, err := i.releaseService.GetReleaseInfos(ctx, serviceRelease.UUID)
|
||||
if err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fmt.Errorf("get service release info error: %w,service id is %s", err, s.Id)
|
||||
}
|
||||
continue
|
||||
return nil, fmt.Errorf("no service found,service id is %s", serviceId)
|
||||
}
|
||||
_, _, apiDocRelease, _, _, err := i.releaseService.GetReleaseInfos(ctx, serviceRelease.UUID)
|
||||
if err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fmt.Errorf("get service release info error: %w,service id is %s", err, s.Id)
|
||||
}
|
||||
commit, err := i.apiDocService.GetDocCommit(ctx, apiDocRelease.Commit)
|
||||
if err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fmt.Errorf("get api doc release error: %w,service id is %s", err, s.Id)
|
||||
}
|
||||
continue
|
||||
return nil, fmt.Errorf("no service found,service id is %s", serviceId)
|
||||
}
|
||||
commit, err := i.apiDocService.GetDocCommit(ctx, apiDocRelease.Commit)
|
||||
if err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fmt.Errorf("get api doc release error: %w,service id is %s", err, s.Id)
|
||||
}
|
||||
T, err := openapi3Loader.LoadFromData([]byte(commit.Data.Content))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load openapi3 error: %w,service id is %s", err, s.Id)
|
||||
}
|
||||
result = append(result, &mcp_dto.ServiceAPI{
|
||||
ServiceID: s.Id,
|
||||
ServiceName: s.Name,
|
||||
APIDoc: T,
|
||||
})
|
||||
return nil, fmt.Errorf("no service found,service id is %s", serviceId)
|
||||
}
|
||||
T, err := openapi3Loader.LoadFromData([]byte(commit.Data.Content))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("load openapi3 error: %w,service id is %s", err, s.Id)
|
||||
}
|
||||
|
||||
result := &mcp_dto.ServiceAPI{
|
||||
ServiceID: serviceId,
|
||||
ServiceName: s.Name,
|
||||
APIDoc: T,
|
||||
}
|
||||
data, _ := json.Marshal(result)
|
||||
return mcp.NewToolResultText(string(data)), nil
|
||||
}
|
||||
|
||||
//func (i *imlMcpModule) SubscriberAuthorizations(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
// serviceId, ok := req.GetArguments()["service"].(string)
|
||||
// if !ok {
|
||||
// return nil, fmt.Errorf("service id is required")
|
||||
// }
|
||||
// subscribes, err := i.subscriberService.Subscribers(ctx, serviceId, subscribe.ApplyStatusSubscribe)
|
||||
// if err != nil {
|
||||
// return nil, fmt.Errorf("get subscriber error: %w,service id is %s", err, serviceId)
|
||||
// }
|
||||
// appIds := utils.SliceToSlice(subscribes, func(s *subscribe.Subscribe) string {
|
||||
// return s.Application
|
||||
// })
|
||||
// if len(appIds) == 0 {
|
||||
// return nil, fmt.Errorf("no subscriber found,service id is %s", serviceId)
|
||||
// }
|
||||
// list, err := i.appAuthorizationService.ListByApp(ctx, appIds...)
|
||||
// if err != nil {
|
||||
// return nil, fmt.Errorf("get app authorization error: %w,app ids is %s", err, appIds)
|
||||
// }
|
||||
// result := utils.SliceToSlice(list, func(a *application_authorization.Authorization) *mcp_dto.AppAuthorization {
|
||||
// return &mcp_dto.AppAuthorization{
|
||||
// Id: a.UUID,
|
||||
// Name: a.Name,
|
||||
// position: a.position,
|
||||
// TokenName: a.TokenName,
|
||||
// Config: a.Config,
|
||||
// }
|
||||
// }, func(a *application_authorization.Authorization) bool {
|
||||
// if a.Type != "apikey" {
|
||||
// return false
|
||||
// }
|
||||
// if a.ExpireTime != 0 && a.ExpireTime < time.Now().Unix() {
|
||||
// return false
|
||||
// }
|
||||
// return true
|
||||
// })
|
||||
// data, _ := json.Marshal(result)
|
||||
// return mcp.NewToolResultText(string(data)), nil
|
||||
//}
|
||||
|
||||
var (
|
||||
client = &http.Client{}
|
||||
)
|
||||
@@ -309,8 +275,14 @@ func (i *imlMcpModule) Invoke(ctx context.Context, req mcp.CallToolRequest) (*mc
|
||||
request.Header = headerParam
|
||||
request.Header.Set("Content-Type", contentType)
|
||||
apikey := utils.Label(ctx, "apikey")
|
||||
|
||||
if apikey != "" {
|
||||
request.Header.Set("Authorization", utils.Md5(apikey))
|
||||
appId := utils.Label(ctx, "app")
|
||||
if appId == "" {
|
||||
request.Header.Set("Authorization", utils.Md5(apikey))
|
||||
} else {
|
||||
request.Header.Set("Authorization", apikey)
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := client.Do(request)
|
||||
|
||||
@@ -12,13 +12,7 @@ import (
|
||||
type IMcpModule interface {
|
||||
// Services 获取服务列表
|
||||
Services(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error)
|
||||
// Apps 获取应用列表
|
||||
//Apps(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error)
|
||||
// APIs 获取API列表
|
||||
APIs(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error)
|
||||
|
||||
// SubscriberAuthorizations 获取订阅者授权
|
||||
//SubscriberAuthorizations(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error)
|
||||
Invoke(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error)
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,46 @@ type imlAPIKeyModule struct {
|
||||
transaction store.ITransaction `autowired:""`
|
||||
}
|
||||
|
||||
func (i *imlAPIKeyModule) MyAPIKeysByApp(ctx context.Context, appId string) ([]*system_apikey_dto.AuthorizationItem, error) {
|
||||
appInfo, err := i.serviceService.Get(ctx, appId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
auths, err := i.applicationAuthorizationService.ListByApp(ctx, appId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := make(map[string]*system_apikey_dto.AuthorizationItem)
|
||||
for _, a := range auths {
|
||||
if a.Type != "apikey" {
|
||||
continue
|
||||
}
|
||||
|
||||
m := make(map[string]string)
|
||||
json.Unmarshal([]byte(a.Config), &m)
|
||||
if m["apikey"] == "" {
|
||||
continue
|
||||
}
|
||||
if _, ok := result[appInfo.Id]; !ok {
|
||||
result[appInfo.Id] = &system_apikey_dto.AuthorizationItem{
|
||||
Id: appInfo.Id,
|
||||
Name: appInfo.Name,
|
||||
Apikeys: []system_apikey_dto.SimpleItem{},
|
||||
}
|
||||
}
|
||||
result[appInfo.Id].Apikeys = append(result[appInfo.Id].Apikeys, system_apikey_dto.SimpleItem{
|
||||
Id: a.UUID,
|
||||
Name: a.Name,
|
||||
Value: m["apikey"],
|
||||
Expired: a.ExpireTime,
|
||||
})
|
||||
|
||||
}
|
||||
return utils.MapToSlice(result, func(k string, t *system_apikey_dto.AuthorizationItem) *system_apikey_dto.AuthorizationItem {
|
||||
return t
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (i *imlAPIKeyModule) MyAPIKeysByService(ctx context.Context, serviceId string) ([]*system_apikey_dto.AuthorizationItem, error) {
|
||||
list, err := i.subscribeService.ListBySubscribeStatus(ctx, serviceId, subscribe.ApplyStatusSubscribe)
|
||||
if err != nil {
|
||||
|
||||
@@ -19,6 +19,7 @@ type IAPIKeyModule interface {
|
||||
SimpleList(ctx context.Context) ([]*system_apikey_dto.SimpleItem, error)
|
||||
MyAPIKeys(ctx context.Context) ([]*system_apikey_dto.SimpleItem, error)
|
||||
MyAPIKeysByService(ctx context.Context, serviceId string) ([]*system_apikey_dto.AuthorizationItem, error)
|
||||
MyAPIKeysByApp(ctx context.Context, appId string) ([]*system_apikey_dto.AuthorizationItem, error)
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
Reference in New Issue
Block a user