diff options
author | 2023-06-13 16:47:56 +0200 | |
---|---|---|
committer | 2023-06-13 15:47:56 +0100 | |
commit | 24fbdf2b0a820684b69b10893e82cdb1a76ca14d (patch) | |
tree | d44a092d0bffb8159e4844bfaf4ef84a82f41e2e /internal/federation/federatingprotocol_test.go | |
parent | [docs] Add certificates and firewalling to advanced (#1888) (diff) | |
download | gotosocial-24fbdf2b0a820684b69b10893e82cdb1a76ca14d.tar.xz |
[chore] Refactor AP authentication, other small bits of tidying up (#1874)
Diffstat (limited to 'internal/federation/federatingprotocol_test.go')
-rw-r--r-- | internal/federation/federatingprotocol_test.go | 595 |
1 files changed, 329 insertions, 266 deletions
diff --git a/internal/federation/federatingprotocol_test.go b/internal/federation/federatingprotocol_test.go index 3350099b0..8da6859dd 100644 --- a/internal/federation/federatingprotocol_test.go +++ b/internal/federation/federatingprotocol_test.go @@ -18,7 +18,10 @@ package federation_test import ( + "bytes" "context" + "encoding/json" + "io" "net/http" "net/http/httptest" "net/url" @@ -27,7 +30,7 @@ import ( "github.com/go-fed/httpsig" "github.com/stretchr/testify/suite" "github.com/superseriousbusiness/gotosocial/internal/ap" - "github.com/superseriousbusiness/gotosocial/internal/federation" + "github.com/superseriousbusiness/gotosocial/internal/gtscontext" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/testrig" ) @@ -36,342 +39,402 @@ type FederatingProtocolTestSuite struct { FederatorStandardTestSuite } -func (suite *FederatingProtocolTestSuite) TestPostInboxRequestBodyHook1() { - // the activity we're gonna use - activity := suite.testActivities["dm_for_zork"] - - httpClient := testrig.NewMockHTTPClient(nil, "../../testrig/media") - tc := testrig.NewTestTransportController(&suite.state, httpClient) - // setup module being tested - federator := federation.NewFederator(&suite.state, testrig.NewTestFederatingDB(&suite.state), tc, suite.tc, testrig.NewTestMediaManager(&suite.state)) - - // setup request - ctx := context.Background() - request := httptest.NewRequest(http.MethodPost, "http://localhost:8080/users/the_mighty_zork/inbox", nil) // the endpoint we're hitting - request.Header.Set("Signature", activity.SignatureHeader) - - // trigger the function being tested, and return the new context it creates - newContext, err := federator.PostInboxRequestBodyHook(ctx, request, activity.Activity) - suite.NoError(err) - suite.NotNil(newContext) - - involvedIRIsI := newContext.Value(ap.ContextOtherInvolvedIRIs) - involvedIRIs, ok := involvedIRIsI.([]*url.URL) - if !ok { - suite.FailNow("couldn't get involved IRIs from context") +func (suite *FederatingProtocolTestSuite) postInboxRequestBodyHook( + ctx context.Context, + receivingAccount *gtsmodel.Account, + activity testrig.ActivityWithSignature, +) context.Context { + raw, err := ap.Serialize(activity.Activity) + if err != nil { + suite.FailNow(err.Error()) } - suite.Len(involvedIRIs, 1) - suite.Contains(involvedIRIs, testrig.URLMustParse("http://localhost:8080/users/the_mighty_zork")) -} - -func (suite *FederatingProtocolTestSuite) TestPostInboxRequestBodyHook2() { - // the activity we're gonna use - activity := suite.testActivities["reply_to_turtle_for_zork"] - - httpClient := testrig.NewMockHTTPClient(nil, "../../testrig/media") - tc := testrig.NewTestTransportController(&suite.state, httpClient) - - // setup module being tested - federator := federation.NewFederator(&suite.state, testrig.NewTestFederatingDB(&suite.state), tc, suite.tc, testrig.NewTestMediaManager(&suite.state)) - - // setup request - ctx := context.Background() - request := httptest.NewRequest(http.MethodPost, "http://localhost:8080/users/the_mighty_zork/inbox", nil) // the endpoint we're hitting - request.Header.Set("Signature", activity.SignatureHeader) - - // trigger the function being tested, and return the new context it creates - newContext, err := federator.PostInboxRequestBodyHook(ctx, request, activity.Activity) - suite.NoError(err) - suite.NotNil(newContext) - - involvedIRIsI := newContext.Value(ap.ContextOtherInvolvedIRIs) - involvedIRIs, ok := involvedIRIsI.([]*url.URL) - if !ok { - suite.FailNow("couldn't get involved IRIs from context") + b, err := json.Marshal(raw) + if err != nil { + suite.FailNow(err.Error()) } - - suite.Len(involvedIRIs, 2) - suite.Contains(involvedIRIs, testrig.URLMustParse("http://localhost:8080/users/1happyturtle")) - suite.Contains(involvedIRIs, testrig.URLMustParse("http://fossbros-anonymous.io/users/foss_satan/followers")) -} - -func (suite *FederatingProtocolTestSuite) TestPostInboxRequestBodyHook3() { - // the activity we're gonna use - activity := suite.testActivities["reply_to_turtle_for_turtle"] - - httpClient := testrig.NewMockHTTPClient(nil, "../../testrig/media") - tc := testrig.NewTestTransportController(&suite.state, httpClient) - - // setup module being tested - federator := federation.NewFederator(&suite.state, testrig.NewTestFederatingDB(&suite.state), tc, suite.tc, testrig.NewTestMediaManager(&suite.state)) - - // setup request - ctx := context.Background() - request := httptest.NewRequest(http.MethodPost, "http://localhost:8080/users/1happyturtle/inbox", nil) // the endpoint we're hitting - request.Header.Set("Signature", activity.SignatureHeader) - - // trigger the function being tested, and return the new context it creates - newContext, err := federator.PostInboxRequestBodyHook(ctx, request, activity.Activity) suite.NoError(err) - suite.NotNil(newContext) + request := httptest.NewRequest(http.MethodPost, receivingAccount.InboxURI, bytes.NewBuffer(b)) + request.Header.Set("Signature", activity.SignatureHeader) + request.Header.Set("Date", activity.DateHeader) + request.Header.Set("Digest", activity.DigestHeader) - involvedIRIsI := newContext.Value(ap.ContextOtherInvolvedIRIs) - involvedIRIs, ok := involvedIRIsI.([]*url.URL) - if !ok { - suite.FailNow("couldn't get involved IRIs from context") + newContext, err := suite.federator.PostInboxRequestBodyHook(ctx, request, activity.Activity) + if err != nil { + suite.FailNow(err.Error()) } - suite.Len(involvedIRIs, 2) - suite.Contains(involvedIRIs, testrig.URLMustParse("http://localhost:8080/users/1happyturtle")) - suite.Contains(involvedIRIs, testrig.URLMustParse("http://fossbros-anonymous.io/users/foss_satan/followers")) + return newContext } -func (suite *FederatingProtocolTestSuite) TestAuthenticatePostInbox() { - // the activity we're gonna use - activity := suite.testActivities["dm_for_zork"] - sendingAccount := suite.testAccounts["remote_account_1"] - inboxAccount := suite.testAccounts["local_account_1"] - - httpClient := testrig.NewMockHTTPClient(nil, "../../testrig/media") - tc := testrig.NewTestTransportController(&suite.state, httpClient) +func (suite *FederatingProtocolTestSuite) authenticatePostInbox( + ctx context.Context, + receivingAccount *gtsmodel.Account, + activity testrig.ActivityWithSignature, +) (context.Context, bool, []byte, int) { + raw, err := ap.Serialize(activity.Activity) + if err != nil { + suite.FailNow(err.Error()) + } - // now setup module being tested, with the mock transport controller - federator := federation.NewFederator(&suite.state, testrig.NewTestFederatingDB(&suite.state), tc, suite.tc, testrig.NewTestMediaManager(&suite.state)) + b, err := json.Marshal(raw) + if err != nil { + suite.FailNow(err.Error()) + } - request := httptest.NewRequest(http.MethodPost, "http://localhost:8080/users/the_mighty_zork/inbox", nil) - // we need these headers for the request to be validated + request := httptest.NewRequest(http.MethodPost, receivingAccount.InboxURI, bytes.NewBuffer(b)) request.Header.Set("Signature", activity.SignatureHeader) request.Header.Set("Date", activity.DateHeader) request.Header.Set("Digest", activity.DigestHeader) verifier, err := httpsig.NewVerifier(request) - suite.NoError(err) + if err != nil { + suite.FailNow(err.Error()) + } - ctx := context.Background() - // by the time AuthenticatePostInbox is called, PostInboxRequestBodyHook should have already been called, - // which should have set the account and username onto the request. We can replicate that behavior here: - ctxWithAccount := context.WithValue(ctx, ap.ContextReceivingAccount, inboxAccount) - ctxWithVerifier := context.WithValue(ctxWithAccount, ap.ContextRequestingPublicKeyVerifier, verifier) - ctxWithSignature := context.WithValue(ctxWithVerifier, ap.ContextRequestingPublicKeySignature, activity.SignatureHeader) + ctx = gtscontext.SetReceivingAccount(ctx, receivingAccount) + ctx = gtscontext.SetHTTPSignatureVerifier(ctx, verifier) + ctx = gtscontext.SetHTTPSignature(ctx, activity.SignatureHeader) + ctx = gtscontext.SetHTTPSignaturePubKeyID(ctx, testrig.URLMustParse(verifier.KeyId())) - // we can pass this recorder as a writer and read it back after recorder := httptest.NewRecorder() + newContext, authed, err := suite.federator.AuthenticatePostInbox(ctx, recorder, request) + if err != nil { + suite.FailNow(err.Error()) + } - // trigger the function being tested, and return the new context it creates - newContext, authed, err := federator.AuthenticatePostInbox(ctxWithSignature, recorder, request) - suite.NoError(err) - suite.True(authed) + res := recorder.Result() + defer res.Body.Close() - // since we know this account already it should be set on the context - requestingAccountI := newContext.Value(ap.ContextRequestingAccount) - suite.NotNil(requestingAccountI) - requestingAccount, ok := requestingAccountI.(*gtsmodel.Account) - suite.True(ok) - suite.Equal(sendingAccount.Username, requestingAccount.Username) + b, err = io.ReadAll(res.Body) + if err != nil { + suite.FailNow(err.Error()) + } + + return newContext, authed, b, res.StatusCode } -func (suite *FederatingProtocolTestSuite) TestAuthenticatePostGone() { - // the activity we're gonna use - activity := suite.testActivities["delete_https://somewhere.mysterious/users/rest_in_piss#main-key"] - inboxAccount := suite.testAccounts["local_account_1"] +func (suite *FederatingProtocolTestSuite) TestPostInboxRequestBodyHookDM() { + var ( + receivingAccount = suite.testAccounts["local_account_1"] + activity = suite.testActivities["dm_for_zork"] + ) + + ctx := suite.postInboxRequestBodyHook( + context.Background(), + receivingAccount, + activity, + ) + + otherIRIs := gtscontext.OtherIRIs(ctx) + otherIRIStrs := make([]string, 0, len(otherIRIs)) + for _, i := range otherIRIs { + otherIRIStrs = append(otherIRIStrs, i.String()) + } - httpClient := testrig.NewMockHTTPClient(nil, "../../testrig/media") - tc := testrig.NewTestTransportController(&suite.state, httpClient) + suite.Equal([]string{ + "http://fossbros-anonymous.io/users/foss_satan/statuses/5424b153-4553-4f30-9358-7b92f7cd42f6/activity", + "http://localhost:8080/users/the_mighty_zork", + "http://fossbros-anonymous.io/users/foss_satan/statuses/5424b153-4553-4f30-9358-7b92f7cd42f6", + }, otherIRIStrs) +} - // now setup module being tested, with the mock transport controller - federator := federation.NewFederator(&suite.state, testrig.NewTestFederatingDB(&suite.state), tc, suite.tc, testrig.NewTestMediaManager(&suite.state)) +func (suite *FederatingProtocolTestSuite) TestPostInboxRequestBodyHookReply() { + var ( + receivingAccount = suite.testAccounts["local_account_1"] + activity = suite.testActivities["reply_to_turtle_for_zork"] + ) + + ctx := suite.postInboxRequestBodyHook( + context.Background(), + receivingAccount, + activity, + ) + + otherIRIs := gtscontext.OtherIRIs(ctx) + otherIRIStrs := make([]string, 0, len(otherIRIs)) + for _, i := range otherIRIs { + otherIRIStrs = append(otherIRIStrs, i.String()) + } - request := httptest.NewRequest(http.MethodPost, "http://localhost:8080/users/the_mighty_zork/inbox", nil) - // we need these headers for the request to be validated - request.Header.Set("Signature", activity.SignatureHeader) - request.Header.Set("Date", activity.DateHeader) - request.Header.Set("Digest", activity.DigestHeader) + suite.Equal([]string{ + "http://fossbros-anonymous.io/users/foss_satan/statuses/2f1195a6-5cb0-4475-adf5-92ab9a0147fe", + "http://fossbros-anonymous.io/users/foss_satan/followers", + "http://localhost:8080/users/1happyturtle", + }, otherIRIStrs) +} - verifier, err := httpsig.NewVerifier(request) - suite.NoError(err) +func (suite *FederatingProtocolTestSuite) TestPostInboxRequestBodyHookReplyToReply() { + var ( + receivingAccount = suite.testAccounts["local_account_2"] + activity = suite.testActivities["reply_to_turtle_for_turtle"] + ) + + ctx := suite.postInboxRequestBodyHook( + context.Background(), + receivingAccount, + activity, + ) + + otherIRIs := gtscontext.OtherIRIs(ctx) + otherIRIStrs := make([]string, 0, len(otherIRIs)) + for _, i := range otherIRIs { + otherIRIStrs = append(otherIRIStrs, i.String()) + } - ctx := context.Background() - // by the time AuthenticatePostInbox is called, PostInboxRequestBodyHook should have already been called, - // which should have set the account and username onto the request. We can replicate that behavior here: - ctxWithAccount := context.WithValue(ctx, ap.ContextReceivingAccount, inboxAccount) - ctxWithVerifier := context.WithValue(ctxWithAccount, ap.ContextRequestingPublicKeyVerifier, verifier) - ctxWithSignature := context.WithValue(ctxWithVerifier, ap.ContextRequestingPublicKeySignature, activity.SignatureHeader) + suite.Equal([]string{ + "http://fossbros-anonymous.io/users/foss_satan/statuses/2f1195a6-5cb0-4475-adf5-92ab9a0147fe", + "http://fossbros-anonymous.io/users/foss_satan/followers", + "http://localhost:8080/users/1happyturtle", + }, otherIRIStrs) +} - // we can pass this recorder as a writer and read it back after - recorder := httptest.NewRecorder() +func (suite *FederatingProtocolTestSuite) TestPostInboxRequestBodyHookAnnounceForwardedToTurtle() { + var ( + receivingAccount = suite.testAccounts["local_account_2"] + activity = suite.testActivities["announce_forwarded_1_turtle"] + ) + + ctx := suite.postInboxRequestBodyHook( + context.Background(), + receivingAccount, + activity, + ) + + otherIRIs := gtscontext.OtherIRIs(ctx) + otherIRIStrs := make([]string, 0, len(otherIRIs)) + for _, i := range otherIRIs { + otherIRIStrs = append(otherIRIStrs, i.String()) + } - // trigger the function being tested, and return the new context it creates - _, authed, err := federator.AuthenticatePostInbox(ctxWithSignature, recorder, request) - suite.NoError(err) - suite.False(authed) - suite.Equal(http.StatusAccepted, recorder.Code) + suite.Equal([]string{ + "http://fossbros-anonymous.io/users/foss_satan/first_announce", + "http://example.org/users/Some_User", + "http://example.org/users/Some_User/statuses/afaba698-5740-4e32-a702-af61aa543bc1", + }, otherIRIStrs) } -func (suite *FederatingProtocolTestSuite) TestAuthenticatePostGoneNoTombstoneYet() { - // delete the relevant tombstone - if err := suite.db.DeleteTombstone(context.Background(), suite.testTombstones["https://somewhere.mysterious/users/rest_in_piss#main-key"].ID); err != nil { - suite.FailNow(err.Error()) +func (suite *FederatingProtocolTestSuite) TestPostInboxRequestBodyHookAnnounceForwardedToZork() { + var ( + receivingAccount = suite.testAccounts["local_account_1"] + activity = suite.testActivities["announce_forwarded_2_zork"] + ) + + ctx := suite.postInboxRequestBodyHook( + context.Background(), + receivingAccount, + activity, + ) + + otherIRIs := gtscontext.OtherIRIs(ctx) + otherIRIStrs := make([]string, 0, len(otherIRIs)) + for _, i := range otherIRIs { + otherIRIStrs = append(otherIRIStrs, i.String()) } - // the activity we're gonna use - activity := suite.testActivities["delete_https://somewhere.mysterious/users/rest_in_piss#main-key"] - inboxAccount := suite.testAccounts["local_account_1"] + suite.Equal([]string{ + "http://fossbros-anonymous.io/users/foss_satan/second_announce", + "http://example.org/users/Some_User", + "http://example.org/users/Some_User/statuses/afaba698-5740-4e32-a702-af61aa543bc1", + }, otherIRIStrs) +} - httpClient := testrig.NewMockHTTPClient(nil, "../../testrig/media") - tc := testrig.NewTestTransportController(&suite.state, httpClient) +func (suite *FederatingProtocolTestSuite) TestAuthenticatePostInbox() { + var ( + activity = suite.testActivities["dm_for_zork"] + receivingAccount = suite.testAccounts["local_account_1"] + ) + + ctx, authed, resp, code := suite.authenticatePostInbox( + context.Background(), + receivingAccount, + activity, + ) + + suite.NotNil(gtscontext.RequestingAccount(ctx)) + suite.True(authed) + suite.Equal([]byte{}, resp) + suite.Equal(http.StatusOK, code) +} - // now setup module being tested, with the mock transport controller - federator := federation.NewFederator(&suite.state, testrig.NewTestFederatingDB(&suite.state), tc, suite.tc, testrig.NewTestMediaManager(&suite.state)) +func (suite *FederatingProtocolTestSuite) TestAuthenticatePostGoneWithTombstone() { + var ( + activity = suite.testActivities["delete_https://somewhere.mysterious/users/rest_in_piss#main-key"] + receivingAccount = suite.testAccounts["local_account_1"] + ) - request := httptest.NewRequest(http.MethodPost, "http://localhost:8080/users/the_mighty_zork/inbox", nil) - // we need these headers for the request to be validated - request.Header.Set("Signature", activity.SignatureHeader) - request.Header.Set("Date", activity.DateHeader) - request.Header.Set("Digest", activity.DigestHeader) + ctx, authed, resp, code := suite.authenticatePostInbox( + context.Background(), + receivingAccount, + activity, + ) - verifier, err := httpsig.NewVerifier(request) - suite.NoError(err) + // Tombstone exists for this account, should simply return accepted. + suite.Nil(gtscontext.RequestingAccount(ctx)) + suite.False(authed) + suite.Equal([]byte{}, resp) + suite.Equal(http.StatusAccepted, code) +} - ctx := context.Background() - // by the time AuthenticatePostInbox is called, PostInboxRequestBodyHook should have already been called, - // which should have set the account and username onto the request. We can replicate that behavior here: - ctxWithAccount := context.WithValue(ctx, ap.ContextReceivingAccount, inboxAccount) - ctxWithVerifier := context.WithValue(ctxWithAccount, ap.ContextRequestingPublicKeyVerifier, verifier) - ctxWithSignature := context.WithValue(ctxWithVerifier, ap.ContextRequestingPublicKeySignature, activity.SignatureHeader) +func (suite *FederatingProtocolTestSuite) TestAuthenticatePostGoneNoTombstone() { + var ( + activity = suite.testActivities["delete_https://somewhere.mysterious/users/rest_in_piss#main-key"] + receivingAccount = suite.testAccounts["local_account_1"] + testTombstone = suite.testTombstones["https://somewhere.mysterious/users/rest_in_piss#main-key"] + ) - // we can pass this recorder as a writer and read it back after - recorder := httptest.NewRecorder() + // Delete the tombstone; it'll have to be created again. + if err := suite.state.DB.DeleteTombstone(context.Background(), testTombstone.ID); err != nil { + suite.FailNow(err.Error()) + } - // trigger the function being tested, and return the new context it creates - _, authed, err := federator.AuthenticatePostInbox(ctxWithSignature, recorder, request) - suite.NoError(err) - suite.False(authed) - suite.Equal(http.StatusAccepted, recorder.Code) + ctx, authed, resp, code := suite.authenticatePostInbox( + context.Background(), + receivingAccount, + activity, + ) - // there should be a tombstone in the db now for this account - exists, err := suite.db.TombstoneExistsWithURI(ctx, "https://somewhere.mysterious/users/rest_in_piss#main-key") + suite.Nil(gtscontext.RequestingAccount(ctx)) + suite.False(authed) + suite.Equal([]byte{}, resp) + suite.Equal(http.StatusAccepted, code) + + // Tombstone should be back, baby! + exists, err := suite.state.DB.TombstoneExistsWithURI( + context.Background(), + "https://somewhere.mysterious/users/rest_in_piss#main-key", + ) suite.NoError(err) suite.True(exists) } -func (suite *FederatingProtocolTestSuite) TestBlocked1() { - httpClient := testrig.NewMockHTTPClient(nil, "../../testrig/media") - tc := testrig.NewTestTransportController(&suite.state, httpClient) - federator := federation.NewFederator(&suite.state, testrig.NewTestFederatingDB(&suite.state), tc, suite.tc, testrig.NewTestMediaManager(&suite.state)) - - sendingAccount := suite.testAccounts["remote_account_1"] - inboxAccount := suite.testAccounts["local_account_1"] - otherInvolvedIRIs := []*url.URL{} - actorIRIs := []*url.URL{ - testrig.URLMustParse(sendingAccount.URI), - } +func (suite *FederatingProtocolTestSuite) blocked( + ctx context.Context, + receivingAccount *gtsmodel.Account, + requestingAccount *gtsmodel.Account, + otherIRIs []*url.URL, + actorIRIs []*url.URL, +) (bool, error) { + ctx = gtscontext.SetReceivingAccount(ctx, receivingAccount) + ctx = gtscontext.SetRequestingAccount(ctx, requestingAccount) + ctx = gtscontext.SetOtherIRIs(ctx, otherIRIs) + return suite.federator.Blocked(ctx, actorIRIs) +} - ctx := context.Background() - ctxWithReceivingAccount := context.WithValue(ctx, ap.ContextReceivingAccount, inboxAccount) - ctxWithRequestingAccount := context.WithValue(ctxWithReceivingAccount, ap.ContextRequestingAccount, sendingAccount) - ctxWithOtherInvolvedIRIs := context.WithValue(ctxWithRequestingAccount, ap.ContextOtherInvolvedIRIs, otherInvolvedIRIs) +func (suite *FederatingProtocolTestSuite) TestBlockedNoProblem() { + var ( + receivingAccount = suite.testAccounts["local_account_1"] + requestingAccount = suite.testAccounts["remote_account_1"] + otherIRIs = []*url.URL{} + actorIRIs = []*url.URL{ + testrig.URLMustParse(requestingAccount.URI), + } + ) + + blocked, err := suite.blocked( + context.Background(), + receivingAccount, + requestingAccount, + otherIRIs, + actorIRIs, + ) - blocked, err := federator.Blocked(ctxWithOtherInvolvedIRIs, actorIRIs) suite.NoError(err) suite.False(blocked) } -func (suite *FederatingProtocolTestSuite) TestBlocked2() { - httpClient := testrig.NewMockHTTPClient(nil, "../../testrig/media") - tc := testrig.NewTestTransportController(&suite.state, httpClient) - federator := federation.NewFederator(&suite.state, testrig.NewTestFederatingDB(&suite.state), tc, suite.tc, testrig.NewTestMediaManager(&suite.state)) - - sendingAccount := suite.testAccounts["remote_account_1"] - inboxAccount := suite.testAccounts["local_account_1"] - otherInvolvedIRIs := []*url.URL{} - actorIRIs := []*url.URL{ - testrig.URLMustParse(sendingAccount.URI), - } - - ctx := context.Background() - ctxWithReceivingAccount := context.WithValue(ctx, ap.ContextReceivingAccount, inboxAccount) - ctxWithRequestingAccount := context.WithValue(ctxWithReceivingAccount, ap.ContextRequestingAccount, sendingAccount) - ctxWithOtherInvolvedIRIs := context.WithValue(ctxWithRequestingAccount, ap.ContextOtherInvolvedIRIs, otherInvolvedIRIs) - - // insert a block from inboxAccount targeting sendingAccount - if err := suite.db.PutBlock(context.Background(), >smodel.Block{ +func (suite *FederatingProtocolTestSuite) TestBlockedReceiverBlocksRequester() { + var ( + receivingAccount = suite.testAccounts["local_account_1"] + requestingAccount = suite.testAccounts["remote_account_1"] + otherIRIs = []*url.URL{} + actorIRIs = []*url.URL{ + testrig.URLMustParse(requestingAccount.URI), + } + ) + + // Insert a block from receivingAccount targeting requestingAccount. + if err := suite.state.DB.PutBlock(context.Background(), >smodel.Block{ ID: "01G3KBEMJD4VQ2D615MPV7KTRD", URI: "whatever", - AccountID: inboxAccount.ID, - TargetAccountID: sendingAccount.ID, + AccountID: receivingAccount.ID, + TargetAccountID: requestingAccount.ID, }); err != nil { suite.Fail(err.Error()) } - // request should be blocked now - blocked, err := federator.Blocked(ctxWithOtherInvolvedIRIs, actorIRIs) + blocked, err := suite.blocked( + context.Background(), + receivingAccount, + requestingAccount, + otherIRIs, + actorIRIs, + ) + suite.NoError(err) suite.True(blocked) } -func (suite *FederatingProtocolTestSuite) TestBlocked3() { - httpClient := testrig.NewMockHTTPClient(nil, "../../testrig/media") - tc := testrig.NewTestTransportController(&suite.state, httpClient) - federator := federation.NewFederator(&suite.state, testrig.NewTestFederatingDB(&suite.state), tc, suite.tc, testrig.NewTestMediaManager(&suite.state)) - - sendingAccount := suite.testAccounts["remote_account_1"] - inboxAccount := suite.testAccounts["local_account_1"] - ccedAccount := suite.testAccounts["remote_account_2"] - - otherInvolvedIRIs := []*url.URL{ - testrig.URLMustParse(ccedAccount.URI), - } - actorIRIs := []*url.URL{ - testrig.URLMustParse(sendingAccount.URI), - } - - ctx := context.Background() - ctxWithReceivingAccount := context.WithValue(ctx, ap.ContextReceivingAccount, inboxAccount) - ctxWithRequestingAccount := context.WithValue(ctxWithReceivingAccount, ap.ContextRequestingAccount, sendingAccount) - ctxWithOtherInvolvedIRIs := context.WithValue(ctxWithRequestingAccount, ap.ContextOtherInvolvedIRIs, otherInvolvedIRIs) - - // insert a block from inboxAccount targeting CCed account - if err := suite.db.PutBlock(context.Background(), >smodel.Block{ +func (suite *FederatingProtocolTestSuite) TestBlockedCCd() { + var ( + receivingAccount = suite.testAccounts["local_account_1"] + requestingAccount = suite.testAccounts["remote_account_1"] + ccedAccount = suite.testAccounts["remote_account_2"] + otherIRIs = []*url.URL{ + testrig.URLMustParse(ccedAccount.URI), + } + actorIRIs = []*url.URL{ + testrig.URLMustParse(requestingAccount.URI), + } + ) + + // Insert a block from receivingAccount targeting ccedAccount. + if err := suite.state.DB.PutBlock(context.Background(), >smodel.Block{ ID: "01G3KBEMJD4VQ2D615MPV7KTRD", URI: "whatever", - AccountID: inboxAccount.ID, + AccountID: receivingAccount.ID, TargetAccountID: ccedAccount.ID, }); err != nil { suite.Fail(err.Error()) } - blocked, err := federator.Blocked(ctxWithOtherInvolvedIRIs, actorIRIs) - suite.NoError(err) - suite.True(blocked) -} - -func (suite *FederatingProtocolTestSuite) TestBlocked4() { - httpClient := testrig.NewMockHTTPClient(nil, "../../testrig/media") - tc := testrig.NewTestTransportController(&suite.state, httpClient) - federator := federation.NewFederator(&suite.state, testrig.NewTestFederatingDB(&suite.state), tc, suite.tc, testrig.NewTestMediaManager(&suite.state)) - - sendingAccount := suite.testAccounts["remote_account_1"] - inboxAccount := suite.testAccounts["local_account_1"] - repliedStatus := suite.testStatuses["local_account_2_status_1"] - - otherInvolvedIRIs := []*url.URL{ - testrig.URLMustParse(repliedStatus.URI), // this status is involved because the hypothetical activity is a reply to this status - } - actorIRIs := []*url.URL{ - testrig.URLMustParse(sendingAccount.URI), - } - - ctx := context.Background() - ctxWithReceivingAccount := context.WithValue(ctx, ap.ContextReceivingAccount, inboxAccount) - ctxWithRequestingAccount := context.WithValue(ctxWithReceivingAccount, ap.ContextRequestingAccount, sendingAccount) - ctxWithOtherInvolvedIRIs := context.WithValue(ctxWithRequestingAccount, ap.ContextOtherInvolvedIRIs, otherInvolvedIRIs) + blocked, err := suite.blocked( + context.Background(), + receivingAccount, + requestingAccount, + otherIRIs, + actorIRIs, + ) - // local account 2 (replied status account) blocks sending account already so we don't need to add a block here + suite.EqualError(err, "block exists between http://localhost:8080/users/the_mighty_zork and one or more of [http://example.org/users/Some_User]") + suite.False(blocked) +} - blocked, err := federator.Blocked(ctxWithOtherInvolvedIRIs, actorIRIs) - suite.NoError(err) - suite.True(blocked) +func (suite *FederatingProtocolTestSuite) TestBlockedRepliedStatus() { + var ( + receivingAccount = suite.testAccounts["local_account_1"] + requestingAccount = suite.testAccounts["remote_account_1"] + repliedStatus = suite.testStatuses["local_account_2_status_1"] + otherIRIs = []*url.URL{ + // This status is involved because the + // hypothetical activity replies to it. + testrig.URLMustParse(repliedStatus.URI), + } + actorIRIs = []*url.URL{ + testrig.URLMustParse(requestingAccount.URI), + } + ) + + blocked, err := suite.blocked( + context.Background(), + receivingAccount, + requestingAccount, + otherIRIs, + actorIRIs, + ) + + suite.EqualError(err, "block exists between http://fossbros-anonymous.io/users/foss_satan and one or more of [http://localhost:8080/users/1happyturtle/statuses/01F8MHBQCBTDKN6X5VHGMMN4MA]") + suite.False(blocked) } func TestFederatingProtocolTestSuite(t *testing.T) { |