diff options
author | 2021-09-30 10:56:02 +0200 | |
---|---|---|
committer | 2021-09-30 10:56:02 +0200 | |
commit | 36a09dd0df06e1b6f64347ed3d3c2c8ca963fc73 (patch) | |
tree | 78e032fecd7c2e6b0260c2a285d9d3bc1238ffcb /internal/processing | |
parent | upstep bun to v1.0.9 (#252) (diff) | |
download | gotosocial-36a09dd0df06e1b6f64347ed3d3c2c8ca963fc73.tar.xz |
handle remote account deletion more systematically (#254)
Diffstat (limited to 'internal/processing')
-rw-r--r-- | internal/processing/account/delete.go | 20 | ||||
-rw-r--r-- | internal/processing/fromfederator.go | 8 | ||||
-rw-r--r-- | internal/processing/fromfederator_test.go | 81 | ||||
-rw-r--r-- | internal/processing/processor_test.go | 2 |
4 files changed, 104 insertions, 7 deletions
diff --git a/internal/processing/account/delete.go b/internal/processing/account/delete.go index 5de706045..632f49751 100644 --- a/internal/processing/account/delete.go +++ b/internal/processing/account/delete.go @@ -31,7 +31,7 @@ import ( // Delete handles the complete deletion of an account. // -// TODO in this function: +// To be done in this function: // 1. Delete account's application(s), clients, and oauth tokens // 2. Delete account's blocks // 3. Delete account's emoji @@ -51,12 +51,16 @@ import ( // 17. Delete account's timeline // 18. Delete account itself func (p *processor) Delete(ctx context.Context, account *gtsmodel.Account, origin string) error { - l := p.log.WithFields(logrus.Fields{ + fields := logrus.Fields{ "func": "Delete", "username": account.Username, - }) + } + if account.Domain != "" { + fields["domain"] = account.Domain + } + l := p.log.WithFields(fields) - l.Debugf("beginning account delete process for username %s", account.Username) + l.Debug("beginning account delete process") // 1. Delete account's application(s), clients, and oauth tokens // we only need to do this step for local account since remote ones won't have any tokens or applications on our server @@ -214,10 +218,16 @@ selectStatusesLoop: // 10. Delete account's notifications l.Debug("deleting account notifications") + // first notifications created by account if err := p.db.DeleteWhere(ctx, []db.Where{{Key: "origin_account_id", Value: account.ID}}, &[]*gtsmodel.Notification{}); err != nil { l.Errorf("error deleting notifications created by account: %s", err) } + // now notifications targeting account + if err := p.db.DeleteWhere(ctx, []db.Where{{Key: "target_account_id", Value: account.ID}}, &[]*gtsmodel.Notification{}); err != nil { + l.Errorf("error deleting notifications targeting account: %s", err) + } + // 11. Delete account's bookmarks l.Debug("deleting account bookmarks") if err := p.db.DeleteWhere(ctx, []db.Where{{Key: "account_id", Value: account.ID}}, &[]*gtsmodel.StatusBookmark{}); err != nil { @@ -267,8 +277,6 @@ selectStatusesLoop: account.HideCollections = true account.Discoverable = false - account.UpdatedAt = time.Now() - account.SuspendedAt = time.Now() account.SuspensionOrigin = origin diff --git a/internal/processing/fromfederator.go b/internal/processing/fromfederator.go index feb22b2ba..ffaf625d3 100644 --- a/internal/processing/fromfederator.go +++ b/internal/processing/fromfederator.go @@ -181,7 +181,13 @@ func (p *processor) ProcessFromFederator(ctx context.Context, federatorMsg messa return p.deleteStatusFromTimelines(ctx, statusToDelete) case ap.ObjectProfile: // DELETE A PROFILE/ACCOUNT - // TODO: handle side effects of account deletion here: delete all objects, statuses, media etc associated with account + // handle side effects of account deletion here: delete all objects, statuses, media etc associated with account + account, ok := federatorMsg.GTSModel.(*gtsmodel.Account) + if !ok { + return errors.New("account delete was not parseable as *gtsmodel.Account") + } + + return p.accountProcessor.Delete(ctx, account, account.ID) } case ap.ActivityAccept: // ACCEPT diff --git a/internal/processing/fromfederator_test.go b/internal/processing/fromfederator_test.go index ba2aaf03e..605a18bdc 100644 --- a/internal/processing/fromfederator_test.go +++ b/internal/processing/fromfederator_test.go @@ -20,6 +20,7 @@ package processing_test import ( "context" + "fmt" "testing" "time" @@ -276,6 +277,86 @@ func (suite *FromFederatorTestSuite) TestProcessFaveWithDifferentReceivingAccoun suite.Empty(stream.Messages) } +func (suite *FromFederatorTestSuite) TestProcessAccountDelete() { + ctx := context.Background() + + deletedAccount := suite.testAccounts["remote_account_1"] + receivingAccount := suite.testAccounts["local_account_1"] + + // before doing the delete.... + // make local_account_1 and remote_account_1 into mufos + zorkFollowSatan := >smodel.Follow{ + ID: "01FGRY72ASHBSET64353DPHK9T", + CreatedAt: time.Now().Add(-1 * time.Hour), + UpdatedAt: time.Now().Add(-1 * time.Hour), + AccountID: deletedAccount.ID, + TargetAccountID: receivingAccount.ID, + ShowReblogs: true, + URI: fmt.Sprintf("%s/follows/01FGRY72ASHBSET64353DPHK9T", deletedAccount.URI), + Notify: false, + } + err := suite.db.Put(ctx, zorkFollowSatan) + suite.NoError(err) + + satanFollowZork := >smodel.Follow{ + ID: "01FGRYAVAWWPP926J175QGM0WV", + CreatedAt: time.Now().Add(-1 * time.Hour), + UpdatedAt: time.Now().Add(-1 * time.Hour), + AccountID: receivingAccount.ID, + TargetAccountID: deletedAccount.ID, + ShowReblogs: true, + URI: fmt.Sprintf("%s/follows/01FGRYAVAWWPP926J175QGM0WV", receivingAccount.URI), + Notify: false, + } + err = suite.db.Put(ctx, satanFollowZork) + suite.NoError(err) + + // now they are mufos! + + err = suite.processor.ProcessFromFederator(ctx, messages.FromFederator{ + APObjectType: ap.ObjectProfile, + APActivityType: ap.ActivityDelete, + GTSModel: deletedAccount, + ReceivingAccount: receivingAccount, + }) + suite.NoError(err) + + // local account 2 blocked foss_satan, that block should be gone now + testBlock := suite.testBlocks["local_account_2_block_remote_account_1"] + dbBlock := >smodel.Block{} + err = suite.db.GetByID(ctx, testBlock.ID, dbBlock) + suite.ErrorIs(err, db.ErrNoEntries) + + // the mufos should be gone now too + satanFollowsZork, err := suite.db.IsFollowing(ctx, deletedAccount, receivingAccount) + suite.NoError(err) + suite.False(satanFollowsZork) + zorkFollowsSatan, err := suite.db.IsFollowing(ctx, receivingAccount, deletedAccount) + suite.NoError(err) + suite.False(zorkFollowsSatan) + + // no statuses from foss satan should be left in the database + dbStatuses, err := suite.db.GetAccountStatuses(ctx, deletedAccount.ID, 0, false, "", false, false) + suite.ErrorIs(err, db.ErrNoEntries) + suite.Empty(dbStatuses) + + dbAccount, err := suite.db.GetAccountByID(ctx, deletedAccount.ID) + suite.NoError(err) + + suite.Empty(dbAccount.Note) + suite.Empty(dbAccount.DisplayName) + suite.Empty(dbAccount.AvatarMediaAttachmentID) + suite.Empty(dbAccount.AvatarRemoteURL) + suite.Empty(dbAccount.HeaderMediaAttachmentID) + suite.Empty(dbAccount.HeaderRemoteURL) + suite.Empty(dbAccount.Reason) + suite.Empty(dbAccount.Fields) + suite.True(dbAccount.HideCollections) + suite.False(dbAccount.Discoverable) + suite.WithinDuration(time.Now(), dbAccount.SuspendedAt, 30*time.Second) + suite.Equal(dbAccount.ID, dbAccount.SuspensionOrigin) +} + func TestFromFederatorTestSuite(t *testing.T) { suite.Run(t, &FromFederatorTestSuite{}) } diff --git a/internal/processing/processor_test.go b/internal/processing/processor_test.go index daaf46726..e0f44b0d7 100644 --- a/internal/processing/processor_test.go +++ b/internal/processing/processor_test.go @@ -62,6 +62,7 @@ type ProcessingStandardTestSuite struct { testTags map[string]*gtsmodel.Tag testMentions map[string]*gtsmodel.Mention testAutheds map[string]*oauth.Auth + testBlocks map[string]*gtsmodel.Block processor processing.Processor } @@ -83,6 +84,7 @@ func (suite *ProcessingStandardTestSuite) SetupSuite() { Account: suite.testAccounts["local_account_1"], }, } + suite.testBlocks = testrig.NewTestBlocks() } func (suite *ProcessingStandardTestSuite) SetupTest() { |