summaryrefslogtreecommitdiff
path: root/internal/filter/visibility
diff options
context:
space:
mode:
Diffstat (limited to 'internal/filter/visibility')
-rw-r--r--internal/filter/visibility/account.go2
-rw-r--r--internal/filter/visibility/filter.go4
-rw-r--r--internal/filter/visibility/home_timeline.go2
-rw-r--r--internal/filter/visibility/public_timeline.go2
-rw-r--r--internal/filter/visibility/status.go64
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.