Skip to content

Commit

Permalink
[bugfix] Prevent future statuses entering timelines (#1134)
Browse files Browse the repository at this point in the history
* [bugfix] Prevent future statuses entering timeline
Statuses created more than 5 minutes into the future are now rejected in the visibility package.

* Come on buddy
  • Loading branch information
tsmethurst committed Nov 24, 2022
1 parent fcb9c0b commit da89548
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 13 deletions.
2 changes: 1 addition & 1 deletion internal/visibility/filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ func (suite *FilterStandardTestSuite) SetupSuite() {
}

func (suite *FilterStandardTestSuite) SetupTest() {
testrig.InitTestLog()
testrig.InitTestConfig()
testrig.InitTestLog()

suite.db = testrig.NewTestDB()
suite.filter = visibility.NewFilter(suite.db)
Expand Down
16 changes: 13 additions & 3 deletions internal/visibility/statushometimelineable.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,27 @@ package visibility
import (
"context"
"fmt"
"time"

"codeberg.org/gruf/go-kv"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/internal/log"
)

func (f *filter) StatusHometimelineable(ctx context.Context, targetStatus *gtsmodel.Status, timelineOwnerAccount *gtsmodel.Account) (bool, error) {
l := log.WithFields(kv.Fields{
l := log.WithFields(kv.Fields{{"statusID", targetStatus.ID}}...)

{"statusID", targetStatus.ID},
}...)
// don't timeline statuses more than 5 min in the future
maxID, err := id.NewULIDFromTime(time.Now().Add(5 * time.Minute))
if err != nil {
return false, err
}

if targetStatus.ID > maxID {
l.Debug("status not hometimelineable because it's from more than 5 minutes in the future")
return false, nil
}

// status owner should always be able to see their own status in their timeline so we can return early if this is the case
if targetStatus.AccountID == timelineOwnerAccount.ID {
Expand Down
40 changes: 40 additions & 0 deletions internal/visibility/statushometimelineable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ package visibility_test
import (
"context"
"testing"
"time"

"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/testrig"
)

Expand Down Expand Up @@ -65,6 +67,44 @@ func (suite *StatusStatusHometimelineableTestSuite) TestNotFollowingStatusHometi
suite.False(timelineable)
}

func (suite *StatusStatusHometimelineableTestSuite) TestStatusTooNewNotTimelineable() {
testStatus := &gtsmodel.Status{}
*testStatus = *suite.testStatuses["local_account_1_status_1"]

var err error
testStatus.ID, err = id.NewULIDFromTime(time.Now().Add(10 * time.Minute))
if err != nil {
suite.FailNow(err.Error())
}

testAccount := suite.testAccounts["local_account_1"]
ctx := context.Background()

timelineable, err := suite.filter.StatusHometimelineable(ctx, testStatus, testAccount)
suite.NoError(err)

suite.False(timelineable)
}

func (suite *StatusStatusHometimelineableTestSuite) TestStatusNotTooNewTimelineable() {
testStatus := &gtsmodel.Status{}
*testStatus = *suite.testStatuses["local_account_1_status_1"]

var err error
testStatus.ID, err = id.NewULIDFromTime(time.Now().Add(4 * time.Minute))
if err != nil {
suite.FailNow(err.Error())
}

testAccount := suite.testAccounts["local_account_1"]
ctx := context.Background()

timelineable, err := suite.filter.StatusHometimelineable(ctx, testStatus, testAccount)
suite.NoError(err)

suite.True(timelineable)
}

func (suite *StatusStatusHometimelineableTestSuite) TestChainReplyFollowersOnly() {
ctx := context.Background()

Expand Down
16 changes: 13 additions & 3 deletions internal/visibility/statuspublictimelineable.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,27 @@ package visibility
import (
"context"
"fmt"
"time"

"codeberg.org/gruf/go-kv"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/internal/log"
)

func (f *filter) StatusPublictimelineable(ctx context.Context, targetStatus *gtsmodel.Status, timelineOwnerAccount *gtsmodel.Account) (bool, error) {
l := log.WithFields(kv.Fields{
l := log.WithFields(kv.Fields{{"statusID", targetStatus.ID}}...)

{"statusID", targetStatus.ID},
}...)
// don't timeline statuses more than 5 min in the future
maxID, err := id.NewULIDFromTime(time.Now().Add(5 * time.Minute))
if err != nil {
return false, err
}

if targetStatus.ID > maxID {
l.Debug("status not hometimelineable because it's from more than 5 minutes in the future")
return false, nil
}

// Don't timeline boosted statuses
if targetStatus.BoostOfID != "" {
Expand Down
8 changes: 2 additions & 6 deletions internal/visibility/statusvisible.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,10 @@ import (
)

func (f *filter) StatusVisible(ctx context.Context, targetStatus *gtsmodel.Status, requestingAccount *gtsmodel.Account) (bool, error) {
const getBoosted = true

l := log.WithFields(kv.Fields{

{"statusID", targetStatus.ID},
}...)
l := log.WithFields(kv.Fields{{"statusID", targetStatus.ID}}...)

// Fetch any relevant accounts for the target status
const getBoosted = true
relevantAccounts, err := f.relevantAccounts(ctx, targetStatus, getBoosted)
if err != nil {
l.Debugf("error pulling relevant accounts for status %s: %s", targetStatus.ID, err)
Expand Down

0 comments on commit da89548

Please sign in to comment.