Only show Followers that current user can access (#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
							
								
									ed13d7aadf
								
							
						
					
					
						commit
						45f17528a8
					
				|  | @ -316,37 +316,45 @@ func (u *User) GenerateEmailActivateCode(email string) string { | |||
| } | ||||
| 
 | ||||
| // GetUserFollowers returns range of user's followers.
 | ||||
| func GetUserFollowers(u *User, listOptions db.ListOptions) ([]*User, error) { | ||||
| 	sess := db.GetEngine(db.DefaultContext). | ||||
| func GetUserFollowers(ctx context.Context, u, viewer *User, listOptions db.ListOptions) ([]*User, int64, error) { | ||||
| 	sess := db.GetEngine(ctx). | ||||
| 		Select("`user`.*"). | ||||
| 		Join("LEFT", "follow", "`user`.id=follow.user_id"). | ||||
| 		Where("follow.follow_id=?", u.ID). | ||||
| 		Join("LEFT", "follow", "`user`.id=follow.user_id") | ||||
| 		And(isUserVisibleToViewerCond(viewer)) | ||||
| 
 | ||||
| 	if listOptions.Page != 0 { | ||||
| 		sess = db.SetSessionPagination(sess, &listOptions) | ||||
| 
 | ||||
| 		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) | ||||
| 	return users, sess.Find(&users) | ||||
| 	count, err := sess.FindAndCount(&users) | ||||
| 	return users, count, err | ||||
| } | ||||
| 
 | ||||
| // 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). | ||||
| 		Select("`user`.*"). | ||||
| 		Join("LEFT", "follow", "`user`.id=follow.follow_id"). | ||||
| 		Where("follow.user_id=?", u.ID). | ||||
| 		Join("LEFT", "follow", "`user`.id=follow.follow_id") | ||||
| 		And(isUserVisibleToViewerCond(viewer)) | ||||
| 
 | ||||
| 	if listOptions.Page != 0 { | ||||
| 		sess = db.SetSessionPagination(sess, &listOptions) | ||||
| 
 | ||||
| 		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) | ||||
| 	return users, sess.Find(&users) | ||||
| 	count, err := sess.FindAndCount(&users) | ||||
| 	return users, count, err | ||||
| } | ||||
| 
 | ||||
| // NewGitSig generates and returns the signature of given user.
 | ||||
|  | @ -1222,6 +1230,39 @@ func GetAdminUser() (*User, error) { | |||
| 	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
 | ||||
| func IsUserVisibleToViewer(ctx context.Context, u, viewer *User) bool { | ||||
| 	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) { | ||||
| 	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 { | ||||
| 		ctx.Error(http.StatusInternalServerError, "GetUserFollowers", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.SetTotalCountHeader(int64(u.NumFollowers)) | ||||
| 	ctx.SetTotalCountHeader(count) | ||||
| 	responseAPIUsers(ctx, users) | ||||
| } | ||||
| 
 | ||||
|  | @ -86,13 +86,13 @@ func ListFollowers(ctx *context.APIContext) { | |||
| } | ||||
| 
 | ||||
| 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 { | ||||
| 		ctx.Error(http.StatusInternalServerError, "GetUserFollowing", err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.SetTotalCountHeader(int64(u.NumFollowing)) | ||||
| 	ctx.SetTotalCountHeader(count) | ||||
| 	responseAPIUsers(ctx, users) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -157,7 +157,7 @@ func Profile(ctx *context.Context) { | |||
| 
 | ||||
| 	switch tab { | ||||
| 	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, | ||||
| 			Page:     page, | ||||
| 		}) | ||||
|  | @ -167,9 +167,9 @@ func Profile(ctx *context.Context) { | |||
| 		} | ||||
| 		ctx.Data["Cards"] = items | ||||
| 
 | ||||
| 		total = ctx.ContextUser.NumFollowers | ||||
| 		total = int(count) | ||||
| 	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, | ||||
| 			Page:     page, | ||||
| 		}) | ||||
|  | @ -179,7 +179,7 @@ func Profile(ctx *context.Context) { | |||
| 		} | ||||
| 		ctx.Data["Cards"] = items | ||||
| 
 | ||||
| 		total = ctx.ContextUser.NumFollowing | ||||
| 		total = int(count) | ||||
| 	case "activity": | ||||
| 		ctx.Data["Feeds"], err = models.GetFeeds(ctx, models.GetFeedsOptions{ | ||||
| 			RequestedUser:   ctx.ContextUser, | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue