Use OrderedCollection by default for collections.
The 'liked', 'likes', 'followers', and 'following' collections now default to the 'OrderedCollection' type instead of throwing an error if the client application does not supply an IRI, 'Collection', or 'OrderedCollection' type on the actor or object.
このコミットが含まれているのは:
コミット
f8b24eef88
@ -1,6 +1,10 @@
|
||||
master (Release Candidate for v0.2.0)
|
||||
|
||||
* Begin FederateAPI unofficial implementation report.
|
||||
* Use 'OrderedCollection' as the default type for 'likes', 'liked',
|
||||
'following', and 'followers' properties if the actor or object does not
|
||||
have an IRI, 'Collection', or 'OrderedCollection' set for these
|
||||
properties.
|
||||
* Examine the IRI of 'objects' when applying the Origin Check policy for Update
|
||||
and Delete activities.
|
||||
* If a federated Activity was already received, do not execute its side effects
|
||||
|
16
pub/fed.go
16
pub/fed.go
@ -803,7 +803,9 @@ func (f *federator) handleClientLike(ctx context.Context, deliverable *bool) fun
|
||||
*loc = actor.GetLikedOrderedCollection()
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("cannot determine type of actor liked")
|
||||
*loc = &vocab.OrderedCollection{}
|
||||
actor.SetLikedOrderedCollection(*loc)
|
||||
return false, nil
|
||||
}
|
||||
if err := f.addAllObjectsToActorCollection(ctx, getter, s.Raw(), true); err != nil {
|
||||
return err
|
||||
@ -990,7 +992,9 @@ func (f *federator) handleFollow(c context.Context, inboxURL *url.URL) func(s *s
|
||||
*loc = object.GetFollowersOrderedCollection()
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("cannot determine type of object followers")
|
||||
*loc = &vocab.OrderedCollection{}
|
||||
object.SetFollowersOrderedCollection(*loc)
|
||||
return false, nil
|
||||
}
|
||||
var err error
|
||||
if ownsAny, err = f.addAllActorsToObjectCollection(c, getter, raw, true); err != nil {
|
||||
@ -1046,7 +1050,9 @@ func (f *federator) handleAccept(c context.Context) func(s *streams.Accept) erro
|
||||
*loc = actor.GetFollowingOrderedCollection()
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("cannot determine type of actor following")
|
||||
*loc = &vocab.OrderedCollection{}
|
||||
actor.SetFollowingOrderedCollection(*loc)
|
||||
return false, nil
|
||||
}
|
||||
if err := f.addAllObjectsToActorCollection(c, getter, follow, true); err != nil {
|
||||
return err
|
||||
@ -1227,7 +1233,9 @@ func (f *federator) handleLike(c context.Context) func(s *streams.Like) error {
|
||||
*loc = object.GetLikesOrderedCollection()
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("cannot determine type of object likes")
|
||||
*loc = &vocab.OrderedCollection{}
|
||||
object.SetLikesOrderedCollection(*loc)
|
||||
return false, nil
|
||||
}
|
||||
if _, err := f.addActivityToObjectCollection(c, getter, s.Raw(), true); err != nil {
|
||||
return err
|
||||
|
331
pub/fed_test.go
331
pub/fed_test.go
@ -2750,6 +2750,146 @@ func TestPostInbox_Follow_AutoAccept(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostInbox_Follow_AutoAcceptDefaultFollowersOrderedCollection(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(testFollow))))
|
||||
gotOnFollow := 0
|
||||
fedApp.onFollow = func(c context.Context, s *streams.Follow) FollowResponse {
|
||||
gotOnFollow++
|
||||
return AutomaticAccept
|
||||
}
|
||||
gotNewSigner := 0
|
||||
fedApp.newSigner = func() (httpsig.Signer, error) {
|
||||
gotNewSigner++
|
||||
s, _, err := httpsig.NewSigner([]httpsig.Algorithm{httpsig.RSA_SHA256}, nil, httpsig.Signature)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return s, err
|
||||
}
|
||||
gotPrivateKey := 0
|
||||
var gotPrivateKeyIRI *url.URL
|
||||
fedApp.privateKey = func(boxIRI *url.URL) (crypto.PrivateKey, string, error) {
|
||||
gotPrivateKey++
|
||||
gotPrivateKeyIRI = boxIRI
|
||||
return testPrivateKey, testPublicKeyId, nil
|
||||
}
|
||||
fedCb.follow = func(c context.Context, s *streams.Follow) error {
|
||||
return nil
|
||||
}
|
||||
gotHttpDo := 0
|
||||
var httpActorRequest *http.Request
|
||||
var httpDeliveryRequest *http.Request
|
||||
httpClient.do = func(req *http.Request) (*http.Response, error) {
|
||||
gotHttpDo++
|
||||
if gotHttpDo == 1 {
|
||||
httpActorRequest = req
|
||||
actorResp := &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: ioutil.NopCloser(bytes.NewBuffer(sallyActorJSON)),
|
||||
}
|
||||
return actorResp, nil
|
||||
} else if gotHttpDo == 2 {
|
||||
httpDeliveryRequest = req
|
||||
okResp := &http.Response{
|
||||
StatusCode: http.StatusOK,
|
||||
Body: ioutil.NopCloser(bytes.NewBuffer([]byte{})),
|
||||
}
|
||||
return okResp, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
gotDoDelivery := 0
|
||||
var doDeliveryURL *url.URL
|
||||
var bytesToSend []byte
|
||||
d.do = func(b []byte, u *url.URL, toDo func(b []byte, u *url.URL) error) {
|
||||
gotDoDelivery++
|
||||
doDeliveryURL = u
|
||||
bytesToSend = b
|
||||
if err := toDo(b, u); err != nil {
|
||||
t.Fatalf("Unexpected error in MockDeliverer.Do: %s", err)
|
||||
}
|
||||
}
|
||||
gotOwns := 0
|
||||
var ownsIRI *url.URL
|
||||
app.MockFederateApp.owns = func(c context.Context, id *url.URL) bool {
|
||||
gotOwns++
|
||||
ownsIRI = id
|
||||
return true
|
||||
}
|
||||
gotGet := 0
|
||||
var getIRI *url.URL
|
||||
app.MockFederateApp.get = func(c context.Context, id *url.URL, rw RWType) (PubObject, error) {
|
||||
if rw != ReadWrite {
|
||||
t.Fatalf("expected RWType of %d, got %d", ReadWrite, rw)
|
||||
}
|
||||
gotGet++
|
||||
getIRI = id
|
||||
samActor := &vocab.Person{}
|
||||
samActor.SetInboxAnyURI(samIRIInbox)
|
||||
samActor.SetId(samIRI)
|
||||
return samActor, nil
|
||||
}
|
||||
gotSet := 0
|
||||
var setObject PubObject
|
||||
app.MockFederateApp.set = func(c context.Context, o PubObject) error {
|
||||
gotSet++
|
||||
if gotSet == 1 {
|
||||
setObject = o
|
||||
}
|
||||
return nil
|
||||
}
|
||||
expected := &vocab.Accept{}
|
||||
expected.AppendObject(testFollow)
|
||||
expected.AppendToIRI(sallyIRI)
|
||||
expectedFollowers := &vocab.OrderedCollection{}
|
||||
expectedFollowers.AppendOrderedItemsIRI(sallyIRI)
|
||||
expectedActor := &vocab.Person{}
|
||||
expectedActor.SetInboxAnyURI(samIRIInbox)
|
||||
expectedActor.SetId(samIRI)
|
||||
expectedActor.SetFollowersOrderedCollection(expectedFollowers)
|
||||
handled, err := p.PostInbox(context.Background(), resp, req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !handled {
|
||||
t.Fatalf("expected handled, got !handled")
|
||||
} else if gotOnFollow != 1 {
|
||||
t.Fatalf("expected %d, got %d", 1, gotOnFollow)
|
||||
} else if gotNewSigner != 1 {
|
||||
t.Fatalf("expected %d, got %d", 1, gotNewSigner)
|
||||
} else if gotPrivateKey != 1 {
|
||||
t.Fatalf("expected %d, got %d", 1, gotPrivateKey)
|
||||
} else if s := gotPrivateKeyIRI.String(); s != testInboxURI {
|
||||
t.Fatalf("expected %s, got %s", testInboxURI, s)
|
||||
} else if gotHttpDo != 2 {
|
||||
t.Fatalf("expected %d, got %d", 2, gotHttpDo)
|
||||
} else if s := httpActorRequest.URL.String(); s != sallyIRIString {
|
||||
t.Fatalf("expected %s, got %s", sallyIRIString, s)
|
||||
} else if s := httpDeliveryRequest.URL.String(); s != sallyIRIInboxString {
|
||||
t.Fatalf("expected %s, got %s", sallyIRIInboxString, s)
|
||||
} else if gotDoDelivery != 1 {
|
||||
t.Fatalf("expected %d, got %d", 1, gotDoDelivery)
|
||||
} else if doDeliveryURL.String() != sallyIRIInboxString {
|
||||
t.Fatalf("expected %s, got %s", sallyIRIInboxString, doDeliveryURL.String())
|
||||
} else if err := VocabEquals(bytes.NewBuffer(bytesToSend), expected); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if gotOwns != 1 {
|
||||
t.Fatalf("expected %d, got %d", 1, gotOwns)
|
||||
} else if ownsIRI.String() != samIRIString {
|
||||
t.Fatalf("expected %s, got %s", samIRIString, ownsIRI.String())
|
||||
} else if gotGet != 1 {
|
||||
t.Fatalf("expected %d, got %d", 1, gotGet)
|
||||
} else if getIRI.String() != samIRIString {
|
||||
t.Fatalf("expected %s, got %s", samIRIString, getIRI.String())
|
||||
} else if gotSet != 2 {
|
||||
t.Fatalf("expected %d, got %d", 2, gotSet)
|
||||
} else if err := PubObjectEquals(setObject, expectedActor); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostInbox_Follow_DoesNotAddForAutoAcceptIfAlreadyPresent(t *testing.T) {
|
||||
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
|
||||
PreparePubberPostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
|
||||
@ -3153,6 +3293,69 @@ func TestPostInbox_Accept_AcceptFollowAddsToFollowersIfOwned(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostInbox_Accept_AcceptFollowAddsToDefaultFollowersOrderedCollection(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(testAcceptFollow))))
|
||||
gotOwns := 0
|
||||
var ownsIRI *url.URL
|
||||
app.MockFederateApp.owns = func(c context.Context, id *url.URL) bool {
|
||||
gotOwns++
|
||||
ownsIRI = id
|
||||
return true
|
||||
}
|
||||
gotGet := 0
|
||||
var getIRI *url.URL
|
||||
app.MockFederateApp.get = func(c context.Context, id *url.URL, rw RWType) (PubObject, error) {
|
||||
if rw != ReadWrite {
|
||||
t.Fatalf("expected RWType of %d, got %d", ReadWrite, rw)
|
||||
}
|
||||
gotGet++
|
||||
getIRI = id
|
||||
sallyActor := &vocab.Person{}
|
||||
sallyActor.SetInboxAnyURI(sallyIRIInbox)
|
||||
sallyActor.SetId(sallyIRI)
|
||||
return sallyActor, nil
|
||||
}
|
||||
gotSet := 0
|
||||
var setObject PubObject
|
||||
app.MockFederateApp.set = func(c context.Context, o PubObject) error {
|
||||
gotSet++
|
||||
if gotSet == 1 {
|
||||
setObject = o
|
||||
}
|
||||
return nil
|
||||
}
|
||||
fedCb.accept = func(c context.Context, s *streams.Accept) error {
|
||||
return nil
|
||||
}
|
||||
expectedFollowing := &vocab.OrderedCollection{}
|
||||
expectedFollowing.AppendOrderedItemsIRI(samIRI)
|
||||
expectedActor := &vocab.Person{}
|
||||
expectedActor.SetInboxAnyURI(sallyIRIInbox)
|
||||
expectedActor.SetId(sallyIRI)
|
||||
expectedActor.SetFollowingOrderedCollection(expectedFollowing)
|
||||
handled, err := p.PostInbox(context.Background(), resp, req)
|
||||
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 ownsIRI.String() != sallyIRIString {
|
||||
t.Fatalf("expected %s, got %s", sallyIRIString, ownsIRI.String())
|
||||
} else if gotGet != 1 {
|
||||
t.Fatalf("expected %d, got %d", 1, gotGet)
|
||||
} else if getIRI.String() != sallyIRIString {
|
||||
t.Fatalf("expected %s, got %s", sallyIRIString, getIRI.String())
|
||||
} else if gotSet != 2 {
|
||||
t.Fatalf("expected %d, got %d", 2, gotSet)
|
||||
} else if err := PubObjectEquals(setObject, expectedActor); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostInbox_Accept_AcceptFollowDoesNotAddIfAlreadyInCollection(t *testing.T) {
|
||||
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
|
||||
PreparePubberPostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
|
||||
@ -3823,6 +4026,71 @@ func TestPostInbox_Like_AddsToLikeCollection(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostInbox_Like_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(testLikeNote))))
|
||||
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 %d, got %d", 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
|
||||
}
|
||||
fedCb.like = func(c context.Context, s *streams.Like) error {
|
||||
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.SetLikesOrderedCollection(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_Like_DoesNotAddLikeToCollectionIfAlreadyPresent(t *testing.T) {
|
||||
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
|
||||
PreparePubberPostInboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
|
||||
@ -5812,6 +6080,69 @@ func TestPostOutbox_Like_AddsToLikedCollection(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostOutbox_Like_AddsToDefaultOrderedCollection(t *testing.T) {
|
||||
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
|
||||
PreparePubberPostOutboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
|
||||
resp := httptest.NewRecorder()
|
||||
req := Sign(ActivityPubRequest(httptest.NewRequest("POST", testOutboxURI, bytes.NewBuffer(MustSerialize(testLikeNote)))))
|
||||
gotOwns := 0
|
||||
var gotOwnsIri *url.URL
|
||||
app.MockFederateApp.owns = func(c context.Context, iri *url.URL) bool {
|
||||
gotOwns++
|
||||
gotOwnsIri = iri
|
||||
return true
|
||||
}
|
||||
gotGet := 0
|
||||
var gotGetIri *url.URL
|
||||
app.MockFederateApp.get = func(c context.Context, iri *url.URL, rw RWType) (PubObject, error) {
|
||||
if rw != ReadWrite {
|
||||
t.Fatalf("expected RWType of %d, got %d", ReadWrite, rw)
|
||||
}
|
||||
gotGet++
|
||||
gotGetIri = iri
|
||||
v := &vocab.Person{}
|
||||
v.AppendNameString("Sally")
|
||||
v.SetId(sallyIRI)
|
||||
return v, nil
|
||||
}
|
||||
gotSet := 0
|
||||
var gotSetObj PubObject
|
||||
app.MockFederateApp.set = func(c context.Context, o PubObject) error {
|
||||
gotSet++
|
||||
if gotSet == 1 {
|
||||
gotSetObj = o
|
||||
}
|
||||
return nil
|
||||
}
|
||||
socialCb.like = func(c context.Context, s *streams.Like) error {
|
||||
return nil
|
||||
}
|
||||
handled, err := p.PostOutbox(context.Background(), resp, req)
|
||||
expectedLikes := &vocab.OrderedCollection{}
|
||||
expectedLikes.AppendOrderedItemsIRI(noteIRI)
|
||||
expectedActor := &vocab.Person{}
|
||||
expectedActor.AppendNameString("Sally")
|
||||
expectedActor.SetId(sallyIRI)
|
||||
expectedActor.SetLikedOrderedCollection(expectedLikes)
|
||||
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 gotOwnsString := gotOwnsIri.String(); gotOwnsString != sallyIRIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, sallyIRIString)
|
||||
} else if gotGet != 1 {
|
||||
t.Fatalf("expected %d, got %d", 1, gotGet)
|
||||
} else if gotGetString := gotGetIri.String(); gotGetString != sallyIRIString {
|
||||
t.Fatalf("expected %s, got %s", noteURIString, sallyIRIString)
|
||||
} else if gotSet != 3 {
|
||||
t.Fatalf("expected %d, got %d", 3, gotSet)
|
||||
} else if err := PubObjectEquals(gotSetObj, expectedActor); err != nil {
|
||||
t.Fatalf("set obj: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostOutbox_Like_DoesNotAddIfAlreadyLiked(t *testing.T) {
|
||||
app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p := NewPubberTest(t)
|
||||
PreparePubberPostOutboxTest(t, app, socialApp, fedApp, socialCb, fedCb, d, httpClient, p)
|
||||
|
読み込み中…
新しいイシューから参照
ユーザーをブロックする