From 5343ec15090c734541ed40728a956ec6eaf29f7a Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Fri, 24 Mar 2023 00:43:16 +0000 Subject: [PATCH 1/7] fix --- models/issues/issue.go | 59 ++++++++++++++++++++++++++++++++++++---- models/repo/repo_list.go | 26 ++++++++++++++++++ 2 files changed, 80 insertions(+), 5 deletions(-) diff --git a/models/issues/issue.go b/models/issues/issue.go index edd74261ecfa5..11751b1d84741 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -1374,6 +1374,8 @@ func teamUnitsRepoCond(id string, userID, orgID, teamID int64, units ...unit.Typ "`team_unit`.org_id": orgID, }.And( builder.In("`team_unit`.type", units), + ).And( + builder.Gt{"`team_unit`.access_mode": int(perm.AccessModeNone)}, ), ), ), @@ -1402,17 +1404,64 @@ func issuePullAccessibleRepoCond(repoIDstr string, userID int64, org *organizati } else { cond = cond.And( builder.Or( - repo_model.UserOwnedRepoCond(userID), // owned repos - repo_model.UserAccessRepoCond(repoIDstr, userID), // user can access repo in a unit independent way - repo_model.UserAssignedRepoCond(repoIDstr, userID), // user has been assigned accessible public repos - repo_model.UserMentionedRepoCond(repoIDstr, userID), // user has been mentioned accessible public repos - repo_model.UserCreateIssueRepoCond(repoIDstr, userID, isPull), // user has created issue/pr accessible public repos + repo_model.UserOwnedRepoCond(userID), // owned repos + repo_model.UserUnitAccessRepoCond(repoIDstr, userID, unitType), // user can access repo in a unit independent way + UserAssignedIssueCond(userID), // user has been assigned accessible public repos + UserMentionedIssueCond(userID), // user has been mentioned accessible public repos + UserCreateIssueCond(userID, isPull), // user has created issue/pr accessible public repos ), ) } return cond } +// UserAssignedIssueCond return user as assignee issues list +func UserAssignedIssueCond(userID int64) builder.Cond { + return builder.And( + builder.Eq{ + "repository.is_private": false, + }, + builder.In("issue.id", + builder.Select("issue_assignees.issue_id").From("issue_assignees"). + Where(builder.Eq{ + "issue_assignees.assignee_id": userID, + }), + ), + ) +} + +// UserMentionedIssueCond return user metinoed issues list +func UserMentionedIssueCond(userID int64) builder.Cond { + return builder.And( + builder.Eq{ + "repository.is_private": false, + }, + builder.In("issue.id", + builder.Select("issue_user.issue_id").From("issue_user"). + Where(builder.Eq{ + "issue_user.is_mentioned": true, + "issue_user.uid": userID, + }), + ), + ) +} + +// UserCreateIssueCond return user created issues list +func UserCreateIssueCond(userID int64, isPull bool) builder.Cond { + return builder.And( + builder.Eq{ + "repository.is_private": false, + }, + builder.In("issue.id", + builder.Select("issue.id").From("issue"). + Where(builder.Eq{ + "issue.poster_id": userID, + "issue.is_pull": isPull, + }), + ), + ) +} + func applyAssigneeCondition(sess *xorm.Session, assigneeID int64) *xorm.Session { return sess.Join("INNER", "issue_assignees", "issue.id = issue_assignees.issue_id"). And("issue_assignees.assignee_id = ?", assigneeID) diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go index 92b9c15b4bd8d..d306e092133f9 100644 --- a/models/repo/repo_list.go +++ b/models/repo/repo_list.go @@ -256,6 +256,32 @@ func UserAccessRepoCond(idStr string, userID int64) builder.Cond { ) } +// UserUnitAccessRepoCond returns a condition for selecting all repositories a user has unit independent access to and can access the special unit +func UserUnitAccessRepoCond(idStr string, userID int64, unitType unit.Type) builder.Cond { + return builder.In(idStr, builder.Select("`access`.repo_id"). + From("`access`"). + Join("INNER", "repository", "`repository`.id = `access`.repo_id"). + Join("INNER", "user", "`user`.id = `repository`.owner_id"). + Where( + builder.And( + builder.Eq{"`access`.user_id": userID}, + builder.Gt{"`access`.mode": int(perm.AccessModeNone)}, + builder.Or( + // if repo is an org repo, user need to have unit access permission of the team or be a collaborator of this repo + builder.And( + builder.Eq{"`user`.type": int(user_model.UserTypeOrganization)}, + builder.Or( + builder.In("`access`.repo_id", userOrgTeamUnitRepoBuilder(userID, unitType)), + UserCollaborationRepoCond("`access`.repo_id", userID), + ), + ), + builder.Eq{"`user`.type": int(user_model.UserTypeIndividual)}, + ), + ), + ), + ) +} + // userCollaborationRepoCond returns a condition for selecting all repositories a user is collaborator in func UserCollaborationRepoCond(idStr string, userID int64) builder.Cond { return builder.In(idStr, builder.Select("repo_id"). From 085a44e1960e4b7c784182334c8bad91118435c7 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Fri, 24 Mar 2023 01:05:39 +0000 Subject: [PATCH 2/7] fix ui --- routers/web/user/home.go | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/routers/web/user/home.go b/routers/web/user/home.go index a0a5dc3c4b9ba..73744d4abb98b 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -444,21 +444,6 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { repoOpts.TeamID = team.ID } - switch filterMode { - case issues_model.FilterModeAll: - case issues_model.FilterModeYourRepositories: - case issues_model.FilterModeAssign: - opts.AssigneeID = ctx.Doer.ID - case issues_model.FilterModeCreate: - opts.PosterID = ctx.Doer.ID - case issues_model.FilterModeMention: - opts.MentionedID = ctx.Doer.ID - case issues_model.FilterModeReviewRequested: - opts.ReviewRequestedID = ctx.Doer.ID - case issues_model.FilterModeReviewed: - opts.ReviewedID = ctx.Doer.ID - } - // keyword holds the search term entered into the search field. keyword := strings.Trim(ctx.FormString("q"), " ") ctx.Data["Keyword"] = keyword @@ -495,6 +480,23 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { } } + // In order to display all issues count in repo filter, + // we need to check filterMode after CountIssuesByRepo + switch filterMode { + case issues_model.FilterModeAll: + case issues_model.FilterModeYourRepositories: + case issues_model.FilterModeAssign: + opts.AssigneeID = ctx.Doer.ID + case issues_model.FilterModeCreate: + opts.PosterID = ctx.Doer.ID + case issues_model.FilterModeMention: + opts.MentionedID = ctx.Doer.ID + case issues_model.FilterModeReviewRequested: + opts.ReviewRequestedID = ctx.Doer.ID + case issues_model.FilterModeReviewed: + opts.ReviewedID = ctx.Doer.ID + } + // Make sure page number is at least 1. Will be posted to ctx.Data. page := ctx.FormInt("page") if page <= 1 { From da6e7f8a32bcbbcf36825ad271c153aca515a5d5 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Fri, 24 Mar 2023 02:50:24 +0000 Subject: [PATCH 3/7] fix unit test --- models/issues/issue_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/models/issues/issue_test.go b/models/issues/issue_test.go index 3a83d8d2b791e..26e57409d5964 100644 --- a/models/issues/issue_test.go +++ b/models/issues/issue_test.go @@ -218,7 +218,7 @@ func TestGetUserIssueStats(t *testing.T) { AssignCount: 1, // 6 CreateCount: 1, // 6 OpenCount: 1, // 6 - ClosedCount: 1, // 1 + ClosedCount: 0, // issue(id:5) is posted by user2 and user1 is not owner or collaborator of repo(id:1) }, }, { @@ -229,11 +229,11 @@ func TestGetUserIssueStats(t *testing.T) { IsClosed: true, }, issues_model.IssueStats{ - YourRepositoriesCount: 1, // 6 + YourRepositoriesCount: 0, // 6 AssignCount: 0, CreateCount: 0, OpenCount: 1, // 6 - ClosedCount: 1, // 1 + ClosedCount: 0, // issue(id:5) is posted by user2 and user1 is not owner or collaborator of repo(id:1) }, }, { From 862c85385928158a13455054cb70e0c2b46a7182 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Thu, 20 Apr 2023 05:21:22 +0000 Subject: [PATCH 4/7] fix sql error --- models/repo/repo_list.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go index d306e092133f9..1191432ccaa4f 100644 --- a/models/repo/repo_list.go +++ b/models/repo/repo_list.go @@ -261,7 +261,7 @@ func UserUnitAccessRepoCond(idStr string, userID int64, unitType unit.Type) buil return builder.In(idStr, builder.Select("`access`.repo_id"). From("`access`"). Join("INNER", "repository", "`repository`.id = `access`.repo_id"). - Join("INNER", "user", "`user`.id = `repository`.owner_id"). + Join("INNER", "`user`", "`user`.id = `repository`.owner_id"). Where( builder.And( builder.Eq{"`access`.user_id": userID}, From 331a4e8e4b3163fdea68bae0c4a7068a0d7c4aec Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Mon, 22 May 2023 02:56:22 +0000 Subject: [PATCH 5/7] fix broken changes --- models/issues/issue_list.go | 47 +++++++++++++++++++++++++++++++++++ models/issues/issue_search.go | 10 ++++---- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/models/issues/issue_list.go b/models/issues/issue_list.go index 6ddadd27ed442..3e0620be6d7fe 100644 --- a/models/issues/issue_list.go +++ b/models/issues/issue_list.go @@ -603,3 +603,50 @@ func (issues IssueList) GetApprovalCounts(ctx context.Context) (map[int64][]*Rev return approvalCountMap, nil } + +// UserAssignedIssueCond return user as assignee issues list +func UserAssignedIssueCond(userID int64) builder.Cond { + return builder.And( + builder.Eq{ + "repository.is_private": false, + }, + builder.In("issue.id", + builder.Select("issue_assignees.issue_id").From("issue_assignees"). + Where(builder.Eq{ + "issue_assignees.assignee_id": userID, + }), + ), + ) +} + +// UserMentionedIssueCond return user metinoed issues list +func UserMentionedIssueCond(userID int64) builder.Cond { + return builder.And( + builder.Eq{ + "repository.is_private": false, + }, + builder.In("issue.id", + builder.Select("issue_user.issue_id").From("issue_user"). + Where(builder.Eq{ + "issue_user.is_mentioned": true, + "issue_user.uid": userID, + }), + ), + ) +} + +// UserCreateIssueCond return user created issues list +func UserCreateIssueCond(userID int64, isPull bool) builder.Cond { + return builder.And( + builder.Eq{ + "repository.is_private": false, + }, + builder.In("issue.id", + builder.Select("issue.id").From("issue"). + Where(builder.Eq{ + "issue.poster_id": userID, + "issue.is_pull": isPull, + }), + ), + ) +} diff --git a/models/issues/issue_search.go b/models/issues/issue_search.go index 9fd13f09956af..41d1578c4e9a5 100644 --- a/models/issues/issue_search.go +++ b/models/issues/issue_search.go @@ -311,11 +311,11 @@ func issuePullAccessibleRepoCond(repoIDstr string, userID int64, org *organizati } else { cond = cond.And( builder.Or( - repo_model.UserOwnedRepoCond(userID), // owned repos - repo_model.UserAccessRepoCond(repoIDstr, userID), // user can access repo in a unit independent way - repo_model.UserAssignedRepoCond(repoIDstr, userID), // user has been assigned accessible public repos - repo_model.UserMentionedRepoCond(repoIDstr, userID), // user has been mentioned accessible public repos - repo_model.UserCreateIssueRepoCond(repoIDstr, userID, isPull), // user has created issue/pr accessible public repos + repo_model.UserOwnedRepoCond(userID), // owned repos + repo_model.UserUnitAccessRepoCond(repoIDstr, userID, unitType), // user can access repo in a unit independent way + UserAssignedIssueCond(userID), // user has been assigned accessible public repos + UserMentionedIssueCond(userID), // user has been mentioned accessible public repos + UserCreateIssueCond(userID, isPull), // user has created issue/pr accessible public repos ), ) } From b3e982f0360c9c278762c58c626cc4afd6fc0ced Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Fri, 21 Jul 2023 07:48:00 +0000 Subject: [PATCH 6/7] improve --- models/issues/issue_search.go | 21 +++++++++++---------- models/issues/issue_stats.go | 2 +- models/repo/repo_list.go | 25 ++++++------------------- 3 files changed, 18 insertions(+), 30 deletions(-) diff --git a/models/issues/issue_search.go b/models/issues/issue_search.go index 41d1578c4e9a5..0d62a85313135 100644 --- a/models/issues/issue_search.go +++ b/models/issues/issue_search.go @@ -242,7 +242,7 @@ func applyConditions(sess *xorm.Session, opts *IssuesOptions) *xorm.Session { applyLabelsCondition(sess, opts) if opts.User != nil { - sess.And(issuePullAccessibleRepoCond("issue.repo_id", opts.User.ID, opts.Org, opts.Team, opts.IsPull.IsTrue())) + sess.And(issuePullAccessibleRepoCond("issue.repo_id", opts.User, opts.Org, opts.Team, opts.IsPull.IsTrue())) } return sess @@ -291,7 +291,8 @@ func teamUnitsRepoCond(id string, userID, orgID, teamID int64, units ...unit.Typ } // issuePullAccessibleRepoCond userID must not be zero, this condition require join repository table -func issuePullAccessibleRepoCond(repoIDstr string, userID int64, org *organization.Organization, team *organization.Team, isPull bool) builder.Cond { +// user should not be nil +func issuePullAccessibleRepoCond(repoIDstr string, user *user_model.User, org *organization.Organization, team *organization.Team, isPull bool) builder.Cond { cond := builder.NewCond() unitType := unit.TypeIssues if isPull { @@ -299,23 +300,23 @@ func issuePullAccessibleRepoCond(repoIDstr string, userID int64, org *organizati } if org != nil { if team != nil { - cond = cond.And(teamUnitsRepoCond(repoIDstr, userID, org.ID, team.ID, unitType)) // special team member repos + cond = cond.And(teamUnitsRepoCond(repoIDstr, user.ID, org.ID, team.ID, unitType)) // special team member repos } else { cond = cond.And( builder.Or( - repo_model.UserOrgUnitRepoCond(repoIDstr, userID, org.ID, unitType), // team member repos - repo_model.UserOrgPublicUnitRepoCond(userID, org.ID), // user org public non-member repos, TODO: check repo has issues + repo_model.UserOrgUnitRepoCond(repoIDstr, user.ID, org.ID, unitType), // team member repos + repo_model.UserOrgPublicUnitRepoCond(user.ID, org.ID), // user org public non-member repos, TODO: check repo has issues ), ) } } else { cond = cond.And( builder.Or( - repo_model.UserOwnedRepoCond(userID), // owned repos - repo_model.UserUnitAccessRepoCond(repoIDstr, userID, unitType), // user can access repo in a unit independent way - UserAssignedIssueCond(userID), // user has been assigned accessible public repos - UserMentionedIssueCond(userID), // user has been mentioned accessible public repos - UserCreateIssueCond(userID, isPull), // user has created issue/pr accessible public repos + repo_model.UserOwnedRepoCond(user.ID), // owned repos + repo_model.UserUnitAccessRepoCond(repoIDstr, user, unitType), // user can access repo in a unit independent way + UserAssignedIssueCond(user.ID), // user has been assigned accessible public repos + UserMentionedIssueCond(user.ID), // user has been mentioned accessible public repos + UserCreateIssueCond(user.ID, isPull), // user has created issue/pr accessible public repos ), ) } diff --git a/models/issues/issue_stats.go b/models/issues/issue_stats.go index d86123a824d6d..386f44e10ea3a 100644 --- a/models/issues/issue_stats.go +++ b/models/issues/issue_stats.go @@ -210,7 +210,7 @@ func GetUserIssueStats(filterMode int, opts IssuesOptions) (*IssueStats, error) } if opts.User != nil { - cond = cond.And(issuePullAccessibleRepoCond("issue.repo_id", opts.User.ID, opts.Org, opts.Team, opts.IsPull.IsTrue())) + cond = cond.And(issuePullAccessibleRepoCond("issue.repo_id", opts.User, opts.Org, opts.Team, opts.IsPull.IsTrue())) } sess := func(cond builder.Cond) *xorm.Session { diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go index 25228b0d5fb44..5eb4ccdf604c4 100644 --- a/models/repo/repo_list.go +++ b/models/repo/repo_list.go @@ -257,28 +257,15 @@ func UserAccessRepoCond(idStr string, userID int64) builder.Cond { } // UserUnitAccessRepoCond returns a condition for selecting all repositories a user has unit independent access to and can access the special unit -func UserUnitAccessRepoCond(idStr string, userID int64, unitType unit.Type) builder.Cond { +func UserUnitAccessRepoCond(idStr string, user *user_model.User, unitType unit.Type) builder.Cond { return builder.In(idStr, builder.Select("`access`.repo_id"). From("`access`"). Join("INNER", "repository", "`repository`.id = `access`.repo_id"). - Join("INNER", "`user`", "`user`.id = `repository`.owner_id"). - Where( - builder.And( - builder.Eq{"`access`.user_id": userID}, - builder.Gt{"`access`.mode": int(perm.AccessModeNone)}, - builder.Or( - // if repo is an org repo, user need to have unit access permission of the team or be a collaborator of this repo - builder.And( - builder.Eq{"`user`.type": int(user_model.UserTypeOrganization)}, - builder.Or( - builder.In("`access`.repo_id", userOrgTeamUnitRepoBuilder(userID, unitType)), - UserCollaborationRepoCond("`access`.repo_id", userID), - ), - ), - builder.Eq{"`user`.type": int(user_model.UserTypeIndividual)}, - ), - ), - ), + Where(builder.And( + builder.Eq{"`access`.user_id": user.ID}, + builder.Gt{"`access`.mode": int(perm.AccessModeNone)}, + AccessibleRepositoryCondition(user, unitType), + )), ) } From 33ba5c9526299e7de6060f7d00ae511e695a279d Mon Sep 17 00:00:00 2001 From: silverwind Date: Wed, 9 Aug 2023 17:46:54 +0200 Subject: [PATCH 7/7] Update models/issues/issue_list.go --- models/issues/issue_list.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/issues/issue_list.go b/models/issues/issue_list.go index a3c3b4f4c99a4..f878c4e2694aa 100644 --- a/models/issues/issue_list.go +++ b/models/issues/issue_list.go @@ -615,7 +615,7 @@ func UserAssignedIssueCond(userID int64) builder.Cond { ) } -// UserMentionedIssueCond return user metinoed issues list +// UserMentionedIssueCond return user mentioned issues list func UserMentionedIssueCond(userID int64) builder.Cond { return builder.And( builder.Eq{