mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	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:
		@@ -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 New Issue
	
	Block a user