diff --git a/internal/cache/status.go b/internal/cache/status.go index 028abc8f7..f6fe45d99 100644 --- a/internal/cache/status.go +++ b/internal/cache/status.go @@ -144,7 +144,10 @@ func copyStatus(status *gtsmodel.Status) *gtsmodel.Status { Sensitive: status.Sensitive, Language: status.Language, CreatedWithApplicationID: status.CreatedWithApplicationID, - VisibilityAdvanced: status.VisibilityAdvanced, + Federated: status.Federated, + Boostable: status.Boostable, + Replyable: status.Replyable, + Likeable: status.Likeable, ActivityStreamsType: status.ActivityStreamsType, Text: status.Text, Pinned: status.Pinned, diff --git a/internal/db/bundb/status_test.go b/internal/db/bundb/status_test.go index ff86390fe..64079c78f 100644 --- a/internal/db/bundb/status_test.go +++ b/internal/db/bundb/status_test.go @@ -43,10 +43,14 @@ func (suite *StatusTestSuite) TestGetStatusByID() { suite.Nil(status.BoostOfAccount) suite.Nil(status.InReplyTo) suite.Nil(status.InReplyToAccount) + suite.True(status.Federated) + suite.True(status.Boostable) + suite.True(status.Replyable) + suite.True(status.Likeable) } func (suite *StatusTestSuite) TestGetStatusByURI() { - status, err := suite.db.GetStatusByURI(context.Background(), suite.testStatuses["local_account_1_status_1"].URI) + status, err := suite.db.GetStatusByURI(context.Background(), suite.testStatuses["local_account_2_status_3"].URI) if err != nil { suite.FailNow(err.Error()) } @@ -57,6 +61,10 @@ func (suite *StatusTestSuite) TestGetStatusByURI() { suite.Nil(status.BoostOfAccount) suite.Nil(status.InReplyTo) suite.Nil(status.InReplyToAccount) + suite.True(status.Federated) + suite.True(status.Boostable) + suite.False(status.Replyable) + suite.False(status.Likeable) } func (suite *StatusTestSuite) TestGetStatusWithExtras() { @@ -70,6 +78,10 @@ func (suite *StatusTestSuite) TestGetStatusWithExtras() { suite.NotEmpty(status.Tags) suite.NotEmpty(status.Attachments) suite.NotEmpty(status.Emojis) + suite.True(status.Federated) + suite.True(status.Boostable) + suite.True(status.Replyable) + suite.True(status.Likeable) } func (suite *StatusTestSuite) TestGetStatusWithMention() { @@ -83,6 +95,10 @@ func (suite *StatusTestSuite) TestGetStatusWithMention() { suite.NotEmpty(status.MentionIDs) suite.NotEmpty(status.InReplyToID) suite.NotEmpty(status.InReplyToAccountID) + suite.True(status.Federated) + suite.True(status.Boostable) + suite.True(status.Replyable) + suite.True(status.Likeable) } func (suite *StatusTestSuite) TestGetStatusTwice() { @@ -109,6 +125,11 @@ func (suite *StatusTestSuite) TestGetStatusChildren() { children, err := suite.db.GetStatusChildren(context.Background(), targetStatus, true, "") suite.NoError(err) suite.Len(children, 2) + for _, c := range children { + suite.Equal(targetStatus.URI, c.InReplyToURI) + suite.Equal(targetStatus.AccountID, c.InReplyToAccountID) + suite.Equal(targetStatus.ID, c.InReplyToID) + } } func TestStatusTestSuite(t *testing.T) { diff --git a/internal/federation/dereferencing/announce.go b/internal/federation/dereferencing/announce.go index d5cc5ad0c..f0b4c9e9a 100644 --- a/internal/federation/dereferencing/announce.go +++ b/internal/federation/dereferencing/announce.go @@ -60,7 +60,10 @@ func (d *deref) DereferenceAnnounce(ctx context.Context, announce *gtsmodel.Stat announce.BoostOfID = boostedStatus.ID announce.BoostOfAccountID = boostedStatus.AccountID announce.Visibility = boostedStatus.Visibility - announce.VisibilityAdvanced = boostedStatus.VisibilityAdvanced + announce.Federated = boostedStatus.Federated + announce.Boostable = boostedStatus.Boostable + announce.Replyable = boostedStatus.Replyable + announce.Likeable = boostedStatus.Likeable announce.BoostOf = boostedStatus return nil } diff --git a/internal/federation/dereferencing/status_test.go b/internal/federation/dereferencing/status_test.go index aef83f689..636870232 100644 --- a/internal/federation/dereferencing/status_test.go +++ b/internal/federation/dereferencing/status_test.go @@ -58,6 +58,10 @@ func (suite *StatusTestSuite) TestDereferenceSimpleStatus() { dbStatus, err := suite.db.GetStatusByURI(context.Background(), status.URI) suite.NoError(err) suite.Equal(status.ID, dbStatus.ID) + suite.True(dbStatus.Federated) + suite.True(dbStatus.Boostable) + suite.True(dbStatus.Replyable) + suite.True(dbStatus.Likeable) // account should be in the database now too account, err := suite.db.GetAccountByURI(context.Background(), status.AccountURI) @@ -96,6 +100,10 @@ func (suite *StatusTestSuite) TestDereferenceStatusWithMention() { dbStatus, err := suite.db.GetStatusByURI(context.Background(), status.URI) suite.NoError(err) suite.Equal(status.ID, dbStatus.ID) + suite.True(dbStatus.Federated) + suite.True(dbStatus.Boostable) + suite.True(dbStatus.Replyable) + suite.True(dbStatus.Likeable) // account should be in the database now too account, err := suite.db.GetAccountByURI(context.Background(), status.AccountURI) diff --git a/internal/gtsmodel/status.go b/internal/gtsmodel/status.go index f298e71cd..38cb6e9c1 100644 --- a/internal/gtsmodel/status.go +++ b/internal/gtsmodel/status.go @@ -57,10 +57,13 @@ type Status struct { Language string `validate:"-" bun:",nullzero"` // what language is this status written in? CreatedWithApplicationID string `validate:"required_if=Local true,omitempty,ulid" bun:"type:CHAR(26),nullzero"` // Which application was used to create this status? CreatedWithApplication *Application `validate:"-" bun:"rel:belongs-to"` // application corresponding to createdWithApplicationID - VisibilityAdvanced VisibilityAdvanced `validate:"required" bun:",nullzero,notnull" ` // advanced visibility for this status ActivityStreamsType string `validate:"required" bun:",nullzero,notnull"` // What is the activitystreams type of this status? See: https://www.w3.org/TR/activitystreams-vocabulary/#object-types. Will probably almost always be Note but who knows!. Text string `validate:"-" bun:",nullzero"` // Original text of the status without formatting - Pinned bool `validate:"-" bun:",notnull,default:false" ` // Has this status been pinned by its owner? + Pinned bool `validate:"-" bun:",notnull,default:false"` // Has this status been pinned by its owner? + Federated bool `validate:"-" bun:",notnull"` // This status will be federated beyond the local timeline(s) + Boostable bool `validate:"-" bun:",notnull"` // This status can be boosted/reblogged + Replyable bool `validate:"-" bun:",notnull"` // This status can be replied to + Likeable bool `validate:"-" bun:",notnull"` // This status can be liked/faved } // StatusToTag is an intermediate struct to facilitate the many2many relationship between a status and one or more tags. @@ -96,21 +99,3 @@ const ( // VisibilityDefault is used when no other setting can be found. VisibilityDefault Visibility = VisibilityUnlocked ) - -// VisibilityAdvanced models flags for fine-tuning visibility and interactivity of a status. -// -// All flags default to true. -// -// If PUBLIC is selected, flags will all be overwritten to TRUE regardless of what is selected. -// -// If UNLOCKED is selected, any flags can be turned on or off in any combination. -// -// If FOLLOWERS-ONLY or MUTUALS-ONLY are selected, boostable will always be FALSE. Other flags can be turned on or off as desired. -// -// If DIRECT is selected, boostable will be FALSE, and all other flags will be TRUE. -type VisibilityAdvanced struct { - Federated bool `validate:"-" bun:",notnull,default:true"` // This status will be federated beyond the local timeline(s) - Boostable bool `validate:"-" bun:",notnull,default:true"` // This status can be boosted/reblogged - Replyable bool `validate:"-" bun:",notnull,default:true"` // This status can be replied to - Likeable bool `validate:"-" bun:",notnull,default:true"` // This status can be liked/faved -} diff --git a/internal/processing/fromclientapi.go b/internal/processing/fromclientapi.go index 5f1ed325b..5fd88d8e4 100644 --- a/internal/processing/fromclientapi.go +++ b/internal/processing/fromclientapi.go @@ -51,7 +51,7 @@ func (p *processor) ProcessFromClientAPI(ctx context.Context, clientMsg messages return err } - if status.VisibilityAdvanced.Federated { + if status.Federated { return p.federateStatus(ctx, status) } case ap.ActivityFollow: diff --git a/internal/processing/status/boost.go b/internal/processing/status/boost.go index d6c4ada41..4276ca9fa 100644 --- a/internal/processing/status/boost.go +++ b/internal/processing/status/boost.go @@ -46,7 +46,7 @@ func (p *processor) Boost(ctx context.Context, requestingAccount *gtsmodel.Accou if !visible { return nil, gtserror.NewErrorNotFound(errors.New("status is not visible")) } - if !targetStatus.VisibilityAdvanced.Boostable { + if !targetStatus.Boostable { return nil, gtserror.NewErrorForbidden(errors.New("status is not boostable")) } diff --git a/internal/processing/status/fave.go b/internal/processing/status/fave.go index 195bfa56a..f3f10c43c 100644 --- a/internal/processing/status/fave.go +++ b/internal/processing/status/fave.go @@ -49,7 +49,7 @@ func (p *processor) Fave(ctx context.Context, requestingAccount *gtsmodel.Accoun if !visible { return nil, gtserror.NewErrorNotFound(errors.New("status is not visible")) } - if !targetStatus.VisibilityAdvanced.Likeable { + if !targetStatus.Likeable { return nil, gtserror.NewErrorForbidden(errors.New("status is not faveable")) } diff --git a/internal/processing/status/util.go b/internal/processing/status/util.go index 8861a532b..5ed63d919 100644 --- a/internal/processing/status/util.go +++ b/internal/processing/status/util.go @@ -33,12 +33,10 @@ import ( func (p *processor) ProcessVisibility(ctx context.Context, form *apimodel.AdvancedStatusCreateForm, accountDefaultVis gtsmodel.Visibility, status *gtsmodel.Status) error { // by default all flags are set to true - gtsAdvancedVis := gtsmodel.VisibilityAdvanced{ - Federated: true, - Boostable: true, - Replyable: true, - Likeable: true, - } + federated := true + boostable := true + replyable := true + likeable := true var vis gtsmodel.Visibility // If visibility isn't set on the form, then just take the account default. @@ -58,47 +56,50 @@ func (p *processor) ProcessVisibility(ctx context.Context, form *apimodel.Advanc case gtsmodel.VisibilityUnlocked: // for unlocked the user can set any combination of flags they like so look at them all to see if they're set and then apply them if form.Federated != nil { - gtsAdvancedVis.Federated = *form.Federated + federated = *form.Federated } if form.Boostable != nil { - gtsAdvancedVis.Boostable = *form.Boostable + boostable = *form.Boostable } if form.Replyable != nil { - gtsAdvancedVis.Replyable = *form.Replyable + replyable = *form.Replyable } if form.Likeable != nil { - gtsAdvancedVis.Likeable = *form.Likeable + likeable = *form.Likeable } case gtsmodel.VisibilityFollowersOnly, gtsmodel.VisibilityMutualsOnly: // for followers or mutuals only, boostable will *always* be false, but the other fields can be set so check and apply them - gtsAdvancedVis.Boostable = false + boostable = false if form.Federated != nil { - gtsAdvancedVis.Federated = *form.Federated + federated = *form.Federated } if form.Replyable != nil { - gtsAdvancedVis.Replyable = *form.Replyable + replyable = *form.Replyable } if form.Likeable != nil { - gtsAdvancedVis.Likeable = *form.Likeable + likeable = *form.Likeable } case gtsmodel.VisibilityDirect: // direct is pretty easy: there's only one possible setting so return it - gtsAdvancedVis.Federated = true - gtsAdvancedVis.Boostable = false - gtsAdvancedVis.Federated = true - gtsAdvancedVis.Likeable = true + federated = true + boostable = false + replyable = true + likeable = true } status.Visibility = vis - status.VisibilityAdvanced = gtsAdvancedVis + status.Federated = federated + status.Boostable = boostable + status.Replyable = replyable + status.Likeable = likeable return nil } @@ -123,7 +124,7 @@ func (p *processor) ProcessReplyToID(ctx context.Context, form *apimodel.Advance } return fmt.Errorf("status with id %s not replyable: %s", form.InReplyToID, err) } - if !repliedStatus.VisibilityAdvanced.Replyable { + if !repliedStatus.Replyable { return fmt.Errorf("status with id %s is marked as not replyable", form.InReplyToID) } diff --git a/internal/typeutils/astointernal.go b/internal/typeutils/astointernal.go index 580f999bc..9b87e03d3 100644 --- a/internal/typeutils/astointernal.go +++ b/internal/typeutils/astointernal.go @@ -325,6 +325,11 @@ func (c *converter) ASStatusToStatus(ctx context.Context, statusable ap.Statusab // advanced visibility for this status // TODO: a lot of work to be done here -- a new type needs to be created for this in go-fed/activity using ASTOOL + // for now we just set everything to true + status.Federated = true + status.Boostable = true + status.Replyable = true + status.Likeable = true // sensitive // TODO: this is a bool diff --git a/internal/typeutils/internal.go b/internal/typeutils/internal.go index 23839b9a8..b6a425732 100644 --- a/internal/typeutils/internal.go +++ b/internal/typeutils/internal.go @@ -70,7 +70,10 @@ func (c *converter) StatusToBoost(ctx context.Context, s *gtsmodel.Status, boost BoostOfID: s.ID, BoostOfAccountID: s.AccountID, Visibility: s.Visibility, - VisibilityAdvanced: s.VisibilityAdvanced, + Federated: s.Federated, + Boostable: s.Boostable, + Replyable: s.Replyable, + Likeable: s.Likeable, // attach these here for convenience -- the boosted status/account won't go in the DB // but they're needed in the processor and for the frontend. Since we have them, we can diff --git a/internal/validate/status_test.go b/internal/validate/status_test.go index 7c85414b1..333cc408d 100644 --- a/internal/validate/status_test.go +++ b/internal/validate/status_test.go @@ -63,15 +63,13 @@ func happyStatus() *gtsmodel.Status { Language: "en", CreatedWithApplicationID: "01FEBBZHF4GFVRXSJVXD0JTZZ2", CreatedWithApplication: nil, - VisibilityAdvanced: gtsmodel.VisibilityAdvanced{ - Federated: true, - Boostable: true, - Replyable: true, - Likeable: true, - }, - ActivityStreamsType: ap.ObjectNote, - Text: "Test status! #hello", - Pinned: false, + Federated: true, + Boostable: true, + Replyable: true, + Likeable: true, + ActivityStreamsType: ap.ObjectNote, + Text: "Test status! #hello", + Pinned: false, } } diff --git a/testrig/testmodels.go b/testrig/testmodels.go index 311b89e4b..91335c2a3 100644 --- a/testrig/testmodels.go +++ b/testrig/testmodels.go @@ -816,13 +816,11 @@ func NewTestStatuses() map[string]*gtsmodel.Status { Sensitive: false, Language: "en", CreatedWithApplicationID: "01F8MGXQRHYF5QPMTMXP78QC2F", - VisibilityAdvanced: gtsmodel.VisibilityAdvanced{ - Federated: true, - Boostable: true, - Replyable: true, - Likeable: true, - }, - ActivityStreamsType: ap.ObjectNote, + Federated: true, + Boostable: true, + Replyable: true, + Likeable: true, + ActivityStreamsType: ap.ObjectNote, }, "admin_account_status_2": { ID: "01F8MHAAY43M6RJ473VQFCVH37", @@ -841,13 +839,11 @@ func NewTestStatuses() map[string]*gtsmodel.Status { Sensitive: true, Language: "en", CreatedWithApplicationID: "01F8MGXQRHYF5QPMTMXP78QC2F", - VisibilityAdvanced: gtsmodel.VisibilityAdvanced{ - Federated: true, - Boostable: true, - Replyable: true, - Likeable: true, - }, - ActivityStreamsType: ap.ObjectNote, + Federated: true, + Boostable: true, + Replyable: true, + Likeable: true, + ActivityStreamsType: ap.ObjectNote, }, "admin_account_status_3": { ID: "01FF25D5Q0DH7CHD57CTRS6WK0", @@ -868,13 +864,11 @@ func NewTestStatuses() map[string]*gtsmodel.Status { Sensitive: false, Language: "en", CreatedWithApplicationID: "01F8MGXQRHYF5QPMTMXP78QC2F", - VisibilityAdvanced: gtsmodel.VisibilityAdvanced{ - Federated: true, - Boostable: true, - Replyable: true, - Likeable: true, - }, - ActivityStreamsType: ap.ObjectNote, + Federated: true, + Boostable: true, + Replyable: true, + Likeable: true, + ActivityStreamsType: ap.ObjectNote, }, "local_account_1_status_1": { ID: "01F8MHAMCHF6Y650WCRSCP4WMY", @@ -893,13 +887,11 @@ func NewTestStatuses() map[string]*gtsmodel.Status { Sensitive: true, Language: "en", CreatedWithApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG", - VisibilityAdvanced: gtsmodel.VisibilityAdvanced{ - Federated: true, - Boostable: true, - Replyable: true, - Likeable: true, - }, - ActivityStreamsType: ap.ObjectNote, + Federated: true, + Boostable: true, + Replyable: true, + Likeable: true, + ActivityStreamsType: ap.ObjectNote, }, "local_account_1_status_2": { ID: "01F8MHAYFKS4KMXF8K5Y1C0KRN", @@ -918,13 +910,11 @@ func NewTestStatuses() map[string]*gtsmodel.Status { Sensitive: false, Language: "en", CreatedWithApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG", - VisibilityAdvanced: gtsmodel.VisibilityAdvanced{ - Federated: false, - Boostable: true, - Replyable: true, - Likeable: true, - }, - ActivityStreamsType: ap.ObjectNote, + Federated: false, + Boostable: true, + Replyable: true, + Likeable: true, + ActivityStreamsType: ap.ObjectNote, }, "local_account_1_status_3": { ID: "01F8MHBBN8120SYH7D5S050MGK", @@ -943,13 +933,11 @@ func NewTestStatuses() map[string]*gtsmodel.Status { Sensitive: false, Language: "en", CreatedWithApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG", - VisibilityAdvanced: gtsmodel.VisibilityAdvanced{ - Federated: true, - Boostable: false, - Replyable: false, - Likeable: false, - }, - ActivityStreamsType: ap.ObjectNote, + Federated: true, + Boostable: false, + Replyable: false, + Likeable: false, + ActivityStreamsType: ap.ObjectNote, }, "local_account_1_status_4": { ID: "01F8MH82FYRXD2RC6108DAJ5HB", @@ -969,13 +957,11 @@ func NewTestStatuses() map[string]*gtsmodel.Status { Sensitive: false, Language: "en", CreatedWithApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG", - VisibilityAdvanced: gtsmodel.VisibilityAdvanced{ - Federated: true, - Boostable: true, - Replyable: true, - Likeable: true, - }, - ActivityStreamsType: ap.ObjectNote, + Federated: true, + Boostable: true, + Replyable: true, + Likeable: true, + ActivityStreamsType: ap.ObjectNote, }, "local_account_1_status_5": { ID: "01FCTA44PW9H1TB328S9AQXKDS", @@ -995,13 +981,11 @@ func NewTestStatuses() map[string]*gtsmodel.Status { Sensitive: false, Language: "en", CreatedWithApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG", - VisibilityAdvanced: gtsmodel.VisibilityAdvanced{ - Federated: true, - Boostable: true, - Replyable: true, - Likeable: true, - }, - ActivityStreamsType: ap.ObjectNote, + Federated: true, + Boostable: true, + Replyable: true, + Likeable: true, + ActivityStreamsType: ap.ObjectNote, }, "local_account_2_status_1": { ID: "01F8MHBQCBTDKN6X5VHGMMN4MA", @@ -1020,13 +1004,11 @@ func NewTestStatuses() map[string]*gtsmodel.Status { Sensitive: true, Language: "en", CreatedWithApplicationID: "01F8MGYG9E893WRHW0TAEXR8GJ", - VisibilityAdvanced: gtsmodel.VisibilityAdvanced{ - Federated: true, - Boostable: true, - Replyable: true, - Likeable: true, - }, - ActivityStreamsType: ap.ObjectNote, + Federated: true, + Boostable: true, + Replyable: true, + Likeable: true, + ActivityStreamsType: ap.ObjectNote, }, "local_account_2_status_2": { ID: "01F8MHC0H0A7XHTVH5F596ZKBM", @@ -1045,13 +1027,11 @@ func NewTestStatuses() map[string]*gtsmodel.Status { Sensitive: true, Language: "en", CreatedWithApplicationID: "01F8MGYG9E893WRHW0TAEXR8GJ", - VisibilityAdvanced: gtsmodel.VisibilityAdvanced{ - Federated: true, - Boostable: true, - Replyable: false, - Likeable: true, - }, - ActivityStreamsType: ap.ObjectNote, + Federated: true, + Boostable: true, + Replyable: false, + Likeable: true, + ActivityStreamsType: ap.ObjectNote, }, "local_account_2_status_3": { ID: "01F8MHC8VWDRBQR0N1BATDDEM5", @@ -1070,13 +1050,11 @@ func NewTestStatuses() map[string]*gtsmodel.Status { Sensitive: true, Language: "en", CreatedWithApplicationID: "01F8MGYG9E893WRHW0TAEXR8GJ", - VisibilityAdvanced: gtsmodel.VisibilityAdvanced{ - Federated: true, - Boostable: true, - Replyable: false, - Likeable: false, - }, - ActivityStreamsType: ap.ObjectNote, + Federated: true, + Boostable: true, + Replyable: false, + Likeable: false, + ActivityStreamsType: ap.ObjectNote, }, "local_account_2_status_4": { ID: "01F8MHCP5P2NWYQ416SBA0XSEV", @@ -1095,12 +1073,11 @@ func NewTestStatuses() map[string]*gtsmodel.Status { Sensitive: true, Language: "en", CreatedWithApplicationID: "01F8MGYG9E893WRHW0TAEXR8GJ", - VisibilityAdvanced: gtsmodel.VisibilityAdvanced{ - Federated: false, - Boostable: false, - Replyable: true, - Likeable: true, - }, + Federated: false, + Boostable: false, + Replyable: true, + Likeable: true, + ActivityStreamsType: ap.ObjectNote, }, "local_account_2_status_5": { @@ -1123,13 +1100,11 @@ func NewTestStatuses() map[string]*gtsmodel.Status { Sensitive: false, Language: "en", CreatedWithApplicationID: "01F8MGYG9E893WRHW0TAEXR8GJ", - VisibilityAdvanced: gtsmodel.VisibilityAdvanced{ - Federated: true, - Boostable: true, - Replyable: true, - Likeable: true, - }, - ActivityStreamsType: ap.ObjectNote, + Federated: true, + Boostable: true, + Replyable: true, + Likeable: true, + ActivityStreamsType: ap.ObjectNote, }, } }