diff --git a/models/perm/access/access.go b/models/perm/access/access.go index 53d14fca1b..23a708f296 100644 --- a/models/perm/access/access.go +++ b/models/perm/access/access.go @@ -231,10 +231,7 @@ func RecalculateTeamAccesses(ctx context.Context, repo *repo_model.Repository, i // RecalculateUserAccess recalculates new access for a single user // Usable if we know access only affected one user func RecalculateUserAccess(ctx context.Context, repo *repo_model.Repository, uid int64) (err error) { - minMode := perm.AccessModeRead - if !repo.IsPrivate { - minMode = perm.AccessModeWrite - } + minMode := perm.AccessModeNone accessMode := perm.AccessModeNone e := db.GetEngine(ctx) @@ -270,7 +267,7 @@ func RecalculateUserAccess(ctx context.Context, repo *repo_model.Repository, uid // Delete old user accesses and insert new one for repository. if _, err = e.Delete(&Access{RepoID: repo.ID, UserID: uid}); err != nil { return fmt.Errorf("delete old user accesses: %w", err) - } else if accessMode >= minMode { + } else if accessMode > minMode { if err = db.Insert(ctx, &Access{RepoID: repo.ID, UserID: uid, Mode: accessMode}); err != nil { return fmt.Errorf("insert new user accesses: %w", err) } diff --git a/models/perm/access/access_test.go b/models/perm/access/access_test.go index eb2c58caf5..ba4216ffcd 100644 --- a/models/perm/access/access_test.go +++ b/models/perm/access/access_test.go @@ -26,6 +26,7 @@ func TestAccess(t *testing.T) { t.Run("RecalculateAccesses2", testRecalculateAccesses2) t.Run("RecalculateAccessesUpdateMode", testRecalculateAccessesUpdateMode) t.Run("RecalculateAccessesRemoveAccess", testRecalculateAccessesRemoveAccess) + t.Run("RecalculateUserAccess", testRecalculateUserAccess) } func testAccessLevel(t *testing.T) { @@ -201,3 +202,35 @@ func testRecalculateAccessesRemoveAccess(t *testing.T) { assert.NoError(t, err) assert.False(t, has, "Access should be deleted after removing collaboration") } + +func testRecalculateUserAccess(t *testing.T) { + t.Run("NoAccessForUserWithoutCollaboration", func(t *testing.T) { + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) + assert.NoError(t, repo.LoadOwner(t.Context())) + + userID := int64(8) + _, _ = db.GetEngine(t.Context()).Where("user_id = ? AND repo_id = ?", userID, repo.ID).Delete(&access_model.Access{}) + assert.NoError(t, access_model.RecalculateUserAccess(t.Context(), repo, userID)) + + access := &access_model.Access{UserID: userID, RepoID: repo.ID} + has, err := db.GetEngine(t.Context()).Get(access) + assert.NoError(t, err) + assert.False(t, has, "User without collaboration/team membership should have no access record") + }) + + t.Run("CollaboratorGetsAccess", func(t *testing.T) { + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) + assert.NoError(t, repo.LoadOwner(t.Context())) + + userID := int64(4) + _ = db.Insert(t.Context(), &repo_model.Collaboration{UserID: userID, RepoID: repo.ID, Mode: perm_model.AccessModeWrite}) + + assert.NoError(t, access_model.RecalculateUserAccess(t.Context(), repo, userID)) + + access := &access_model.Access{UserID: userID, RepoID: repo.ID} + has, err := db.GetEngine(t.Context()).Get(access) + assert.NoError(t, err) + assert.True(t, has) + assert.Equal(t, perm_model.AccessModeWrite, access.Mode) + }) +}