From 5b5f39657d4a8c28244b92e7a624a9257c39c372 Mon Sep 17 00:00:00 2001 From: Anna <2496253516@qq.com> Date: Tue, 22 Apr 2025 17:32:04 +0800 Subject: [PATCH] feat: call other platforms using virtual user --story=122806009 --- pkg/tenant/logics/tenant.go | 34 ++++-- pkg/tenant/tools/tenant.go | 48 ++++++++ src/apiserver/app/server.go | 28 +---- src/apiserver/service/filter.go | 4 +- src/common/http/header/util/util.go | 3 +- src/common/metadata/audit.go | 2 +- src/scene_server/admin_server/app/server.go | 2 +- .../admin_server/service/migrate.go | 4 +- .../admin_server/service/tenant.go | 6 +- .../sync/hostidentifier/common.go | 4 +- src/thirdparty/apigw/apigw.go | 18 ++- src/thirdparty/apigw/apigwutil/user/user.go | 106 ++++++++++++++++++ src/thirdparty/apigw/gse/api.go | 82 ++++++++++---- src/thirdparty/apigw/gse/service.go | 5 +- src/thirdparty/apigw/login/api.go | 20 +++- src/thirdparty/apigw/login/service.go | 5 +- src/thirdparty/apigw/notice/api.go | 20 +++- src/thirdparty/apigw/notice/service.go | 5 +- src/thirdparty/apigw/user/api.go | 88 ++++++++++++--- src/thirdparty/apigw/user/service.go | 12 +- .../apigw/user/{ => types}/types.go | 30 ++--- src/web_server/app/server.go | 2 +- src/web_server/middleware/login.go | 4 +- .../user/plugins/method/blueking/userinfo.go | 10 +- .../middleware/user/plugins/method/utils.go | 4 +- src/web_server/middleware/user/public.go | 4 +- .../service/excel/core/field_func.go | 10 +- src/web_server/service/service.go | 3 +- 28 files changed, 418 insertions(+), 145 deletions(-) create mode 100644 pkg/tenant/tools/tenant.go create mode 100644 src/thirdparty/apigw/apigwutil/user/user.go rename src/thirdparty/apigw/user/{ => types}/types.go (84%) diff --git a/pkg/tenant/logics/tenant.go b/pkg/tenant/logics/tenant.go index 5f8125c70a..4fb8d324ab 100644 --- a/pkg/tenant/logics/tenant.go +++ b/pkg/tenant/logics/tenant.go @@ -19,19 +19,33 @@ package logics import ( "fmt" + "time" - "configcenter/src/common" + "configcenter/pkg/tenant" + "configcenter/src/apimachinery" + "configcenter/src/common/blog" + "configcenter/src/common/types" ) -// ValidateDisableTenantMode validate disable multi-tenant mode -func ValidateDisableTenantMode(tenantID string, enableTenantMode bool) (string, error) { - if !enableTenantMode { - if tenantID == "" || tenantID == common.BKSingleTenantID { - return common.BKSingleTenantID, nil +// InitTenant init tenant, refresh tenants info while server is starting +func InitTenant(apiMachineryCli apimachinery.ClientSetInterface) error { + coreExist := false + for retry := 0; retry < 10; retry++ { + if _, err := apiMachineryCli.Healthz().HealthCheck(types.CC_MODULE_CORESERVICE); err != nil { + blog.Errorf("connect core server failed: %v", err) + time.Sleep(time.Second * 2) + continue } - - return "", fmt.Errorf("tenant mode is disable, but tenant id %s is set", tenantID) + coreExist = true + break } - - return tenantID, nil + if !coreExist { + blog.Errorf("core server not exist") + return fmt.Errorf("core server not exist") + } + err := tenant.Init(&tenant.Options{ApiMachineryCli: apiMachineryCli}) + if err != nil { + return err + } + return nil } diff --git a/pkg/tenant/tools/tenant.go b/pkg/tenant/tools/tenant.go new file mode 100644 index 0000000000..9ff5fe9e14 --- /dev/null +++ b/pkg/tenant/tools/tenant.go @@ -0,0 +1,48 @@ +/* + * Tencent is pleased to support the open source community by making + * 蓝鲸智云 - 配置平台 (BlueKing - Configuration System) available. + * Copyright (C) 2017 THL A29 Limited, + * a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * We undertake not to change the open source license (MIT license) applicable + * to the current version of the project delivered to anyone in the future. + */ + +package tools + +import ( + "fmt" + + "configcenter/src/common" + cc "configcenter/src/common/backbone/configcenter" +) + +// GetDefaultTenant get default tenant +func GetDefaultTenant() string { + enableMultiTenant, _ := cc.Bool("tenant.enableMultiTenantMode") + if enableMultiTenant { + return common.BKDefaultTenantID + } + + return common.BKSingleTenantID +} + +// ValidateDisableTenantMode validate disable multi-tenant mode +func ValidateDisableTenantMode(tenantID string, enableTenantMode bool) (string, error) { + if !enableTenantMode { + if tenantID == "" || tenantID == common.BKSingleTenantID { + return common.BKSingleTenantID, nil + } + + return "", fmt.Errorf("tenant mode is disable, but tenant id %s is set", tenantID) + } + + return tenantID, nil +} diff --git a/src/apiserver/app/server.go b/src/apiserver/app/server.go index c52c968867..89db57e733 100644 --- a/src/apiserver/app/server.go +++ b/src/apiserver/app/server.go @@ -15,10 +15,8 @@ package app import ( "context" "fmt" - "time" - "configcenter/pkg/tenant" - "configcenter/src/apimachinery" + "configcenter/pkg/tenant/logics" "configcenter/src/apimachinery/util" "configcenter/src/apiserver/app/options" "configcenter/src/apiserver/service" @@ -95,7 +93,7 @@ func Run(ctx context.Context, cancel context.CancelFunc, op *options.ServerOptio ctnr.Add(item) } apiSvr.Core = engine - if err = initTenant(engine.CoreAPI); err != nil { + if err = logics.InitTenant(engine.CoreAPI); err != nil { return err } err = backbone.StartServer(ctx, cancel, engine, ctnr, false) @@ -109,28 +107,6 @@ func Run(ctx context.Context, cancel context.CancelFunc, op *options.ServerOptio return nil } -func initTenant(apiMachineryCli apimachinery.ClientSetInterface) error { - coreExist := false - for retry := 0; retry < 10; retry++ { - if _, err := apiMachineryCli.Healthz().HealthCheck(types.CC_MODULE_CORESERVICE); err != nil { - blog.Errorf("connect core server failed: %v", err) - time.Sleep(time.Second * 2) - continue - } - coreExist = true - break - } - if !coreExist { - blog.Errorf("core server not exist") - return fmt.Errorf("core server not exist") - } - err := tenant.Init(&tenant.Options{ApiMachineryCli: apiMachineryCli}) - if err != nil { - return err - } - return nil -} - // APIServer TODO type APIServer struct { Core *backbone.Engine diff --git a/src/apiserver/service/filter.go b/src/apiserver/service/filter.go index fc976231f3..74c900ac67 100644 --- a/src/apiserver/service/filter.go +++ b/src/apiserver/service/filter.go @@ -20,7 +20,7 @@ import ( "strings" "configcenter/pkg/tenant" - "configcenter/pkg/tenant/logics" + "configcenter/pkg/tenant/tools" "configcenter/pkg/tenant/types" tenantset "configcenter/pkg/types/tenant-set" "configcenter/src/ac/meta" @@ -503,7 +503,7 @@ func (s *service) JwtFilter() func(req *restful.Request, resp *restful.Response, func (s *service) TenantVerify() func(req *restful.Request, resp *restful.Response, fchain *restful.FilterChain) { return func(req *restful.Request, resp *restful.Response, fchain *restful.FilterChain) { - tenantID, err := logics.ValidateDisableTenantMode(httpheader.GetTenantID(req.Request.Header), + tenantID, err := tools.ValidateDisableTenantMode(httpheader.GetTenantID(req.Request.Header), s.config.EnableMultiTenantMode) if err != nil { blog.Errorf("get tenant with mode failed, err: %v, rid: %s", err, httpheader.GetRid(req.Request.Header)) diff --git a/src/common/http/header/util/util.go b/src/common/http/header/util/util.go index e5067a425b..0d2d499135 100644 --- a/src/common/http/header/util/util.go +++ b/src/common/http/header/util/util.go @@ -22,6 +22,7 @@ import ( "context" "net/http" + "configcenter/pkg/tenant/tools" "configcenter/src/common" httpheader "configcenter/src/common/http/header" "configcenter/src/common/util" @@ -56,7 +57,7 @@ func GenCommonHeader(user, tenantID, rid string) http.Header { } if tenantID == "" { - tenantID = common.BKDefaultTenantID + tenantID = tools.GetDefaultTenant() } if rid == "" { diff --git a/src/common/metadata/audit.go b/src/common/metadata/audit.go index 0136494a9d..e93f7b3b3f 100644 --- a/src/common/metadata/audit.go +++ b/src/common/metadata/audit.go @@ -1357,7 +1357,7 @@ var auditEnDict = []resourceTypeInfo{ }, { ID: TenantTemplateRes, - Name: "tenant template", + Name: "Tenant Template", Operations: []actionTypeInfo{ actionInfoEnMap[AuditCreate], actionInfoEnMap[AuditUpdate], diff --git a/src/scene_server/admin_server/app/server.go b/src/scene_server/admin_server/app/server.go index 105f62e021..5df1ad50f9 100644 --- a/src/scene_server/admin_server/app/server.go +++ b/src/scene_server/admin_server/app/server.go @@ -106,7 +106,7 @@ func Run(ctx context.Context, cancel context.CancelFunc, op *options.ServerOptio return err } - if err := service.BackgroundTask(*process.Config); err != nil { + if err = service.BackgroundTask(*process.Config); err != nil { return err } err = backbone.StartServer(ctx, cancel, process.Core, service.WebService(), true) diff --git a/src/scene_server/admin_server/service/migrate.go b/src/scene_server/admin_server/service/migrate.go index 5d18d9e4ff..a35c74e1e1 100644 --- a/src/scene_server/admin_server/service/migrate.go +++ b/src/scene_server/admin_server/service/migrate.go @@ -25,7 +25,7 @@ import ( "time" "configcenter/pkg/tenant" - tenantlogics "configcenter/pkg/tenant/logics" + "configcenter/pkg/tenant/tools" "configcenter/src/common" "configcenter/src/common/blog" httpheader "configcenter/src/common/http/header" @@ -52,7 +52,7 @@ func (s *Service) migrateDatabase(req *restful.Request, resp *restful.Response) defErr := s.CCErr.CreateDefaultCCErrorIf(httpheader.GetLanguage(rHeader)) // get tenant id - tenantID, err := tenantlogics.ValidateDisableTenantMode(req.Request.Header.Get(httpheader.TenantHeader), + tenantID, err := tools.ValidateDisableTenantMode(req.Request.Header.Get(httpheader.TenantHeader), s.Config.EnableMultiTenantMode) if err != nil { result := &metadata.RespError{ diff --git a/src/scene_server/admin_server/service/tenant.go b/src/scene_server/admin_server/service/tenant.go index 5c90613fc6..c2b1912fd7 100644 --- a/src/scene_server/admin_server/service/tenant.go +++ b/src/scene_server/admin_server/service/tenant.go @@ -37,8 +37,6 @@ import ( "configcenter/src/storage/dal/mongo/local" daltypes "configcenter/src/storage/dal/types" "configcenter/src/storage/driver/mongodb" - "configcenter/src/thirdparty/apigw/user" - "github.com/emicklei/go-restful/v3" ) @@ -74,12 +72,12 @@ func (s *Service) addTenant(req *restful.Request, resp *restful.Response) { resp.WriteError(http.StatusInternalServerError, result) } - tenantMap := make(map[string]user.Status) + tenantMap := make(map[string]types.Status) for _, tenant := range tenants { tenantMap[tenant.ID] = tenant.Status } - if status, ok := tenantMap[kit.TenantID]; !ok || status != user.EnabledStatus { + if status, ok := tenantMap[kit.TenantID]; !ok || status != types.EnabledStatus { blog.Errorf("tenant %s invalid, rid: %s", kit.TenantID, kit.Rid) result := &metadata.RespError{ Msg: defErr.Errorf(common.CCErrCommAddTenantErr, diff --git a/src/scene_server/event_server/sync/hostidentifier/common.go b/src/scene_server/event_server/sync/hostidentifier/common.go index c0e806be36..6f5b6ba0b0 100644 --- a/src/scene_server/event_server/sync/hostidentifier/common.go +++ b/src/scene_server/event_server/sync/hostidentifier/common.go @@ -20,6 +20,7 @@ import ( "strings" "time" + "configcenter/pkg/tenant/tools" "configcenter/src/common" "configcenter/src/common/blog" headerutil "configcenter/src/common/http/header/util" @@ -49,7 +50,8 @@ func sleepForFail(failCount int) { func newHeaderWithRid() (http.Header, string) { rid := util.GenerateRID() - header := headerutil.GenCommonHeader(common.CCSystemOperatorUserName, common.BKDefaultTenantID, rid) + tenantID := tools.GetDefaultTenant() + header := headerutil.GenCommonHeader(common.CCSystemOperatorUserName, tenantID, rid) return header, rid } diff --git a/src/thirdparty/apigw/apigw.go b/src/thirdparty/apigw/apigw.go index 11369d9faf..c89db9d81d 100644 --- a/src/thirdparty/apigw/apigw.go +++ b/src/thirdparty/apigw/apigw.go @@ -84,8 +84,13 @@ func NewClientSet(config *apigwutil.ApiGWConfig, metric prometheus.Registerer, n neededCliMap[neededClient] = struct{}{} } + cs.user, err = user.NewClient(options) + if err != nil { + return nil, err + } + if _, exists := neededCliMap[Gse]; exists { - cs.gse, err = gse.NewClient(options) + cs.gse, err = gse.NewClient(options, cs.user) if err != nil { return nil, err } @@ -99,21 +104,14 @@ func NewClientSet(config *apigwutil.ApiGWConfig, metric prometheus.Registerer, n } if _, exists := neededCliMap[Notice]; exists { - cs.notice, err = notice.NewClient(options) + cs.notice, err = notice.NewClient(options, cs.user) if err != nil { return nil, err } } if _, exists := neededCliMap[Login]; exists { - cs.login, err = login.NewClient(options) - if err != nil { - return nil, err - } - } - - if _, exists := neededCliMap[User]; exists { - cs.user, err = user.NewClient(options) + cs.login, err = login.NewClient(options, cs.user) if err != nil { return nil, err } diff --git a/src/thirdparty/apigw/apigwutil/user/user.go b/src/thirdparty/apigw/apigwutil/user/user.go new file mode 100644 index 0000000000..f440e45e1c --- /dev/null +++ b/src/thirdparty/apigw/apigwutil/user/user.go @@ -0,0 +1,106 @@ +/* + * Tencent is pleased to support the open source community by making + * 蓝鲸智云 - 配置平台 (BlueKing - Configuration System) available. + * Copyright (C) 2017 THL A29 Limited, + * a Tencent company. All rights reserved. + * Licensed under the MIT License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://opensource.org/licenses/MIT + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * We undertake not to change the open source license (MIT license) applicable + * to the current version of the project delivered to anyone in the future. + */ + +package user + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "sync" + + "configcenter/src/common/blog" + httpheader "configcenter/src/common/http/header" + "configcenter/src/thirdparty/apigw/apigwutil" + "configcenter/src/thirdparty/apigw/user/types" +) + +// VirtualUserClientI is the user api gateway client for virtual user +type VirtualUserClientI interface { + BatchSearchVirtualUser(ctx context.Context, h http.Header, loginNames []string) ([]types.VirtualUserItem, error) +} + +var ( + virtualUserAuth = make(map[string]string) + lock sync.RWMutex +) + +// getAuthConfigByTenant get virtual user by tenantID +func getAuthConfigByTenant(tenantID string) (string, bool) { + lock.RLock() + defer lock.RUnlock() + authConfig, exist := virtualUserAuth[tenantID] + if !exist { + return "", false + } + return authConfig, true +} + +// setAuthConfig set virtual user by tenantID +func setAuthConfig(tenantID string, authConfig string) { + lock.Lock() + defer lock.Unlock() + virtualUserAuth[tenantID] = authConfig + return +} + +// SetBKAuthHeader set api gateway authorization header +func SetBKAuthHeader(ctx context.Context, conf *apigwutil.ApiGWConfig, header http.Header, + userCli VirtualUserClientI) (http.Header, error) { + + tenantID := httpheader.GetTenantID(header) + if tenantID == "" { + fmt.Errorf("tenant id is empty") + return nil, fmt.Errorf("tenant id is empty") + } + + if authInfo, exist := getAuthConfigByTenant(tenantID); exist { + header = httpheader.SetBkAuth(header, authInfo) + return header, nil + } + + authConf := apigwutil.AuthConfig{ + AppAuthConfig: apigwutil.AppAuthConfig{ + AppCode: conf.AppCode, + AppSecret: conf.AppSecret, + }, + } + + resp, err := userCli.BatchSearchVirtualUser(ctx, header, []string{"bk_admin"}) + if err != nil { + blog.Errorf("search virtual user failed, err: %v", err) + return nil, err + } + + if len(resp) != 1 { + blog.Errorf("search virtual user failed, resp: %v", resp) + return header, fmt.Errorf("search virtual user failed, resp: %v", resp) + } + + authConf.UserName = resp[0].VirtualUserName + + authInfo, err := json.Marshal(authConf) + if err != nil { + blog.Errorf("marshal default api auth config %+v failed, err: %v", authConf, err) + return header, err + } + + header = httpheader.SetBkAuth(header, string(authInfo)) + setAuthConfig(tenantID, string(authInfo)) + return header, nil +} diff --git a/src/thirdparty/apigw/gse/api.go b/src/thirdparty/apigw/gse/api.go index 060d2fd651..85b67d048d 100644 --- a/src/thirdparty/apigw/gse/api.go +++ b/src/thirdparty/apigw/gse/api.go @@ -22,9 +22,9 @@ import ( "fmt" "net/http" - httpheader "configcenter/src/common/http/header" "configcenter/src/common/metadata" "configcenter/src/thirdparty/apigw/apigwutil" + "configcenter/src/thirdparty/apigw/apigwutil/user" ) // ListAgentState list gse agent state @@ -34,11 +34,16 @@ func (p *gse) ListAgentState(ctx context.Context, h http.Header, data *ListAgent resp := new(ListAgentStateResp) subPath := "/api/v2/cluster/list_agent_state" - err := p.service.Client.Post(). + h, err := user.SetBKAuthHeader(ctx, p.service.Config, h, p.userCli) + if err != nil { + return nil, err + } + + err = p.service.Client.Post(). WithContext(ctx). Body(data). SubResourcef(subPath). - WithHeaders(httpheader.SetBkAuth(h, p.service.Auth)). + WithHeaders(h). Do(). Into(resp) @@ -60,11 +65,16 @@ func (p *gse) AsyncPushFile(ctx context.Context, h http.Header, data *AsyncPushF resp := new(AsyncPushFileResp) subPath := "/api/v2/task/async_push_file" - err := p.service.Client.Post(). + h, err := user.SetBKAuthHeader(ctx, p.service.Config, h, p.userCli) + if err != nil { + return nil, err + } + + err = p.service.Client.Post(). WithContext(ctx). Body(data). SubResourcef(subPath). - WithHeaders(httpheader.SetBkAuth(h, p.service.Auth)). + WithHeaders(h). Do(). Into(resp) @@ -86,11 +96,16 @@ func (p *gse) GetTransferFileResult(ctx context.Context, h http.Header, data *Ge resp := new(GetTransferFileResultResp) subPath := "/api/v2/task/async/get_transfer_file_result" - err := p.service.Client.Post(). + h, err := user.SetBKAuthHeader(ctx, p.service.Config, h, p.userCli) + if err != nil { + return nil, err + } + + err = p.service.Client.Post(). WithContext(ctx). Body(data). SubResourcef(subPath). - WithHeaders(httpheader.SetBkAuth(h, p.service.Auth)). + WithHeaders(h). Do(). Into(resp) @@ -112,11 +127,15 @@ func (p *gse) ConfigAddStreamTo(ctx context.Context, h http.Header, data *metada resp := new(AddStreamToResp) subPath := "/api/v2/data/add_streamto/" - err := p.service.Client.Post(). + h, err := user.SetBKAuthHeader(ctx, p.service.Config, h, p.userCli) + if err != nil { + return nil, err + } + err = p.service.Client.Post(). WithContext(ctx). Body(data). SubResourcef(subPath). - WithHeaders(httpheader.SetBkAuth(h, p.service.Auth)). + WithHeaders(h). Do(). Into(resp) @@ -138,11 +157,16 @@ func (p *gse) ConfigUpdateStreamTo(ctx context.Context, h http.Header, resp := new(apigwutil.ApiGWBaseResponse) subPath := "/api/v2/data/update_streamto/" - err := p.service.Client.Post(). + h, err := user.SetBKAuthHeader(ctx, p.service.Config, h, p.userCli) + if err != nil { + return err + } + + err = p.service.Client.Post(). WithContext(ctx). Body(data). SubResourcef(subPath). - WithHeaders(httpheader.SetBkAuth(h, p.service.Auth)). + WithHeaders(h). Do(). Into(resp) @@ -164,11 +188,16 @@ func (p *gse) ConfigQueryStreamTo(ctx context.Context, h http.Header, data *meta resp := new(QueryStreamToResp) subPath := "/api/v2/data/query_streamto/" - err := p.service.Client.Post(). + h, err := user.SetBKAuthHeader(ctx, p.service.Config, h, p.userCli) + if err != nil { + return nil, err + } + + err = p.service.Client.Post(). WithContext(ctx). Body(data). SubResourcef(subPath). - WithHeaders(httpheader.SetBkAuth(h, p.service.Auth)). + WithHeaders(h). Do(). Into(resp) @@ -195,11 +224,16 @@ func (p *gse) ConfigAddRoute(ctx context.Context, h http.Header, data *metadata. resp := new(AddRouteResp) subPath := "/api/v2/data/add_route/" - err := p.service.Client.Post(). + h, err := user.SetBKAuthHeader(ctx, p.service.Config, h, p.userCli) + if err != nil { + return nil, err + } + + err = p.service.Client.Post(). WithContext(ctx). Body(data). SubResourcef(subPath). - WithHeaders(httpheader.SetBkAuth(h, p.service.Auth)). + WithHeaders(h). Do(). Into(resp) @@ -220,11 +254,16 @@ func (p *gse) ConfigUpdateRoute(ctx context.Context, h http.Header, data *metada resp := new(apigwutil.ApiGWBaseResponse) subPath := "/api/v2/data/update_route/" - err := p.service.Client.Post(). + h, err := user.SetBKAuthHeader(ctx, p.service.Config, h, p.userCli) + if err != nil { + return err + } + + err = p.service.Client.Post(). WithContext(ctx). Body(data). SubResourcef(subPath). - WithHeaders(httpheader.SetBkAuth(h, p.service.Auth)). + WithHeaders(h). Do(). Into(resp) @@ -246,11 +285,16 @@ func (p *gse) ConfigQueryRoute(ctx context.Context, h http.Header, data *metadat resp := new(QueryRouteResp) subPath := "/api/v2/data/query_route/" - err := p.service.Client.Post(). + h, err := user.SetBKAuthHeader(ctx, p.service.Config, h, p.userCli) + if err != nil { + return nil, false, err + } + + err = p.service.Client.Post(). WithContext(ctx). Body(data). SubResourcef(subPath). - WithHeaders(httpheader.SetBkAuth(h, p.service.Auth)). + WithHeaders(h). Do(). Into(resp) diff --git a/src/thirdparty/apigw/gse/service.go b/src/thirdparty/apigw/gse/service.go index 2a6e06347d..b1bbde9eb0 100644 --- a/src/thirdparty/apigw/gse/service.go +++ b/src/thirdparty/apigw/gse/service.go @@ -22,6 +22,7 @@ import ( "net/http" "configcenter/src/thirdparty/apigw/apigwutil" + "configcenter/src/thirdparty/apigw/apigwutil/user" "configcenter/src/thirdparty/dataid" ) @@ -36,10 +37,11 @@ type ClientI interface { type gse struct { service *apigwutil.ApiGWSrv + userCli user.VirtualUserClientI } // NewClient create gse api gateway client -func NewClient(options *apigwutil.ApiGWOptions) (ClientI, error) { +func NewClient(options *apigwutil.ApiGWOptions, userCli user.VirtualUserClientI) (ClientI, error) { service, err := apigwutil.NewApiGW(options, "apiGW.bkGseApiGatewayUrl") if err != nil { return nil, err @@ -47,5 +49,6 @@ func NewClient(options *apigwutil.ApiGWOptions) (ClientI, error) { return &gse{ service: service, + userCli: userCli, }, nil } diff --git a/src/thirdparty/apigw/login/api.go b/src/thirdparty/apigw/login/api.go index 032fedcb14..a7b325719b 100644 --- a/src/thirdparty/apigw/login/api.go +++ b/src/thirdparty/apigw/login/api.go @@ -22,7 +22,7 @@ import ( "fmt" "net/http" - httpheader "configcenter/src/common/http/header" + "configcenter/src/thirdparty/apigw/apigwutil/user" ) // VerifyToken verify user token @@ -31,11 +31,16 @@ func (l *login) VerifyToken(ctx context.Context, h http.Header, token string) (* resp := new(BkLoginResponse[*VerifyTokenRes]) - err := l.service.Client.Get(). + h, err := user.SetBKAuthHeader(ctx, l.service.Config, h, l.userCli) + if err != nil { + return nil, err + } + + err = l.service.Client.Get(). WithContext(ctx). WithParam("bk_token", token). SubResourcef("/login/api/v3/open/bk-tokens/verify/"). - WithHeaders(httpheader.SetBkAuth(h, l.service.Auth)). + WithHeaders(h). Do(). Into(resp) @@ -54,11 +59,16 @@ func (l *login) VerifyToken(ctx context.Context, h http.Header, token string) (* func (l *login) GetUserByToken(ctx context.Context, h http.Header, token string) (*UserInfo, error) { resp := new(BkLoginResponse[*UserInfo]) - err := l.service.Client.Get(). + h, err := user.SetBKAuthHeader(ctx, l.service.Config, h, l.userCli) + if err != nil { + return nil, err + } + + err = l.service.Client.Get(). WithContext(ctx). WithParam("bk_token", token). SubResourcef("/login/api/v3/open/bk-tokens/userinfo/"). - WithHeaders(httpheader.SetBkAuth(h, l.service.Auth)). + WithHeaders(h). Do(). Into(resp) diff --git a/src/thirdparty/apigw/login/service.go b/src/thirdparty/apigw/login/service.go index bd63102443..b9ef66fcec 100644 --- a/src/thirdparty/apigw/login/service.go +++ b/src/thirdparty/apigw/login/service.go @@ -23,6 +23,7 @@ import ( "net/http" "configcenter/src/thirdparty/apigw/apigwutil" + "configcenter/src/thirdparty/apigw/apigwutil/user" ) // ClientI is the bk-login api gateway client @@ -33,10 +34,11 @@ type ClientI interface { type login struct { service *apigwutil.ApiGWSrv + userCli user.VirtualUserClientI } // NewClient create bk-login api gateway client -func NewClient(options *apigwutil.ApiGWOptions) (ClientI, error) { +func NewClient(options *apigwutil.ApiGWOptions, userCli user.VirtualUserClientI) (ClientI, error) { service, err := apigwutil.NewApiGW(options, "apiGW.bkLoginApiGatewayUrl") if err != nil { return nil, err @@ -44,5 +46,6 @@ func NewClient(options *apigwutil.ApiGWOptions) (ClientI, error) { return &login{ service: service, + userCli: userCli, }, nil } diff --git a/src/thirdparty/apigw/notice/api.go b/src/thirdparty/apigw/notice/api.go index a2e1819573..f5d732c694 100644 --- a/src/thirdparty/apigw/notice/api.go +++ b/src/thirdparty/apigw/notice/api.go @@ -22,7 +22,7 @@ import ( "fmt" "net/http" - httpheader "configcenter/src/common/http/header" + "configcenter/src/thirdparty/apigw/apigwutil/user" ) // GetCurAnn get current announcements @@ -31,11 +31,16 @@ func (n *notice) GetCurAnn(ctx context.Context, h http.Header, params map[string subPath := "/apigw/v1/announcement/get_current_announcements" params["platform"] = n.service.Config.AppCode - err := n.service.Client.Get(). + h, err := user.SetBKAuthHeader(ctx, n.service.Config, h, n.userCli) + if err != nil { + return nil, err + } + + err = n.service.Client.Get(). WithContext(ctx). WithParams(params). SubResourcef(subPath). - WithHeaders(httpheader.SetBkAuth(h, n.service.Auth)). + WithHeaders(h). Do(). Into(resp) @@ -55,10 +60,15 @@ func (n *notice) RegApp(ctx context.Context, h http.Header) (*RegAppData, error) resp := new(RegAppResp) subPath := "/apigw/v1/register" - err := n.service.Client.Post(). + h, err := user.SetBKAuthHeader(ctx, n.service.Config, h, n.userCli) + if err != nil { + return nil, err + } + + err = n.service.Client.Post(). WithContext(ctx). SubResourcef(subPath). - WithHeaders(httpheader.SetBkAuth(h, n.service.Auth)). + WithHeaders(h). Do(). Into(resp) diff --git a/src/thirdparty/apigw/notice/service.go b/src/thirdparty/apigw/notice/service.go index f9a03daf41..34976bc9fa 100644 --- a/src/thirdparty/apigw/notice/service.go +++ b/src/thirdparty/apigw/notice/service.go @@ -22,6 +22,7 @@ import ( "net/http" "configcenter/src/thirdparty/apigw/apigwutil" + "configcenter/src/thirdparty/apigw/apigwutil/user" ) // ClientI is the bk-notice api gateway client @@ -32,10 +33,11 @@ type ClientI interface { type notice struct { service *apigwutil.ApiGWSrv + userCli user.VirtualUserClientI } // NewClient create bk-notice api gateway client -func NewClient(options *apigwutil.ApiGWOptions) (ClientI, error) { +func NewClient(options *apigwutil.ApiGWOptions, userCli user.VirtualUserClientI) (ClientI, error) { service, err := apigwutil.NewApiGW(options, "apiGW.bkNoticeApiGatewayUrl") if err != nil { return nil, err @@ -43,5 +45,6 @@ func NewClient(options *apigwutil.ApiGWOptions) (ClientI, error) { return ¬ice{ service: service, + userCli: userCli, }, nil } diff --git a/src/thirdparty/apigw/user/api.go b/src/thirdparty/apigw/user/api.go index 8ddcd990cc..54a3f8a7ae 100644 --- a/src/thirdparty/apigw/user/api.go +++ b/src/thirdparty/apigw/user/api.go @@ -26,17 +26,24 @@ import ( "configcenter/src/common" httpheader "configcenter/src/common/http/header" + utiluser "configcenter/src/thirdparty/apigw/apigwutil/user" + "configcenter/src/thirdparty/apigw/user/types" ) // GetTenants get all tenants from bk user -func (u *user) GetTenants(ctx context.Context, h http.Header) ([]Tenant, error) { - resp := new(BkUserResponse[[]Tenant]) - +func (u *user) GetTenants(ctx context.Context, h http.Header) ([]types.Tenant, error) { + resp := new(types.BkUserResponse[[]types.Tenant]) httpheader.SetTenantID(h, common.BKDefaultTenantID) - err := u.service.Client.Get(). + + h, err := utiluser.SetBKAuthHeader(ctx, u.service.Config, h, u) + if err != nil { + return nil, err + } + + err = u.service.Client.Get(). WithContext(ctx). SubResourcef("/api/v3/open/tenants/"). - WithHeaders(httpheader.SetBkAuth(h, u.service.Auth)). + WithHeaders(h). Do(). Into(resp) @@ -56,8 +63,9 @@ func (u *user) GetTenants(ctx context.Context, h http.Header) ([]Tenant, error) } // ListUsers list users -func (u *user) ListUsers(ctx context.Context, h http.Header, page *PageOptions) (*ListUserResult, error) { - resp := new(BkUserResponse[*ListUserResult]) +func (u *user) ListUsers(ctx context.Context, h http.Header, page *types.PageOptions) (*types.ListUserResult, + error) { + resp := new(types.BkUserResponse[*types.ListUserResult]) params := make(map[string]string) if page != nil { @@ -69,11 +77,16 @@ func (u *user) ListUsers(ctx context.Context, h http.Header, page *PageOptions) } } - err := u.service.Client.Get(). + h, err := utiluser.SetBKAuthHeader(ctx, u.service.Config, h, u) + if err != nil { + return nil, err + } + + err = u.service.Client.Get(). WithContext(ctx). WithParams(params). SubResourcef("/api/v3/open/tenant/users/"). - WithHeaders(httpheader.SetBkAuth(h, u.service.Auth)). + WithHeaders(h). Do(). Into(resp) @@ -93,16 +106,21 @@ func (u *user) ListUsers(ctx context.Context, h http.Header, page *PageOptions) } // BatchQueryUserDisplayInfo batch query user display name info -func (u *user) BatchQueryUserDisplayInfo(ctx context.Context, h http.Header, opts *QueryUserDisplayInfoOpts) ( - []UserDisplayInfo, error) { +func (u *user) BatchQueryUserDisplayInfo(ctx context.Context, h http.Header, opts *types.QueryUserDisplayInfoOpts) ( + []types.UserDisplayInfo, error) { - resp := new(BkUserResponse[[]UserDisplayInfo]) + resp := new(types.BkUserResponse[[]types.UserDisplayInfo]) - err := u.service.Client.Get(). + h, err := utiluser.SetBKAuthHeader(ctx, u.service.Config, h, u) + if err != nil { + return nil, err + } + + err = u.service.Client.Get(). WithContext(ctx). WithParam("bk_usernames", strings.Join(opts.BkUsernames, ",")). SubResourcef("/api/v3/open/tenant/users/-/display_info/"). - WithHeaders(httpheader.SetBkAuth(h, u.service.Auth)). + WithHeaders(h). Do(). Into(resp) @@ -122,7 +140,8 @@ func (u *user) BatchQueryUserDisplayInfo(ctx context.Context, h http.Header, opt } // BatchLookupDept batch lookup department -func (u *user) BatchLookupDept(ctx context.Context, h http.Header, opts *BatchLookupDeptOpts) ([]DepartmentItem, +func (u *user) BatchLookupDept(ctx context.Context, h http.Header, + opts *types.BatchLookupDeptOpts) ([]types.DepartmentItem, error) { strDeptIDs := make([]string, len(opts.DeptIDs)) @@ -137,12 +156,47 @@ func (u *user) BatchLookupDept(ctx context.Context, h http.Header, opts *BatchLo params["with_organization_path"] = "true" } - resp := new(BkUserResponse[[]DepartmentItem]) + h, err := utiluser.SetBKAuthHeader(ctx, u.service.Config, h, u) + if err != nil { + return nil, err + } + + resp := new(types.BkUserResponse[[]types.DepartmentItem]) - err := u.service.Client.Get(). + err = u.service.Client.Get(). WithContext(ctx). WithParams(params). SubResourcef("/api/v3/open/tenant/departments/-/lookup/"). + WithHeaders(h). + Do(). + Into(resp) + + if err != nil { + return nil, err + } + + if resp.Code != 0 { + return nil, fmt.Errorf("code: %d, message: %s", resp.Code, resp.Message) + } + + if resp.Error != nil { + return nil, fmt.Errorf("code: %s, message: %s", resp.Error.Code, resp.Error.Message) + } + + return resp.Data, nil +} + +// BatchSearchVirtualUser query user virtual name info +func (u *user) BatchSearchVirtualUser(ctx context.Context, h http.Header, loginNames []string) ( + []types.VirtualUserItem, error) { + + resp := new(types.BkUserResponse[[]types.VirtualUserItem]) + + err := u.service.Client.Get(). + WithContext(ctx). + WithParam("lookup_field", "login_name"). + WithParam("lookups", strings.Join(loginNames, ",")). + SubResourcef("/api/v3/open/tenant/virtual-users/-/lookup/"). WithHeaders(httpheader.SetBkAuth(h, u.service.Auth)). Do(). Into(resp) diff --git a/src/thirdparty/apigw/user/service.go b/src/thirdparty/apigw/user/service.go index 72ba82c6d2..cd8240d674 100644 --- a/src/thirdparty/apigw/user/service.go +++ b/src/thirdparty/apigw/user/service.go @@ -22,15 +22,17 @@ import ( "net/http" "configcenter/src/thirdparty/apigw/apigwutil" + "configcenter/src/thirdparty/apigw/user/types" ) // ClientI is the bk-user api gateway client type ClientI interface { - GetTenants(ctx context.Context, h http.Header) ([]Tenant, error) - ListUsers(ctx context.Context, h http.Header, page *PageOptions) (*ListUserResult, error) - BatchQueryUserDisplayInfo(ctx context.Context, h http.Header, opts *QueryUserDisplayInfoOpts) ([]UserDisplayInfo, - error) - BatchLookupDept(ctx context.Context, h http.Header, opts *BatchLookupDeptOpts) ([]DepartmentItem, error) + GetTenants(ctx context.Context, h http.Header) ([]types.Tenant, error) + ListUsers(ctx context.Context, h http.Header, page *types.PageOptions) (*types.ListUserResult, error) + BatchQueryUserDisplayInfo(ctx context.Context, h http.Header, opts *types.QueryUserDisplayInfoOpts) ( + []types.UserDisplayInfo, error) + BatchLookupDept(ctx context.Context, h http.Header, opts *types.BatchLookupDeptOpts) ([]types.DepartmentItem, error) + BatchSearchVirtualUser(ctx context.Context, h http.Header, loginNames []string) ([]types.VirtualUserItem, error) } type user struct { diff --git a/src/thirdparty/apigw/user/types.go b/src/thirdparty/apigw/user/types/types.go similarity index 84% rename from src/thirdparty/apigw/user/types.go rename to src/thirdparty/apigw/user/types/types.go index 368d1b0c65..4a18195cde 100644 --- a/src/thirdparty/apigw/user/types.go +++ b/src/thirdparty/apigw/user/types/types.go @@ -15,27 +15,20 @@ * to the current version of the project delivered to anyone in the future. */ -package user +package types -import "configcenter/src/thirdparty/apigw/apigwutil" +import ( + "configcenter/pkg/tenant/types" + "configcenter/src/thirdparty/apigw/apigwutil" +) // Tenant is the result from bk-user. type Tenant struct { - ID string `json:"id"` - Name string `json:"name"` - Status Status `json:"status"` + ID string `json:"id"` + Name string `json:"name"` + Status types.Status `json:"status"` } -// Status is the tenant status -type Status string - -const ( - // DisabledStatus is the disabled status for tenant - DisabledStatus Status = "disabled" - // EnabledStatus is the enabled status for tenant - EnabledStatus Status = "enabled" -) - // BkUserResponse is bk user api gateway response type BkUserResponse[T any] struct { apigwutil.ApiGWBaseResponse `json:",inline"` @@ -91,3 +84,10 @@ type DepartmentItem struct { Name string `json:"name"` OrganizationPath string `json:"organization_path"` } + +// VirtualUserItem is the batch lookup virtual user info result +type VirtualUserItem struct { + DisplayName string `json:"display_name"` + LoginName string `json:"login_name"` + VirtualUserName string `json:"bk_username"` +} diff --git a/src/web_server/app/server.go b/src/web_server/app/server.go index 1fb136c952..869ed2bff0 100644 --- a/src/web_server/app/server.go +++ b/src/web_server/app/server.go @@ -83,7 +83,7 @@ func Run(ctx context.Context, cancel context.CancelFunc, op *options.ServerOptio return err } - if err := service.InitNotice(); err != nil { + if err = service.InitNotice(); err != nil { return err } diff --git a/src/web_server/middleware/login.go b/src/web_server/middleware/login.go index a72936deba..7f22e25fbf 100644 --- a/src/web_server/middleware/login.go +++ b/src/web_server/middleware/login.go @@ -17,7 +17,7 @@ import ( "net/http" "strings" - "configcenter/pkg/tenant/logics" + "configcenter/pkg/tenant/tools" "configcenter/src/apimachinery/discovery" "configcenter/src/common" "configcenter/src/common/backbone" @@ -181,7 +181,7 @@ func isAuthed(c *gin.Context, config options.Config) bool { return user.LoginUser(c) } - tenant, err := logics.ValidateDisableTenantMode(sessionTenantID, config.EnableMultiTenantMode) + tenant, err := tools.ValidateDisableTenantMode(sessionTenantID, config.EnableMultiTenantMode) if err != nil { return user.LoginUser(c) } diff --git a/src/web_server/middleware/user/plugins/method/blueking/userinfo.go b/src/web_server/middleware/user/plugins/method/blueking/userinfo.go index 11d7649df6..4a6fab9536 100644 --- a/src/web_server/middleware/user/plugins/method/blueking/userinfo.go +++ b/src/web_server/middleware/user/plugins/method/blueking/userinfo.go @@ -16,7 +16,7 @@ package blueking import ( "fmt" - "configcenter/pkg/tenant/logics" + "configcenter/pkg/tenant/tools" "configcenter/src/common" cc "configcenter/src/common/backbone/configcenter" "configcenter/src/common/blog" @@ -25,7 +25,7 @@ import ( headerutil "configcenter/src/common/http/header/util" "configcenter/src/common/metadata" apigwcli "configcenter/src/common/resource/apigw" - apigwuser "configcenter/src/thirdparty/apigw/user" + usertypes "configcenter/src/thirdparty/apigw/user/types" "configcenter/src/web_server/app/options" "configcenter/src/web_server/middleware/user/plugins/manager" @@ -81,7 +81,7 @@ func (m *user) LoginUser(c *gin.Context, config options.Config, isMultiOwner boo return nil, false } - tenantID, err := logics.ValidateDisableTenantMode(user.TenantUin, config.EnableMultiTenantMode) + tenantID, err := tools.ValidateDisableTenantMode(user.TenantUin, config.EnableMultiTenantMode) if err != nil { blog.Infof("tenant mode not enabled, but tenantUin is not empty, rid: %s", rid) return nil, false @@ -148,7 +148,7 @@ func (m *user) GetUserList(c *gin.Context, opts *metadata.GetUserListOptions) ([ if opts.NeedAll { // get paged user lists from apigw users := make([]*metadata.LoginSystemUserInfo, 0) - pageOpts := &apigwuser.PageOptions{ + pageOpts := &usertypes.PageOptions{ Page: 1, PageSize: 1000, } @@ -178,7 +178,7 @@ func (m *user) GetUserList(c *gin.Context, opts *metadata.GetUserListOptions) ([ // get user info by user names from bk-user displayInfoRes, err := apigwcli.Client().User().BatchQueryUserDisplayInfo(c.Request.Context(), c.Request.Header, - &apigwuser.QueryUserDisplayInfoOpts{BkUsernames: opts.Usernames}) + &usertypes.QueryUserDisplayInfoOpts{BkUsernames: opts.Usernames}) if err != nil { blog.Errorf("get users by apigw client failed, http failed, err: %+v, rid: %s", err, rid) return nil, &errors.RawErrorInfo{ diff --git a/src/web_server/middleware/user/plugins/method/utils.go b/src/web_server/middleware/user/plugins/method/utils.go index bf3453c56a..5d9d4c5d95 100644 --- a/src/web_server/middleware/user/plugins/method/utils.go +++ b/src/web_server/middleware/user/plugins/method/utils.go @@ -20,7 +20,7 @@ package method import ( "fmt" - "configcenter/pkg/tenant/logics" + "configcenter/pkg/tenant/tools" "configcenter/src/common" "configcenter/src/common/blog" httpheader "configcenter/src/common/http/header" @@ -35,7 +35,7 @@ func SetTenantFromCookie(c *gin.Context, config options.Config, session sessions rid := httpheader.GetRid(c.Request.Header) cookieTenantID, cookieErr := c.Cookie(common.HTTPCookieTenant) - tenantID, err := logics.ValidateDisableTenantMode(cookieTenantID, config.EnableMultiTenantMode) + tenantID, err := tools.ValidateDisableTenantMode(cookieTenantID, config.EnableMultiTenantMode) if err != nil { return "", err } diff --git a/src/web_server/middleware/user/public.go b/src/web_server/middleware/user/public.go index b521a5428c..41b1c95e93 100644 --- a/src/web_server/middleware/user/public.go +++ b/src/web_server/middleware/user/public.go @@ -15,7 +15,7 @@ package user import ( "encoding/json" - "configcenter/pkg/tenant/logics" + "configcenter/pkg/tenant/tools" "configcenter/src/common" "configcenter/src/common/backbone" "configcenter/src/common/blog" @@ -62,7 +62,7 @@ func (m *publicUser) LoginUser(c *gin.Context) bool { session := sessions.Default(c) - tenantID, err := logics.ValidateDisableTenantMode(userInfo.TenantUin, m.config.EnableMultiTenantMode) + tenantID, err := tools.ValidateDisableTenantMode(userInfo.TenantUin, m.config.EnableMultiTenantMode) if err != nil { blog.Errorf("get tenant id failed, err: %v", err) return false diff --git a/src/web_server/service/excel/core/field_func.go b/src/web_server/service/excel/core/field_func.go index a171ab41c8..9438d926b1 100644 --- a/src/web_server/service/excel/core/field_func.go +++ b/src/web_server/service/excel/core/field_func.go @@ -34,7 +34,7 @@ import ( "configcenter/src/common/metadata" "configcenter/src/common/resource/apigw" "configcenter/src/common/util" - "configcenter/src/thirdparty/apigw/user" + "configcenter/src/thirdparty/apigw/user/types" "configcenter/src/web_server/middleware/user/plugins" ) @@ -271,14 +271,14 @@ func (d *Client) GetInstWithOrgName(kit *rest.Kit, ccLang language.DefaultCCLang } // getAllOrganization get organization info from paas -func getAllOrganization(kit *rest.Kit, orgIDs []int64) ([]user.DepartmentItem, errors.CCErrorCoder) { +func getAllOrganization(kit *rest.Kit, orgIDs []int64) ([]types.DepartmentItem, errors.CCErrorCoder) { loginVersion, _ := cc.String("webServer.login.version") if loginVersion == common.BKOpenSourceLoginPluginVersion || loginVersion == common.BKSkipLoginPluginVersion { - return make([]user.DepartmentItem, 0), nil + return make([]types.DepartmentItem, 0), nil } orgIDList := util.SplitArr(orgIDs, 100) - departments := make([]user.DepartmentItem, 0) + departments := make([]types.DepartmentItem, 0) var wg sync.WaitGroup var lock sync.RWMutex var firstErr error @@ -293,7 +293,7 @@ func getAllOrganization(kit *rest.Kit, orgIDs []int64) ([]user.DepartmentItem, e <-pipeline }() - deptOpts := &user.BatchLookupDeptOpts{ + deptOpts := &types.BatchLookupDeptOpts{ DeptIDs: ids, } result, err := apigw.Client().User().BatchLookupDept(kit.Ctx, kit.Header, deptOpts) diff --git a/src/web_server/service/service.go b/src/web_server/service/service.go index e110b78ed3..1a9cfdb8ac 100644 --- a/src/web_server/service/service.go +++ b/src/web_server/service/service.go @@ -24,6 +24,7 @@ import ( "configcenter/src/common" "configcenter/src/common/backbone" "configcenter/src/common/blog" + "configcenter/src/common/http/header/util" "configcenter/src/common/metadata" "configcenter/src/common/metric" apigwcli "configcenter/src/common/resource/apigw" @@ -222,7 +223,7 @@ func (s *Service) InitNotice() error { } s.NoticeCli = apigwcli.Client().Notice() - if _, err := s.NoticeCli.RegApp(context.Background(), http.Header{}); err != nil { + if _, err := s.NoticeCli.RegApp(context.Background(), util.GenDefaultHeader()); err != nil { blog.Errorf("register to the notification center failed, err: %v", err) return err }