From 58d50bd36724d09db4599cd8c2b84f0bf2e8fa3b Mon Sep 17 00:00:00 2001
From: 6543 <6543@obermui.de>
Date: Thu, 18 Nov 2021 15:12:15 +0100
Subject: [PATCH 01/11] add test for modules.activityReadable()

---
 models/action_test.go | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/models/action_test.go b/models/action_test.go
index 87bbcf3fb7750..965b8ed5ce994 100644
--- a/models/action_test.go
+++ b/models/action_test.go
@@ -90,3 +90,43 @@ func TestGetFeeds2(t *testing.T) {
 	assert.NoError(t, err)
 	assert.Len(t, actions, 0)
 }
+
+func TestActivityReadable(t *testing.T) {
+	tt := []struct {
+		desc   string
+		user   *User
+		doer   *User
+		result bool
+	}{{
+		desc:   "user should see own activity",
+		user:   &User{ID: 1},
+		doer:   &User{ID: 1},
+		result: true,
+	}, {
+		desc:   "anon should see activity if public",
+		user:   &User{ID: 1},
+		result: true,
+	}, {
+		desc:   "anon should NOT see activity",
+		user:   &User{ID: 1, KeepActivityPrivate: true},
+		result: false,
+	}, {
+		desc:   "user should see own activity if private too",
+		user:   &User{ID: 1, KeepActivityPrivate: true},
+		doer:   &User{ID: 1},
+		result: true,
+	}, {
+		desc:   "other user should NOT see activity",
+		user:   &User{ID: 1, KeepActivityPrivate: true},
+		doer:   &User{ID: 2},
+		result: false,
+	}, {
+		desc:   "admin should see activity",
+		user:   &User{ID: 1, KeepActivityPrivate: true},
+		doer:   &User{ID: 2, IsAdmin: true},
+		result: true,
+	}}
+	for _, test := range tt {
+		assert.Equal(t, test.result, activityReadable(test.user, test.doer), test.desc)
+	}
+}

From 9a6b303033af66e9f3ce14724ccee41c177f110d Mon Sep 17 00:00:00 2001
From: 6543 <6543@obermui.de>
Date: Thu, 18 Nov 2021 15:51:40 +0100
Subject: [PATCH 02/11] optimize activityReadable()

---
 models/action.go | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/models/action.go b/models/action.go
