This is an automated email from the ASF dual-hosted git repository. github-bot pushed a commit to branch release-v0.19-auto-cherry-pick-6380 in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
commit 9905266ab93a1c8ba5c5ad4fc40c39d499d1a481 Author: abeizn <[email protected]> AuthorDate: Wed Nov 1 04:52:10 2023 -0500 fix: github apps auth can not show repos (#6380) --- backend/plugins/github/api/remote.go | 187 +++++++++++++++++++++++++++++++---- 1 file changed, 166 insertions(+), 21 deletions(-) diff --git a/backend/plugins/github/api/remote.go b/backend/plugins/github/api/remote.go index 2444b23d8..b437ee704 100644 --- a/backend/plugins/github/api/remote.go +++ b/backend/plugins/github/api/remote.go @@ -184,6 +184,123 @@ func (r repo) ConvertApiScope() plugin.ToolLayerScope { return githubRepository } +type GithubAppRepo struct { + TotalCount int `json:"total_count"` + Repositories []struct { + ID int `json:"id"` + NodeID string `json:"node_id"` + Name string `json:"name"` + FullName string `json:"full_name"` + Owner struct { + Login string `json:"login"` + ID int `json:"id"` + NodeID string `json:"node_id"` + AvatarURL string `json:"avatar_url"` + GravatarID string `json:"gravatar_id"` + URL string `json:"url"` + HTMLURL string `json:"html_url"` + FollowersURL string `json:"followers_url"` + FollowingURL string `json:"following_url"` + GistsURL string `json:"gists_url"` + StarredURL string `json:"starred_url"` + SubscriptionsURL string `json:"subscriptions_url"` + OrganizationsURL string `json:"organizations_url"` + ReposURL string `json:"repos_url"` + EventsURL string `json:"events_url"` + ReceivedEventsURL string `json:"received_events_url"` + Type string `json:"type"` + SiteAdmin bool `json:"site_admin"` + } `json:"owner"` + Private bool `json:"private"` + HTMLURL string `json:"html_url"` + Description string `json:"description"` + Fork bool `json:"fork"` + URL string `json:"url"` + ArchiveURL string `json:"archive_url"` + AssigneesURL string `json:"assignees_url"` + BlobsURL string `json:"blobs_url"` + BranchesURL string `json:"branches_url"` + CollaboratorsURL string `json:"collaborators_url"` + CommentsURL string `json:"comments_url"` + CommitsURL string `json:"commits_url"` + CompareURL string `json:"compare_url"` + ContentsURL string `json:"contents_url"` + ContributorsURL string `json:"contributors_url"` + DeploymentsURL string `json:"deployments_url"` + DownloadsURL string `json:"downloads_url"` + EventsURL string `json:"events_url"` + ForksURL string `json:"forks_url"` + GitCommitsURL string `json:"git_commits_url"` + GitRefsURL string `json:"git_refs_url"` + GitTagsURL string `json:"git_tags_url"` + GitURL string `json:"git_url"` + IssueCommentURL string `json:"issue_comment_url"` + IssueEventsURL string `json:"issue_events_url"` + IssuesURL string `json:"issues_url"` + KeysURL string `json:"keys_url"` + LabelsURL string `json:"labels_url"` + LanguagesURL string `json:"languages_url"` + MergesURL string `json:"merges_url"` + MilestonesURL string `json:"milestones_url"` + NotificationsURL string `json:"notifications_url"` + PullsURL string `json:"pulls_url"` + ReleasesURL string `json:"releases_url"` + SSHURL string `json:"ssh_url"` + StargazersURL string `json:"stargazers_url"` + StatusesURL string `json:"statuses_url"` + SubscribersURL string `json:"subscribers_url"` + SubscriptionURL string `json:"subscription_url"` + TagsURL string `json:"tags_url"` + TeamsURL string `json:"teams_url"` + TreesURL string `json:"trees_url"` + CloneURL string `json:"clone_url"` + MirrorURL string `json:"mirror_url"` + HooksURL string `json:"hooks_url"` + SvnURL string `json:"svn_url"` + Homepage string `json:"homepage"` + Language any `json:"language"` + ForksCount int `json:"forks_count"` + StargazersCount int `json:"stargazers_count"` + WatchersCount int `json:"watchers_count"` + Size int `json:"size"` + DefaultBranch string `json:"default_branch"` + OpenIssuesCount int `json:"open_issues_count"` + IsTemplate bool `json:"is_template"` + Topics []string `json:"topics"` + HasIssues bool `json:"has_issues"` + HasProjects bool `json:"has_projects"` + HasWiki bool `json:"has_wiki"` + HasPages bool `json:"has_pages"` + HasDownloads bool `json:"has_downloads"` + Archived bool `json:"archived"` + Disabled bool `json:"disabled"` + Visibility string `json:"visibility"` + PushedAt time.Time `json:"pushed_at"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + AllowRebaseMerge bool `json:"allow_rebase_merge"` + TemplateRepository any `json:"template_repository"` + TempCloneToken string `json:"temp_clone_token"` + AllowSquashMerge bool `json:"allow_squash_merge"` + AllowAutoMerge bool `json:"allow_auto_merge"` + DeleteBranchOnMerge bool `json:"delete_branch_on_merge"` + AllowMergeCommit bool `json:"allow_merge_commit"` + SubscribersCount int `json:"subscribers_count"` + NetworkCount int `json:"network_count"` + License struct { + Key string `json:"key"` + Name string `json:"name"` + URL string `json:"url"` + SpdxID string `json:"spdx_id"` + NodeID string `json:"node_id"` + HTMLURL string `json:"html_url"` + } `json:"license"` + Forks int `json:"forks"` + OpenIssues int `json:"open_issues"` + Watchers int `json:"watchers"` + } `json:"repositories"` +} + // RemoteScopes list all available scope for users // @Summary list all available scope for users // @Description list all available scope for users @@ -206,29 +323,57 @@ func RemoteScopes(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, er return nil, errors.BadInput.Wrap(err, "failed to get create apiClient") } query := initialQuery(queryData) - res, err := apiClient.Get("user/orgs", query, nil) - if err != nil { - return nil, err - } - var resBody []org - err = api.UnmarshalResponse(res, &resBody) - if err != nil { - return nil, err - } - res, err = apiClient.Get("user", nil, nil) - if err != nil { - return nil, err - } + result := make([]plugin.ApiGroup, 0) var o owner - err = api.UnmarshalResponse(res, &o) - if err != nil { - return nil, err - } - result := make([]plugin.ApiGroup, 0, len(resBody)+1) - for _, v := range resBody { - result = append(result, v) + var res *http.Response + if connection.AuthMethod == plugin.AUTH_METHOD_APPKEY { + resApp, err := apiClient.Get("installation/repositories", query, nil) + if err != nil { + return nil, err + } + var resAppBody GithubAppRepo + err = api.UnmarshalResponse(resApp, &resAppBody) + if err != nil { + return nil, err + } + var resOwner []owner + processedOrgs := make(map[string]struct{}) + for _, v := range resAppBody.Repositories { + orgName := v.Owner.Login + if _, exists := processedOrgs[orgName]; !exists && orgName != "" { + o.ID = v.Owner.ID + o.Login = orgName + resOwner = append(resOwner, o) + processedOrgs[orgName] = struct{}{} + } + } + for _, v := range resOwner { + result = append(result, v) + } + } else { + var resBody []org + resToken, err := apiClient.Get("user/orgs", query, nil) + if err != nil { + return nil, err + } + err = api.UnmarshalResponse(resToken, &resBody) + if err != nil { + return nil, err + } + res, err = apiClient.Get("user", nil, nil) + if err != nil { + return nil, err + } + err = api.UnmarshalResponse(res, &o) + if err != nil { + return nil, err + } + result = append(result, o) + for _, v := range resBody { + result = append(result, v) + } } - result = append(result, o) + return result, err }, func(basicRes context.BasicRes, gid string, queryData *api.RemoteQueryData, connection models.GithubConnection) ([]repo, errors.Error) {
