Skip to content

Commit 1410838

Browse files
klindclaudeklesh
authored
fix(github): show private repos for authenticated user's own account (#8680) (#8681)
Previously, when listing repos for the PAT owner's own account, the code used /users/{username}/repos which only returns public repos. Changes: - Add getOwnerInfo() to fetch owner type (User/Organization) from API - Add getAuthenticatedUserID() to get current user's ID - Use switch on owner type to select the correct endpoint: - Organization: /orgs/{owner}/repos - Authenticated user: /user/repos (includes private repos) - Other users: /users/{owner}/repos (public only) - Rename function to listGithubOwnerRepos and parameter to 'owner' - Add type=all query parameter to include all repo types Closes #8680 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: Klesh Wong <klesh@qq.com>
1 parent 8ac9386 commit 1410838

File tree

1 file changed

+59
-8
lines changed

1 file changed

+59
-8
lines changed

backend/plugins/github/api/remote_api.go

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func listGithubRemoteScopes(
5252
if groupId == "" {
5353
return listGithubUserOrgs(apiClient, page)
5454
}
55-
return listGithubOrgRepos(apiClient, groupId, page)
55+
return listGithubOwnerRepos(apiClient, groupId, page)
5656
}
5757

5858
func listGithubUserOrgs(
@@ -112,9 +112,41 @@ func listGithubUserOrgs(
112112
return children, nextPage, nil
113113
}
114114

115-
func listGithubOrgRepos(
115+
// getOwnerInfo fetches the owner's type and ID from the GitHub API.
116+
func getOwnerInfo(apiClient plugin.ApiClient, owner string) (ownerType string, ownerID int, err errors.Error) {
117+
resp, err := apiClient.Get(fmt.Sprintf("users/%s", owner), nil, nil)
118+
if err != nil {
119+
return "", 0, err
120+
}
121+
var info struct {
122+
ID int `json:"id"`
123+
Type string `json:"type"`
124+
}
125+
errors.Must(api.UnmarshalResponse(resp, &info))
126+
return info.Type, info.ID, nil
127+
}
128+
129+
// getAuthenticatedUserID returns the ID of the currently authenticated user.
130+
func getAuthenticatedUserID(apiClient plugin.ApiClient) (int, errors.Error) {
131+
resp, err := apiClient.Get("user", nil, nil)
132+
if err != nil {
133+
return 0, err
134+
}
135+
var user struct {
136+
ID int `json:"id"`
137+
}
138+
errors.Must(api.UnmarshalResponse(resp, &user))
139+
return user.ID, nil
140+
}
141+
142+
// listGithubOwnerRepos lists repositories for a given owner (user or organization).
143+
// It determines the owner type via the GitHub API and uses the appropriate endpoint:
144+
// - For organizations: /orgs/{owner}/repos
145+
// - For the authenticated user: /user/repos (includes private repos)
146+
// - For other users: /users/{owner}/repos (public repos only)
147+
func listGithubOwnerRepos(
116148
apiClient plugin.ApiClient,
117-
org string,
149+
owner string,
118150
page GithubRemotePagination,
119151
) (
120152
children []dsmodels.DsRemoteApiScopeListEntry[models.GithubRepo],
@@ -124,19 +156,38 @@ func listGithubOrgRepos(
124156
query := url.Values{
125157
"page": []string{fmt.Sprintf("%v", page.Page)},
126158
"per_page": []string{fmt.Sprintf("%v", page.PerPage)},
159+
"type": []string{"all"},
127160
}
128-
// user's orgs
129-
reposBody, err := apiClient.Get(fmt.Sprintf("orgs/%s/repos", org), query, nil)
161+
162+
ownerType, ownerID, err := getOwnerInfo(apiClient, owner)
130163
if err != nil {
131164
return nil, nil, err
132165
}
133-
// if not found, try to get user repos
134-
if reposBody.StatusCode == http.StatusNotFound {
135-
reposBody, err = apiClient.Get(fmt.Sprintf("users/%s/repos", org), query, nil)
166+
167+
var reposBody *http.Response
168+
switch ownerType {
169+
case "Organization":
170+
reposBody, err = apiClient.Get(fmt.Sprintf("orgs/%s/repos", owner), query, nil)
171+
case "User":
172+
authUserID, err := getAuthenticatedUserID(apiClient)
136173
if err != nil {
137174
return nil, nil, err
138175
}
176+
if authUserID == ownerID {
177+
// Authenticated user's own account - includes private repos
178+
reposBody, err = apiClient.Get("user/repos", query, nil)
179+
} else {
180+
// Another user's account - public repos only
181+
reposBody, err = apiClient.Get(fmt.Sprintf("users/%s/repos", owner), query, nil)
182+
}
183+
default:
184+
// Fallback for unknown types
185+
reposBody, err = apiClient.Get(fmt.Sprintf("users/%s/repos", owner), query, nil)
139186
}
187+
if err != nil {
188+
return nil, nil, err
189+
}
190+
140191
var repos []repo
141192
errors.Must(api.UnmarshalResponse(reposBody, &repos))
142193
for _, repo := range repos {

0 commit comments

Comments
 (0)