forked from forgejo/forgejo
Restricted users (#4334): initial implementation
* Add User.IsRestricted & UI to edit it * Pass user object instead of user id to places where IsRestricted flag matters * Restricted users: maintain access rows for all referenced repos (incl public) * Take logged in user & IsRestricted flag into account in org/repo listings, searches and accesses * Add basic repo access tests for restricted users Signed-off-by: Manush Dodunekov <manush@stendahls.se>
This commit is contained in:
parent
5749b26cdd
commit
836f9d86aa
30 changed files with 281 additions and 117 deletions
|
@ -132,6 +132,7 @@ type User struct {
|
|||
// Permissions
|
||||
IsActive bool `xorm:"INDEX"` // Activate primary email
|
||||
IsAdmin bool
|
||||
IsRestricted bool `xorm:"NOT NULL DEFAULT false"`
|
||||
AllowGitHook bool
|
||||
AllowImportLocal bool // Allow migrate repository by local path
|
||||
AllowCreateOrganization bool `xorm:"DEFAULT true"`
|
||||
|
@ -641,7 +642,7 @@ func (u *User) GetOrgRepositoryIDs(units ...UnitType) ([]int64, error) {
|
|||
if err := x.Table("repository").
|
||||
Cols("repository.id").
|
||||
Join("INNER", "team_user", "repository.owner_id = team_user.org_id").
|
||||
Join("INNER", "team_repo", "repository.is_private != ? OR (team_user.team_id = team_repo.team_id AND repository.id = team_repo.repo_id)", true).
|
||||
Join("INNER", "team_repo", "(? != ? and repository.is_private != ?) OR (team_user.team_id = team_repo.team_id AND repository.id = team_repo.repo_id)", true, u.IsRestricted, true).
|
||||
Where("team_user.uid = ?", u.ID).
|
||||
GroupBy("repository.id").Find(&ids); err != nil {
|
||||
return nil, err
|
||||
|
@ -1470,7 +1471,7 @@ type SearchUserOptions struct {
|
|||
OrderBy SearchOrderBy
|
||||
Page int
|
||||
Private bool // Include private orgs in search
|
||||
OwnerID int64 // id of user for visibility calculation
|
||||
Actor *User // The user doing the search
|
||||
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
|
||||
|
@ -1497,7 +1498,7 @@ func (opts *SearchUserOptions) toConds() builder.Cond {
|
|||
cond = cond.And(builder.In("visibility", structs.VisibleTypePublic))
|
||||
}
|
||||
|
||||
if opts.OwnerID > 0 {
|
||||
if opts.Actor != nil && opts.Type == UserTypeOrganization {
|
||||
var exprCond builder.Cond
|
||||
if setting.Database.UseMySQL {
|
||||
exprCond = builder.Expr("org_user.org_id = user.id")
|
||||
|
@ -1506,9 +1507,15 @@ func (opts *SearchUserOptions) toConds() builder.Cond {
|
|||
} else {
|
||||
exprCond = builder.Expr("org_user.org_id = \"user\".id")
|
||||
}
|
||||
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))
|
||||
var accessCond = builder.NewCond()
|
||||
if !opts.Actor.IsRestricted {
|
||||
accessCond = builder.Or(
|
||||
builder.In("id", builder.Select("org_id").From("org_user").LeftJoin("`user`", exprCond).Where(builder.And(builder.Eq{"uid": opts.Actor.ID}, builder.Eq{"visibility": structs.VisibleTypePrivate}))),
|
||||
builder.In("visibility", structs.VisibleTypePublic, structs.VisibleTypeLimited))
|
||||
} else {
|
||||
// restricted users only see orgs they are a member of
|
||||
accessCond = builder.In("id", builder.Select("org_id").From("org_user").LeftJoin("`user`", exprCond).Where(builder.And(builder.Eq{"uid": opts.Actor.ID})))
|
||||
}
|
||||
cond = cond.And(accessCond)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue