Browse Source

Allow collaborators to view repo owned private org (#6965)

Handle case where an orginization is private but a user who is not a
member of the orgninization has been added as a collaborator of a repo
within that org

Fixes #6962
mrsdizzie 1 month ago
parent
commit
68a83cc5a2
3 changed files with 27 additions and 4 deletions
  1. 9 0
      integrations/org_test.go
  2. 6 0
      models/fixtures/collaboration.yml
  3. 12 4
      models/repo_permission.go

+ 9 - 0
integrations/org_test.go

@@ -92,6 +92,15 @@ func TestPrivateOrg(t *testing.T) {
 	req = NewRequest(t, "GET", "/privated_org/private_repo_on_private_org")
 	session.MakeRequest(t, req, http.StatusNotFound)
 
+	// non-org member who is collaborator on repo in private org
+	session = loginUser(t, "user4")
+	req = NewRequest(t, "GET", "/privated_org")
+	session.MakeRequest(t, req, http.StatusNotFound)
+	req = NewRequest(t, "GET", "/privated_org/public_repo_on_private_org") // colab of this repo
+	session.MakeRequest(t, req, http.StatusOK)
+	req = NewRequest(t, "GET", "/privated_org/private_repo_on_private_org")
+	session.MakeRequest(t, req, http.StatusNotFound)
+
 	// site admin
 	session = loginUser(t, "user1")
 	req = NewRequest(t, "GET", "/privated_org")

+ 6 - 0
models/fixtures/collaboration.yml

@@ -9,3 +9,9 @@
   repo_id: 4
   user_id: 4
   mode: 2 # write
+
+-
+  id: 3
+  repo_id: 40
+  user_id: 4
+  mode: 2 # write

+ 12 - 4
models/repo_permission.go

@@ -168,7 +168,17 @@ func getUserRepoPermission(e Engine, repo *Repository, user *User) (perm Permiss
 		repo.mustOwner(e)
 	}
 
-	if repo.Owner.IsOrganization() && !HasOrgVisible(repo.Owner, user) {
+	var isCollaborator bool
+	if user != nil {
+		isCollaborator, err = repo.isCollaborator(e, user.ID)
+		if err != nil {
+			return perm, err
+		}
+	}
+
+	// Prevent strangers from checking out public repo of private orginization
+	// Allow user if they are collaborator of a repo within a private orginization but not a member of the orginization itself
+	if repo.Owner.IsOrganization() && !HasOrgVisible(repo.Owner, user) && !isCollaborator {
 		perm.AccessMode = AccessModeNone
 		return
 	}
@@ -207,9 +217,7 @@ func getUserRepoPermission(e Engine, repo *Repository, user *User) (perm Permiss
 	perm.UnitsMode = make(map[UnitType]AccessMode)
 
 	// Collaborators on organization
-	if isCollaborator, err := repo.isCollaborator(e, user.ID); err != nil {
-		return perm, err
-	} else if isCollaborator {
+	if isCollaborator {
 		for _, u := range repo.Units {
 			perm.UnitsMode[u.Type] = perm.AccessMode
 		}