diff options
Diffstat (limited to 'internal/federation/dereferencing')
| -rw-r--r-- | internal/federation/dereferencing/account.go | 42 | ||||
| -rw-r--r-- | internal/federation/dereferencing/account_test.go | 18 | 
2 files changed, 56 insertions, 4 deletions
| diff --git a/internal/federation/dereferencing/account.go b/internal/federation/dereferencing/account.go index 0fda96bf4..6a633a54a 100644 --- a/internal/federation/dereferencing/account.go +++ b/internal/federation/dereferencing/account.go @@ -29,6 +29,7 @@ import (  	"sync"  	"time" +	"github.com/miekg/dns"  	"github.com/superseriousbusiness/activity/streams"  	"github.com/superseriousbusiness/activity/streams/vocab"  	"github.com/superseriousbusiness/gotosocial/internal/ap" @@ -197,10 +198,12 @@ func (d *deref) GetRemoteAccount(ctx context.Context, params GetRemoteAccountPar  		accountDomain = params.RemoteAccountHost  	} -	// to save on remote calls: only webfinger if we don't have a remoteAccount yet, or if we haven't -	// fingered the remote account for at least 2 days; don't finger instance accounts +	// to save on remote calls, only webfinger if: +	// - we don't know the remote account ActivityPub ID yet OR +	// - we haven't found the account yet in some other way OR +	// - we haven't webfingered the account for two days AND the account isn't an instance account  	var fingered time.Time -	if foundAccount == nil || (foundAccount.LastWebfingeredAt.Before(time.Now().Add(webfingerInterval)) && !instanceAccount(foundAccount)) { +	if params.RemoteAccountID == nil || foundAccount == nil || (foundAccount.LastWebfingeredAt.Before(time.Now().Add(webfingerInterval)) && !instanceAccount(foundAccount)) {  		accountDomain, params.RemoteAccountID, err = d.fingerRemoteAccount(ctx, params.RequestingUsername, params.RemoteAccountUsername, params.RemoteAccountHost)  		if err != nil {  			err = fmt.Errorf("GetRemoteAccount: error while fingering: %s", err) @@ -279,6 +282,37 @@ func (d *deref) GetRemoteAccount(ctx context.Context, params GetRemoteAccountPar  		}  	} +	// if SharedInboxURI is nil, that means we don't know yet if this account has +	// a shared inbox available for it, so we need to check this here +	var sharedInboxChanged bool +	if foundAccount.SharedInboxURI == nil { +		// we need the accountable for this, so get it if we don't have it yet +		if accountable == nil { +			accountable, err = d.dereferenceAccountable(ctx, params.RequestingUsername, params.RemoteAccountID) +			if err != nil { +				err = fmt.Errorf("GetRemoteAccount: error dereferencing accountable: %s", err) +				return +			} +		} + +		// This can be: +		// - an empty string (we know it doesn't have a shared inbox) OR +		// - a string URL (we know it does a shared inbox). +		// Set it either way! +		var sharedInbox string + +		if sharedInboxURI := ap.ExtractSharedInbox(accountable); sharedInboxURI != nil { +			// only trust shared inbox if it has at least two domains, +			// from the right, in common with the domain of the account +			if dns.CompareDomainName(foundAccount.Domain, sharedInboxURI.Host) >= 2 { +				sharedInbox = sharedInboxURI.String() +			} +		} + +		sharedInboxChanged = true +		foundAccount.SharedInboxURI = &sharedInbox +	} +  	// make sure the account fields are populated before returning:  	// the caller might want to block until everything is loaded  	var fieldsChanged bool @@ -293,7 +327,7 @@ func (d *deref) GetRemoteAccount(ctx context.Context, params GetRemoteAccountPar  		foundAccount.LastWebfingeredAt = fingered  	} -	if fieldsChanged || fingeredChanged { +	if fieldsChanged || fingeredChanged || sharedInboxChanged {  		foundAccount.UpdatedAt = time.Now()  		foundAccount, err = d.db.UpdateAccount(ctx, foundAccount)  		if err != nil { diff --git a/internal/federation/dereferencing/account_test.go b/internal/federation/dereferencing/account_test.go index 77ebb7cac..4f1a83a96 100644 --- a/internal/federation/dereferencing/account_test.go +++ b/internal/federation/dereferencing/account_test.go @@ -101,6 +101,24 @@ func (suite *AccountTestSuite) TestDereferenceLocalAccountAsRemoteURL() {  	suite.Empty(fetchedAccount.Domain)  } +func (suite *AccountTestSuite) TestDereferenceLocalAccountAsRemoteURLNoSharedInboxYet() { +	fetchingAccount := suite.testAccounts["local_account_1"] +	targetAccount := suite.testAccounts["local_account_2"] + +	targetAccount.SharedInboxURI = nil +	if _, err := suite.db.UpdateAccount(context.Background(), targetAccount); err != nil { +		suite.FailNow(err.Error()) +	} + +	fetchedAccount, err := suite.dereferencer.GetRemoteAccount(context.Background(), dereferencing.GetRemoteAccountParams{ +		RequestingUsername: fetchingAccount.Username, +		RemoteAccountID:    testrig.URLMustParse(targetAccount.URI), +	}) +	suite.NoError(err) +	suite.NotNil(fetchedAccount) +	suite.Empty(fetchedAccount.Domain) +} +  func (suite *AccountTestSuite) TestDereferenceLocalAccountAsUsername() {  	fetchingAccount := suite.testAccounts["local_account_1"]  	targetAccount := suite.testAccounts["local_account_2"] | 
