diff options
author | 2024-07-24 13:27:42 +0200 | |
---|---|---|
committer | 2024-07-24 12:27:42 +0100 | |
commit | c9b6220fef01dce80a31436660cd06b4e1db030f (patch) | |
tree | 5fbade865a920a5ea04fdd63763eca1880d60c5d /internal/filter/visibility/status.go | |
parent | [chore] renames the `GTS` caches to `DB` caches (#3127) (diff) | |
download | gotosocial-c9b6220fef01dce80a31436660cd06b4e1db030f.tar.xz |
[chore] Add interaction filter to complement existing visibility filter (#3111)
* [chore] Add interaction filter to complement existing visibility filter
* pass in ptr to visibility and interaction filters to Processor{} to ensure shared
* use int constants for for match type, cache db calls in filterctx
* function name typo :innocent:
---------
Co-authored-by: kim <grufwub@gmail.com>
Diffstat (limited to 'internal/filter/visibility/status.go')
-rw-r--r-- | internal/filter/visibility/status.go | 65 |
1 files changed, 61 insertions, 4 deletions
diff --git a/internal/filter/visibility/status.go b/internal/filter/visibility/status.go index 5e2052ae4..be1c6a350 100644 --- a/internal/filter/visibility/status.go +++ b/internal/filter/visibility/status.go @@ -25,6 +25,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/gtserror" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/log" + "github.com/superseriousbusiness/gotosocial/internal/util" ) // StatusesVisible calls StatusVisible for each status in the statuses slice, and returns a slice of only statuses which are visible to the requester. @@ -41,8 +42,15 @@ func (f *Filter) StatusesVisible(ctx context.Context, requester *gtsmodel.Accoun return filtered, errs.Combine() } -// StatusVisible will check if given status is visible to requester, accounting for requester with no auth (i.e is nil), suspensions, disabled local users, account blocks and status privacy. -func (f *Filter) StatusVisible(ctx context.Context, requester *gtsmodel.Account, status *gtsmodel.Status) (bool, error) { +// StatusVisible will check if status is visible to requester, +// accounting for requester with no auth (i.e is nil), suspensions, +// disabled local users, pending approvals, account blocks, +// and status visibility settings. +func (f *Filter) StatusVisible( + ctx context.Context, + requester *gtsmodel.Account, + status *gtsmodel.Status, +) (bool, error) { const vtype = cache.VisibilityTypeStatus // By default we assume no auth. @@ -75,8 +83,14 @@ func (f *Filter) StatusVisible(ctx context.Context, requester *gtsmodel.Account, return visibility.Value, nil } -// isStatusVisible will check if status is visible to requester. It is the "meat" of the logic to Filter{}.StatusVisible() which is called within cache loader callback. -func (f *Filter) isStatusVisible(ctx context.Context, requester *gtsmodel.Account, status *gtsmodel.Status) (bool, error) { +// isStatusVisible will check if status is visible to requester. +// It is the "meat" of the logic to Filter{}.StatusVisible() +// which is called within cache loader callback. +func (f *Filter) isStatusVisible( + ctx context.Context, + requester *gtsmodel.Account, + status *gtsmodel.Status, +) (bool, error) { // Ensure that status is fully populated for further processing. if err := f.state.DB.PopulateStatus(ctx, status); err != nil { return false, gtserror.Newf("error populating status %s: %w", status.ID, err) @@ -90,6 +104,14 @@ func (f *Filter) isStatusVisible(ctx context.Context, requester *gtsmodel.Accoun return false, nil } + if util.PtrOrValue(status.PendingApproval, false) { + // Use a different visibility heuristic + // for pending approval statuses. + return f.isPendingStatusVisible(ctx, + requester, status, + ) + } + if status.Visibility == gtsmodel.VisibilityPublic { // This status will be visible to all. return true, nil @@ -176,6 +198,41 @@ func (f *Filter) isStatusVisible(ctx context.Context, requester *gtsmodel.Accoun } } +func (f *Filter) isPendingStatusVisible( + _ context.Context, + requester *gtsmodel.Account, + status *gtsmodel.Status, +) (bool, error) { + if requester == nil { + // Any old tom, dick, and harry can't + // see pending-approval statuses, + // no matter what their visibility. + return false, nil + } + + if status.AccountID == requester.ID { + // This is requester's status, + // so they can always see it. + return true, nil + } + + if status.InReplyToAccountID == requester.ID { + // This status replies to requester, + // so they can always see it (else + // they can't approve it). + return true, nil + } + + if status.BoostOfAccountID == requester.ID { + // This status boosts requester, + // so they can always see it. + return true, nil + } + + // Nobody else can see this. + return false, nil +} + // 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. |