mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	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:
		| @@ -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) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user