diff options
Diffstat (limited to 'internal/filter')
-rw-r--r-- | internal/filter/visibility/status.go | 32 | ||||
-rw-r--r-- | internal/filter/visibility/status_test.go | 37 |
2 files changed, 59 insertions, 10 deletions
diff --git a/internal/filter/visibility/status.go b/internal/filter/visibility/status.go index be1c6a350..fdeefedde 100644 --- a/internal/filter/visibility/status.go +++ b/internal/filter/visibility/status.go @@ -97,10 +97,10 @@ func (f *Filter) isStatusVisible( } // Check whether status accounts are visible to the requester. - visible, err := f.areStatusAccountsVisible(ctx, requester, status) + acctsVisible, err := f.areStatusAccountsVisible(ctx, requester, status) if err != nil { return false, gtserror.Newf("error checking status %s account visibility: %w", status.ID, err) - } else if !visible { + } else if !acctsVisible { return false, nil } @@ -112,22 +112,34 @@ func (f *Filter) isStatusVisible( ) } - if status.Visibility == gtsmodel.VisibilityPublic { - // This status will be visible to all. - return true, nil + if requester == nil { + // The request is unauthed. Only federated, Public statuses are visible without auth. + visibleUnauthed := !status.IsLocalOnly() && status.Visibility == gtsmodel.VisibilityPublic + return visibleUnauthed, nil } - if requester == nil { - // This request is WITHOUT auth, and status is NOT public. - log.Trace(ctx, "unauthorized request to non-public status") + /* + From this point down we know the request is authed. + */ + + if requester.IsRemote() && status.IsLocalOnly() { + // Remote accounts can't see local-only + // posts regardless of their visibility. return false, nil } - if status.Visibility == gtsmodel.VisibilityUnlocked { - // This status is visible to all auth'd accounts. + if status.Visibility == gtsmodel.VisibilityPublic || + status.Visibility == gtsmodel.VisibilityUnlocked { + // This status is visible to all auth'd accounts + // (pending blocks, which we already checked above). return true, nil } + /* + From this point down we know the request + is of visibility followers-only or below. + */ + if requester.ID == status.AccountID { // Author can always see their own status. return true, nil diff --git a/internal/filter/visibility/status_test.go b/internal/filter/visibility/status_test.go index 6f8bb12b4..9b210e500 100644 --- a/internal/filter/visibility/status_test.go +++ b/internal/filter/visibility/status_test.go @@ -200,6 +200,43 @@ func (suite *StatusVisibleTestSuite) TestVisiblePending() { } } +func (suite *StatusVisibleTestSuite) TestVisibleLocalOnly() { + ctx := context.Background() + + // Local-only, Public status. + testStatus := suite.testStatuses["local_account_2_status_4"] + + for _, testCase := range []struct { + acct *gtsmodel.Account + visible bool + }{ + { + acct: suite.testAccounts["local_account_2"], + visible: true, // Own status, always visible. + }, + { + acct: nil, + visible: false, // No auth, should not be visible.. + }, + { + acct: suite.testAccounts["local_account_1"], + visible: true, // Local account, should be visible. + }, + { + acct: suite.testAccounts["remote_account_1"], + visible: false, // Blocked account, should not be visible. + }, + { + acct: suite.testAccounts["remote_account_2"], + visible: false, // Remote account, should not be visible. + }, + } { + visible, err := suite.filter.StatusVisible(ctx, testCase.acct, testStatus) + suite.NoError(err) + suite.Equal(testCase.visible, visible) + } +} + func TestStatusVisibleTestSuite(t *testing.T) { suite.Run(t, new(StatusVisibleTestSuite)) } |