Skip to content

Commit b42df31

Browse files
authored
Only show Followers that current user can access (#20220) (#20253)
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 <[email protected]>
1 parent 6162fb0 commit b42df31

File tree

3 files changed

+60
-18
lines changed

3 files changed

+60
-18
lines changed

Diff for: models/user/user.go

+50-9
Original file line numberDiff line numberDiff line change
@@ -316,37 +316,45 @@ func (u *User) GenerateEmailActivateCode(email string) string {
316316
}
317317

318318
// GetUserFollowers returns range of user's followers.
319-
func GetUserFollowers(u *User, listOptions db.ListOptions) ([]*User, error) {
320-
sess := db.GetEngine(db.DefaultContext).
319+
func GetUserFollowers(ctx context.Context, u, viewer *User, listOptions db.ListOptions) ([]*User, int64, error) {
320+
sess := db.GetEngine(ctx).
321+
Select("`user`.*").
322+
Join("LEFT", "follow", "`user`.id=follow.user_id").
321323
Where("follow.follow_id=?", u.ID).
322-
Join("LEFT", "follow", "`user`.id=follow.user_id")
324+
And(isUserVisibleToViewerCond(viewer))
323325

324326
if listOptions.Page != 0 {
325327
sess = db.SetSessionPagination(sess, &listOptions)
326328

327329
users := make([]*User, 0, listOptions.PageSize)
328-
return users, sess.Find(&users)
330+
count, err := sess.FindAndCount(&users)
331+
return users, count, err
329332
}
330333

331334
users := make([]*User, 0, 8)
332-
return users, sess.Find(&users)
335+
count, err := sess.FindAndCount(&users)
336+
return users, count, err
333337
}
334338

335339
// GetUserFollowing returns range of user's following.
336-
func GetUserFollowing(u *User, listOptions db.ListOptions) ([]*User, error) {
340+
func GetUserFollowing(ctx context.Context, u, viewer *User, listOptions db.ListOptions) ([]*User, int64, error) {
337341
sess := db.GetEngine(db.DefaultContext).
342+
Select("`user`.*").
343+
Join("LEFT", "follow", "`user`.id=follow.follow_id").
338344
Where("follow.user_id=?", u.ID).
339-
Join("LEFT", "follow", "`user`.id=follow.follow_id")
345+
And(isUserVisibleToViewerCond(viewer))
340346

341347
if listOptions.Page != 0 {
342348
sess = db.SetSessionPagination(sess, &listOptions)
343349

344350
users := make([]*User, 0, listOptions.PageSize)
345-
return users, sess.Find(&users)
351+
count, err := sess.FindAndCount(&users)
352+
return users, count, err
346353
}
347354

348355
users := make([]*User, 0, 8)
349-
return users, sess.Find(&users)
356+
count, err := sess.FindAndCount(&users)
357+
return users, count, err
350358
}
351359

352360
// NewGitSig generates and returns the signature of given user.
@@ -1231,3 +1239,36 @@ func GetAdminUser() (*User, error) {
12311239

12321240
return &admin, nil
12331241
}
1242+
1243+
func isUserVisibleToViewerCond(viewer *User) builder.Cond {
1244+
if viewer != nil && viewer.IsAdmin {
1245+
return builder.NewCond()
1246+
}
1247+
1248+
if viewer == nil || viewer.IsRestricted {
1249+
return builder.Eq{
1250+
"`user`.visibility": structs.VisibleTypePublic,
1251+
}
1252+
}
1253+
1254+
return builder.Neq{
1255+
"`user`.visibility": structs.VisibleTypePrivate,
1256+
}.Or(
1257+
builder.In("`user`.id",
1258+
builder.
1259+
Select("`follow`.user_id").
1260+
From("follow").
1261+
Where(builder.Eq{"`follow`.follow_id": viewer.ID})),
1262+
builder.In("`user`.id",
1263+
builder.
1264+
Select("`team_user`.uid").
1265+
From("team_user").
1266+
Join("INNER", "`team_user` AS t2", "`team_user`.id = `t2`.id").
1267+
Where(builder.Eq{"`t2`.uid": viewer.ID})),
1268+
builder.In("`user`.id",
1269+
builder.
1270+
Select("`team_user`.uid").
1271+
From("team_user").
1272+
Join("INNER", "`team_user` AS t2", "`team_user`.org_id = `t2`.org_id").
1273+
Where(builder.Eq{"`t2`.uid": viewer.ID})))
1274+
}

Diff for: routers/api/v1/user/follower.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ func responseAPIUsers(ctx *context.APIContext, users []*user_model.User) {
2424
}
2525

2626
func listUserFollowers(ctx *context.APIContext, u *user_model.User) {
27-
users, err := user_model.GetUserFollowers(u, utils.GetListOptions(ctx))
27+
users, count, err := user_model.GetUserFollowers(ctx, u, ctx.User, utils.GetListOptions(ctx))
2828
if err != nil {
2929
ctx.Error(http.StatusInternalServerError, "GetUserFollowers", err)
3030
return
3131
}
3232

33-
ctx.SetTotalCountHeader(int64(u.NumFollowers))
33+
ctx.SetTotalCountHeader(count)
3434
responseAPIUsers(ctx, users)
3535
}
3636

@@ -90,13 +90,13 @@ func ListFollowers(ctx *context.APIContext) {
9090
}
9191

9292
func listUserFollowing(ctx *context.APIContext, u *user_model.User) {
93-
users, err := user_model.GetUserFollowing(u, utils.GetListOptions(ctx))
93+
users, count, err := user_model.GetUserFollowing(ctx, u, ctx.User, utils.GetListOptions(ctx))
9494
if err != nil {
9595
ctx.Error(http.StatusInternalServerError, "GetUserFollowing", err)
9696
return
9797
}
9898

99-
ctx.SetTotalCountHeader(int64(u.NumFollowing))
99+
ctx.SetTotalCountHeader(count)
100100
responseAPIUsers(ctx, users)
101101
}
102102

Diff for: routers/web/user/profile.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ func Profile(ctx *context.Context) {
234234
ctx.Data["Keyword"] = keyword
235235
switch tab {
236236
case "followers":
237-
items, err := user_model.GetUserFollowers(ctxUser, db.ListOptions{
237+
items, count, err := user_model.GetUserFollowers(ctx, ctxUser, ctx.User, db.ListOptions{
238238
PageSize: setting.UI.User.RepoPagingNum,
239239
Page: page,
240240
})
@@ -244,9 +244,9 @@ func Profile(ctx *context.Context) {
244244
}
245245
ctx.Data["Cards"] = items
246246

247-
total = ctxUser.NumFollowers
247+
total = int(count)
248248
case "following":
249-
items, err := user_model.GetUserFollowing(ctxUser, db.ListOptions{
249+
items, count, err := user_model.GetUserFollowing(ctx, ctxUser, ctx.User, db.ListOptions{
250250
PageSize: setting.UI.User.RepoPagingNum,
251251
Page: page,
252252
})
@@ -256,9 +256,10 @@ func Profile(ctx *context.Context) {
256256
}
257257
ctx.Data["Cards"] = items
258258

259-
total = ctxUser.NumFollowing
259+
total = int(count)
260260
case "activity":
261-
ctx.Data["Feeds"] = feed.RetrieveFeeds(ctx, models.GetFeedsOptions{RequestedUser: ctxUser,
261+
ctx.Data["Feeds"] = feed.RetrieveFeeds(ctx, models.GetFeedsOptions{
262+
RequestedUser: ctxUser,
262263
Actor: ctx.User,
263264
IncludePrivate: showPrivate,
264265
OnlyPerformedBy: true,

0 commit comments

Comments
 (0)