From 791d08c15f596e2e44cce90cadca6da4ef7e7dfa Mon Sep 17 00:00:00 2001 From: Pavel Sturc Date: Thu, 26 Mar 2026 15:09:15 +0100 Subject: [PATCH] fix: sonarqube: missing api/users/search endpoint --- backend/plugins/sonarqube/impl/impl.go | 1 + backend/plugins/sonarqube/tasks/accounts_collector.go | 11 ++++++++++- backend/plugins/sonarqube/tasks/task_data.go | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/backend/plugins/sonarqube/impl/impl.go b/backend/plugins/sonarqube/impl/impl.go index 5c1a774867b..a6d6bd258ab 100644 --- a/backend/plugins/sonarqube/impl/impl.go +++ b/backend/plugins/sonarqube/impl/impl.go @@ -136,6 +136,7 @@ func (p Sonarqube) PrepareTaskData(taskCtx plugin.TaskContext, options map[strin Options: op, ApiClient: apiClient, TaskStartTime: time.Now(), + IsCloud: connection.IsCloud(), } // even we have project in _tool_sonaqube_projects, we still need to collect project to update LastAnalysisDate var apiProject *models.SonarqubeApiProject diff --git a/backend/plugins/sonarqube/tasks/accounts_collector.go b/backend/plugins/sonarqube/tasks/accounts_collector.go index 6bb02272e12..0a30b57f014 100644 --- a/backend/plugins/sonarqube/tasks/accounts_collector.go +++ b/backend/plugins/sonarqube/tasks/accounts_collector.go @@ -36,11 +36,20 @@ func CollectAccounts(taskCtx plugin.SubTaskContext) errors.Error { logger := taskCtx.GetLogger() logger.Info("collect accounts") rawDataSubTaskArgs, data := CreateRawDataSubTaskArgs(taskCtx, RAW_ACCOUNTS_TABLE) + + // SonarCloud removed api/users/search - use organizations/search_members instead + // The "organization" query param is auto-added by PrepareApiClient + urlTemplate := "users/search" + if data.IsCloud { + urlTemplate = "organizations/search_members" + logger.Info("using organizations/search_members for SonarCloud") + } + collector, err := helper.NewApiCollector(helper.ApiCollectorArgs{ RawDataSubTaskArgs: *rawDataSubTaskArgs, ApiClient: data.ApiClient, PageSize: 100, - UrlTemplate: "users/search", + UrlTemplate: urlTemplate, Query: func(reqData *helper.RequestData) (url.Values, errors.Error) { query := url.Values{} query.Set("p", fmt.Sprintf("%v", reqData.Pager.Page)) diff --git a/backend/plugins/sonarqube/tasks/task_data.go b/backend/plugins/sonarqube/tasks/task_data.go index e898befa0db..06cb83dd5b0 100644 --- a/backend/plugins/sonarqube/tasks/task_data.go +++ b/backend/plugins/sonarqube/tasks/task_data.go @@ -37,6 +37,7 @@ type SonarqubeTaskData struct { ApiClient *api.ApiAsyncClient LastAnalysisDate *time.Time TaskStartTime time.Time + IsCloud bool } func DecodeAndValidateTaskOptions(options map[string]interface{}) (*SonarqubeOptions, errors.Error) {