Don't return duplicated users who can create org repo (#22560)
- Currently the function `GetUsersWhoCanCreateOrgRepo` uses a query that
is able to have duplicated users in the result, this is can happen under
the condition that a user is in team that either is the owner team or
has permission to create organization repositories.
- Add test code to simulate the above condition for user 3,
[`TestGetUsersWhoCanCreateOrgRepo`](a1fcb1cfb8/models/organization/org_test.go (L435)
)
is the test function that tests for this.
- The fix is quite trivial use a map keyed by user id in order to drop
duplicates.
---------
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
parent
be315c76fb
commit
1b53a9e914
|
@ -151,7 +151,7 @@ func CreateRepoTransferNotification(ctx context.Context, doer, newOwner *user_mo
|
||||||
}
|
}
|
||||||
for i := range users {
|
for i := range users {
|
||||||
notify = append(notify, &Notification{
|
notify = append(notify, &Notification{
|
||||||
UserID: users[i].ID,
|
UserID: i,
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
Status: NotificationStatusUnread,
|
Status: NotificationStatusUnread,
|
||||||
UpdatedBy: doer.ID,
|
UpdatedBy: doer.ID,
|
||||||
|
|
|
@ -140,3 +140,14 @@
|
||||||
num_members: 1
|
num_members: 1
|
||||||
includes_all_repositories: false
|
includes_all_repositories: false
|
||||||
can_create_org_repo: false
|
can_create_org_repo: false
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 14
|
||||||
|
org_id: 3
|
||||||
|
lower_name: teamcreaterepo
|
||||||
|
name: teamCreateRepo
|
||||||
|
authorize: 2 # write
|
||||||
|
num_repos: 0
|
||||||
|
num_members: 1
|
||||||
|
includes_all_repositories: false
|
||||||
|
can_create_org_repo: true
|
||||||
|
|
|
@ -93,3 +93,9 @@
|
||||||
org_id: 19
|
org_id: 19
|
||||||
team_id: 6
|
team_id: 6
|
||||||
uid: 31
|
uid: 31
|
||||||
|
|
||||||
|
-
|
||||||
|
id: 17
|
||||||
|
org_id: 3
|
||||||
|
team_id: 14
|
||||||
|
uid: 2
|
||||||
|
|
|
@ -104,7 +104,7 @@
|
||||||
num_following: 0
|
num_following: 0
|
||||||
num_stars: 0
|
num_stars: 0
|
||||||
num_repos: 3
|
num_repos: 3
|
||||||
num_teams: 4
|
num_teams: 5
|
||||||
num_members: 3
|
num_members: 3
|
||||||
visibility: 0
|
visibility: 0
|
||||||
repo_admin_change_team_access: false
|
repo_admin_change_team_access: false
|
||||||
|
|
|
@ -397,13 +397,14 @@ func (org *Organization) GetOrgUserMaxAuthorizeLevel(uid int64) (perm.AccessMode
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUsersWhoCanCreateOrgRepo returns users which are able to create repo in organization
|
// GetUsersWhoCanCreateOrgRepo returns users which are able to create repo in organization
|
||||||
func GetUsersWhoCanCreateOrgRepo(ctx context.Context, orgID int64) ([]*user_model.User, error) {
|
func GetUsersWhoCanCreateOrgRepo(ctx context.Context, orgID int64) (map[int64]*user_model.User, error) {
|
||||||
users := make([]*user_model.User, 0, 10)
|
// Use a map, in order to de-duplicate users.
|
||||||
|
users := make(map[int64]*user_model.User)
|
||||||
return users, db.GetEngine(ctx).
|
return users, db.GetEngine(ctx).
|
||||||
Join("INNER", "`team_user`", "`team_user`.uid=`user`.id").
|
Join("INNER", "`team_user`", "`team_user`.uid=`user`.id").
|
||||||
Join("INNER", "`team`", "`team`.id=`team_user`.team_id").
|
Join("INNER", "`team`", "`team`.id=`team_user`.team_id").
|
||||||
Where(builder.Eq{"team.can_create_org_repo": true}.Or(builder.Eq{"team.authorize": perm.AccessModeOwner})).
|
Where(builder.Eq{"team.can_create_org_repo": true}.Or(builder.Eq{"team.authorize": perm.AccessModeOwner})).
|
||||||
And("team_user.org_id = ?", orgID).Asc("`user`.name").Find(&users)
|
And("team_user.org_id = ?", orgID).Find(&users)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchOrganizationsOptions options to filter organizations
|
// SearchOrganizationsOptions options to filter organizations
|
||||||
|
|
|
@ -91,11 +91,12 @@ func TestUser_GetTeams(t *testing.T) {
|
||||||
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
|
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
|
||||||
teams, err := org.LoadTeams()
|
teams, err := org.LoadTeams()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
if assert.Len(t, teams, 4) {
|
if assert.Len(t, teams, 5) {
|
||||||
assert.Equal(t, int64(1), teams[0].ID)
|
assert.Equal(t, int64(1), teams[0].ID)
|
||||||
assert.Equal(t, int64(2), teams[1].ID)
|
assert.Equal(t, int64(2), teams[1].ID)
|
||||||
assert.Equal(t, int64(12), teams[2].ID)
|
assert.Equal(t, int64(12), teams[2].ID)
|
||||||
assert.Equal(t, int64(7), teams[3].ID)
|
assert.Equal(t, int64(14), teams[3].ID)
|
||||||
|
assert.Equal(t, int64(7), teams[4].ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +293,7 @@ func TestUser_GetUserTeamIDs(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, expected, teamIDs)
|
assert.Equal(t, expected, teamIDs)
|
||||||
}
|
}
|
||||||
testSuccess(2, []int64{1, 2})
|
testSuccess(2, []int64{1, 2, 14})
|
||||||
testSuccess(4, []int64{2})
|
testSuccess(4, []int64{2})
|
||||||
testSuccess(unittest.NonexistentID, []int64{})
|
testSuccess(unittest.NonexistentID, []int64{})
|
||||||
}
|
}
|
||||||
|
@ -447,7 +448,7 @@ func TestGetUsersWhoCanCreateOrgRepo(t *testing.T) {
|
||||||
users, err = organization.GetUsersWhoCanCreateOrgRepo(db.DefaultContext, 7)
|
users, err = organization.GetUsersWhoCanCreateOrgRepo(db.DefaultContext, 7)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, users, 1)
|
assert.Len(t, users, 1)
|
||||||
assert.EqualValues(t, 5, users[0].ID)
|
assert.NotNil(t, users[5])
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUser_RemoveOrgRepo(t *testing.T) {
|
func TestUser_RemoveOrgRepo(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue