From 83277d57c9a01cae478cded960f900597f3f8ab7 Mon Sep 17 00:00:00 2001 From: Cory Slep Date: Tue, 21 Aug 2018 20:49:24 +0200 Subject: [PATCH] Announce activities now add to shares collections on objects. --- pub/fed.go | 31 +++++- pub/fed_test.go | 257 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 286 insertions(+), 2 deletions(-) diff --git a/pub/fed.go b/pub/fed.go index 47488d6..2883cab 100644 --- a/pub/fed.go +++ b/pub/fed.go @@ -1051,8 +1051,8 @@ func (f *federator) getPostInboxResolver(c context.Context, inboxURL *url.URL) * UndoCallback: f.handleUndo(c), BlockCallback: f.handleBlock(c), // Other activities whose behaviors are not examined by the pub - // package, and are passed through to extensions of the - // Callbacker interface. + // package (except for Announce), and are passed through to + // extensions of the Callbacker interface. AnnounceCallback: f.handleAnnounce(c), ArriveCallback: f.handleArrive(c), DislikeCallback: f.handleDislike(c), @@ -1492,6 +1492,33 @@ func (f *federator) handleBlock(c context.Context) func(s *streams.Block) error func (f *federator) handleAnnounce(c context.Context) func(s *streams.Announce) error { return func(s *streams.Announce) error { + getter := func(object vocab.ObjectType, lc *vocab.CollectionType, loc *vocab.OrderedCollectionType) (bool, error) { + if object.IsSharesAnyURI() { + pObj, err := f.App.Get(c, object.GetSharesAnyURI(), ReadWrite) + if err != nil { + return true, err + } + ok := false + if *lc, ok = pObj.(vocab.CollectionType); !ok { + if *loc, ok = pObj.(vocab.OrderedCollectionType); !ok { + return true, fmt.Errorf("object shares collection not CollectionType nor OrderedCollectionType") + } + } + return true, nil + } else if object.IsSharesCollection() { + *lc = object.GetSharesCollection() + return false, nil + } else if object.IsSharesOrderedCollection() { + *loc = object.GetSharesOrderedCollection() + return false, nil + } + *loc = &vocab.OrderedCollection{} + object.SetSharesOrderedCollection(*loc) + return false, nil + } + if _, err := f.addActivityToObjectCollection(c, getter, s.Raw(), true); err != nil { + return err + } if t, ok := f.ServerCallbacker.(callbackerAnnounce); ok { return t.Announce(c, s) } diff --git a/pub/fed_test.go b/pub/fed_test.go index 144ccd7..f873f8d 100644 --- a/pub/fed_test.go +++ b/pub/fed_test.go @@ -77,6 +77,7 @@ var ( testRemoveNote *vocab.Remove testLikeNote *vocab.Like testUndoLike *vocab.Undo + testAnnounceNote *vocab.Announce testBlock *vocab.Block testClientExpectedNote *vocab.Note testClientExpectedCreateNote *vocab.Create @@ -263,6 +264,11 @@ func init() { testBlock.SetId(noteActivityIRI) testBlock.AppendActorObject(sallyActor) testBlock.AppendObject(samActor) + testAnnounceNote = &vocab.Announce{} + testAnnounceNote.SetId(noteActivityIRI) + testAnnounceNote.AppendActorObject(sallyActor) + testAnnounceNote.AppendObject(testNote) + testAnnounceNote.AppendToObject(samActor) testClientExpectedNote = &vocab.Note{} testClientExpectedNote.SetId(testNewIRI2) @@ -8057,3 +8063,254 @@ func TestPostInbox_CallbackerExtensions(t *testing.T) { } } } + +func TestPostInbox_Announce_AddsToSharesCollection(t *testing.T) { + app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t) + PreparePubberPostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p) + resp := httptest.NewRecorder() + req := ActivityPubRequest(httptest.NewRequest("POST", testInboxURI, bytes.NewBuffer(MustSerialize(testAnnounceNote)))) + gotOwns := 0 + var gotOwnsId *url.URL + app.MockFederateApp.owns = func(c context.Context, id *url.URL) bool { + gotOwns++ + gotOwnsId = id + return true + } + gotGet := 0 + var gotGetId *url.URL + app.MockFederateApp.get = func(c context.Context, id *url.URL, rw RWType) (PubObject, error) { + if rw != ReadWrite { + t.Fatalf("expected RWType of %v, got %v", ReadWrite, rw) + } + gotGet++ + gotGetId = id + v := &vocab.Note{} + v.SetId(noteIRI) + v.AppendNameString(noteName) + v.AppendContentString("This is a simple note") + v.SetSharesCollection(&vocab.Collection{}) + return v, nil + } + gotSet := 0 + var gotSetObject PubObject + app.MockFederateApp.set = func(c context.Context, target PubObject) error { + gotSet++ + if gotSet == 1 { + gotSetObject = target + } + return nil + } + handled, err := p.PostInbox(context.Background(), resp, req) + expected := &vocab.Collection{} + expected.AppendItemsIRI(noteActivityIRI) + expectedNote := &vocab.Note{} + expectedNote.SetId(noteIRI) + expectedNote.AppendNameString(noteName) + expectedNote.AppendContentString("This is a simple note") + expectedNote.SetSharesCollection(expected) + if err != nil { + t.Fatal(err) + } else if !handled { + t.Fatalf("expected handled, got !handled") + } else if gotOwns != 1 { + t.Fatalf("expected %d, got %d", 1, gotOwns) + } else if gotOwnsId.String() != noteURIString { + t.Fatalf("expected %s, got %s", noteURIString, gotOwnsId.String()) + } else if gotGet != 1 { + t.Fatalf("expected %d, got %d", 1, gotGet) + } else if gotGetId.String() != noteURIString { + t.Fatalf("expected %s, got %s", noteURIString, gotGetId.String()) + } else if gotSet != 2 { + t.Fatalf("expected %d, got %d", 2, gotSet) + } else if err := PubObjectEquals(gotSetObject, expectedNote); err != nil { + t.Fatalf("unexpected callback object: %s", err) + } +} + +func TestPostInbox_Announce_AddsToDefaultOrderedCollection(t *testing.T) { + app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t) + PreparePubberPostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p) + resp := httptest.NewRecorder() + req := ActivityPubRequest(httptest.NewRequest("POST", testInboxURI, bytes.NewBuffer(MustSerialize(testAnnounceNote)))) + gotOwns := 0 + var gotOwnsId *url.URL + app.MockFederateApp.owns = func(c context.Context, id *url.URL) bool { + gotOwns++ + gotOwnsId = id + return true + } + gotGet := 0 + var gotGetId *url.URL + app.MockFederateApp.get = func(c context.Context, id *url.URL, rw RWType) (PubObject, error) { + if rw != ReadWrite { + t.Fatalf("expected RWType of %v, got %v", ReadWrite, rw) + } + gotGet++ + gotGetId = id + v := &vocab.Note{} + v.SetId(noteIRI) + v.AppendNameString(noteName) + v.AppendContentString("This is a simple note") + return v, nil + } + gotSet := 0 + var gotSetObject PubObject + app.MockFederateApp.set = func(c context.Context, target PubObject) error { + gotSet++ + if gotSet == 1 { + gotSetObject = target + } + return nil + } + handled, err := p.PostInbox(context.Background(), resp, req) + expected := &vocab.OrderedCollection{} + expected.AppendOrderedItemsIRI(noteActivityIRI) + expectedNote := &vocab.Note{} + expectedNote.SetId(noteIRI) + expectedNote.AppendNameString(noteName) + expectedNote.AppendContentString("This is a simple note") + expectedNote.SetSharesOrderedCollection(expected) + if err != nil { + t.Fatal(err) + } else if !handled { + t.Fatalf("expected handled, got !handled") + } else if gotOwns != 1 { + t.Fatalf("expected %d, got %d", 1, gotOwns) + } else if gotOwnsId.String() != noteURIString { + t.Fatalf("expected %s, got %s", noteURIString, gotOwnsId.String()) + } else if gotGet != 1 { + t.Fatalf("expected %d, got %d", 1, gotGet) + } else if gotGetId.String() != noteURIString { + t.Fatalf("expected %s, got %s", noteURIString, gotGetId.String()) + } else if gotSet != 2 { + t.Fatalf("expected %d, got %d", 2, gotSet) + } else if err := PubObjectEquals(gotSetObject, expectedNote); err != nil { + t.Fatalf("unexpected callback object: %s", err) + } +} + +func TestPostInbox_Announce_DoesNotAddSharesToCollectionIfAlreadyPresent(t *testing.T) { + app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t) + PreparePubberPostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p) + resp := httptest.NewRecorder() + req := ActivityPubRequest(httptest.NewRequest("POST", testInboxURI, bytes.NewBuffer(MustSerialize(testAnnounceNote)))) + app.MockFederateApp.owns = func(c context.Context, id *url.URL) bool { + return true + } + app.MockFederateApp.get = func(c context.Context, id *url.URL, rw RWType) (PubObject, error) { + shares := &vocab.Collection{} + shares.AppendItemsIRI(noteActivityIRI) + v := &vocab.Note{} + v.SetId(noteIRI) + v.AppendNameString(noteName) + v.AppendContentString("This is a simple note") + v.SetSharesCollection(shares) + return v, nil + } + gotSet := 0 + var gotSetObject PubObject + app.MockFederateApp.set = func(c context.Context, target PubObject) error { + gotSet++ + if gotSet == 1 { + gotSetObject = target + } + return nil + } + handled, err := p.PostInbox(context.Background(), resp, req) + expected := &vocab.OrderedCollection{} + expected.AppendOrderedItemsIRI(noteActivityIRI) + if err != nil { + t.Fatal(err) + } else if !handled { + t.Fatalf("expected handled, got !handled") + } else if gotSet != 1 { + t.Fatalf("expected %d, got %d", 1, gotSet) + } else if err := PubObjectEquals(gotSetObject, expected); err != nil { + t.Fatalf("unexpected callback object: %s", err) + } +} + +func TestPostInbox_Announce_AddsToSharesOrderedCollection(t *testing.T) { + app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t) + PreparePubberPostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p) + resp := httptest.NewRecorder() + req := ActivityPubRequest(httptest.NewRequest("POST", testInboxURI, bytes.NewBuffer(MustSerialize(testAnnounceNote)))) + app.MockFederateApp.owns = func(c context.Context, id *url.URL) bool { + return true + } + app.MockFederateApp.get = func(c context.Context, id *url.URL, rw RWType) (PubObject, error) { + v := &vocab.Note{} + v.SetId(noteIRI) + v.AppendNameString(noteName) + v.AppendContentString("This is a simple note") + v.SetSharesOrderedCollection(&vocab.OrderedCollection{}) + return v, nil + } + gotSet := 0 + var gotSetObject PubObject + app.MockFederateApp.set = func(c context.Context, target PubObject) error { + gotSet++ + if gotSet == 1 { + gotSetObject = target + } + return nil + } + handled, err := p.PostInbox(context.Background(), resp, req) + expected := &vocab.OrderedCollection{} + expected.AppendOrderedItemsIRI(noteActivityIRI) + expectedNote := &vocab.Note{} + expectedNote.SetId(noteIRI) + expectedNote.AppendNameString(noteName) + expectedNote.AppendContentString("This is a simple note") + expectedNote.SetSharesOrderedCollection(expected) + if err != nil { + t.Fatal(err) + } else if !handled { + t.Fatalf("expected handled, got !handled") + } else if err := PubObjectEquals(gotSetObject, expectedNote); err != nil { + t.Fatalf("unexpected callback object: %s", err) + } +} + +func TestPostInbox_Announce_AddsToSharesIRI(t *testing.T) { + app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t) + PreparePubberPostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p) + resp := httptest.NewRecorder() + req := ActivityPubRequest(httptest.NewRequest("POST", testInboxURI, bytes.NewBuffer(MustSerialize(testAnnounceNote)))) + app.MockFederateApp.owns = func(c context.Context, id *url.URL) bool { + return true + } + app.MockFederateApp.get = func(c context.Context, id *url.URL, rw RWType) (PubObject, error) { + if *id == *noteIRI { + v := &vocab.Note{} + v.SetId(noteIRI) + v.AppendNameString(noteName) + v.AppendContentString("This is a simple note") + v.SetSharesAnyURI(testNewIRI) + return v, nil + } else if *id == *testNewIRI { + return &vocab.OrderedCollection{}, nil + } + t.Fatalf("unexpected get(%s)", id) + return nil, nil + } + gotSet := 0 + var gotSetObject PubObject + app.MockFederateApp.set = func(c context.Context, target PubObject) error { + gotSet++ + if gotSet == 1 { + gotSetObject = target + } + return nil + } + handled, err := p.PostInbox(context.Background(), resp, req) + expected := &vocab.OrderedCollection{} + expected.AppendOrderedItemsIRI(noteActivityIRI) + if err != nil { + t.Fatal(err) + } else if !handled { + t.Fatalf("expected handled, got !handled") + } else if err := PubObjectEquals(gotSetObject, expected); err != nil { + t.Fatalf("unexpected callback object: %s", err) + } +}