Explorar o código

models/repo: allow SearchRepos to return private but accessible repositories (#4273)

* models/repo.go SearchRepositoryByName()
Updated function to return public and private repositories that the logged in user has been given rights to view
issue #3088

* models/repo.go SearchRepositoryName
changed repository table alias to 'repo'
removed debug line

* models/repo.go SearchRepositoryByName
modified UserID search query to use the "access" table instead of team_repo, team_user etc

* models/repo.go SearchRepositoryByName
1) uppercased SQL keywords
2) removed alias for ACCESS table
Rob Richards %!s(int64=8) %!d(string=hai) anos
pai
achega
aaadc61ee8
Modificáronse 2 ficheiros con 18 adicións e 8 borrados
  1. 17 8
      models/repo.go
  2. 1 0
      routers/home.go

+ 17 - 8
models/repo.go

@@ -1570,6 +1570,7 @@ func GetRepositoryCount(u *User) (int64, error) {
 type SearchRepoOptions struct {
 	Keyword  string
 	OwnerID  int64
+	UserID   int64 // if set results will contain all public/private repositories user has access to
 	OrderBy  string
 	Private  bool // Include private repositories in results
 	Page     int
@@ -1589,14 +1590,22 @@ func SearchRepositoryByName(opts *SearchRepoOptions) (repos []*Repository, _ int
 	}
 
 	repos = make([]*Repository, 0, opts.PageSize)
-
-	// Append conditions
-	sess := x.Where("LOWER(lower_name) LIKE ?", "%"+opts.Keyword+"%")
-	if opts.OwnerID > 0 {
-		sess.And("owner_id = ?", opts.OwnerID)
+	sess := x.Alias("repo")
+	// Attempt to find repositories that opts.UserId has access to
+	// This does not include other people's private repositories even if opts.UserId is an admin
+	if !opts.Private && opts.UserID > 0 {
+		sess.Join("LEFT", "access", "access.repo_id = repo.id")
+		sess.Where("repo.lower_name LIKE ? AND (repo.owner_id=? OR access.user_id=? OR repo.is_private=?)",
+			"%"+opts.Keyword+"%", opts.UserID, opts.UserID, false)
+	} else {
+		sess.Where("repo.lower_name LIKE ?", "%"+opts.Keyword+"%")
+		// only return public repositories if opts.Private is not set
+		if !opts.Private {
+			sess.And("repo.is_private=?", false)
+		}
 	}
-	if !opts.Private {
-		sess.And("is_private=?", false)
+	if opts.OwnerID > 0 {
+		sess.And("repo.owner_id=?", opts.OwnerID)
 	}
 
 	var countSess xorm.Session
@@ -1607,7 +1616,7 @@ func SearchRepositoryByName(opts *SearchRepoOptions) (repos []*Repository, _ int
 	}
 
 	if len(opts.OrderBy) > 0 {
-		sess.OrderBy(opts.OrderBy)
+		sess.OrderBy("repo." + opts.OrderBy)
 	}
 	return repos, count, sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&repos)
 }

+ 1 - 0
routers/home.go

@@ -77,6 +77,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
 	} else {
 		repos, count, err = models.SearchRepositoryByName(&models.SearchRepoOptions{
 			Keyword:  keyword,
+			UserID:   ctx.User.ID,
 			OrderBy:  opts.OrderBy,
 			Private:  opts.Private,
 			Page:     page,