summaryrefslogtreecommitdiff
path: root/internal/filter/visibility/status.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/filter/visibility/status.go')
-rw-r--r--internal/filter/visibility/status.go64
1 files changed, 60 insertions, 4 deletions
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.