]> source.dussan.org Git - gitea.git/commitdiff
Don't return duplicated users who can create org repo (#22560)
authorGusted <postmaster@gusted.xyz>
Mon, 30 Jan 2023 10:12:45 +0000 (11:12 +0100)
committerGitHub <noreply@github.com>
Mon, 30 Jan 2023 10:12:45 +0000 (18:12 +0800)
- 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`](https://github.com/go-gitea/gitea/blob/a1fcb1cfb84fd6b36c8fe9fd56588119fa4377bc/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>
models/activities/notification.go
models/fixtures/team.yml
models/fixtures/team_user.yml
models/fixtures/user.yml
models/organization/org.go
models/organization/org_test.go

index 321d543c736ae35663f86f0f6c13d29ba6c036a8..f153eb0589aa58170d4e8d72ffdd10e5e4b9e42c 100644 (file)
@@ -151,7 +151,7 @@ func CreateRepoTransferNotification(ctx context.Context, doer, newOwner *user_mo
                        }
                        for i := range users {
                                notify = append(notify, &Notification{
-                                       UserID:    users[i].ID,
+                                       UserID:    i,
                                        RepoID:    repo.ID,
                                        Status:    NotificationStatusUnread,
                                        UpdatedBy: doer.ID,
index ea47a33f1c4db10cc37e25725acfc08e964d36d1..dd434d78a980c20515e9f24a3ce9b4e92451959d 100644 (file)
   num_members: 1
   includes_all_repositories: 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
index 845741effddf8f78d9f322067621b882daba6ca3..de4f29d977cbb05e70be1fe47c09c04c3e3533b5 100644 (file)
@@ -93,3 +93,9 @@
   org_id: 19
   team_id: 6
   uid: 31
+
+-
+  id: 17
+  org_id: 3
+  team_id: 14
+  uid: 2
index 3afed37df965590101a9e1a0e9684975dfbba05c..63a5e0f890552150b46772d7e1ebe11245d1edd5 100644 (file)
   num_following: 0
   num_stars: 0
   num_repos: 3
-  num_teams: 4
+  num_teams: 5
   num_members: 3
   visibility: 0
   repo_admin_change_team_access: false
index 9d9e9cda46a485cf27128c4cf0cf23d1e448a7d9..05eaead60bf0934bdc01580d750c7aebecbcc3ac 100644 (file)
@@ -397,13 +397,14 @@ func (org *Organization) GetOrgUserMaxAuthorizeLevel(uid int64) (perm.AccessMode
 }
 
 // GetUsersWhoCanCreateOrgRepo returns users which are able to create repo in organization
-func GetUsersWhoCanCreateOrgRepo(ctx context.Context, orgID int64) ([]*user_model.User, error) {
-       users := make([]*user_model.User, 0, 10)
+func GetUsersWhoCanCreateOrgRepo(ctx context.Context, orgID int64) (map[int64]*user_model.User, error) {
+       // Use a map, in order to de-duplicate users.
+       users := make(map[int64]*user_model.User)
        return users, db.GetEngine(ctx).
                Join("INNER", "`team_user`", "`team_user`.uid=`user`.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})).
-               And("team_user.org_id = ?", orgID).Asc("`user`.name").Find(&users)
+               And("team_user.org_id = ?", orgID).Find(&users)
 }
 
 // SearchOrganizationsOptions options to filter organizations
index 2f821e3a4c1fa471f0514c79a3e4592f66181d0b..0a38365924ed6be9f34d7329918c487147943f37 100644 (file)
@@ -91,11 +91,12 @@ func TestUser_GetTeams(t *testing.T) {
        org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
        teams, err := org.LoadTeams()
        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(2), teams[1].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.Equal(t, expected, teamIDs)
        }
-       testSuccess(2, []int64{1, 2})
+       testSuccess(2, []int64{1, 2, 14})
        testSuccess(4, []int64{2})
        testSuccess(unittest.NonexistentID, []int64{})
 }
@@ -447,7 +448,7 @@ func TestGetUsersWhoCanCreateOrgRepo(t *testing.T) {
        users, err = organization.GetUsersWhoCanCreateOrgRepo(db.DefaultContext, 7)
        assert.NoError(t, err)
        assert.Len(t, users, 1)
-       assert.EqualValues(t, 5, users[0].ID)
+       assert.NotNil(t, users[5])
 }
 
 func TestUser_RemoveOrgRepo(t *testing.T) {