125 lines
3.9 KiB
Go
125 lines
3.9 KiB
Go
package tenant
|
|
|
|
import (
|
|
"context"
|
|
|
|
v1 "github.com/qianfree/team-api/api/tenant/v1"
|
|
"github.com/qianfree/team-api/internal/dao"
|
|
"github.com/qianfree/team-api/internal/logic/common"
|
|
"github.com/qianfree/team-api/internal/middleware"
|
|
"github.com/qianfree/team-api/internal/plugin"
|
|
|
|
"github.com/gogf/gf/v2/errors/gerror"
|
|
)
|
|
|
|
func (s *sTenant) TenantPluginList(ctx context.Context, req *v1.TenantPluginListReq) (*v1.TenantPluginListRes, error) {
|
|
tenantID := middleware.GetTenantID(ctx)
|
|
entries := plugin.AllPlugins()
|
|
items := make([]v1.TenantPluginItem, 0, len(entries))
|
|
|
|
// 查询租户已启用的插件
|
|
tenantPlugins, _ := dao.TntTenantPlugins.Ctx(ctx).
|
|
Where("tenant_id", tenantID).
|
|
All()
|
|
tenantEnabled := make(map[string]bool)
|
|
for _, r := range tenantPlugins {
|
|
tenantEnabled[r["plugin_name"].String()] = r["enabled"].Bool()
|
|
}
|
|
|
|
for _, entry := range entries {
|
|
// 只展示已全局启用的插件
|
|
if entry.Status != plugin.StatusEnabled {
|
|
continue
|
|
}
|
|
|
|
items = append(items, v1.TenantPluginItem{
|
|
Name: entry.Info.Name,
|
|
Label: entry.Info.Label,
|
|
Description: entry.Info.Description,
|
|
Version: entry.Info.Version,
|
|
Category: entry.Info.Category,
|
|
Enabled: tenantEnabled[entry.Info.Name],
|
|
})
|
|
}
|
|
|
|
return &v1.TenantPluginListRes{List: items}, nil
|
|
}
|
|
|
|
func (s *sTenant) TenantPluginDetail(ctx context.Context, req *v1.TenantPluginDetailReq) (*v1.TenantPluginDetailRes, error) {
|
|
tenantID := middleware.GetTenantID(ctx)
|
|
entry := plugin.GetPlugin(req.Name)
|
|
if entry == nil {
|
|
return nil, gerror.New("插件不存在")
|
|
}
|
|
|
|
config, _ := plugin.GetPluginConfigForTenant(ctx, req.Name, tenantID)
|
|
if config == nil {
|
|
config = make(map[string]interface{})
|
|
}
|
|
|
|
// 检查租户是否启用
|
|
enabled := false
|
|
record, _ := dao.TntTenantPlugins.Ctx(ctx).
|
|
Where("tenant_id = ? AND plugin_name = ?", tenantID, req.Name).
|
|
One()
|
|
if record != nil {
|
|
enabled = record["enabled"].Bool()
|
|
}
|
|
|
|
return &v1.TenantPluginDetailRes{
|
|
Name: entry.Info.Name,
|
|
Label: entry.Info.Label,
|
|
Description: entry.Info.Description,
|
|
Version: entry.Info.Version,
|
|
Category: entry.Info.Category,
|
|
Enabled: enabled,
|
|
Config: config,
|
|
}, nil
|
|
}
|
|
|
|
// assertPluginManager 校验插件的写操作权限。
|
|
//
|
|
// 插件配置与启停是【组织级】设置:一次改动对整个租户的全部成员生效,配置里还可能包含
|
|
// 第三方凭据。此前三个写接口只取了 tenantID 就直接落库,任意 member 都能改掉或关停
|
|
// 全组织的插件,与 List/Detail(读)同权。读保持全员可见,写收敛到 owner/admin。
|
|
func assertPluginManager(ctx context.Context) error {
|
|
role := middleware.GetUserRole(ctx)
|
|
if role != "owner" && role != "admin" {
|
|
return common.NewForbiddenError("需要 owner 或 admin 权限")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *sTenant) TenantPluginConfigUpdate(ctx context.Context, req *v1.TenantPluginConfigUpdateReq) (*v1.TenantPluginConfigUpdateRes, error) {
|
|
if err := assertPluginManager(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
tenantID := middleware.GetTenantID(ctx)
|
|
if err := plugin.UpdatePluginConfigForTenant(ctx, req.Name, tenantID, req.Config); err != nil {
|
|
return nil, err
|
|
}
|
|
return &v1.TenantPluginConfigUpdateRes{}, nil
|
|
}
|
|
|
|
func (s *sTenant) TenantPluginEnable(ctx context.Context, req *v1.TenantPluginEnableReq) (*v1.TenantPluginEnableRes, error) {
|
|
if err := assertPluginManager(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
tenantID := middleware.GetTenantID(ctx)
|
|
if err := plugin.EnableForTenant(ctx, req.Name, tenantID); err != nil {
|
|
return nil, err
|
|
}
|
|
return &v1.TenantPluginEnableRes{}, nil
|
|
}
|
|
|
|
func (s *sTenant) TenantPluginDisable(ctx context.Context, req *v1.TenantPluginDisableReq) (*v1.TenantPluginDisableRes, error) {
|
|
if err := assertPluginManager(ctx); err != nil {
|
|
return nil, err
|
|
}
|
|
tenantID := middleware.GetTenantID(ctx)
|
|
if err := plugin.DisableForTenant(ctx, req.Name, tenantID); err != nil {
|
|
return nil, err
|
|
}
|
|
return &v1.TenantPluginDisableRes{}, nil
|
|
}
|