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

Fix showing issues in your repositories (#18916) #19191

Merged
merged 1 commit into from
Mar 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion models/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -1551,6 +1551,7 @@ const (
FilterModeCreate
FilterModeMention
FilterModeReviewRequested
FilterModeYourRepositories
)

func parseCountResult(results []map[string][]byte) int64 {
Expand Down Expand Up @@ -1695,6 +1696,7 @@ type UserIssueStatsOptions struct {
IssueIDs []int64
IsArchived util.OptionalBool
LabelIDs []int64
RepoCond builder.Cond
Org *Organization
Team *Team
}
Expand All @@ -1712,6 +1714,9 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) {
if len(opts.IssueIDs) > 0 {
cond = cond.And(builder.In("issue.id", opts.IssueIDs))
}
if opts.RepoCond != nil {
cond = cond.And(opts.RepoCond)
}

if opts.UserID > 0 {
cond = cond.And(issuePullAccessibleRepoCond("issue.repo_id", opts.UserID, opts.Org, opts.Team, opts.IsPull))
Expand All @@ -1733,7 +1738,7 @@ func GetUserIssueStats(opts UserIssueStatsOptions) (*IssueStats, error) {
}

switch opts.FilterMode {
case FilterModeAll:
case FilterModeAll, FilterModeYourRepositories:
stats.OpenCount, err = sess(cond).
And("issue.is_closed = ?", false).
Count(new(Issue))
Expand Down
69 changes: 55 additions & 14 deletions routers/web/user/home.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ func Milestones(ctx *context.Context) {
if issueReposQueryPattern.MatchString(reposQuery) {
// remove "[" and "]" from string
reposQuery = reposQuery[1 : len(reposQuery)-1]
//for each ID (delimiter ",") add to int to repoIDs
// for each ID (delimiter ",") add to int to repoIDs

for _, rID := range strings.Split(reposQuery, ",") {
// Ensure nonempty string entries
Expand Down Expand Up @@ -350,7 +350,6 @@ func Issues(ctx *context.Context) {
var issueReposQueryPattern = regexp.MustCompile(`^\[\d+(,\d+)*,?\]$`)

func buildIssueOverview(ctx *context.Context, unitType unit.Type) {

// ----------------------------------------------------
// Determine user; can be either user or organization.
// Return with NotFound or ServerError if unsuccessful.
Expand All @@ -364,7 +363,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
var (
viewType string
sortType = ctx.FormString("sort")
filterMode = models.FilterModeAll
filterMode int
)

// --------------------------------------------------------------------------------
Expand All @@ -390,8 +389,10 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
filterMode = models.FilterModeMention
case "review_requested":
filterMode = models.FilterModeReviewRequested
case "your_repositories": // filterMode already set to All
case "your_repositories":
fallthrough
default:
filterMode = models.FilterModeYourRepositories
viewType = "your_repositories"
}

Expand Down Expand Up @@ -421,6 +422,30 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
User: ctx.User,
}

// Search all repositories which
//
// As user:
// - Owns the repository.
// - Have collaborator permissions in repository.
//
// As org:
// - Owns the repository.
//
// As team:
// - Team org's owns the repository.
// - Team has read permission to repository.
repoOpts := &models.SearchRepoOptions{
Actor: ctx.User,
OwnerID: ctx.User.ID,
Private: true,
AllPublic: false,
AllLimited: false,
}

if ctxUser.IsOrganization() && ctx.Org.Team != nil {
repoOpts.TeamID = ctx.Org.Team.ID
}

switch filterMode {
case models.FilterModeAll:
case models.FilterModeAssign:
Expand All @@ -431,6 +456,19 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
opts.MentionedID = ctx.User.ID
case models.FilterModeReviewRequested:
opts.ReviewRequestedID = ctx.User.ID
case models.FilterModeYourRepositories:
if ctxUser.IsOrganization() && ctx.Org.Team != nil {
// Fixes a issue whereby the user's ID would be used
// to check if it's in the team(which possible isn't the case).
opts.User = nil
}
userRepoIDs, _, err := models.SearchRepositoryIDs(repoOpts)
if err != nil {
ctx.ServerError("models.SearchRepositoryIDs: %v", err)
return
}

opts.RepoIDs = userRepoIDs
}

// keyword holds the search term entered into the search field.
Expand Down Expand Up @@ -562,8 +600,12 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
Org: org,
Team: team,
}
if len(repoIDs) > 0 {
statsOpts.RepoIDs = repoIDs
if filterMode == models.FilterModeYourRepositories {
statsOpts.RepoCond = models.SearchRepositoryCondition(repoOpts)
}
// Detect when we only should search by team.
if opts.User == nil {
statsOpts.UserID = 0
}
issueStats, err = models.GetUserIssueStats(statsOpts)
if err != nil {
Expand All @@ -586,8 +628,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {

ctx.Data["IsShowClosed"] = isShowClosed

ctx.Data["IssueRefEndNames"], ctx.Data["IssueRefURLs"] =
issue_service.GetRefEndNamesAndURLs(issues, ctx.FormString("RepoLink"))
ctx.Data["IssueRefEndNames"], ctx.Data["IssueRefURLs"] = issue_service.GetRefEndNamesAndURLs(issues, ctx.FormString("RepoLink"))

ctx.Data["Issues"] = issues

Expand Down Expand Up @@ -661,7 +702,7 @@ func getRepoIDs(reposQuery string) []int64 {
var repoIDs []int64
// remove "[" and "]" from string
reposQuery = reposQuery[1 : len(reposQuery)-1]
//for each ID (delimiter ",") add to int to repoIDs
// for each ID (delimiter ",") add to int to repoIDs
for _, rID := range strings.Split(reposQuery, ",") {
// Ensure nonempty string entries
if rID != "" && rID != "0" {
Expand Down Expand Up @@ -693,8 +734,8 @@ func issueIDsFromSearch(ctxUser *user_model.User, keyword string, opts *models.I
}

func loadRepoByIDs(ctxUser *user_model.User, issueCountByRepo map[int64]int64, unitType unit.Type) (map[int64]*repo_model.Repository, error) {
var totalRes = make(map[int64]*repo_model.Repository, len(issueCountByRepo))
var repoIDs = make([]int64, 0, 500)
totalRes := make(map[int64]*repo_model.Repository, len(issueCountByRepo))
repoIDs := make([]int64, 0, 500)
for id := range issueCountByRepo {
if id <= 0 {
continue
Expand Down Expand Up @@ -745,7 +786,7 @@ func ShowGPGKeys(ctx *context.Context, uid int64) {
if err != nil {
if asymkey_model.IsErrGPGKeyImportNotExist(err) {
failedEntitiesID = append(failedEntitiesID, k.KeyID)
continue //Skip previous import without backup of imported armored key
continue // Skip previous import without backup of imported armored key
}
ctx.ServerError("ShowGPGKeys", err)
return
Expand All @@ -755,12 +796,12 @@ func ShowGPGKeys(ctx *context.Context, uid int64) {
var buf bytes.Buffer

headers := make(map[string]string)
if len(failedEntitiesID) > 0 { //If some key need re-import to be exported
if len(failedEntitiesID) > 0 { // If some key need re-import to be exported
headers["Note"] = fmt.Sprintf("The keys with the following IDs couldn't be exported and need to be reuploaded %s", strings.Join(failedEntitiesID, ", "))
}
writer, _ := armor.Encode(&buf, "PGP PUBLIC KEY BLOCK", headers)
for _, e := range entities {
err = e.Serialize(writer) //TODO find why key are exported with a different cipherTypeByte as original (should not be blocking but strange)
err = e.Serialize(writer) // TODO find why key are exported with a different cipherTypeByte as original (should not be blocking but strange)
if err != nil {
ctx.ServerError("ShowGPGKeys", err)
return
Expand Down