@ -432,6 +432,62 @@ func (u *User) IsPasswordSet() bool {
return len ( u . Passwd ) != 0
}
// IsVisibleToUser check if viewer is able to see user profile
func ( u * User ) IsVisibleToUser ( viewer * User ) bool {
return u . isVisibleToUser ( x , viewer )
}
func ( u * User ) isVisibleToUser ( e Engine , viewer * User ) bool {
if viewer != nil && viewer . IsAdmin {
return true
}
switch u . Visibility {
case structs . VisibleTypePublic :
return true
case structs . VisibleTypeLimited :
if viewer == nil || viewer . IsRestricted {
return false
}
return true
case structs . VisibleTypePrivate :
if viewer == nil || viewer . IsRestricted {
return false
}
// If they follow - they see each over
follower := IsFollowing ( u . ID , viewer . ID )
if follower {
return true
}
// Now we need to check if they in some organization together
count , err := x . Table ( "team_user" ) .
Where (
builder . And (
builder . Eq { "uid" : viewer . ID } ,
builder . Or (
builder . Eq { "org_id" : u . ID } ,
builder . In ( "org_id" ,
builder . Select ( "org_id" ) .
From ( "team_user" , "t2" ) .
Where ( builder . Eq { "uid" : u . ID } ) ) ) ) ) .
Count ( new ( TeamUser ) )
if err != nil {
return false
}
if count < 0 {
// No common organization
return false
}
// they are in an organization together
return true
}
return false
}
// IsOrganization returns true if user is actually a organization.
func ( u * User ) IsOrganization ( ) bool {
return u . Type == UserTypeOrganization
@ -796,8 +852,13 @@ func IsUsableUsername(name string) error {
return isUsableName ( reservedUsernames , reservedUserPatterns , name )
}
// CreateUserOverwriteOptions are an optional options who overwrite system defaults on user creation
type CreateUserOverwriteOptions struct {
Visibility structs . VisibleType
}
// CreateUser creates record of a new user.
func CreateUser ( u * User ) ( err error ) {
func CreateUser ( u * User , overwriteDefault ... * CreateUserOverwriteOptions ) ( err error ) {
if err = IsUsableUsername ( u . Name ) ; err != nil {
return err
}
@ -831,8 +892,6 @@ func CreateUser(u *User) (err error) {
return ErrEmailAlreadyUsed { u . Email }
}
u . KeepEmailPrivate = setting . Service . DefaultKeepEmailPrivate
u . LowerName = strings . ToLower ( u . Name )
u . AvatarEmail = u . Email
if u . Rands , err = GetUserSalt ( ) ; err != nil {
@ -841,10 +900,18 @@ func CreateUser(u *User) (err error) {
if err = u . SetPassword ( u . Passwd ) ; err != nil {
return err
}
// set system defaults
u . KeepEmailPrivate = setting . Service . DefaultKeepEmailPrivate
u . Visibility = setting . Service . DefaultUserVisibilityMode
u . AllowCreateOrganization = setting . Service . DefaultAllowCreateOrganization && ! setting . Admin . DisableRegularOrgCreation
u . EmailNotificationsPreference = setting . Admin . DefaultEmailNotification
u . MaxRepoCreation = - 1
u . Theme = setting . UI . DefaultTheme
// overwrite defaults if set
if len ( overwriteDefault ) != 0 && overwriteDefault [ 0 ] != nil {
u . Visibility = overwriteDefault [ 0 ] . Visibility
}
if _ , err = sess . Insert ( u ) ; err != nil {
return err
@ -1527,10 +1594,9 @@ func (opts *SearchUserOptions) toConds() builder.Cond {
cond = cond . And ( keywordCond )
}
// If visibility filtered
if len ( opts . Visible ) > 0 {
cond = cond . And ( builder . In ( "visibility" , opts . Visible ) )
} else {
cond = cond . And ( builder . In ( "visibility" , structs . VisibleTypePublic ) )
}
if opts . Actor != nil {
@ -1543,16 +1609,27 @@ func (opts *SearchUserOptions) toConds() builder.Cond {
exprCond = builder . Expr ( "org_user.org_id = \"user\".id" )
}
var accessCond builder . Cond
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 } ) ) )
// If Admin - they see all users!
if ! opts . Actor . IsAdmin {
// Force visiblity for privacy
var accessCond builder . Cond
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 } ) ) )
}
// Don't forget about self
accessCond = accessCond . Or ( builder . Eq { "id" : opts . Actor . ID } )
cond = cond . And ( accessCond )
}
cond = cond . And ( accessCond )
} else {
// Force visiblity for privacy
// Not logged in - only public users
cond = cond . And ( builder . In ( "visibility" , structs . VisibleTypePublic ) )
}
if opts . UID > 0 {