Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MM-809]: Fixed the issue of getting errors when using github api with revoked/invalid token #832

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
193 changes: 147 additions & 46 deletions server/plugin/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -664,10 +664,18 @@ func (p *Plugin) getMentions(c *UserContext, w http.ResponseWriter, r *http.Requ
orgList := p.configuration.getOrganizations()
query := getMentionSearchQuery(username, orgList)

result, _, err := githubClient.Search.Issues(c.Ctx, query, &github.SearchOptions{})
if err != nil {
var result *github.IssuesSearchResult
var err error
cErr := p.useGitHubClient(c.GHInfo, func(info *GitHubUserInfo, token *oauth2.Token) error {
result, _, err = githubClient.Search.Issues(c.Ctx, query, &github.SearchOptions{})
if err != nil {
return err
}
return nil
})
if cErr != nil {
p.writeAPIError(w, &APIErrorResponse{Message: "failed to search for issues", StatusCode: http.StatusInternalServerError})
c.Log.WithError(err).With(logger.LogContext{"query": query}).Warnf("Failed to search for issues")
c.Log.WithError(cErr).With(logger.LogContext{"query": query}).Warnf("Failed to search for issues")
return
}

Expand All @@ -676,9 +684,17 @@ func (p *Plugin) getMentions(c *UserContext, w http.ResponseWriter, r *http.Requ

func (p *Plugin) getUnreadsData(c *UserContext) []*FilteredNotification {
githubClient := p.githubConnectUser(c.Context.Ctx, c.GHInfo)
notifications, _, err := githubClient.Activity.ListNotifications(c.Ctx, &github.NotificationListOptions{})
if err != nil {
c.Log.WithError(err).Warnf("Failed to list notifications")
var notifications []*github.Notification
var err error
cErr := p.useGitHubClient(c.GHInfo, func(info *GitHubUserInfo, token *oauth2.Token) error {
notifications, _, err = githubClient.Activity.ListNotifications(c.Ctx, &github.NotificationListOptions{})
if err != nil {
return err
}
return nil
})
if cErr != nil {
c.Log.WithError(cErr).Warnf("Failed to list notifications")
return nil
}

Expand Down Expand Up @@ -817,9 +833,17 @@ func (p *Plugin) searchIssues(c *UserContext, w http.ResponseWriter, r *http.Req
allIssues := []*github.Issue{}
for _, org := range orgsList {
query := getIssuesSearchQuery(org, searchTerm)
result, _, err := githubClient.Search.Issues(c.Ctx, query, &github.SearchOptions{})
if err != nil {
c.Log.WithError(err).With(logger.LogContext{"query": query}).Warnf("Failed to search for issues")
var result *github.IssuesSearchResult
var err error
cErr := p.useGitHubClient(c.GHInfo, func(info *GitHubUserInfo, token *oauth2.Token) error {
result, _, err = githubClient.Search.Issues(c.Ctx, query, &github.SearchOptions{})
if err != nil {
return err
}
return nil
})
if cErr != nil {
c.Log.WithError(cErr).With(logger.LogContext{"query": query}).Warnf("Failed to search for issues")
p.writeJSON(w, make([]*github.Issue, 0))
return
}
Expand Down Expand Up @@ -935,12 +959,24 @@ func (p *Plugin) createIssueComment(c *UserContext, w http.ResponseWriter, r *ht
Body: &req.Comment,
}

result, rawResponse, err := githubClient.Issues.CreateComment(c.Ctx, req.Owner, req.Repo, req.Number, comment)
if err != nil {
var result *github.IssueComment
var rawResponse *github.Response
if cErr := p.useGitHubClient(c.GHInfo, func(info *GitHubUserInfo, token *oauth2.Token) error {
result, rawResponse, err = githubClient.Issues.CreateComment(c.Ctx, req.Owner, req.Repo, req.Number, comment)
if err != nil {
return err
}
return nil
}); cErr != nil {
Kshitij-Katiyar marked this conversation as resolved.
Show resolved Hide resolved
statusCode := 500
if rawResponse != nil {
statusCode = rawResponse.StatusCode
}
c.Log.WithError(err).With(logger.LogContext{
"owner": req.Owner,
"repo": req.Repo,
"number": req.Number,
}).Errorf("failed to create an issue comment")
p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "failed to create an issue comment: " + getFailReason(statusCode, req.Repo, currentUsername), StatusCode: statusCode})
return
}
Expand Down Expand Up @@ -1006,9 +1042,8 @@ func (p *Plugin) getSidebarContent(c *UserContext, w http.ResponseWriter, r *htt

func (p *Plugin) postToDo(c *UserContext, w http.ResponseWriter, r *http.Request) {
githubClient := p.githubConnectUser(c.Context.Ctx, c.GHInfo)
username := c.GHInfo.GitHubUsername

text, err := p.GetToDo(c.Ctx, username, githubClient)
text, err := p.GetToDo(c.Ctx, c.GHInfo, githubClient)
if err != nil {
c.Log.WithError(err).Warnf("Failed to get Todos")
p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "Encountered an error getting the to do items.", StatusCode: http.StatusUnauthorized})
Expand Down Expand Up @@ -1062,12 +1097,18 @@ func (p *Plugin) getIssueByNumber(c *UserContext, w http.ResponseWriter, r *http

githubClient := p.githubConnectUser(c.Context.Ctx, c.GHInfo)

result, _, err := githubClient.Issues.Get(c.Ctx, owner, repo, numberInt)
if err != nil {
var result *github.Issue
if cErr := p.useGitHubClient(c.GHInfo, func(info *GitHubUserInfo, token *oauth2.Token) error {
result, _, err = githubClient.Issues.Get(c.Ctx, owner, repo, numberInt)
if err != nil {
return err
}
return nil
}); cErr != nil {
// If the issue is not found, it's probably behind a private repo.
// Return an empty repose in this case.
// Return an empty response in this case.
var gerr *github.ErrorResponse
Kshitij-Katiyar marked this conversation as resolved.
Show resolved Hide resolved
if errors.As(err, &gerr) && gerr.Response.StatusCode == http.StatusNotFound {
if errors.As(cErr, &gerr) && gerr.Response.StatusCode == http.StatusNotFound {
c.Log.WithError(err).With(logger.LogContext{
"owner": owner,
"repo": repo,
Expand All @@ -1077,7 +1118,7 @@ func (p *Plugin) getIssueByNumber(c *UserContext, w http.ResponseWriter, r *http
return
}

c.Log.WithError(err).With(logger.LogContext{
c.Log.WithError(cErr).With(logger.LogContext{
"owner": owner,
"repo": repo,
"number": numberInt,
Expand All @@ -1103,13 +1144,18 @@ func (p *Plugin) getPrByNumber(c *UserContext, w http.ResponseWriter, r *http.Re
}

githubClient := p.githubConnectUser(c.Context.Ctx, c.GHInfo)

result, _, err := githubClient.PullRequests.Get(c.Ctx, owner, repo, numberInt)
if err != nil {
var result *github.PullRequest
if cErr := p.useGitHubClient(c.GHInfo, func(userInfo *GitHubUserInfo, token *oauth2.Token) error {
result, _, err = githubClient.PullRequests.Get(c.Ctx, owner, repo, numberInt)
if err != nil {
return err
}
return nil
}); cErr != nil {
// If the pull request is not found, it's probably behind a private repo.
// Return an empty repose in this case.
var gerr *github.ErrorResponse
if errors.As(err, &gerr) && gerr.Response.StatusCode == http.StatusNotFound {
if errors.As(cErr, &gerr) && gerr.Response.StatusCode == http.StatusNotFound {
c.Log.With(logger.LogContext{
"owner": owner,
"repo": repo,
Expand All @@ -1120,7 +1166,7 @@ func (p *Plugin) getPrByNumber(c *UserContext, w http.ResponseWriter, r *http.Re
return
}

c.Log.WithError(err).With(logger.LogContext{
c.Log.WithError(cErr).With(logger.LogContext{
"owner": owner,
"repo": repo,
"number": numberInt,
Expand All @@ -1146,9 +1192,19 @@ func (p *Plugin) getLabels(c *UserContext, w http.ResponseWriter, r *http.Reques
opt := github.ListOptions{PerPage: 50}

for {
labels, resp, err := githubClient.Issues.ListLabels(c.Ctx, owner, repo, &opt)
if err != nil {
c.Log.WithError(err).Warnf("Failed to list labels")
var labels []*github.Label
var resp *github.Response
if cErr := p.useGitHubClient(c.GHInfo, func(info *GitHubUserInfo, token *oauth2.Token) error {
labels, resp, err = githubClient.Issues.ListLabels(c.Ctx, owner, repo, &opt)
if err != nil {
return err
}
return nil
}); cErr != nil {
c.Log.WithError(cErr).With(logger.LogContext{
"owner": owner,
"repo": repo,
}).Warnf("Failed to list labels")
p.writeAPIError(w, &APIErrorResponse{Message: "Failed to fetch labels", StatusCode: http.StatusInternalServerError})
return
}
Expand All @@ -1174,9 +1230,19 @@ func (p *Plugin) getAssignees(c *UserContext, w http.ResponseWriter, r *http.Req
opt := github.ListOptions{PerPage: 50}

for {
assignees, resp, err := githubClient.Issues.ListAssignees(c.Ctx, owner, repo, &opt)
if err != nil {
c.Log.WithError(err).Warnf("Failed to list assignees")
var assignees []*github.User
var resp *github.Response
if cErr := p.useGitHubClient(c.GHInfo, func(info *GitHubUserInfo, token *oauth2.Token) error {
assignees, resp, err = githubClient.Issues.ListAssignees(c.Ctx, owner, repo, &opt)
if err != nil {
return err
}
return nil
}); cErr != nil {
c.Log.WithError(cErr).With(logger.LogContext{
"owner": owner,
"repo": repo,
}).Warnf("Failed to list assignees")
p.writeAPIError(w, &APIErrorResponse{Message: "Failed to fetch assignees", StatusCode: http.StatusInternalServerError})
return
}
Expand All @@ -1202,9 +1268,19 @@ func (p *Plugin) getMilestones(c *UserContext, w http.ResponseWriter, r *http.Re
opt := github.ListOptions{PerPage: 50}

for {
milestones, resp, err := githubClient.Issues.ListMilestones(c.Ctx, owner, repo, &github.MilestoneListOptions{ListOptions: opt})
if err != nil {
c.Log.WithError(err).Warnf("Failed to list milestones")
var milestones []*github.Milestone
var resp *github.Response
if cErr := p.useGitHubClient(c.GHInfo, func(info *GitHubUserInfo, token *oauth2.Token) error {
milestones, resp, err = githubClient.Issues.ListMilestones(c.Ctx, owner, repo, &github.MilestoneListOptions{ListOptions: opt})
if err != nil {
return err
}
return nil
}); cErr != nil {
c.Log.WithError(cErr).With(logger.LogContext{
"owner": owner,
"repo": repo,
}).Warnf("Failed to list milestones")
p.writeAPIError(w, &APIErrorResponse{Message: "Failed to fetch milestones", StatusCode: http.StatusInternalServerError})
return
}
Expand All @@ -1218,12 +1294,21 @@ func (p *Plugin) getMilestones(c *UserContext, w http.ResponseWriter, r *http.Re
p.writeJSON(w, allMilestones)
}

func getRepositoryList(c context.Context, userName string, githubClient *github.Client, opt github.ListOptions) ([]*github.Repository, error) {
func (p *Plugin) getRepositoryList(c context.Context, ghInfo *GitHubUserInfo, userName string, githubClient *github.Client, opt github.ListOptions) ([]*github.Repository, error) {
var allRepos []*github.Repository
for {
repos, resp, err := githubClient.Repositories.List(c, userName, &github.RepositoryListOptions{ListOptions: opt})
if err != nil {
return nil, err
var repos []*github.Repository
var resp *github.Response
var err error
cErr := p.useGitHubClient(ghInfo, func(info *GitHubUserInfo, token *oauth2.Token) error {
repos, resp, err = githubClient.Repositories.List(c, userName, &github.RepositoryListOptions{ListOptions: opt})
if err != nil {
return err
}
return nil
})
if cErr != nil {
return nil, cErr
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to log the error here or it is handled somewhere else?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is logged from where it is called

}

allRepos = append(allRepos, repos...)
Expand All @@ -1237,12 +1322,21 @@ func getRepositoryList(c context.Context, userName string, githubClient *github.
return allRepos, nil
}

func getRepositoryListByOrg(c context.Context, org string, githubClient *github.Client, opt github.ListOptions) ([]*github.Repository, int, error) {
func (p *Plugin) getRepositoryListByOrg(c context.Context, ghInfo *GitHubUserInfo, org string, githubClient *github.Client, opt github.ListOptions) ([]*github.Repository, int, error) {
var allRepos []*github.Repository
for {
repos, resp, err := githubClient.Repositories.ListByOrg(c, org, &github.RepositoryListByOrgOptions{Sort: "full_name", ListOptions: opt})
if err != nil {
return nil, resp.StatusCode, err
var repos []*github.Repository
var resp *github.Response
var err error
cErr := p.useGitHubClient(ghInfo, func(info *GitHubUserInfo, token *oauth2.Token) error {
repos, resp, err = githubClient.Repositories.ListByOrg(c, org, &github.RepositoryListByOrgOptions{Sort: "full_name", ListOptions: opt})
if err != nil {
return err
}
return nil
})
if cErr != nil {
return nil, resp.StatusCode, cErr
}

allRepos = append(allRepos, repos...)
Expand All @@ -1265,7 +1359,7 @@ func (p *Plugin) getRepositories(c *UserContext, w http.ResponseWriter, r *http.
opt := github.ListOptions{PerPage: 50}

if org == "" {
allRepos, err = getRepositoryList(c.Ctx, "", githubClient, opt)
allRepos, err = p.getRepositoryList(c.Ctx, c.GHInfo, "", githubClient, opt)
if err != nil {
c.Log.WithError(err).Warnf("Failed to list repositories")
p.writeAPIError(w, &APIErrorResponse{Message: "Failed to fetch repositories", StatusCode: http.StatusInternalServerError})
Expand All @@ -1274,10 +1368,10 @@ func (p *Plugin) getRepositories(c *UserContext, w http.ResponseWriter, r *http.
} else {
orgsList := p.configuration.getOrganizations()
for _, org := range orgsList {
orgRepos, statusCode, err := getRepositoryListByOrg(c.Ctx, org, githubClient, opt)
orgRepos, statusCode, err := p.getRepositoryListByOrg(c.Ctx, c.GHInfo, org, githubClient, opt)
if err != nil {
if statusCode == http.StatusNotFound {
orgRepos, err = getRepositoryList(c.Ctx, org, githubClient, opt)
orgRepos, err = p.getRepositoryList(c.Ctx, c.GHInfo, org, githubClient, opt)
if err != nil {
c.Log.WithError(err).Warnf("Failed to list repositories", "Organization", org)
p.writeAPIError(w, &APIErrorResponse{Message: "Failed to fetch repositories", StatusCode: http.StatusInternalServerError})
Expand Down Expand Up @@ -1408,14 +1502,21 @@ func (p *Plugin) createIssue(c *UserContext, w http.ResponseWriter, r *http.Requ
repoName := splittedRepo[1]

githubClient := p.githubConnectUser(c.Context.Ctx, c.GHInfo)
result, resp, err := githubClient.Issues.Create(c.Ctx, owner, repoName, ghIssue)
if err != nil {
var resp *github.Response
var result *github.Issue
if cErr := p.useGitHubClient(c.GHInfo, func(info *GitHubUserInfo, token *oauth2.Token) error {
result, resp, err = githubClient.Issues.Create(c.Ctx, owner, repoName, ghIssue)
if err != nil {
return err
}
return nil
}); cErr != nil {
if resp != nil && resp.Response.StatusCode == http.StatusGone {
p.writeAPIError(w, &APIErrorResponse{ID: "", Message: "Issues are disabled on this repository.", StatusCode: http.StatusMethodNotAllowed})
return
}

c.Log.WithError(err).Warnf("Failed to create issue")
c.Log.WithError(cErr).Warnf("Failed to create issue")
p.writeAPIError(w,
&APIErrorResponse{
ID: "",
Expand Down
Loading
Loading