Backport #20220 Users who are following or being followed by a user should only be displayed if the viewing user can see them. Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
parent
42be548ecc
commit
a92d247fdd
3 changed files with 58 additions and 17 deletions
|
@ -316,37 +316,45 @@ func (u *User) GenerateEmailActivateCode(email string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserFollowers returns range of user's followers.
|
// GetUserFollowers returns range of user's followers.
|
||||||
func GetUserFollowers(u *User, listOptions db.ListOptions) ([]*User, error) {
|
func GetUserFollowers(ctx context.Context, u, viewer *User, listOptions db.ListOptions) ([]*User, int64, error) {
|
||||||
sess := db.GetEngine(db.DefaultContext).
|
sess := db.GetEngine(ctx).
|
||||||
|
Select("`user`.*").
|
||||||
|
Join("LEFT", "follow", "`user`.id=follow.user_id").
|
||||||
Where("follow.follow_id=?", u.ID).
|
Where("follow.follow_id=?", u.ID).
|
||||||
Join("LEFT", "follow", "`user`.id=follow.user_id")
|
And(isUserVisibleToViewerCond(viewer))
|
||||||
|
|
||||||
if listOptions.Page != 0 {
|
if listOptions.Page != 0 {
|
||||||
sess = db.SetSessionPagination(sess, &listOptions)
|
sess = db.SetSessionPagination(sess, &listOptions)
|
||||||
|
|
||||||
users := make([]*User, 0, listOptions.PageSize)
|
users := make([]*User, 0, listOptions.PageSize)
|
||||||
return users, sess.Find(&users)
|
count, err := sess.FindAndCount(&users)
|
||||||
|
return users, count, err
|
||||||
}
|
}
|
||||||
|
|
||||||
users := make([]*User, 0, 8)
|
users := make([]*User, 0, 8)
|
||||||
return users, sess.Find(&users)
|
count, err := sess.FindAndCount(&users)
|
||||||
|
return users, count, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserFollowing returns range of user's following.
|
// GetUserFollowing returns range of user's following.
|
||||||
func GetUserFollowing(u *User, listOptions db.ListOptions) ([]*User, error) {
|
func GetUserFollowing(ctx context.Context, u, viewer *User, listOptions db.ListOptions) ([]*User, int64, error) {
|
||||||
sess := db.GetEngine(db.DefaultContext).
|
sess := db.GetEngine(db.DefaultContext).
|
||||||
|
Select("`user`.*").
|
||||||
|
Join("LEFT", "follow", "`user`.id=follow.follow_id").
|
||||||
Where("follow.user_id=?", u.ID).
|
Where("follow.user_id=?", u.ID).
|
||||||
Join("LEFT", "follow", "`user`.id=follow.follow_id")
|
And(isUserVisibleToViewerCond(viewer))
|
||||||
|
|
||||||
if listOptions.Page != 0 {
|
if listOptions.Page != 0 {
|
||||||
sess = db.SetSessionPagination(sess, &listOptions)
|
sess = db.SetSessionPagination(sess, &listOptions)
|
||||||
|
|
||||||
users := make([]*User, 0, listOptions.PageSize)
|
users := make([]*User, 0, listOptions.PageSize)
|
||||||
return users, sess.Find(&users)
|
count, err := sess.FindAndCount(&users)
|
||||||
|
return users, count, err
|
||||||
}
|
}
|
||||||
|
|
||||||
users := make([]*User, 0, 8)
|
users := make([]*User, 0, 8)
|
||||||
return users, sess.Find(&users)
|
count, err := sess.FindAndCount(&users)
|
||||||
|
return users, count, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGitSig generates and returns the signature of given user.
|
// NewGitSig generates and returns the signature of given user.
|
||||||
|
@ -1222,6 +1230,39 @@ func GetAdminUser() (*User, error) {
|
||||||
return &admin, nil
|
return &admin, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isUserVisibleToViewerCond(viewer *User) builder.Cond {
|
||||||
|
if viewer != nil && viewer.IsAdmin {
|
||||||
|
return builder.NewCond()
|
||||||
|
}
|
||||||
|
|
||||||
|
if viewer == nil || viewer.IsRestricted {
|
||||||
|
return builder.Eq{
|
||||||
|
"`user`.visibility": structs.VisibleTypePublic,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.Neq{
|
||||||
|
"`user`.visibility": structs.VisibleTypePrivate,
|
||||||
|
}.Or(
|
||||||
|
builder.In("`user`.id",
|
||||||
|
builder.
|
||||||
|
Select("`follow`.user_id").
|
||||||
|
From("follow").
|
||||||
|
Where(builder.Eq{"`follow`.follow_id": viewer.ID})),
|
||||||
|
builder.In("`user`.id",
|
||||||
|
builder.
|
||||||
|
Select("`team_user`.uid").
|
||||||
|
From("team_user").
|
||||||
|
Join("INNER", "`team_user` AS t2", "`team_user`.id = `t2`.id").
|
||||||
|
Where(builder.Eq{"`t2`.uid": viewer.ID})),
|
||||||
|
builder.In("`user`.id",
|
||||||
|
builder.
|
||||||
|
Select("`team_user`.uid").
|
||||||
|
From("team_user").
|
||||||
|
Join("INNER", "`team_user` AS t2", "`team_user`.org_id = `t2`.org_id").
|
||||||
|
Where(builder.Eq{"`t2`.uid": viewer.ID})))
|
||||||
|
}
|
||||||
|
|
||||||
// IsUserVisibleToViewer check if viewer is able to see user profile
|
// IsUserVisibleToViewer check if viewer is able to see user profile
|
||||||
func IsUserVisibleToViewer(ctx context.Context, u, viewer *User) bool {
|
func IsUserVisibleToViewer(ctx context.Context, u, viewer *User) bool {
|
||||||
if viewer != nil && viewer.IsAdmin {
|
if viewer != nil && viewer.IsAdmin {
|
||||||
|
|
|
@ -24,13 +24,13 @@ func responseAPIUsers(ctx *context.APIContext, users []*user_model.User) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func listUserFollowers(ctx *context.APIContext, u *user_model.User) {
|
func listUserFollowers(ctx *context.APIContext, u *user_model.User) {
|
||||||
users, err := user_model.GetUserFollowers(u, utils.GetListOptions(ctx))
|
users, count, err := user_model.GetUserFollowers(ctx, u, ctx.Doer, utils.GetListOptions(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, "GetUserFollowers", err)
|
ctx.Error(http.StatusInternalServerError, "GetUserFollowers", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.SetTotalCountHeader(int64(u.NumFollowers))
|
ctx.SetTotalCountHeader(count)
|
||||||
responseAPIUsers(ctx, users)
|
responseAPIUsers(ctx, users)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,13 +86,13 @@ func ListFollowers(ctx *context.APIContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func listUserFollowing(ctx *context.APIContext, u *user_model.User) {
|
func listUserFollowing(ctx *context.APIContext, u *user_model.User) {
|
||||||
users, err := user_model.GetUserFollowing(u, utils.GetListOptions(ctx))
|
users, count, err := user_model.GetUserFollowing(ctx, u, ctx.Doer, utils.GetListOptions(ctx))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, "GetUserFollowing", err)
|
ctx.Error(http.StatusInternalServerError, "GetUserFollowing", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.SetTotalCountHeader(int64(u.NumFollowing))
|
ctx.SetTotalCountHeader(count)
|
||||||
responseAPIUsers(ctx, users)
|
responseAPIUsers(ctx, users)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ func Profile(ctx *context.Context) {
|
||||||
|
|
||||||
switch tab {
|
switch tab {
|
||||||
case "followers":
|
case "followers":
|
||||||
items, err := user_model.GetUserFollowers(ctx.ContextUser, db.ListOptions{
|
items, count, err := user_model.GetUserFollowers(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{
|
||||||
PageSize: setting.UI.User.RepoPagingNum,
|
PageSize: setting.UI.User.RepoPagingNum,
|
||||||
Page: page,
|
Page: page,
|
||||||
})
|
})
|
||||||
|
@ -167,9 +167,9 @@ func Profile(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
ctx.Data["Cards"] = items
|
ctx.Data["Cards"] = items
|
||||||
|
|
||||||
total = ctx.ContextUser.NumFollowers
|
total = int(count)
|
||||||
case "following":
|
case "following":
|
||||||
items, err := user_model.GetUserFollowing(ctx.ContextUser, db.ListOptions{
|
items, count, err := user_model.GetUserFollowing(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{
|
||||||
PageSize: setting.UI.User.RepoPagingNum,
|
PageSize: setting.UI.User.RepoPagingNum,
|
||||||
Page: page,
|
Page: page,
|
||||||
})
|
})
|
||||||
|
@ -179,7 +179,7 @@ func Profile(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
ctx.Data["Cards"] = items
|
ctx.Data["Cards"] = items
|
||||||
|
|
||||||
total = ctx.ContextUser.NumFollowing
|
total = int(count)
|
||||||
case "activity":
|
case "activity":
|
||||||
ctx.Data["Feeds"], err = models.GetFeeds(ctx, models.GetFeedsOptions{
|
ctx.Data["Feeds"], err = models.GetFeeds(ctx, models.GetFeedsOptions{
|
||||||
RequestedUser: ctx.ContextUser,
|
RequestedUser: ctx.ContextUser,
|
||||||
|
|
Reference in a new issue