diff options
Diffstat (limited to 'internal/filter/visibility')
-rw-r--r-- | internal/filter/visibility/account.go | 2 | ||||
-rw-r--r-- | internal/filter/visibility/filter.go | 4 | ||||
-rw-r--r-- | internal/filter/visibility/home_timeline.go | 2 | ||||
-rw-r--r-- | internal/filter/visibility/public_timeline.go | 2 | ||||
-rw-r--r-- | internal/filter/visibility/status.go | 64 |
5 files changed, 65 insertions, 9 deletions
diff --git a/internal/filter/visibility/account.go b/internal/filter/visibility/account.go index 410daa1ce..ebbbe4a2f 100644 --- a/internal/filter/visibility/account.go +++ b/internal/filter/visibility/account.go @@ -32,7 +32,7 @@ func (f *Filter) AccountVisible(ctx context.Context, requester *gtsmodel.Account const vtype = cache.VisibilityTypeAccount // By default we assume no auth. - requesterID := noauth + requesterID := NoAuth if requester != nil { // Use provided account ID. diff --git a/internal/filter/visibility/filter.go b/internal/filter/visibility/filter.go index c9f007ccf..43f862681 100644 --- a/internal/filter/visibility/filter.go +++ b/internal/filter/visibility/filter.go @@ -21,9 +21,9 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/state" ) -// noauth is a placeholder ID used in cache lookups +// NoAuth is a placeholder ID used in cache lookups // when there is no authorized account ID to use. -const noauth = "noauth" +const NoAuth = "noauth" // Filter packages up a bunch of logic for checking whether // given statuses or accounts are visible to a requester. diff --git a/internal/filter/visibility/home_timeline.go b/internal/filter/visibility/home_timeline.go index af583a847..9c224ffbb 100644 --- a/internal/filter/visibility/home_timeline.go +++ b/internal/filter/visibility/home_timeline.go @@ -35,7 +35,7 @@ func (f *Filter) StatusHomeTimelineable(ctx context.Context, owner *gtsmodel.Acc const vtype = cache.VisibilityTypeHome // By default we assume no auth. - requesterID := noauth + requesterID := NoAuth if owner != nil { // Use provided account ID. diff --git a/internal/filter/visibility/public_timeline.go b/internal/filter/visibility/public_timeline.go index bad7cf991..9cc3c2357 100644 --- a/internal/filter/visibility/public_timeline.go +++ b/internal/filter/visibility/public_timeline.go @@ -33,7 +33,7 @@ func (f *Filter) StatusPublicTimelineable(ctx context.Context, requester *gtsmod const vtype = cache.VisibilityTypePublic // By default we assume no auth. - requesterID := noauth + requesterID := NoAuth if requester != nil { // Use provided account ID. diff --git a/internal/filter/visibility/status.go b/internal/filter/visibility/status.go index fdeefedde..be59e800e 100644 --- a/internal/filter/visibility/status.go +++ b/internal/filter/visibility/status.go @@ -54,7 +54,7 @@ func (f *Filter) StatusVisible( const vtype = cache.VisibilityTypeStatus // By default we assume no auth. - requesterID := noauth + requesterID := NoAuth if requester != nil { // Use provided account ID. @@ -113,9 +113,9 @@ func (f *Filter) isStatusVisible( } 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 + // Use a different visibility + // heuristic for unauthed requests. + return f.isStatusVisibleUnauthed(ctx, status) } /* @@ -245,6 +245,62 @@ func (f *Filter) isPendingStatusVisible( return false, nil } +func (f *Filter) isStatusVisibleUnauthed( + ctx context.Context, + status *gtsmodel.Status, +) (bool, error) { + // For remote accounts, only show + // Public statuses via the web. + if status.Account.IsRemote() { + return status.Visibility == gtsmodel.VisibilityPublic, nil + } + + // If status is local only, + // never show via the web. + if status.IsLocalOnly() { + return false, nil + } + + // Check account's settings to see + // what they expose. Populate these + // from the DB if necessary. + if status.Account.Settings == nil { + var err error + status.Account.Settings, err = f.state.DB.GetAccountSettings(ctx, status.Account.ID) + if err != nil { + return false, gtserror.Newf( + "error getting settings for account %s: %w", + status.Account.ID, err, + ) + } + } + + webVisibility := status.Account.Settings.WebVisibility + switch webVisibility { + + // public_only: status must be Public. + case gtsmodel.VisibilityPublic: + return status.Visibility == gtsmodel.VisibilityPublic, nil + + // unlisted: status must be Public or Unlocked. + case gtsmodel.VisibilityUnlocked: + visible := status.Visibility == gtsmodel.VisibilityPublic || + status.Visibility == gtsmodel.VisibilityUnlocked + return visible, nil + + // none: never show via the web. + case gtsmodel.VisibilityNone: + return false, nil + + // Huh? + default: + return false, gtserror.Newf( + "unrecognized web visibility for account %s: %s", + status.Account.ID, webVisibility, + ) + } +} + // areStatusAccountsVisible calls Filter{}.AccountVisible() on status author and the status boost-of (if set) author, returning visibility of status (and boost-of) to requester. func (f *Filter) areStatusAccountsVisible(ctx context.Context, requester *gtsmodel.Account, status *gtsmodel.Status) (bool, error) { // Check whether status author's account is visible to requester. |