summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2024-11-28 15:37:37 +0000
committerLibravatar GitHub <noreply@github.com>2024-11-28 15:37:37 +0000
commitd9f67efae512673c826b27daeae404a6051d9817 (patch)
treefe89c62e3f43eb285d6ed64b2b407986fe1917bb /internal
parentpulls in the latest exif-terminator version with bugfix and performance optim... (diff)
downloadgotosocial-d9f67efae512673c826b27daeae404a6051d9817.tar.xz
send out poll votes as separate create activities given that no other AP servers support multiple objects in a single activity (#3582)
Diffstat (limited to 'internal')
-rw-r--r--internal/processing/workers/federate.go17
-rw-r--r--internal/typeutils/internaltoas.go42
-rw-r--r--internal/typeutils/internaltoas_test.go64
3 files changed, 75 insertions, 48 deletions
diff --git a/internal/processing/workers/federate.go b/internal/processing/workers/federate.go
index a0fd6bf69..8c08c42b7 100644
--- a/internal/processing/workers/federate.go
+++ b/internal/processing/workers/federate.go
@@ -217,18 +217,23 @@ func (f *federate) CreatePollVote(ctx context.Context, poll *gtsmodel.Poll, vote
return err
}
- // Convert vote to AS Create with vote choices as Objects.
- create, err := f.converter.PollVoteToASCreate(ctx, vote)
+ // Convert vote to AS Creates with vote choices as Objects.
+ creates, err := f.converter.PollVoteToASCreates(ctx, vote)
if err != nil {
return gtserror.Newf("error converting to notes: %w", err)
}
- // Send the Create via the Actor's outbox.
- if _, err := f.FederatingActor().Send(ctx, outboxIRI, create); err != nil {
- return gtserror.Newf("error sending Create activity via outbox %s: %w", outboxIRI, err)
+ var errs gtserror.MultiError
+
+ // Send each create activity.
+ actor := f.FederatingActor()
+ for _, create := range creates {
+ if _, err := actor.Send(ctx, outboxIRI, create); err != nil {
+ errs.Appendf("error sending Create activity via outbox %s: %w", outboxIRI, err)
+ }
}
- return nil
+ return errs.Combine()
}
func (f *federate) DeleteStatus(ctx context.Context, status *gtsmodel.Status) error {
diff --git a/internal/typeutils/internaltoas.go b/internal/typeutils/internaltoas.go
index ed8bc1d8d..a81e5d2c0 100644
--- a/internal/typeutils/internaltoas.go
+++ b/internal/typeutils/internaltoas.go
@@ -1701,10 +1701,14 @@ func (c *Converter) ReportToASFlag(ctx context.Context, r *gtsmodel.Report) (voc
// PollVoteToASCreate converts a vote on a poll into a Create
// activity, suitable for federation, with each choice in the
// vote appended as a Note to the Create's Object field.
-func (c *Converter) PollVoteToASCreate(
+//
+// TODO: as soon as other AP server implementations support
+// the use of multiple objects in a single create, update this
+// to return just the one create event again.
+func (c *Converter) PollVoteToASCreates(
ctx context.Context,
vote *gtsmodel.PollVote,
-) (vocab.ActivityStreamsCreate, error) {
+) ([]vocab.ActivityStreamsCreate, error) {
if len(vote.Choices) == 0 {
panic("no vote.Choices")
}
@@ -1743,22 +1747,25 @@ func (c *Converter) PollVoteToASCreate(
return nil, gtserror.Newf("invalid account uri: %w", err)
}
- // Allocate Create activity and address 'To' poll author.
- create := streams.NewActivityStreamsCreate()
- ap.AppendTo(create, pollAuthorIRI)
+ // Parse each choice to a Note and add it to the list of Creates.
+ creates := make([]vocab.ActivityStreamsCreate, len(vote.Choices))
+ for i, choice := range vote.Choices {
+
+ // Allocate Create activity and address 'To' poll author.
+ create := streams.NewActivityStreamsCreate()
+ ap.AppendTo(create, pollAuthorIRI)
- // Create ID formatted as: {$voterIRI}/activity#vote/{$statusIRI}.
- id := author.URI + "/activity#vote/" + poll.Status.URI
- ap.MustSet(ap.SetJSONLDIdStr, ap.WithJSONLDId(create), id)
+ // Create ID formatted as: {$voterIRI}/activity#vote{$index}/{$statusIRI}.
+ createID := fmt.Sprintf("%s/activity#vote%d/%s", author.URI, i, poll.Status.URI)
+ ap.MustSet(ap.SetJSONLDIdStr, ap.WithJSONLDId(create), createID)
- // Set Create actor appropriately.
- ap.AppendActorIRIs(create, authorIRI)
+ // Set Create actor appropriately.
+ ap.AppendActorIRIs(create, authorIRI)
- // Set publish time for activity.
- ap.SetPublished(create, vote.CreatedAt)
+ // Set publish time for activity.
+ ap.SetPublished(create, vote.CreatedAt)
- // Parse each choice to a Note and add it to the Create.
- for _, choice := range vote.Choices {
+ // Allocate new note to hold the vote.
note := streams.NewActivityStreamsNote()
// For AP IRI generate from author URI + poll ID + vote choice.
@@ -1775,11 +1782,14 @@ func (c *Converter) PollVoteToASCreate(
ap.AppendInReplyTo(note, statusIRI)
ap.AppendTo(note, pollAuthorIRI)
- // Append this note as Create Object.
+ // Append this note to the Create Object.
appendStatusableToActivity(create, note, false)
+
+ // Set create in slice.
+ creates[i] = create
}
- return create, nil
+ return creates, nil
}
// populateValuesForProp appends the given PolicyValues
diff --git a/internal/typeutils/internaltoas_test.go b/internal/typeutils/internaltoas_test.go
index a97eee2b8..c847cfc93 100644
--- a/internal/typeutils/internaltoas_test.go
+++ b/internal/typeutils/internaltoas_test.go
@@ -1104,43 +1104,55 @@ func (suite *InternalToASTestSuite) TestPinnedStatusesToASOneItem() {
func (suite *InternalToASTestSuite) TestPollVoteToASCreate() {
vote := suite.testPollVotes["remote_account_1_status_2_poll_vote_local_account_1"]
- create, err := suite.typeconverter.PollVoteToASCreate(context.Background(), vote)
- if err != nil {
- suite.FailNow(err.Error())
- }
+ creates, err := suite.typeconverter.PollVoteToASCreates(context.Background(), vote)
+ suite.NoError(err)
+ suite.Len(creates, 2)
+
+ createI0, err := ap.Serialize(creates[0])
+ suite.NoError(err)
- createI, err := ap.Serialize(create)
+ createI1, err := ap.Serialize(creates[1])
suite.NoError(err)
- bytes, err := json.MarshalIndent(createI, "", " ")
+ bytes0, err := json.MarshalIndent(createI0, "", " ")
+ suite.NoError(err)
+
+ bytes1, err := json.MarshalIndent(createI1, "", " ")
suite.NoError(err)
suite.Equal(`{
"@context": "https://www.w3.org/ns/activitystreams",
"actor": "http://localhost:8080/users/the_mighty_zork",
- "id": "http://localhost:8080/users/the_mighty_zork/activity#vote/http://fossbros-anonymous.io/users/foss_satan/statuses/01HEN2QRFA8H3C6QPN7RD4KSR6",
- "object": [
- {
- "attributedTo": "http://localhost:8080/users/the_mighty_zork",
- "id": "http://localhost:8080/users/the_mighty_zork#01HEN2R65468ZG657C4ZPHJ4EX/votes/1",
- "inReplyTo": "http://fossbros-anonymous.io/users/foss_satan/statuses/01HEN2QRFA8H3C6QPN7RD4KSR6",
- "name": "tissues",
- "to": "http://fossbros-anonymous.io/users/foss_satan",
- "type": "Note"
- },
- {
- "attributedTo": "http://localhost:8080/users/the_mighty_zork",
- "id": "http://localhost:8080/users/the_mighty_zork#01HEN2R65468ZG657C4ZPHJ4EX/votes/2",
- "inReplyTo": "http://fossbros-anonymous.io/users/foss_satan/statuses/01HEN2QRFA8H3C6QPN7RD4KSR6",
- "name": "financial times",
- "to": "http://fossbros-anonymous.io/users/foss_satan",
- "type": "Note"
- }
- ],
+ "id": "http://localhost:8080/users/the_mighty_zork/activity#vote0/http://fossbros-anonymous.io/users/foss_satan/statuses/01HEN2QRFA8H3C6QPN7RD4KSR6",
+ "object": {
+ "attributedTo": "http://localhost:8080/users/the_mighty_zork",
+ "id": "http://localhost:8080/users/the_mighty_zork#01HEN2R65468ZG657C4ZPHJ4EX/votes/1",
+ "inReplyTo": "http://fossbros-anonymous.io/users/foss_satan/statuses/01HEN2QRFA8H3C6QPN7RD4KSR6",
+ "name": "tissues",
+ "to": "http://fossbros-anonymous.io/users/foss_satan",
+ "type": "Note"
+ },
"published": "2021-09-11T11:45:37+02:00",
"to": "http://fossbros-anonymous.io/users/foss_satan",
"type": "Create"
-}`, string(bytes))
+}`, string(bytes0))
+
+ suite.Equal(`{
+ "@context": "https://www.w3.org/ns/activitystreams",
+ "actor": "http://localhost:8080/users/the_mighty_zork",
+ "id": "http://localhost:8080/users/the_mighty_zork/activity#vote1/http://fossbros-anonymous.io/users/foss_satan/statuses/01HEN2QRFA8H3C6QPN7RD4KSR6",
+ "object": {
+ "attributedTo": "http://localhost:8080/users/the_mighty_zork",
+ "id": "http://localhost:8080/users/the_mighty_zork#01HEN2R65468ZG657C4ZPHJ4EX/votes/2",
+ "inReplyTo": "http://fossbros-anonymous.io/users/foss_satan/statuses/01HEN2QRFA8H3C6QPN7RD4KSR6",
+ "name": "financial times",
+ "to": "http://fossbros-anonymous.io/users/foss_satan",
+ "type": "Note"
+ },
+ "published": "2021-09-11T11:45:37+02:00",
+ "to": "http://fossbros-anonymous.io/users/foss_satan",
+ "type": "Create"
+}`, string(bytes1))
}
func (suite *InternalToASTestSuite) TestInteractionReqToASAcceptAnnounce() {