index 80ac3e16f8524..e661064f7a62d 100644
--- a/models/action.go
+++ b/models/action.go
@@ -328,16 +328,8 @@ func GetFeeds(opts GetFeedsOptions) ([]*Action, error) {
 }
 
 func activityReadable(user, doer *User) bool {
-	var doerID int64
-	if doer != nil {
-		doerID = doer.ID
-	}
-	if doer == nil || !doer.IsAdmin {
-		if user.KeepActivityPrivate && doerID != user.ID {
-			return false
-		}
-	}
-	return true
+	return !user.KeepActivityPrivate ||
+		doer != nil && (doer.IsAdmin || user.ID == doer.ID)
 }
 
 func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) {

From 3c45fb24159ab79f4f7abb2e14d0b5e5d9a04772 Mon Sep 17 00:00:00 2001
From: 6543 <6543@obermui.de>
Date: Thu, 18 Nov 2021 17:07:15 +0100
Subject: [PATCH 03/11] wip...

---
 models/action.go            | 63 ++++++++++++++++++++++++++++---------
 routers/web/feed/profile.go | 43 +++++++++++++------------
 routers/web/user/profile.go | 13 +++-----
 3 files changed, 76 insertions(+), 43 deletions(-)

diff --git a/models/action.go b/models/action.go
index e661064f7a62d..c84183c663702 100644
--- a/models/action.go
+++ b/models/action.go
@@ -294,19 +294,21 @@ func (a *Action) GetIssueContent() string {
 
 // GetFeedsOptions options for retrieving feeds
 type GetFeedsOptions struct {
-	RequestedUser   *User  // the user we want activity for
-	RequestedTeam   *Team  // the team we want activity for
-	Actor           *User  // the user viewing the activity
-	IncludePrivate  bool   // include private actions
-	OnlyPerformedBy bool   // only actions performed by requested user
-	IncludeDeleted  bool   // include deleted actions
-	Date            string // the day we want activity for: YYYY-MM-DD
+	db.ListOptions
+	RequestedUser   *User       // the user we want activity for
+	RequestedTeam   *Team       // the team we want activity for
+	RequestedRepo   *Repository // the repo we want activity for
+	Actor           *User       // the user viewing the activity
+	IncludePrivate  bool        // include private actions
+	OnlyPerformedBy bool        // only actions performed by requested user
+	IncludeDeleted  bool        // include deleted actions
+	Date            string      // the day we want activity for: YYYY-MM-DD
 }
 
 // GetFeeds returns actions according to the provided options
 func GetFeeds(opts GetFeedsOptions) ([]*Action, error) {
-	if !activityReadable(opts.RequestedUser, opts.Actor) {
-		return make([]*Action, 0), nil
+	if opts.RequestedUser == nil && opts.RequestedTeam == nil && opts.RequestedRepo == nil {
+		return nil, fmt.Errorf("need at least one of these filters: RequestedUser, RequestedTeam, RequestedRepo")
 	}
 
 	cond, err := activityQueryCondition(opts)
@@ -314,9 +316,18 @@ func GetFeeds(opts GetFeedsOptions) ([]*Action, error) {
 		return nil, err
 	}
 
-	actions := make([]*Action, 0, setting.UI.FeedPagingNum)
+	sess := db.GetEngine(db.DefaultContext).Where(cond)
+	if opts.Page >= 0 {
+		opts.Page = 1
+	}
+	if opts.PageSize >= setting.API.MaxResponseItems || opts.PageSize <= 0 {
+		opts.PageSize = setting.UI.FeedPagingNum
+	}
+	sess = db.SetSessionPagination(sess, &opts)
+
+	actions := make([]*Action, 0, opts.PageSize)
 
-	if err := db.GetEngine(db.DefaultContext).Limit(setting.UI.FeedPagingNum).Desc("created_unix").Where(cond).Find(&actions); err != nil {
+	if err := sess.Desc("created_unix").Find(&actions); err != nil {
 		return nil, fmt.Errorf("Find: %v", err)
 	}
 
@@ -341,9 +352,28 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) {
 		actorID = opts.Actor.ID
 	}
 
+	if opts.RequestedTeam != nil && opts.RequestedUser == nil {
+		org, err := GetUserByID(opts.RequestedTeam.OrgID)
+		if err != nil {
+			return nil, err
+		}
+		opts.RequestedUser = org
+	}
+
+	// check activity visibility for actor ( equal to activityReadable() )
+	if opts.Actor == nil {
+		cond = cond.And(builder.In("user_id",
+			builder.Select("`user`.id").Where(builder.Eq{"keep_activity_private": true}).From("`user`"),
+		))
+	} else if !opts.Actor.IsAdmin {
+		cond = cond.And(builder.In("user_id",
+			builder.Select("`user`.id").Where(builder.Eq{"keep_activity_private": true}).From("`user`"),
+		).Or(builder.In("user_id", opts.Actor.ID)))
+	}
+
 	// check readable repositories by doer/actor
 	if opts.Actor == nil || !opts.Actor.IsAdmin {
-		if opts.RequestedUser.IsOrganization() {
+		if opts.RequestedUser != nil && opts.RequestedUser.IsOrganization() {
 			env, err := opts.RequestedUser.AccessibleReposEnv(actorID)
 			if err != nil {
 				return nil, fmt.Errorf("AccessibleReposEnv: %v", err)
@@ -366,11 +396,14 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) {
 		cond = cond.And(builder.In("repo_id", teamRepoIDs))
 	}
 
-	cond = cond.And(builder.Eq{"user_id": opts.RequestedUser.ID})
+	if opts.RequestedUser != nil {
+		cond = cond.And(builder.Eq{"user_id": opts.RequestedUser.ID})
 
-	if opts.OnlyPerformedBy {
-		cond = cond.And(builder.Eq{"act_user_id": opts.RequestedUser.ID})
+		if opts.OnlyPerformedBy {
+			cond = cond.And(builder.Eq{"act_user_id": opts.RequestedUser.ID})
+		}
 	}
+
 	if !opts.IncludePrivate {
 		cond = cond.And(builder.Eq{"is_private": false})
 	}
diff --git a/routers/web/feed/profile.go b/routers/web/feed/profile.go
index 8bd0cb7c29c3f..5e2c74dda993f 100644
--- a/routers/web/feed/profile.go
+++ b/routers/web/feed/profile.go
@@ -22,31 +22,34 @@ func RetrieveFeeds(ctx *context.Context, options models.GetFeedsOptions) []*mode
 		return nil
 	}
 
-	userCache := map[int64]*models.User{options.RequestedUser.ID: options.RequestedUser}
-	if ctx.User != nil {
-		userCache[ctx.User.ID] = ctx.User
-	}
-	for _, act := range actions {
-		if act.ActUser != nil {
-			userCache[act.ActUserID] = act.ActUser
+	// TODO: move load repoOwner of act.Repo into models.GetFeeds->loadAttributes()
+	{
+		userCache := map[int64]*models.User{options.RequestedUser.ID: options.RequestedUser}
+		if ctx.User != nil {
+			userCache[ctx.User.ID] = ctx.User
 		}
-	}
-
-	for _, act := range actions {
-		repoOwner, ok := userCache[act.Repo.OwnerID]
-		if !ok {
-			repoOwner, err = models.GetUserByID(act.Repo.OwnerID)
-			if err != nil {
-				if models.IsErrUserNotExist(err) {
-					continue
+		for _, act := range actions {
+			if act.ActUser != nil {
+				userCache[act.ActUserID] = act.ActUser
+			}
+		}
+		for _, act := range actions {
+			repoOwner, ok := userCache[act.Repo.OwnerID]
+			if !ok {
+				repoOwner, err = models.GetUserByID(act.Repo.OwnerID)
+				if err != nil {
+					if models.IsErrUserNotExist(err) {
+						continue
+					}
+					ctx.ServerError("GetUserByID", err)
+					return nil
 				}
-				ctx.ServerError("GetUserByID", err)
-				return nil
+				userCache[repoOwner.ID] = repoOwner
 			}
-			userCache[repoOwner.ID] = repoOwner
+			act.Repo.Owner = repoOwner
 		}
-		act.Repo.Owner = repoOwner
 	}
+
 	return actions
 }
 
diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go
index 72d36761da8ce..4885e8c6e8fa2 100644
--- a/routers/web/user/profile.go
+++ b/routers/web/user/profile.go
@@ -93,14 +93,11 @@ func Profile(ctx *context.Context) {
 	}
 
 	if ctxUser.IsOrganization() {
-		/*
-			// TODO: enable after rss.RetrieveFeeds() do handle org correctly
-			// Show Org RSS feed
-			if len(showFeedType) != 0 {
-				rss.ShowUserFeed(ctx, ctxUser, showFeedType)
-				return
-			}
-		*/
+		// Show Org RSS feed
+		if len(showFeedType) != 0 {
+			feed.ShowUserFeed(ctx, ctxUser, showFeedType)
+			return
+		}
 
 		org.Home(ctx)
 		return

From bd4f80c0459ab41c661429e2a131c863835ad59e Mon Sep 17 00:00:00 2001
From: 6543 <6543@obermui.de>
Date: Sat, 26 Feb 2022 00:22:40 +0100
Subject: [PATCH 04/11] adapt latest refactors

---
 models/action.go | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/models/action.go b/models/action.go
index 1c6fd51000eb8..ae53f29bd7c43 100644
--- a/models/action.go
+++ b/models/action.go
@@ -316,14 +316,14 @@ func (a *Action) GetIssueContent() string {
 // GetFeedsOptions options for retrieving feeds
 type GetFeedsOptions struct {
 	db.ListOptions
-	RequestedUser   *user_model.User // the user we want activity for
-	RequestedTeam   *Team            // the team we want activity for
-	RequestedRepo   *Repository      // the repo we want activity for
-	Actor           *user_model.User // the user viewing the activity
-	IncludePrivate  bool             // include private actions
-	OnlyPerformedBy bool             // only actions performed by requested user
-	IncludeDeleted  bool             // include deleted actions
-	Date            string           // the day we want activity for: YYYY-MM-DD
+	RequestedUser   *user_model.User       // the user we want activity for
+	RequestedTeam   *Team                  // the team we want activity for
+	RequestedRepo   *repo_model.Repository // the repo we want activity for
+	Actor           *user_model.User       // the user viewing the activity
+	IncludePrivate  bool                   // include private actions
+	OnlyPerformedBy bool                   // only actions performed by requested user
+	IncludeDeleted  bool                   // include deleted actions
+	Date            string                 // the day we want activity for: YYYY-MM-DD
 }
 
 // GetFeeds returns actions according to the provided options
@@ -374,7 +374,7 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) {
 	}
 
 	if opts.RequestedTeam != nil && opts.RequestedUser == nil {
-		org, err := GetUserByID(opts.RequestedTeam.OrgID)
+		org, err := user_model.GetUserByID(opts.RequestedTeam.OrgID)
 		if err != nil {
 			return nil, err
 		}

From bd69cc65e27351cfb10c1bad5b3e85a6c902123b Mon Sep 17 00:00:00 2001
From: 6543 <6543@obermui.de>
Date: Tue, 1 Mar 2022 02:34:12 +0100
Subject: [PATCH 05/11] fix & enhance

---
 models/action.go            |  6 +++---
 models/user_heatmap_test.go | 33 +++++++++++++++++----------------
 2 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/models/action.go b/models/action.go
index ae53f29bd7c43..b9f978a6f4846 100644
--- a/models/action.go
+++ b/models/action.go
@@ -384,12 +384,12 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) {
 	// check activity visibility for actor ( equal to activityReadable() )
 	if opts.Actor == nil {
 		cond = cond.And(builder.In("user_id",
-			builder.Select("`user`.id").Where(builder.Eq{"keep_activity_private": true}).From("`user`"),
+			builder.Select("`user`.id").Where(builder.Eq{"keep_activity_private": false}).From("`user`"),
 		))
 	} else if !opts.Actor.IsAdmin {
 		cond = cond.And(builder.In("user_id",
-			builder.Select("`user`.id").Where(builder.Eq{"keep_activity_private": true}).From("`user`"),
-		).Or(builder.In("user_id", opts.Actor.ID)))
+			builder.Select("`user`.id").Where(builder.Eq{"keep_activity_private": false}.Or(builder.Eq{"id": opts.Actor.ID})).From("`user`"),
+		))
 	}
 
 	// check readable repositories by doer/actor
diff --git a/models/user_heatmap_test.go b/models/user_heatmap_test.go
index 7d2997648df4a..50c733a4ca839 100644
--- a/models/user_heatmap_test.go
+++ b/models/user_heatmap_test.go
@@ -19,25 +19,26 @@ import (
 
 func TestGetUserHeatmapDataByUser(t *testing.T) {
 	testCases := []struct {
+		desc        string
 		userID      int64
 		doerID      int64
 		CountResult int
 		JSONResult  string
 	}{
-		// self looks at action in private repo
-		{2, 2, 1, `[{"timestamp":1603227600,"contributions":1}]`},
-		// admin looks at action in private repo
-		{2, 1, 1, `[{"timestamp":1603227600,"contributions":1}]`},
-		// other user looks at action in private repo
-		{2, 3, 0, `[]`},
-		// nobody looks at action in private repo
-		{2, 0, 0, `[]`},
-		// collaborator looks at action in private repo
-		{16, 15, 1, `[{"timestamp":1603267200,"contributions":1}]`},
-		// no action action not performed by target user
-		{3, 3, 0, `[]`},
-		// multiple actions performed with two grouped together
-		{10, 10, 3, `[{"timestamp":1603009800,"contributions":1},{"timestamp":1603010700,"contributions":2}]`},
+		{"self looks at action in private repo",
+			2, 2, 1, `[{"timestamp":1603227600,"contributions":1}]`},
+		{"admin looks at action in private repo",
+			2, 1, 1, `[{"timestamp":1603227600,"contributions":1}]`},
+		{"other user looks at action in private repo",
+			2, 3, 0, `[]`},
+		{"nobody looks at action in private repo",
+			2, 0, 0, `[]`},
+		{"collaborator looks at action in private repo",
+			16, 15, 1, `[{"timestamp":1603267200,"contributions":1}]`},
+		{"no action action not performed by target user",
+			3, 3, 0, `[]`},
+		{"multiple actions performed with two grouped together",
+			10, 10, 3, `[{"timestamp":1603009800,"contributions":1},{"timestamp":1603010700,"contributions":2}]`},
 	}
 	// Prepare
 	assert.NoError(t, unittest.PrepareTestDatabase())
@@ -46,7 +47,7 @@ func TestGetUserHeatmapDataByUser(t *testing.T) {
 	timeutil.Set(time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC))
 	defer timeutil.Unset()
 
-	for i, tc := range testCases {
+	for _, tc := range testCases {
 		user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: tc.userID}).(*user_model.User)
 
 		doer := &user_model.User{ID: tc.doerID}
@@ -74,7 +75,7 @@ func TestGetUserHeatmapDataByUser(t *testing.T) {
 		}
 		assert.NoError(t, err)
 		assert.Len(t, actions, contributions, "invalid action count: did the test data became too old?")
-		assert.Equal(t, tc.CountResult, contributions, fmt.Sprintf("testcase %d", i))
+		assert.Equal(t, tc.CountResult, contributions, fmt.Sprintf("testcase '%s'", tc.desc))
 
 		// Test JSON rendering
 		jsonData, err := json.Marshal(heatmap)

From 648f06ac18de8982da972deb3813ba34212ab7a8 Mon Sep 17 00:00:00 2001
From: 6543 <6543@obermui.de>
Date: Tue, 1 Mar 2022 03:03:02 +0100
Subject: [PATCH 06/11] fix linter

---
 models/user_heatmap_test.go | 42 ++++++++++++++++++++++++-------------
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/models/user_heatmap_test.go b/models/user_heatmap_test.go
index 50c733a4ca839..7915363d9574a 100644
--- a/models/user_heatmap_test.go
+++ b/models/user_heatmap_test.go
@@ -25,20 +25,34 @@ func TestGetUserHeatmapDataByUser(t *testing.T) {
 		CountResult int
 		JSONResult  string
 	}{
-		{"self looks at action in private repo",
-			2, 2, 1, `[{"timestamp":1603227600,"contributions":1}]`},
-		{"admin looks at action in private repo",
-			2, 1, 1, `[{"timestamp":1603227600,"contributions":1}]`},
-		{"other user looks at action in private repo",
-			2, 3, 0, `[]`},
-		{"nobody looks at action in private repo",
-			2, 0, 0, `[]`},
-		{"collaborator looks at action in private repo",
-			16, 15, 1, `[{"timestamp":1603267200,"contributions":1}]`},
-		{"no action action not performed by target user",
-			3, 3, 0, `[]`},
-		{"multiple actions performed with two grouped together",
-			10, 10, 3, `[{"timestamp":1603009800,"contributions":1},{"timestamp":1603010700,"contributions":2}]`},
+		{
+			"self looks at action in private repo",
+			2, 2, 1, `[{"timestamp":1603227600,"contributions":1}]`,
+		},
+		{
+			"admin looks at action in private repo",
+			2, 1, 1, `[{"timestamp":1603227600,"contributions":1}]`,
+		},
+		{
+			"other user looks at action in private repo",
+			2, 3, 0, `[]`,
+		},
+		{
+			"nobody looks at action in private repo",
+			2, 0, 0, `[]`,
+		},
+		{
+			"collaborator looks at action in private repo",
+			16, 15, 1, `[{"timestamp":1603267200,"contributions":1}]`,
+		},
+		{
+			"no action action not performed by target user",
+			3, 3, 0, `[]`,
+		},
+		{
+			"multiple actions performed with two grouped together",
+			10, 10, 3, `[{"timestamp":1603009800,"contributions":1},{"timestamp":1603010700,"contributions":2}]`,
+		},
 	}
 	// Prepare
 	assert.NoError(t, unittest.PrepareTestDatabase())

From a7b9337128b46c2aeb2de4c1430d3a22d71af909 Mon Sep 17 00:00:00 2001
From: 6543 <6543@obermui.de>
Date: Tue, 1 Mar 2022 03:33:55 +0100
Subject: [PATCH 07/11] simplify & make org rss work

---
 models/action.go            | 19 +------------------
 routers/web/feed/profile.go |  2 +-
 2 files changed, 2 insertions(+), 19 deletions(-)

diff --git a/models/action.go b/models/action.go
index b9f978a6f4846..c4e29aa3dbbfa 100644
--- a/models/action.go
+++ b/models/action.go
@@ -367,12 +367,6 @@ func activityReadable(user, doer *user_model.User) bool {
 func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) {
 	cond := builder.NewCond()
 
-	var repoIDs []int64
-	var actorID int64
-	if opts.Actor != nil {
-		actorID = opts.Actor.ID
-	}
-
 	if opts.RequestedTeam != nil && opts.RequestedUser == nil {
 		org, err := user_model.GetUserByID(opts.RequestedTeam.OrgID)
 		if err != nil {
@@ -394,18 +388,7 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) {
 
 	// check readable repositories by doer/actor
 	if opts.Actor == nil || !opts.Actor.IsAdmin {
-		if opts.RequestedUser != nil && opts.RequestedUser.IsOrganization() {
-			env, err := OrgFromUser(opts.RequestedUser).AccessibleReposEnv(actorID)
-			if err != nil {
-				return nil, fmt.Errorf("AccessibleReposEnv: %v", err)
-			}
-			if repoIDs, err = env.RepoIDs(1, opts.RequestedUser.NumRepos); err != nil {
-				return nil, fmt.Errorf("GetUserRepositories: %v", err)
-			}
-			cond = cond.And(builder.In("repo_id", repoIDs))
-		} else {
-			cond = cond.And(builder.In("repo_id", AccessibleRepoIDsQuery(opts.Actor)))
-		}
+		cond = cond.And(builder.In("repo_id", AccessibleRepoIDsQuery(opts.Actor)))
 	}
 
 	if opts.RequestedTeam != nil {
diff --git a/routers/web/feed/profile.go b/routers/web/feed/profile.go
index 834bebdd85e44..4c1eff04a9d94 100644
--- a/routers/web/feed/profile.go
+++ b/routers/web/feed/profile.go
@@ -60,7 +60,7 @@ func ShowUserFeed(ctx *context.Context, ctxUser *user_model.User, formatType str
 		RequestedUser:   ctxUser,
 		Actor:           ctx.User,
 		IncludePrivate:  false,
-		OnlyPerformedBy: true,
+		OnlyPerformedBy: !ctxUser.IsOrganization(),
 		IncludeDeleted:  false,
 		Date:            ctx.FormString("date"),
 	})

From 3cbc9e85099800bfa38070395e3eba1ffa33f92b Mon Sep 17 00:00:00 2001
From: 6543 <6543@obermui.de>
Date: Tue, 1 Mar 2022 03:49:42 +0100
Subject: [PATCH 08/11] respect user visibility

---
 models/action.go | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/models/action.go b/models/action.go
index c4e29aa3dbbfa..ca59f4a2d3f32 100644
--- a/models/action.go
+++ b/models/action.go
@@ -22,6 +22,7 @@ import (
 	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
+	"code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/modules/timeutil"
 	"code.gitea.io/gitea/modules/util"
 
@@ -375,14 +376,19 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) {
 		opts.RequestedUser = org
 	}
 
-	// check activity visibility for actor ( equal to activityReadable() )
+	// check activity visibility for actor ( similar to activityReadable() )
 	if opts.Actor == nil {
-		cond = cond.And(builder.In("user_id",
-			builder.Select("`user`.id").Where(builder.Eq{"keep_activity_private": false}).From("`user`"),
+		cond = cond.And(builder.In("act_user_id",
+			builder.Select("`user`.id").Where(
+				builder.Eq{"keep_activity_private": false, "visibility": structs.VisibleTypePublic},
+			).From("`user`"),
 		))
 	} else if !opts.Actor.IsAdmin {
-		cond = cond.And(builder.In("user_id",
-			builder.Select("`user`.id").Where(builder.Eq{"keep_activity_private": false}.Or(builder.Eq{"id": opts.Actor.ID})).From("`user`"),
+		cond = cond.And(builder.In("act_user_id",
+			builder.Select("`user`.id").Where(
+				builder.Eq{"keep_activity_private": false}.
+					And(builder.In("visibility", structs.VisibleTypePublic, structs.VisibleTypeLimited))).
+				Or(builder.Eq{"id": opts.Actor.ID}).From("`user`"),
 		))
 	}
 

From 9cb3ff427a309a357fc11d3dbe17c8a0bbbf5753 Mon Sep 17 00:00:00 2001
From: 6543 <6543@obermui.de>
Date: Tue, 1 Mar 2022 03:53:47 +0100
Subject: [PATCH 09/11] prepare

---
 models/action.go | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/models/action.go b/models/action.go
index ca59f4a2d3f32..d537dde3499d5 100644
--- a/models/action.go
+++ b/models/action.go
@@ -397,6 +397,10 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) {
 		cond = cond.And(builder.In("repo_id", AccessibleRepoIDsQuery(opts.Actor)))
 	}
 
+	if opts.RequestedRepo != nil {
+		cond = cond.And(builder.Eq{"repo_id": opts.RequestedRepo.ID})
+	}
+
 	if opts.RequestedTeam != nil {
 		env := OrgFromUser(opts.RequestedUser).AccessibleTeamReposEnv(opts.RequestedTeam)
 		teamRepoIDs, err := env.RepoIDs(1, opts.RequestedUser.NumRepos)

From 0b35f38e2c391e86d6fbbcbe2a2cc735c1cf35a4 Mon Sep 17 00:00:00 2001
From: 6543 <6543@obermui.de>
Date: Mon, 7 Mar 2022 20:30:22 +0100
Subject: [PATCH 10/11] Update models/action.go

---
 models/action.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/models/action.go b/models/action.go
index d537dde3499d5..c3d8e5c8d0496 100644
--- a/models/action.go
+++ b/models/action.go
@@ -339,7 +339,7 @@ func GetFeeds(opts GetFeedsOptions) ([]*Action, error) {
 	}
 
 	sess := db.GetEngine(db.DefaultContext).Where(cond)
-	if opts.Page >= 0 {
+	if opts.Page <= 0 {
 		opts.Page = 1
 	}
 	if opts.PageSize >= setting.API.MaxResponseItems || opts.PageSize <= 0 {

From 95376437a57eccad89b7a097e7b986b864d3ca65 Mon Sep 17 00:00:00 2001
From: 6543 <6543@obermui.de>
Date: Tue, 8 Mar 2022 16:31:32 +0100
Subject: [PATCH 11/11] use SetDefaultValues()

---
 models/action.go | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/models/action.go b/models/action.go
index c3d8e5c8d0496..f2723a20147cc 100644
--- a/models/action.go
+++ b/models/action.go
@@ -339,12 +339,8 @@ func GetFeeds(opts GetFeedsOptions) ([]*Action, error) {
 	}
 
 	sess := db.GetEngine(db.DefaultContext).Where(cond)
-	if opts.Page <= 0 {
-		opts.Page = 1
-	}
-	if opts.PageSize >= setting.API.MaxResponseItems || opts.PageSize <= 0 {
-		opts.PageSize = setting.UI.FeedPagingNum
-	}
+
+	opts.SetDefaultValues()
 	sess = db.SetSessionPagination(sess, &opts)
 
 	actions := make([]*Action, 0, opts.PageSize)