diff --git a/models/repo_list.go b/models/repo_list.go index 31593368dd3..a3bdf5b8c35 100644 --- a/models/repo_list.go +++ b/models/repo_list.go @@ -214,14 +214,35 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { } if opts.Collaborate != util.OptionalBoolFalse { + // A Collaboration is: collaborateCond := builder.And( + // 1. Repository we don't own + builder.Neq{"owner_id": opts.OwnerID}, + // 2. But we can see because of: builder.Or( - builder.Expr("repository.id IN (SELECT repo_id FROM `access` WHERE access.user_id = ?)", opts.OwnerID), - builder.In("id", builder.Select("`team_repo`.repo_id"). + // A. We have access + builder.In("`repository`.id", + builder.Select("`access`.repo_id"). + From("access"). + Where(builder.Eq{"`access`.user_id": opts.OwnerID})), + // B. We are in a team for + builder.In("`repository`.id", builder.Select("`team_repo`.repo_id"). From("team_repo"). Where(builder.Eq{"`team_user`.uid": opts.OwnerID}). - Join("INNER", "team_user", "`team_user`.team_id = `team_repo`.team_id"))), - builder.Neq{"owner_id": opts.OwnerID}) + Join("INNER", "team_user", "`team_user`.team_id = `team_repo`.team_id")), + // C. Public repositories in private organizations that we are member of + builder.And( + builder.Eq{"`repository`.is_private": false}, + builder.In("`repository`.owner_id", + builder.Select("`org_user`.org_id"). + From("org_user"). + Join("INNER", "`user`", "`user`.id = `org_user`.org_id"). + Where(builder.Eq{ + "`org_user`.uid": opts.OwnerID, + "`user`.type": UserTypeOrganization, + "`user`.visibility": structs.VisibleTypePrivate, + })))), + ) if !opts.Private { collaborateCond = collaborateCond.And(builder.Expr("owner_id NOT IN (SELECT org_id FROM org_user WHERE org_user.uid = ? AND org_user.is_public = ?)", opts.OwnerID, false)) }