summaryrefslogtreecommitdiffstats
path: root/models/repo_list.go
diff options
context:
space:
mode:
authorzeripath <art27@cantab.net>2019-05-15 16:24:39 +0100
committertechknowlogick <techknowlogick@gitea.io>2019-05-15 11:24:39 -0400
commit56ae539bed7d822980ebaae8db316a0177fc028c (patch)
treeee63a75ba156002cb6c40975c1c35b032954f913 /models/repo_list.go
parent5fb1ad70113d3272232c266b4ff58e9f7f646594 (diff)
downloadgitea-56ae539bed7d822980ebaae8db316a0177fc028c.tar.gz
gitea-56ae539bed7d822980ebaae8db316a0177fc028c.zip
SearchRepositoryByName improvements and unification (#6897)
Diffstat (limited to 'models/repo_list.go')
-rw-r--r--models/repo_list.go132
1 files changed, 70 insertions, 62 deletions
diff --git a/models/repo_list.go b/models/repo_list.go
index 83d2665e8c..9686676eae 100644
--- a/models/repo_list.go
+++ b/models/repo_list.go
@@ -12,7 +12,6 @@ import (
"code.gitea.io/gitea/modules/util"
"github.com/go-xorm/builder"
- "github.com/go-xorm/core"
)
// RepositoryListDefaultPageSize is the default number of repositories
@@ -112,15 +111,17 @@ func (repos MirrorRepositoryList) LoadAttributes() error {
// SearchRepoOptions holds the search options
type SearchRepoOptions struct {
- Keyword string
- OwnerID int64
- OrderBy SearchOrderBy
- Private bool // Include private repositories in results
- Starred bool
- Page int
- IsProfile bool
- AllPublic bool // Include also all public repositories
- PageSize int // Can be smaller than or equal to setting.ExplorePagingNum
+ UserID int64
+ UserIsAdmin bool
+ Keyword string
+ OwnerID int64
+ OrderBy SearchOrderBy
+ Private bool // Include private repositories in results
+ StarredByID int64
+ Page int
+ IsProfile bool
+ AllPublic bool // Include also all public repositories
+ PageSize int // Can be smaller than or equal to setting.ExplorePagingNum
// None -> include collaborative AND non-collaborative
// True -> include just collaborative
// False -> incude just non-collaborative
@@ -168,72 +169,79 @@ func SearchRepositoryByName(opts *SearchRepoOptions) (RepositoryList, int64, err
if opts.Page <= 0 {
opts.Page = 1
}
-
var cond = builder.NewCond()
- if !opts.Private {
+ if opts.Private {
+ if !opts.UserIsAdmin && opts.UserID != 0 && opts.UserID != opts.OwnerID {
+ // OK we're in the context of a User
+ // We should be Either
+ cond = cond.And(builder.Or(
+ // 1. Be able to see all non-private repositories that either:
+ cond.And(
+ builder.Eq{"is_private": false},
+ builder.Or(
+ // A. Aren't in organisations __OR__
+ builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"type": UserTypeOrganization})),
+ // B. Isn't a private organisation. (Limited is OK because we're logged in)
+ builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"visibility": structs.VisibleTypePrivate}))),
+ ),
+ // 2. Be able to see all repositories that we have access to
+ builder.In("id", builder.Select("repo_id").
+ From("`access`").
+ Where(builder.And(
+ builder.Eq{"user_id": opts.UserID},
+ builder.Gt{"mode": int(AccessModeNone)}))),
+ // 3. Be able to see all repositories that we are in a team
+ builder.In("id", builder.Select("`team_repo`.repo_id").
+ From("team_repo").
+ Where(builder.Eq{"`team_user`.uid": opts.UserID}).
+ Join("INNER", "team_user", "`team_user`.team_id = `team_repo`.team_id"))))
+ }
+ } else {
+ // Not looking at private organisations
+ // We should be able to see all non-private repositories that either:
cond = cond.And(builder.Eq{"is_private": false})
accessCond := builder.Or(
- builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Or(builder.Eq{"visibility": structs.VisibleTypeLimited}, builder.Eq{"visibility": structs.VisibleTypePrivate}))),
- builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"type": UserTypeOrganization})))
+ // A. Aren't in organisations __OR__
+ builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"type": UserTypeOrganization})),
+ // B. Isn't a private or limited organisation.
+ builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Or(builder.Eq{"visibility": structs.VisibleTypeLimited}, builder.Eq{"visibility": structs.VisibleTypePrivate}))))
cond = cond.And(accessCond)
}
+ // Restrict to starred repositories
+ if opts.StarredByID > 0 {
+ cond = cond.And(builder.In("id", builder.Select("repo_id").From("star").Where(builder.Eq{"uid": opts.StarredByID})))
+ }
+
+ // Restrict repositories to those the OwnerID owns or contributes to as per opts.Collaborate
if opts.OwnerID > 0 {
- if opts.Starred {
- cond = cond.And(builder.In("id", builder.Select("repo_id").From("star").Where(builder.Eq{"uid": opts.OwnerID})))
- } else {
- var accessCond = builder.NewCond()
- if opts.Collaborate != util.OptionalBoolTrue {
- accessCond = builder.Eq{"owner_id": opts.OwnerID}
- }
+ var accessCond = builder.NewCond()
+ if opts.Collaborate != util.OptionalBoolTrue {
+ accessCond = builder.Eq{"owner_id": opts.OwnerID}
+ }
- if opts.Collaborate != util.OptionalBoolFalse {
- collaborateCond := builder.And(
+ if opts.Collaborate != util.OptionalBoolFalse {
+ collaborateCond := builder.And(
+ builder.Or(
builder.Expr("repository.id IN (SELECT repo_id FROM `access` WHERE access.user_id = ?)", opts.OwnerID),
- builder.Neq{"owner_id": opts.OwnerID})
- 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))
- }
-
- accessCond = accessCond.Or(collaborateCond)
+ builder.In("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})
+ 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))
}
- var exprCond builder.Cond
- if DbCfg.Type == core.POSTGRES {
- exprCond = builder.Expr("org_user.org_id = \"user\".id")
- } else if DbCfg.Type == core.MSSQL {
- exprCond = builder.Expr("org_user.org_id = [user].id")
- } else {
- exprCond = builder.Eq{"org_user.org_id": "user.id"}
- }
-
- visibilityCond := builder.Or(
- builder.In("owner_id",
- builder.Select("org_id").From("org_user").
- LeftJoin("`user`", exprCond).
- Where(
- builder.And(
- builder.Eq{"uid": opts.OwnerID},
- builder.Eq{"visibility": structs.VisibleTypePrivate})),
- ),
- builder.In("owner_id",
- builder.Select("id").From("`user`").
- Where(
- builder.Or(
- builder.Eq{"visibility": structs.VisibleTypePublic},
- builder.Eq{"visibility": structs.VisibleTypeLimited})),
- ),
- builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(builder.Eq{"type": UserTypeOrganization})),
- )
- cond = cond.And(visibilityCond)
-
- if opts.AllPublic {
- accessCond = accessCond.Or(builder.Eq{"is_private": false})
- }
+ accessCond = accessCond.Or(collaborateCond)
+ }
- cond = cond.And(accessCond)
+ if opts.AllPublic {
+ accessCond = accessCond.Or(builder.Eq{"is_private": false})
}
+
+ cond = cond.And(accessCond)
}
if opts.Keyword != "" {