Unblock fix (#247)

* start tests for inbox posts

* go mod tidy

* rename transferContext

* test block/unblock

* improve logging

* improve logging

* fix comment typo
This commit is contained in:
tobi 2021-09-24 17:56:48 +02:00 committed by GitHub
parent d515c9f1ec
commit c7cfbe2702
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 362 additions and 29 deletions

8
go.sum
View file

@ -469,17 +469,11 @@ github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
github.com/uptrace/bun v1.0.5/go.mod h1:aL6D9vPw8DXaTQTwGrEPtUderBYXx7ShUmPfnxnqscw= github.com/uptrace/bun v1.0.8/go.mod h1:aL6D9vPw8DXaTQTwGrEPtUderBYXx7ShUmPfnxnqscw=
github.com/uptrace/bun v1.0.6 h1:o9eMq5ePGBXtxbK3SIreOCRr+rIBQzvJH+/s98kYcVM=
github.com/uptrace/bun v1.0.6/go.mod h1:aL6D9vPw8DXaTQTwGrEPtUderBYXx7ShUmPfnxnqscw=
github.com/uptrace/bun v1.0.9-0.20210922104131-34c982b23581 h1:W8SAI7irrKSZ3t9MzFwehUyEd6f8ajOprqSzCxHFcxo= github.com/uptrace/bun v1.0.9-0.20210922104131-34c982b23581 h1:W8SAI7irrKSZ3t9MzFwehUyEd6f8ajOprqSzCxHFcxo=
github.com/uptrace/bun v1.0.9-0.20210922104131-34c982b23581/go.mod h1:aL6D9vPw8DXaTQTwGrEPtUderBYXx7ShUmPfnxnqscw= github.com/uptrace/bun v1.0.9-0.20210922104131-34c982b23581/go.mod h1:aL6D9vPw8DXaTQTwGrEPtUderBYXx7ShUmPfnxnqscw=
github.com/uptrace/bun/dialect/pgdialect v1.0.5 h1:mq694/aMvs7GwuTar9NIlCLQt/2u4xsF0QMP4I24yHA=
github.com/uptrace/bun/dialect/pgdialect v1.0.5/go.mod h1:MKWjO0PC20ris2oJ3dd6mI/762x24Cjwh8XmbqUhM8A=
github.com/uptrace/bun/dialect/pgdialect v1.0.9-0.20210922104131-34c982b23581 h1:3r8Td1Y3I51f9LYcC/3EuQT8zKuCh+OWiQQ8FVHK4Pg= github.com/uptrace/bun/dialect/pgdialect v1.0.9-0.20210922104131-34c982b23581 h1:3r8Td1Y3I51f9LYcC/3EuQT8zKuCh+OWiQQ8FVHK4Pg=
github.com/uptrace/bun/dialect/pgdialect v1.0.9-0.20210922104131-34c982b23581/go.mod h1:HEGRgyS68SiHcKhFa9LXcDN+KEWo1I4VplvunL0Oi4o= github.com/uptrace/bun/dialect/pgdialect v1.0.9-0.20210922104131-34c982b23581/go.mod h1:HEGRgyS68SiHcKhFa9LXcDN+KEWo1I4VplvunL0Oi4o=
github.com/uptrace/bun/dialect/sqlitedialect v1.0.5 h1:6cIj31YVJr4vvA15C2v76soXL+7WtjFdV6WraApc3r0=
github.com/uptrace/bun/dialect/sqlitedialect v1.0.5/go.mod h1:NW2Gctc9ooQXGSD4kYSac2aiF49lo8YJ3ZAr93lH2p8=
github.com/uptrace/bun/dialect/sqlitedialect v1.0.9-0.20210922104131-34c982b23581 h1:Yfbbo8EQffFLL7EEBq2yUirSg3b7NID4sgRGdNlIJa0= github.com/uptrace/bun/dialect/sqlitedialect v1.0.9-0.20210922104131-34c982b23581 h1:Yfbbo8EQffFLL7EEBq2yUirSg3b7NID4sgRGdNlIJa0=
github.com/uptrace/bun/dialect/sqlitedialect v1.0.9-0.20210922104131-34c982b23581/go.mod h1:v1rNdAcJdw8AgD4x4OAJFIRFA9+sANoXK7u21H9Wvkg= github.com/uptrace/bun/dialect/sqlitedialect v1.0.9-0.20210922104131-34c982b23581/go.mod h1:v1rNdAcJdw8AgD4x4OAJFIRFA9+sANoXK7u21H9Wvkg=
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=

View file

@ -33,8 +33,8 @@
`application/ld+json; profile="https://www.w3.org/ns/activitystreams"`, `application/ld+json; profile="https://www.w3.org/ns/activitystreams"`,
} }
// populateContext transfers the signature verifier and signature from the gin context to the request context // transferContext transfers the signature verifier and signature from the gin context to the request context
func populateContext(c *gin.Context) context.Context { func transferContext(c *gin.Context) context.Context {
ctx := c.Request.Context() ctx := c.Request.Context()
verifier, signed := c.Get(string(util.APRequestingPublicKeyVerifier)) verifier, signed := c.Get(string(util.APRequestingPublicKeyVerifier))

View file

@ -47,7 +47,7 @@ func (m *Module) FollowersGETHandler(c *gin.Context) {
} }
l.Tracef("negotiated format: %s", format) l.Tracef("negotiated format: %s", format)
ctx := populateContext(c) ctx := transferContext(c)
followers, errWithCode := m.processor.GetFediFollowers(ctx, requestedUsername, c.Request.URL) followers, errWithCode := m.processor.GetFediFollowers(ctx, requestedUsername, c.Request.URL)
if errWithCode != nil { if errWithCode != nil {

View file

@ -47,7 +47,7 @@ func (m *Module) FollowingGETHandler(c *gin.Context) {
} }
l.Tracef("negotiated format: %s", format) l.Tracef("negotiated format: %s", format)
ctx := populateContext(c) ctx := transferContext(c)
following, errWithCode := m.processor.GetFediFollowing(ctx, requestedUsername, c.Request.URL) following, errWithCode := m.processor.GetFediFollowing(ctx, requestedUsername, c.Request.URL)
if errWithCode != nil { if errWithCode != nil {

View file

@ -40,12 +40,12 @@ func (m *Module) InboxPOSTHandler(c *gin.Context) {
return return
} }
ctx := populateContext(c) ctx := transferContext(c)
posted, err := m.processor.InboxPost(ctx, c.Writer, c.Request) posted, err := m.processor.InboxPost(ctx, c.Writer, c.Request)
if err != nil { if err != nil {
if withCode, ok := err.(gtserror.WithCode); ok { if withCode, ok := err.(gtserror.WithCode); ok {
l.Debug(withCode.Error()) l.Debugf("InboxPOSTHandler: %s", withCode.Error())
c.JSON(withCode.Code(), withCode.Safe()) c.JSON(withCode.Code(), withCode.Safe())
return return
} }
@ -55,7 +55,7 @@ func (m *Module) InboxPOSTHandler(c *gin.Context) {
} }
if !posted { if !posted {
l.Debugf("request could not be handled as an AP request; headers were: %+v", c.Request.Header) l.Debugf("InboxPOSTHandler: request could not be handled as an AP request; headers were: %+v", c.Request.Header)
c.JSON(http.StatusBadRequest, gin.H{"error": "unable to process request"}) c.JSON(http.StatusBadRequest, gin.H{"error": "unable to process request"})
} }
} }

View file

@ -0,0 +1,228 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package user_test
import (
"bytes"
"context"
"encoding/json"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/gin-gonic/gin"
"github.com/go-fed/activity/streams"
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/gotosocial/internal/api/s2s/user"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id"
"github.com/superseriousbusiness/gotosocial/testrig"
)
type InboxPostTestSuite struct {
UserStandardTestSuite
}
func (suite *InboxPostTestSuite) TestPostBlock() {
blockingAccount := suite.testAccounts["remote_account_1"]
blockedAccount := suite.testAccounts["local_account_1"]
blockURI := testrig.URLMustParse("http://fossbros-anonymous.io/users/foss_satan/blocks/01FG9C441MCTW3R2W117V2PQK3")
block := streams.NewActivityStreamsBlock()
// set the actor property to the block-ing account's URI
actorProp := streams.NewActivityStreamsActorProperty()
actorIRI := testrig.URLMustParse(blockingAccount.URI)
actorProp.AppendIRI(actorIRI)
block.SetActivityStreamsActor(actorProp)
// set the ID property to the blocks's URI
idProp := streams.NewJSONLDIdProperty()
idProp.Set(blockURI)
block.SetJSONLDId(idProp)
// set the object property to the target account's URI
objectProp := streams.NewActivityStreamsObjectProperty()
targetIRI := testrig.URLMustParse(blockedAccount.URI)
objectProp.AppendIRI(targetIRI)
block.SetActivityStreamsObject(objectProp)
// set the TO property to the target account's IRI
toProp := streams.NewActivityStreamsToProperty()
toIRI := testrig.URLMustParse(blockedAccount.URI)
toProp.AppendIRI(toIRI)
block.SetActivityStreamsTo(toProp)
targetURI := testrig.URLMustParse(blockedAccount.InboxURI)
signature, digestHeader, dateHeader := testrig.GetSignatureForActivity(block, blockingAccount.PublicKeyURI, blockingAccount.PrivateKey, targetURI)
bodyI, err := streams.Serialize(block)
suite.NoError(err)
bodyJson, err := json.Marshal(bodyI)
suite.NoError(err)
body := bytes.NewReader(bodyJson)
tc := testrig.NewTestTransportController(testrig.NewMockHTTPClient(nil), suite.db)
federator := testrig.NewTestFederator(suite.db, tc, suite.storage)
processor := testrig.NewTestProcessor(suite.db, suite.storage, federator)
userModule := user.New(suite.config, processor, suite.log).(*user.Module)
// setup request
recorder := httptest.NewRecorder()
ctx, _ := gin.CreateTestContext(recorder)
ctx.Request = httptest.NewRequest(http.MethodPost, targetURI.String(), body) // the endpoint we're hitting
ctx.Request.Header.Set("Signature", signature)
ctx.Request.Header.Set("Date", dateHeader)
ctx.Request.Header.Set("Digest", digestHeader)
ctx.Request.Header.Set("Content-Type", "application/activity+json")
// we need to pass the context through signature check first to set appropriate values on it
suite.securityModule.SignatureCheck(ctx)
// normally the router would populate these params from the path values,
// but because we're calling the function directly, we need to set them manually.
ctx.Params = gin.Params{
gin.Param{
Key: user.UsernameKey,
Value: blockedAccount.Username,
},
}
// trigger the function being tested
userModule.InboxPOSTHandler(ctx)
result := recorder.Result()
defer result.Body.Close()
b, err := ioutil.ReadAll(result.Body)
suite.NoError(err)
suite.Empty(b)
// there should be a block in the database now between the accounts
dbBlock, err := suite.db.GetBlock(context.Background(), blockingAccount.ID, blockedAccount.ID)
suite.NoError(err)
suite.NotNil(dbBlock)
suite.WithinDuration(time.Now(), dbBlock.CreatedAt, 30*time.Second)
suite.WithinDuration(time.Now(), dbBlock.UpdatedAt, 30*time.Second)
suite.Equal("http://fossbros-anonymous.io/users/foss_satan/blocks/01FG9C441MCTW3R2W117V2PQK3", dbBlock.URI)
}
// TestPostUnblock verifies that a remote account with a block targeting one of our instance users should be able to undo that block.
func (suite *InboxPostTestSuite) TestPostUnblock() {
blockingAccount := suite.testAccounts["remote_account_1"]
blockedAccount := suite.testAccounts["local_account_1"]
// first put a block in the database so we have something to undo
blockURI := "http://fossbros-anonymous.io/users/foss_satan/blocks/01FG9C441MCTW3R2W117V2PQK3"
dbBlockID, err := id.NewRandomULID()
suite.NoError(err)
dbBlock := &gtsmodel.Block{
ID: dbBlockID,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
URI: blockURI,
AccountID: blockingAccount.ID,
TargetAccountID: blockedAccount.ID,
}
err = suite.db.Put(context.Background(), dbBlock)
suite.NoError(err)
asBlock, err := suite.tc.BlockToAS(context.Background(), dbBlock)
suite.NoError(err)
targetAccountURI := testrig.URLMustParse(blockedAccount.URI)
// create an Undo and set the appropriate actor on it
undo := streams.NewActivityStreamsUndo()
undo.SetActivityStreamsActor(asBlock.GetActivityStreamsActor())
// Set the block as the 'object' property.
undoObject := streams.NewActivityStreamsObjectProperty()
undoObject.AppendActivityStreamsBlock(asBlock)
undo.SetActivityStreamsObject(undoObject)
// Set the To of the undo as the target of the block
undoTo := streams.NewActivityStreamsToProperty()
undoTo.AppendIRI(targetAccountURI)
undo.SetActivityStreamsTo(undoTo)
undoID := streams.NewJSONLDIdProperty()
undoID.SetIRI(testrig.URLMustParse("http://fossbros-anonymous.io/72cc96a3-f742-4daf-b9f5-3407667260c5"))
undo.SetJSONLDId(undoID)
targetURI := testrig.URLMustParse(blockedAccount.InboxURI)
signature, digestHeader, dateHeader := testrig.GetSignatureForActivity(undo, blockingAccount.PublicKeyURI, blockingAccount.PrivateKey, targetURI)
bodyI, err := streams.Serialize(undo)
suite.NoError(err)
bodyJson, err := json.Marshal(bodyI)
suite.NoError(err)
body := bytes.NewReader(bodyJson)
tc := testrig.NewTestTransportController(testrig.NewMockHTTPClient(nil), suite.db)
federator := testrig.NewTestFederator(suite.db, tc, suite.storage)
processor := testrig.NewTestProcessor(suite.db, suite.storage, federator)
userModule := user.New(suite.config, processor, suite.log).(*user.Module)
// setup request
recorder := httptest.NewRecorder()
ctx, _ := gin.CreateTestContext(recorder)
ctx.Request = httptest.NewRequest(http.MethodPost, targetURI.String(), body) // the endpoint we're hitting
ctx.Request.Header.Set("Signature", signature)
ctx.Request.Header.Set("Date", dateHeader)
ctx.Request.Header.Set("Digest", digestHeader)
ctx.Request.Header.Set("Content-Type", "application/activity+json")
// we need to pass the context through signature check first to set appropriate values on it
suite.securityModule.SignatureCheck(ctx)
// normally the router would populate these params from the path values,
// but because we're calling the function directly, we need to set them manually.
ctx.Params = gin.Params{
gin.Param{
Key: user.UsernameKey,
Value: blockedAccount.Username,
},
}
// trigger the function being tested
userModule.InboxPOSTHandler(ctx)
result := recorder.Result()
defer result.Body.Close()
b, err := ioutil.ReadAll(result.Body)
suite.NoError(err)
suite.Empty(b)
suite.Equal(http.StatusOK, result.StatusCode)
// the block should be undone
block, err := suite.db.GetBlock(context.Background(), blockingAccount.ID, blockedAccount.ID)
suite.ErrorIs(err, db.ErrNoEntries)
suite.Nil(block)
}
func TestInboxPostTestSuite(t *testing.T) {
suite.Run(t, &InboxPostTestSuite{})
}

View file

@ -1,3 +1,21 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package user package user
import ( import (
@ -33,7 +51,7 @@ func (m *Module) PublicKeyGETHandler(c *gin.Context) {
} }
l.Tracef("negotiated format: %s", format) l.Tracef("negotiated format: %s", format)
ctx := populateContext(c) ctx := transferContext(c)
user, errWithCode := m.processor.GetFediUser(ctx, requestedUsername, c.Request.URL) user, errWithCode := m.processor.GetFediUser(ctx, requestedUsername, c.Request.URL)
if errWithCode != nil { if errWithCode != nil {

View file

@ -1,3 +1,21 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package user package user
import ( import (
@ -121,7 +139,7 @@ func (m *Module) StatusRepliesGETHandler(c *gin.Context) {
} }
l.Tracef("negotiated format: %s", format) l.Tracef("negotiated format: %s", format)
ctx := populateContext(c) ctx := transferContext(c)
replies, errWithCode := m.processor.GetFediStatusReplies(ctx, requestedUsername, requestedStatusID, page, onlyOtherAccounts, minID, c.Request.URL) replies, errWithCode := m.processor.GetFediStatusReplies(ctx, requestedUsername, requestedStatusID, page, onlyOtherAccounts, minID, c.Request.URL)
if errWithCode != nil { if errWithCode != nil {

View file

@ -1,3 +1,21 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package user_test package user_test
import ( import (

View file

@ -1,3 +1,21 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package user package user
import ( import (
@ -35,7 +53,7 @@ func (m *Module) StatusGETHandler(c *gin.Context) {
} }
l.Tracef("negotiated format: %s", format) l.Tracef("negotiated format: %s", format)
ctx := populateContext(c) ctx := transferContext(c)
status, errWithCode := m.processor.GetFediStatus(ctx, requestedUsername, requestedStatusID, c.Request.URL) status, errWithCode := m.processor.GetFediStatus(ctx, requestedUsername, requestedStatusID, c.Request.URL)
if errWithCode != nil { if errWithCode != nil {

View file

@ -1,3 +1,21 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package user_test package user_test
import ( import (

View file

@ -55,7 +55,7 @@ func (m *Module) UsersGETHandler(c *gin.Context) {
} }
l.Tracef("negotiated format: %s", format) l.Tracef("negotiated format: %s", format)
ctx := populateContext(c) ctx := transferContext(c)
user, errWithCode := m.processor.GetFediUser(ctx, requestedUsername, c.Request.URL) // GetFediUser handles auth as well user, errWithCode := m.processor.GetFediUser(ctx, requestedUsername, c.Request.URL) // GetFediUser handles auth as well
if errWithCode != nil { if errWithCode != nil {

View file

@ -1,3 +1,21 @@
/*
GoToSocial
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package user_test package user_test
import ( import (

View file

@ -26,7 +26,7 @@
// Relationship contains functions for getting or modifying the relationship between two accounts. // Relationship contains functions for getting or modifying the relationship between two accounts.
type Relationship interface { type Relationship interface {
// IsBlocked checks whether account 1 has a block in place against block2. // IsBlocked checks whether account 1 has a block in place against account2.
// If eitherDirection is true, then the function returns true if account1 blocks account2, OR if account2 blocks account1. // If eitherDirection is true, then the function returns true if account1 blocks account2, OR if account2 blocks account1.
IsBlocked(ctx context.Context, account1 string, account2 string, eitherDirection bool) (bool, Error) IsBlocked(ctx context.Context, account1 string, account2 string, eitherDirection bool) (bool, Error)

View file

@ -203,19 +203,22 @@ func (f *federator) Blocked(ctx context.Context, actorIRIs []*url.URL) (bool, er
if err == db.ErrNoEntries { if err == db.ErrNoEntries {
// we don't have an entry for this account so it's not blocked // we don't have an entry for this account so it's not blocked
// TODO: allow a different default to be set for this behavior // TODO: allow a different default to be set for this behavior
l.Tracef("no entry for account with URI %s so it can't be blocked", uri)
continue continue
} }
return false, fmt.Errorf("error getting account with uri %s: %s", uri.String(), err) return false, fmt.Errorf("error getting account with uri %s: %s", uri.String(), err)
} }
blocked, err = f.db.IsBlocked(ctx, requestedAccount.ID, requestingAccount.ID, true) blocked, err = f.db.IsBlocked(ctx, requestedAccount.ID, requestingAccount.ID, false)
if err != nil { if err != nil {
return false, fmt.Errorf("error checking account block: %s", err) return false, fmt.Errorf("error checking account block: %s", err)
} }
if blocked { if blocked {
l.Tracef("local account %s blocks account with uri %s", requestedAccount.Username, uri)
return true, nil return true, nil
} }
} }
return false, nil return false, nil
} }

View file

@ -1283,7 +1283,7 @@ func NewTestActivities(accounts map[string]*gtsmodel.Account) map[string]Activit
URLMustParse("https://fossbros-anonymous.io/users/foss_satan"), URLMustParse("https://fossbros-anonymous.io/users/foss_satan"),
time.Now(), time.Now(),
dmForZork) dmForZork)
sig, digest, date := getSignatureForActivity(createDmForZork, accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, URLMustParse(accounts["local_account_1"].InboxURI)) sig, digest, date := GetSignatureForActivity(createDmForZork, accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, URLMustParse(accounts["local_account_1"].InboxURI))
return map[string]ActivityWithSignature{ return map[string]ActivityWithSignature{
"dm_for_zork": { "dm_for_zork": {
@ -1391,7 +1391,7 @@ func NewTestDereferenceRequests(accounts map[string]*gtsmodel.Account) map[strin
statuses := NewTestStatuses() statuses := NewTestStatuses()
target = URLMustParse(accounts["local_account_1"].URI) target = URLMustParse(accounts["local_account_1"].URI)
sig, digest, date = getSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target) sig, digest, date = GetSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target)
fossSatanDereferenceZork := ActivityWithSignature{ fossSatanDereferenceZork := ActivityWithSignature{
SignatureHeader: sig, SignatureHeader: sig,
DigestHeader: digest, DigestHeader: digest,
@ -1399,7 +1399,7 @@ func NewTestDereferenceRequests(accounts map[string]*gtsmodel.Account) map[strin
} }
target = URLMustParse(statuses["local_account_1_status_1"].URI + "/replies") target = URLMustParse(statuses["local_account_1_status_1"].URI + "/replies")
sig, digest, date = getSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target) sig, digest, date = GetSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target)
fossSatanDereferenceLocalAccount1Status1Replies := ActivityWithSignature{ fossSatanDereferenceLocalAccount1Status1Replies := ActivityWithSignature{
SignatureHeader: sig, SignatureHeader: sig,
DigestHeader: digest, DigestHeader: digest,
@ -1407,7 +1407,7 @@ func NewTestDereferenceRequests(accounts map[string]*gtsmodel.Account) map[strin
} }
target = URLMustParse(statuses["local_account_1_status_1"].URI + "/replies?only_other_accounts=false&page=true") target = URLMustParse(statuses["local_account_1_status_1"].URI + "/replies?only_other_accounts=false&page=true")
sig, digest, date = getSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target) sig, digest, date = GetSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target)
fossSatanDereferenceLocalAccount1Status1RepliesNext := ActivityWithSignature{ fossSatanDereferenceLocalAccount1Status1RepliesNext := ActivityWithSignature{
SignatureHeader: sig, SignatureHeader: sig,
DigestHeader: digest, DigestHeader: digest,
@ -1415,7 +1415,7 @@ func NewTestDereferenceRequests(accounts map[string]*gtsmodel.Account) map[strin
} }
target = URLMustParse(statuses["local_account_1_status_1"].URI + "/replies?only_other_accounts=false&page=true&min_id=01FF25D5Q0DH7CHD57CTRS6WK0") target = URLMustParse(statuses["local_account_1_status_1"].URI + "/replies?only_other_accounts=false&page=true&min_id=01FF25D5Q0DH7CHD57CTRS6WK0")
sig, digest, date = getSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target) sig, digest, date = GetSignatureForDereference(accounts["remote_account_1"].PublicKeyURI, accounts["remote_account_1"].PrivateKey, target)
fossSatanDereferenceLocalAccount1Status1RepliesLast := ActivityWithSignature{ fossSatanDereferenceLocalAccount1Status1RepliesLast := ActivityWithSignature{
SignatureHeader: sig, SignatureHeader: sig,
DigestHeader: digest, DigestHeader: digest,
@ -1430,9 +1430,9 @@ func NewTestDereferenceRequests(accounts map[string]*gtsmodel.Account) map[strin
} }
} }
// getSignatureForActivity does some sneaky sneaky work with a mock http client and a test transport controller, in order to derive // GetSignatureForActivity does some sneaky sneaky work with a mock http client and a test transport controller, in order to derive
// the HTTP Signature for the given activity, public key ID, private key, and destination. // the HTTP Signature for the given activity, public key ID, private key, and destination.
func getSignatureForActivity(activity pub.Activity, pubKeyID string, privkey crypto.PrivateKey, destination *url.URL) (signatureHeader string, digestHeader string, dateHeader string) { func GetSignatureForActivity(activity pub.Activity, pubKeyID string, privkey crypto.PrivateKey, destination *url.URL) (signatureHeader string, digestHeader string, dateHeader string) {
// create a client that basically just pulls the signature out of the request and sets it // create a client that basically just pulls the signature out of the request and sets it
client := &mockHTTPClient{ client := &mockHTTPClient{
do: func(req *http.Request) (*http.Response, error) { do: func(req *http.Request) (*http.Response, error) {
@ -1473,9 +1473,9 @@ func getSignatureForActivity(activity pub.Activity, pubKeyID string, privkey cry
return return
} }
// getSignatureForDereference does some sneaky sneaky work with a mock http client and a test transport controller, in order to derive // GetSignatureForDereference does some sneaky sneaky work with a mock http client and a test transport controller, in order to derive
// the HTTP Signature for the given derefence GET request using public key ID, private key, and destination. // the HTTP Signature for the given derefence GET request using public key ID, private key, and destination.
func getSignatureForDereference(pubKeyID string, privkey crypto.PrivateKey, destination *url.URL) (signatureHeader string, digestHeader string, dateHeader string) { func GetSignatureForDereference(pubKeyID string, privkey crypto.PrivateKey, destination *url.URL) (signatureHeader string, digestHeader string, dateHeader string) {
// create a client that basically just pulls the signature out of the request and sets it // create a client that basically just pulls the signature out of the request and sets it
client := &mockHTTPClient{ client := &mockHTTPClient{
do: func(req *http.Request) (*http.Response, error) { do: func(req *http.Request) (*http.Response, error) {