summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/migrations/migrations.go1
-rw-r--r--models/org.go36
-rw-r--r--models/org_test.go71
-rw-r--r--models/repo_list.go35
-rw-r--r--models/user.go64
5 files changed, 194 insertions, 13 deletions
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 174e7b5156..d6e7f31e46 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -1,4 +1,5 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
+// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
diff --git a/models/org.go b/models/org.go
index daff110cf5..2e22ae987b 100644
--- a/models/org.go
+++ b/models/org.go
@@ -1,4 +1,5 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
+// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
@@ -11,6 +12,7 @@ import (
"strings"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/structs"
"github.com/Unknwon/com"
"github.com/go-xorm/builder"
@@ -366,6 +368,40 @@ func getOwnedOrgsByUserID(sess *xorm.Session, userID int64) ([]*User, error) {
Find(&orgs)
}
+// HasOrgVisible tells if the given user can see the given org
+func HasOrgVisible(org *User, user *User) bool {
+ // Not SignedUser
+ if user == nil {
+ if org.Visibility == structs.VisibleTypePublic {
+ return true
+ }
+ return false
+ }
+
+ if user.IsAdmin {
+ return true
+ }
+
+ if org.Visibility == structs.VisibleTypePrivate && !org.IsUserPartOfOrg(user.ID) {
+ return false
+ }
+ return true
+}
+
+// HasOrgsVisible tells if the given user can see at least one of the orgs provided
+func HasOrgsVisible(orgs []*User, user *User) bool {
+ if len(orgs) == 0 {
+ return false
+ }
+
+ for _, org := range orgs {
+ if HasOrgVisible(org, user) {
+ return true
+ }
+ }
+ return false
+}
+
// GetOwnedOrgsByUserID returns a list of organizations are owned by given user ID.
func GetOwnedOrgsByUserID(userID int64) ([]*User, error) {
sess := x.NewSession()
diff --git a/models/org_test.go b/models/org_test.go
index 4790f69971..b484208be1 100644
--- a/models/org_test.go
+++ b/models/org_test.go
@@ -7,6 +7,8 @@ package models
import (
"testing"
+ "code.gitea.io/gitea/modules/structs"
+
"github.com/stretchr/testify/assert"
)
@@ -545,3 +547,72 @@ func TestAccessibleReposEnv_MirrorRepos(t *testing.T) {
testSuccess(2, []int64{5})
testSuccess(4, []int64{})
}
+
+func TestHasOrgVisibleTypePublic(t *testing.T) {
+ assert.NoError(t, PrepareTestDatabase())
+ owner := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
+ user3 := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User)
+
+ const newOrgName = "test-org-public"
+ org := &User{
+ Name: newOrgName,
+ Visibility: structs.VisibleTypePublic,
+ }
+
+ AssertNotExistsBean(t, &User{Name: org.Name, Type: UserTypeOrganization})
+ assert.NoError(t, CreateOrganization(org, owner))
+ org = AssertExistsAndLoadBean(t,
+ &User{Name: org.Name, Type: UserTypeOrganization}).(*User)
+ test1 := HasOrgVisible(org, owner)
+ test2 := HasOrgVisible(org, user3)
+ test3 := HasOrgVisible(org, nil)
+ assert.Equal(t, test1, true) // owner of org
+ assert.Equal(t, test2, true) // user not a part of org
+ assert.Equal(t, test3, true) // logged out user
+}
+
+func TestHasOrgVisibleTypeLimited(t *testing.T) {
+ assert.NoError(t, PrepareTestDatabase())
+ owner := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
+ user3 := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User)
+
+ const newOrgName = "test-org-limited"
+ org := &User{
+ Name: newOrgName,
+ Visibility: structs.VisibleTypeLimited,
+ }
+
+ AssertNotExistsBean(t, &User{Name: org.Name, Type: UserTypeOrganization})
+ assert.NoError(t, CreateOrganization(org, owner))
+ org = AssertExistsAndLoadBean(t,
+ &User{Name: org.Name, Type: UserTypeOrganization}).(*User)
+ test1 := HasOrgVisible(org, owner)
+ test2 := HasOrgVisible(org, user3)
+ test3 := HasOrgVisible(org, nil)
+ assert.Equal(t, test1, true) // owner of org
+ assert.Equal(t, test2, true) // user not a part of org
+ assert.Equal(t, test3, false) // logged out user
+}
+
+func TestHasOrgVisibleTypePrivate(t *testing.T) {
+ assert.NoError(t, PrepareTestDatabase())
+ owner := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
+ user3 := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User)
+
+ const newOrgName = "test-org-private"
+ org := &User{
+ Name: newOrgName,
+ Visibility: structs.VisibleTypePrivate,
+ }
+
+ AssertNotExistsBean(t, &User{Name: org.Name, Type: UserTypeOrganization})
+ assert.NoError(t, CreateOrganization(org, owner))
+ org = AssertExistsAndLoadBean(t,
+ &User{Name: org.Name, Type: UserTypeOrganization}).(*User)
+ test1 := HasOrgVisible(org, owner)
+ test2 := HasOrgVisible(org, user3)
+ test3 := HasOrgVisible(org, nil)
+ assert.Equal(t, test1, true) // owner of org
+ assert.Equal(t, test2, false) // user not a part of org
+ assert.Equal(t, test3, false) // logged out user
+}
diff --git a/models/repo_list.go b/models/repo_list.go
index 049d1834f7..83d2665e8c 100644
--- a/models/repo_list.go
+++ b/models/repo_list.go
@@ -8,9 +8,11 @@ import (
"fmt"
"strings"
+ "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"github.com/go-xorm/builder"
+ "github.com/go-xorm/core"
)
// RepositoryListDefaultPageSize is the default number of repositories
@@ -171,6 +173,10 @@ func SearchRepositoryByName(opts *SearchRepoOptions) (RepositoryList, int64, err
if !opts.Private {
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})))
+ cond = cond.And(accessCond)
}
if opts.OwnerID > 0 {
@@ -193,6 +199,35 @@ func SearchRepositoryByName(opts *SearchRepoOptions) (RepositoryList, int64, err
accessCond = accessCond.Or(collaborateCond)
}
+ 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})
}
diff --git a/models/user.go b/models/user.go
index e50385d411..3fb1c3b59e 100644
--- a/models/user.go
+++ b/models/user.go
@@ -25,22 +25,23 @@ import (
"time"
"unicode/utf8"
- "github.com/Unknwon/com"
- "github.com/go-xorm/builder"
- "github.com/go-xorm/xorm"
- "github.com/nfnt/resize"
- "golang.org/x/crypto/pbkdf2"
- "golang.org/x/crypto/ssh"
-
"code.gitea.io/git"
- api "code.gitea.io/sdk/gitea"
-
"code.gitea.io/gitea/modules/avatar"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/generate"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
+ api "code.gitea.io/sdk/gitea"
+
+ "github.com/Unknwon/com"
+ "github.com/go-xorm/builder"
+ "github.com/go-xorm/core"
+ "github.com/go-xorm/xorm"
+ "github.com/nfnt/resize"
+ "golang.org/x/crypto/pbkdf2"
+ "golang.org/x/crypto/ssh"
)
// UserType defines the user type
@@ -136,8 +137,9 @@ type User struct {
Description string
NumTeams int
NumMembers int
- Teams []*Team `xorm:"-"`
- Members []*User `xorm:"-"`
+ Teams []*Team `xorm:"-"`
+ Members []*User `xorm:"-"`
+ Visibility structs.VisibleType `xorm:"NOT NULL DEFAULT 0"`
// Preferences
DiffViewStyle string `xorm:"NOT NULL DEFAULT ''"`
@@ -526,6 +528,16 @@ func (u *User) IsUserOrgOwner(orgID int64) bool {
return isOwner
}
+// IsUserPartOfOrg returns true if user with userID is part of the u organisation.
+func (u *User) IsUserPartOfOrg(userID int64) bool {
+ isMember, err := IsOrganizationMember(u.ID, userID)
+ if err != nil {
+ log.Error(4, "IsOrganizationMember: %v", err)
+ return false
+ }
+ return isMember
+}
+
// IsPublicMember returns true if user public his/her membership in given organization.
func (u *User) IsPublicMember(orgID int64) bool {
isMember, err := IsPublicMembership(orgID, u.ID)
@@ -1341,13 +1353,18 @@ type SearchUserOptions struct {
UID int64
OrderBy SearchOrderBy
Page int
- PageSize int // Can be smaller than or equal to setting.UI.ExplorePagingNum
+ Private bool // Include private orgs in search
+ OwnerID int64 // id of user for visibility calculation
+ PageSize int // Can be smaller than or equal to setting.UI.ExplorePagingNum
IsActive util.OptionalBool
SearchByEmail bool // Search by email as well as username/full name
}
func (opts *SearchUserOptions) toConds() builder.Cond {
- var cond builder.Cond = builder.Eq{"type": opts.Type}
+
+ var cond = builder.NewCond()
+ cond = cond.And(builder.Eq{"type": opts.Type})
+
if len(opts.Keyword) > 0 {
lowerKeyword := strings.ToLower(opts.Keyword)
keywordCond := builder.Or(
@@ -1361,6 +1378,27 @@ func (opts *SearchUserOptions) toConds() builder.Cond {
cond = cond.And(keywordCond)
}
+ if !opts.Private {
+ // user not logged in and so they won't be allowed to see non-public orgs
+ cond = cond.And(builder.In("visibility", structs.VisibleTypePublic))
+ }
+
+ if opts.OwnerID > 0 {
+ var exprCond builder.Cond
+ if DbCfg.Type == core.MYSQL {
+ 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.Expr("org_user.org_id = \"user\".id")
+ }
+ var accessCond = builder.NewCond()
+ accessCond = builder.Or(
+ builder.In("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("visibility", structs.VisibleTypePublic, structs.VisibleTypeLimited))
+ cond = cond.And(accessCond)
+ }
+
if opts.UID > 0 {
cond = cond.And(builder.Eq{"id": opts.UID})
}