[feature] Federate reports to remote instance as Flag (if desired) (#1386)

* reports federate out, we did it lxds

* fix optional line start (should be optional slash)
This commit is contained in:
tobi 2023-01-27 14:48:11 +01:00 committed by GitHub
commit 3283900b0d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 207 additions and 69 deletions

View file

@ -188,6 +188,8 @@ type TypeConverter interface {
//
// Appropriate 'next' and 'prev' fields will be created based on the highest and lowest IDs present in the statuses slice.
StatusesToASOutboxPage(ctx context.Context, outboxID string, maxID string, minID string, statuses []*gtsmodel.Status) (vocab.ActivityStreamsOrderedCollectionPage, error)
// ReportToASFlag converts a gts model report into an activitystreams FLAG, suitable for federation.
ReportToASFlag(ctx context.Context, r *gtsmodel.Report) (vocab.ActivityStreamsFlag, error)
/*
INTERNAL (gts) MODEL TO INTERNAL MODEL

View file

@ -1295,3 +1295,53 @@ func (c *converter) OutboxToASCollection(ctx context.Context, outboxID string) (
return collection, nil
}
func (c *converter) ReportToASFlag(ctx context.Context, r *gtsmodel.Report) (vocab.ActivityStreamsFlag, error) {
flag := streams.NewActivityStreamsFlag()
flagIDProp := streams.NewJSONLDIdProperty()
idURI, err := url.Parse(r.URI)
if err != nil {
return nil, fmt.Errorf("error parsing url %s: %w", r.URI, err)
}
flagIDProp.SetIRI(idURI)
flag.SetJSONLDId(flagIDProp)
// for privacy, set the actor as the INSTANCE ACTOR,
// not as the actor who created the report
instanceAccount, err := c.db.GetInstanceAccount(ctx, "")
if err != nil {
return nil, fmt.Errorf("error getting instance account: %w", err)
}
instanceAccountIRI, err := url.Parse(instanceAccount.URI)
if err != nil {
return nil, fmt.Errorf("error parsing url %s: %w", instanceAccount.URI, err)
}
flagActorProp := streams.NewActivityStreamsActorProperty()
flagActorProp.AppendIRI(instanceAccountIRI)
flag.SetActivityStreamsActor(flagActorProp)
// content should be the comment submitted when the report was created
contentProp := streams.NewActivityStreamsContentProperty()
contentProp.AppendXMLSchemaString(r.Comment)
flag.SetActivityStreamsContent(contentProp)
// set at least the target account uri as the object of the flag
objectProp := streams.NewActivityStreamsObjectProperty()
targetAccountURI, err := url.Parse(r.TargetAccount.URI)
if err != nil {
return nil, fmt.Errorf("error parsing url %s: %w", r.TargetAccount.URI, err)
}
objectProp.AppendIRI(targetAccountURI)
// also set status URIs if they were provided with the report
for _, s := range r.Statuses {
statusURI, err := url.Parse(s.URI)
if err != nil {
return nil, fmt.Errorf("error parsing url %s: %w", s.URI, err)
}
objectProp.AppendIRI(statusURI)
}
flag.SetActivityStreamsObject(objectProp)
return flag, nil
}

View file

@ -510,6 +510,40 @@ func (suite *InternalToASTestSuite) TestSelfBoostFollowersOnlyToAS() {
}`, string(bytes))
}
func (suite *InternalToASTestSuite) TestReportToAS() {
ctx := context.Background()
testReport := suite.testReports["local_account_2_report_remote_account_1"]
account := suite.testAccounts["local_account_2"]
targetAccount := suite.testAccounts["remote_account_1"]
statuses := []*gtsmodel.Status{suite.testStatuses["remote_account_1_status_1"]}
testReport.Account = account
testReport.TargetAccount = targetAccount
testReport.Statuses = statuses
flag, err := suite.typeconverter.ReportToASFlag(ctx, testReport)
suite.NoError(err)
ser, err := streams.Serialize(flag)
suite.NoError(err)
bytes, err := json.MarshalIndent(ser, "", " ")
suite.NoError(err)
suite.Equal(`{
"@context": "https://www.w3.org/ns/activitystreams",
"actor": "http://localhost:8080/users/localhost:8080",
"content": "dark souls sucks, please yeet this nerd",
"id": "http://localhost:8080/reports/01GP3AWY4CRDVRNZKW0TEAMB5R",
"object": [
"http://fossbros-anonymous.io/users/foss_satan",
"http://fossbros-anonymous.io/users/foss_satan/statuses/01FVW7JHQFSFK166WWKR8CBA6M"
],
"type": "Flag"
}`, string(bytes))
}
func TestInternalToASTestSuite(t *testing.T) {
suite.Run(t, new(InternalToASTestSuite))
}