| 
									
										
										
										
											2023-03-12 16:00:57 +01:00
										 |  |  | // GoToSocial | 
					
						
							|  |  |  | // Copyright (C) GoToSocial Authors admin@gotosocial.org | 
					
						
							|  |  |  | // SPDX-License-Identifier: AGPL-3.0-or-later | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // 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/>. | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | package account | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2022-03-15 16:12:35 +01:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2023-03-31 15:01:29 +02:00
										 |  |  | 	"net" | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-19 09:47:55 +01:00
										 |  |  | 	"codeberg.org/gruf/go-kv" | 
					
						
							| 
									
										
										
										
											2023-03-31 15:01:29 +02:00
										 |  |  | 	"github.com/google/uuid" | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/ap" | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/db" | 
					
						
							| 
									
										
										
										
											2022-03-15 16:12:35 +01:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 
					
						
							| 
									
										
										
										
											2022-07-19 09:47:55 +01:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/log" | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/messages" | 
					
						
							| 
									
										
										
										
											2023-08-07 19:38:11 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/util" | 
					
						
							| 
									
										
										
										
											2023-03-31 15:01:29 +02:00
										 |  |  | 	"golang.org/x/crypto/bcrypt" | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | const deleteSelectLimit = 50 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 16:05:26 +01:00
										 |  |  | // Delete deletes an account, and all of that account's statuses, media, follows, notifications, etc etc etc. | 
					
						
							|  |  |  | // The origin passed here should be either the ID of the account doing the delete (can be itself), or the ID of a domain block. | 
					
						
							|  |  |  | func (p *Processor) Delete(ctx context.Context, account *gtsmodel.Account, origin string) gtserror.WithCode { | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	l := log.WithContext(ctx).WithFields(kv.Fields{ | 
					
						
							|  |  |  | 		{"username", account.Username}, | 
					
						
							|  |  |  | 		{"domain", account.Domain}, | 
					
						
							|  |  |  | 	}...) | 
					
						
							|  |  |  | 	l.Trace("beginning account delete process") | 
					
						
							| 
									
										
										
										
											2022-11-20 14:57:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	if err := p.deleteAccountFollows(ctx, account); err != nil { | 
					
						
							|  |  |  | 		return gtserror.NewErrorInternalError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	if err := p.deleteAccountBlocks(ctx, account); err != nil { | 
					
						
							|  |  |  | 		return gtserror.NewErrorInternalError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := p.deleteAccountStatuses(ctx, account); err != nil { | 
					
						
							|  |  |  | 		return gtserror.NewErrorInternalError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := p.deleteAccountNotifications(ctx, account); err != nil { | 
					
						
							|  |  |  | 		return gtserror.NewErrorInternalError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := p.deleteAccountPeripheral(ctx, account); err != nil { | 
					
						
							|  |  |  | 		return gtserror.NewErrorInternalError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-10 15:08:41 +01:00
										 |  |  | 	if account.IsLocal() { | 
					
						
							|  |  |  | 		// we tokens, applications and clients for account as one of the last | 
					
						
							|  |  |  | 		// stages during deletion, as other database models rely on these. | 
					
						
							|  |  |  | 		if err := p.deleteUserAndTokensForAccount(ctx, account); err != nil { | 
					
						
							|  |  |  | 			return gtserror.NewErrorInternalError(err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	// To prevent the account being created again, | 
					
						
							|  |  |  | 	// stubbify it and update it in the db. | 
					
						
							|  |  |  | 	// The account will not be deleted, but it | 
					
						
							|  |  |  | 	// will become completely unusable. | 
					
						
							|  |  |  | 	columns := stubbifyAccount(account, origin) | 
					
						
							|  |  |  | 	if err := p.state.DB.UpdateAccount(ctx, account, columns...); err != nil { | 
					
						
							|  |  |  | 		return gtserror.NewErrorInternalError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	l.Info("account deleted") | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // DeleteSelf is like Delete, but specifically for local accounts deleting themselves. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Calling DeleteSelf results in a delete message being enqueued in the processor, | 
					
						
							|  |  |  | // which causes side effects to occur: delete will be federated out to other instances, | 
					
						
							|  |  |  | // and the above Delete function will be called afterwards from the processor, to clear | 
					
						
							|  |  |  | // out the account's bits and bobs, and stubbify it. | 
					
						
							|  |  |  | func (p *Processor) DeleteSelf(ctx context.Context, account *gtsmodel.Account) gtserror.WithCode { | 
					
						
							|  |  |  | 	fromClientAPIMessage := messages.FromClientAPI{ | 
					
						
							|  |  |  | 		APObjectType:   ap.ActorPerson, | 
					
						
							|  |  |  | 		APActivityType: ap.ActivityDelete, | 
					
						
							|  |  |  | 		OriginAccount:  account, | 
					
						
							|  |  |  | 		TargetAccount:  account, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Process the delete side effects asynchronously. | 
					
						
							|  |  |  | 	p.state.Workers.EnqueueClientAPI(ctx, fromClientAPIMessage) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // deleteUserAndTokensForAccount deletes the gtsmodel.User and | 
					
						
							|  |  |  | // any OAuth tokens and applications for the given account. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Callers to this function should already have checked that | 
					
						
							|  |  |  | // this is a local account, or else it won't have a user associated | 
					
						
							|  |  |  | // with it, and this will fail. | 
					
						
							|  |  |  | func (p *Processor) deleteUserAndTokensForAccount(ctx context.Context, account *gtsmodel.Account) error { | 
					
						
							|  |  |  | 	user, err := p.state.DB.GetUserByAccountID(ctx, account.ID) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 		return gtserror.Newf("db error getting user: %w", err) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tokens := []*gtsmodel.Token{} | 
					
						
							|  |  |  | 	if err := p.state.DB.GetWhere(ctx, []db.Where{{Key: "user_id", Value: user.ID}}, &tokens); err != nil { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 		return gtserror.Newf("db error getting tokens: %w", err) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, t := range tokens { | 
					
						
							|  |  |  | 		// Delete any OAuth clients associated with this token. | 
					
						
							|  |  |  | 		if err := p.state.DB.DeleteByID(ctx, t.ClientID, &[]*gtsmodel.Client{}); err != nil { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 			return gtserror.Newf("db error deleting client: %w", err) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Delete any OAuth applications associated with this token. | 
					
						
							| 
									
										
										
										
											2023-08-10 15:08:41 +01:00
										 |  |  | 		if err := p.state.DB.DeleteApplicationByClientID(ctx, t.ClientID); err != nil { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 			return gtserror.Newf("db error deleting application: %w", err) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Delete the token itself. | 
					
						
							|  |  |  | 		if err := p.state.DB.DeleteByID(ctx, t.ID, t); err != nil { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 			return gtserror.Newf("db error deleting token: %w", err) | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-31 15:01:29 +02:00
										 |  |  | 	columns, err := stubbifyUser(user) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 		return gtserror.Newf("error stubbifying user: %w", err) | 
					
						
							| 
									
										
										
										
											2023-03-31 15:01:29 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := p.state.DB.UpdateUser(ctx, user, columns...); err != nil { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 		return gtserror.Newf("db error updating user: %w", err) | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // deleteAccountFollows deletes: | 
					
						
							|  |  |  | //   - Follows targeting account. | 
					
						
							|  |  |  | //   - Follow requests targeting account. | 
					
						
							|  |  |  | //   - Follows created by account. | 
					
						
							|  |  |  | //   - Follow requests created by account. | 
					
						
							|  |  |  | func (p *Processor) deleteAccountFollows(ctx context.Context, account *gtsmodel.Account) error { | 
					
						
							|  |  |  | 	// Delete follows targeting this account. | 
					
						
							| 
									
										
											  
											
												[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
											
										 
											2023-03-28 14:03:14 +01:00
										 |  |  | 	followedBy, err := p.state.DB.GetAccountFollowers(ctx, account.ID) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	if err != nil && !errors.Is(err, db.ErrNoEntries) { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 		return gtserror.Newf("db error getting follows targeting account %s: %w", account.ID, err) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, follow := range followedBy { | 
					
						
							| 
									
										
											  
											
												[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
											
										 
											2023-03-28 14:03:14 +01:00
										 |  |  | 		if err := p.state.DB.DeleteFollowByID(ctx, follow.ID); err != nil { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 			return gtserror.Newf("db error unfollowing account followedBy: %w", err) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	// Delete follow requests targeting this account. | 
					
						
							| 
									
										
											  
											
												[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
											
										 
											2023-03-28 14:03:14 +01:00
										 |  |  | 	followRequestedBy, err := p.state.DB.GetAccountFollowRequests(ctx, account.ID) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	if err != nil && !errors.Is(err, db.ErrNoEntries) { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 		return gtserror.Newf("db error getting follow requests targeting account %s: %w", account.ID, err) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	for _, followRequest := range followRequestedBy { | 
					
						
							| 
									
										
											  
											
												[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
											
										 
											2023-03-28 14:03:14 +01:00
										 |  |  | 		if err := p.state.DB.DeleteFollowRequestByID(ctx, followRequest.ID); err != nil { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 			return gtserror.Newf("db error unfollowing account followRequestedBy: %w", err) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	var ( | 
					
						
							|  |  |  | 		// Use this slice to batch unfollow messages. | 
					
						
							|  |  |  | 		msgs = []messages.FromClientAPI{} | 
					
						
							|  |  |  | 		// To avoid checking if account is local over + over | 
					
						
							|  |  |  | 		// inside the subsequent loops, just generate static | 
					
						
							|  |  |  | 		// side effects function once now. | 
					
						
							|  |  |  | 		unfollowSideEffects = p.unfollowSideEffectsFunc(account) | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Delete follows originating from this account. | 
					
						
							| 
									
										
											  
											
												[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
											
										 
											2023-03-28 14:03:14 +01:00
										 |  |  | 	following, err := p.state.DB.GetAccountFollows(ctx, account.ID) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	if err != nil && !errors.Is(err, db.ErrNoEntries) { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 		return gtserror.Newf("db error getting follows owned by account %s: %w", account.ID, err) | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	// For each follow owned by this account, unfollow | 
					
						
							|  |  |  | 	// and process side effects (noop if remote account). | 
					
						
							|  |  |  | 	for _, follow := range following { | 
					
						
							| 
									
										
											  
											
												[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
											
										 
											2023-03-28 14:03:14 +01:00
										 |  |  | 		if err := p.state.DB.DeleteFollowByID(ctx, follow.ID); err != nil { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 			return gtserror.Newf("db error unfollowing account: %w", err) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if msg := unfollowSideEffects(ctx, account, follow); msg != nil { | 
					
						
							|  |  |  | 			// There was a side effect to process. | 
					
						
							|  |  |  | 			msgs = append(msgs, *msg) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	// Delete follow requests originating from this account. | 
					
						
							| 
									
										
											  
											
												[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
											
										 
											2023-03-28 14:03:14 +01:00
										 |  |  | 	followRequesting, err := p.state.DB.GetAccountFollowRequesting(ctx, account.ID) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	if err != nil && !errors.Is(err, db.ErrNoEntries) { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 		return gtserror.Newf("db error getting follow requests owned by account %s: %w", account.ID, err) | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	// For each follow owned by this account, unfollow | 
					
						
							|  |  |  | 	// and process side effects (noop if remote account). | 
					
						
							|  |  |  | 	for _, followRequest := range followRequesting { | 
					
						
							| 
									
										
											  
											
												[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
											
										 
											2023-03-28 14:03:14 +01:00
										 |  |  | 		if err := p.state.DB.DeleteFollowRequestByID(ctx, followRequest.ID); err != nil { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 			return gtserror.Newf("db error unfollowingRequesting account: %w", err) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-11-20 14:57:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 		// Dummy out a follow so our side effects func | 
					
						
							|  |  |  | 		// has something to work with. This follow will | 
					
						
							|  |  |  | 		// never enter the db, it's just for convenience. | 
					
						
							|  |  |  | 		follow := >smodel.Follow{ | 
					
						
							| 
									
										
											  
											
												[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
											
										 
											2023-03-28 14:03:14 +01:00
										 |  |  | 			URI:             followRequest.URI, | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 			AccountID:       followRequest.AccountID, | 
					
						
							|  |  |  | 			Account:         followRequest.Account, | 
					
						
							|  |  |  | 			TargetAccountID: followRequest.TargetAccountID, | 
					
						
							|  |  |  | 			TargetAccount:   followRequest.TargetAccount, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if msg := unfollowSideEffects(ctx, account, follow); msg != nil { | 
					
						
							|  |  |  | 			// There was a side effect to process. | 
					
						
							|  |  |  | 			msgs = append(msgs, *msg) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Process accreted messages asynchronously. | 
					
						
							|  |  |  | 	p.state.Workers.EnqueueClientAPI(ctx, msgs...) | 
					
						
							| 
									
										
										
										
											2022-11-20 14:57:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (p *Processor) unfollowSideEffectsFunc(deletedAccount *gtsmodel.Account) func(ctx context.Context, account *gtsmodel.Account, follow *gtsmodel.Follow) *messages.FromClientAPI { | 
					
						
							|  |  |  | 	if !deletedAccount.IsLocal() { | 
					
						
							|  |  |  | 		// Don't try to process side effects | 
					
						
							|  |  |  | 		// for accounts that aren't local. | 
					
						
							|  |  |  | 		return func(ctx context.Context, account *gtsmodel.Account, follow *gtsmodel.Follow) *messages.FromClientAPI { | 
					
						
							|  |  |  | 			return nil // noop | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return func(ctx context.Context, account *gtsmodel.Account, follow *gtsmodel.Follow) *messages.FromClientAPI { | 
					
						
							|  |  |  | 		if follow.TargetAccount == nil { | 
					
						
							|  |  |  | 			// TargetAccount seems to have gone; | 
					
						
							|  |  |  | 			// race condition? db corruption? | 
					
						
							|  |  |  | 			log.WithContext(ctx).WithField("follow", follow).Warn("follow had no TargetAccount, likely race condition") | 
					
						
							|  |  |  | 			return nil | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if follow.TargetAccount.IsLocal() { | 
					
						
							|  |  |  | 			// No side effects for local unfollows. | 
					
						
							|  |  |  | 			return nil | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// There was a follow, process side effects. | 
					
						
							|  |  |  | 		return &messages.FromClientAPI{ | 
					
						
							|  |  |  | 			APObjectType:   ap.ActivityFollow, | 
					
						
							|  |  |  | 			APActivityType: ap.ActivityUndo, | 
					
						
							|  |  |  | 			GTSModel:       follow, | 
					
						
							|  |  |  | 			OriginAccount:  account, | 
					
						
							|  |  |  | 			TargetAccount:  follow.TargetAccount, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (p *Processor) deleteAccountBlocks(ctx context.Context, account *gtsmodel.Account) error { | 
					
						
							| 
									
										
											  
											
												[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
											
										 
											2023-03-28 14:03:14 +01:00
										 |  |  | 	if err := p.state.DB.DeleteAccountBlocks(ctx, account.ID); err != nil { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 		return gtserror.Newf("db error deleting account blocks for %s: %w", account.ID, err) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // deleteAccountStatuses iterates through all statuses owned by | 
					
						
							|  |  |  | // the given account, passing each discovered status (and boosts | 
					
						
							|  |  |  | // thereof) to the processor workers for further async processing. | 
					
						
							|  |  |  | func (p *Processor) deleteAccountStatuses(ctx context.Context, account *gtsmodel.Account) error { | 
					
						
							|  |  |  | 	// We'll select statuses 50 at a time so we don't wreck the db, | 
					
						
							|  |  |  | 	// and pass them through to the client api worker to handle. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// Deleting the statuses in this way also handles deleting the | 
					
						
							|  |  |  | 	// account's media attachments, mentions, and polls, since these | 
					
						
							|  |  |  | 	// are all attached to statuses. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var ( | 
					
						
							|  |  |  | 		statuses []*gtsmodel.Status | 
					
						
							|  |  |  | 		err      error | 
					
						
							|  |  |  | 		maxID    string | 
					
						
							|  |  |  | 		msgs     = []messages.FromClientAPI{} | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | statusLoop: | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	for { | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 		// Page through account's statuses. | 
					
						
							| 
									
										
										
										
											2023-08-10 15:08:41 +01:00
										 |  |  | 		statuses, err = p.state.DB.GetAccountStatuses( | 
					
						
							|  |  |  | 			ctx, | 
					
						
							|  |  |  | 			account.ID, | 
					
						
							|  |  |  | 			deleteSelectLimit, | 
					
						
							|  |  |  | 			false, | 
					
						
							|  |  |  | 			false, | 
					
						
							|  |  |  | 			maxID, | 
					
						
							|  |  |  | 			"", | 
					
						
							|  |  |  | 			false, | 
					
						
							|  |  |  | 			false, | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 		if err != nil && !errors.Is(err, db.ErrNoEntries) { | 
					
						
							|  |  |  | 			// Make sure we don't have a real error. | 
					
						
							|  |  |  | 			return err | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-08 10:33:03 +00:00
										 |  |  | 		if len(statuses) == 0 { | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 			break statusLoop | 
					
						
							| 
									
										
										
										
											2023-01-08 10:33:03 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 		// Update next maxID from last status. | 
					
						
							|  |  |  | 		maxID = statuses[len(statuses)-1].ID | 
					
						
							| 
									
										
										
										
											2022-07-10 16:18:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 		for _, status := range statuses { | 
					
						
							|  |  |  | 			status.Account = account // ensure account is set | 
					
						
							| 
									
										
										
										
											2022-11-20 14:57:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 			// Pass the status delete through the client api worker for processing. | 
					
						
							|  |  |  | 			msgs = append(msgs, messages.FromClientAPI{ | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 				APObjectType:   ap.ObjectNote, | 
					
						
							|  |  |  | 				APActivityType: ap.ActivityDelete, | 
					
						
							| 
									
										
										
										
											2022-11-20 14:57:19 +00:00
										 |  |  | 				GTSModel:       status, | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 				OriginAccount:  account, | 
					
						
							|  |  |  | 				TargetAccount:  account, | 
					
						
							| 
									
										
										
										
											2022-04-28 13:23:11 +01:00
										 |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 			// Look for any boosts of this status in DB. | 
					
						
							| 
									
										
										
										
											2023-08-04 12:28:33 +01:00
										 |  |  | 			boosts, err := p.state.DB.GetStatusBoosts(ctx, status.ID) | 
					
						
							| 
									
										
										
										
											2022-11-20 14:57:19 +00:00
										 |  |  | 			if err != nil && !errors.Is(err, db.ErrNoEntries) { | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 				return gtserror.Newf("error fetching status reblogs for %s: %w", status.ID, err) | 
					
						
							| 
									
										
										
										
											2022-11-20 14:57:19 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for _, boost := range boosts { | 
					
						
							|  |  |  | 				if boost.Account == nil { | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 					// Fetch the relevant account for this status boost. | 
					
						
							| 
									
										
										
										
											2023-03-01 18:26:53 +00:00
										 |  |  | 					boostAcc, err := p.state.DB.GetAccountByID(ctx, boost.AccountID) | 
					
						
							| 
									
										
										
										
											2022-11-20 14:57:19 +00:00
										 |  |  | 					if err != nil { | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 						if errors.Is(err, db.ErrNoEntries) { | 
					
						
							|  |  |  | 							// We don't have an account for this boost | 
					
						
							|  |  |  | 							// for some reason, so just skip processing. | 
					
						
							|  |  |  | 							log.WithContext(ctx).WithField("boost", boost).Warnf("no account found with id %s for boost %s", boost.AccountID, boost.ID) | 
					
						
							|  |  |  | 							continue | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 						return gtserror.Newf("error fetching boosted status account for %s: %w", boost.AccountID, err) | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2022-07-10 16:18:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-20 14:57:19 +00:00
										 |  |  | 					// Set account model | 
					
						
							|  |  |  | 					boost.Account = boostAcc | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 				// Pass the boost delete through the client api worker for processing. | 
					
						
							|  |  |  | 				msgs = append(msgs, messages.FromClientAPI{ | 
					
						
							| 
									
										
										
										
											2022-11-20 14:57:19 +00:00
										 |  |  | 					APObjectType:   ap.ActivityAnnounce, | 
					
						
							|  |  |  | 					APActivityType: ap.ActivityUndo, | 
					
						
							|  |  |  | 					GTSModel:       status, | 
					
						
							|  |  |  | 					OriginAccount:  boost.Account, | 
					
						
							|  |  |  | 					TargetAccount:  account, | 
					
						
							|  |  |  | 				}) | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	// Batch process all accreted messages. | 
					
						
							|  |  |  | 	p.state.Workers.EnqueueClientAPI(ctx, msgs...) | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | func (p *Processor) deleteAccountNotifications(ctx context.Context, account *gtsmodel.Account) error { | 
					
						
							| 
									
										
											  
											
												[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
											
										 
											2023-03-28 14:03:14 +01:00
										 |  |  | 	// Delete all notifications of all types targeting given account. | 
					
						
							|  |  |  | 	if err := p.state.DB.DeleteNotifications(ctx, nil, account.ID, ""); err != nil && !errors.Is(err, db.ErrNoEntries) { | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
											
										 
											2023-03-28 14:03:14 +01:00
										 |  |  | 	// Delete all notifications of all types originating from given account. | 
					
						
							|  |  |  | 	if err := p.state.DB.DeleteNotifications(ctx, nil, "", account.ID); err != nil && !errors.Is(err, db.ErrNoEntries) { | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (p *Processor) deleteAccountPeripheral(ctx context.Context, account *gtsmodel.Account) error { | 
					
						
							|  |  |  | 	// Delete all bookmarks owned by given account. | 
					
						
							|  |  |  | 	if err := p.state.DB.DeleteStatusBookmarks(ctx, account.ID, ""); // nocollapse | 
					
						
							|  |  |  | 	err != nil && !errors.Is(err, db.ErrNoEntries) { | 
					
						
							|  |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	// Delete all bookmarks targeting given account. | 
					
						
							|  |  |  | 	if err := p.state.DB.DeleteStatusBookmarks(ctx, "", account.ID); // nocollapse | 
					
						
							|  |  |  | 	err != nil && !errors.Is(err, db.ErrNoEntries) { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	// Delete all faves owned by given account. | 
					
						
							|  |  |  | 	if err := p.state.DB.DeleteStatusFaves(ctx, account.ID, ""); // nocollapse | 
					
						
							|  |  |  | 	err != nil && !errors.Is(err, db.ErrNoEntries) { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	// Delete all faves targeting given account. | 
					
						
							|  |  |  | 	if err := p.state.DB.DeleteStatusFaves(ctx, "", account.ID); // nocollapse | 
					
						
							|  |  |  | 	err != nil && !errors.Is(err, db.ErrNoEntries) { | 
					
						
							|  |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	// TODO: add status mutes here when they're implemented. | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // stubbifyAccount renders the given account as a stub, | 
					
						
							|  |  |  | // removing most information from it and marking it as | 
					
						
							|  |  |  | // suspended. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The origin parameter refers to the origin of the | 
					
						
							|  |  |  | // suspension action; should be an account ID or domain | 
					
						
							|  |  |  | // block ID. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // For caller's convenience, this function returns the db | 
					
						
							|  |  |  | // names of all columns that are updated by it. | 
					
						
							|  |  |  | func stubbifyAccount(account *gtsmodel.Account, origin string) []string { | 
					
						
							|  |  |  | 	var ( | 
					
						
							| 
									
										
										
										
											2023-08-07 19:38:11 +02:00
										 |  |  | 		now   = time.Now() | 
					
						
							|  |  |  | 		never = time.Time{} | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	account.FetchedAt = never | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	account.AvatarMediaAttachmentID = "" | 
					
						
							|  |  |  | 	account.AvatarRemoteURL = "" | 
					
						
							|  |  |  | 	account.HeaderMediaAttachmentID = "" | 
					
						
							|  |  |  | 	account.HeaderRemoteURL = "" | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	account.DisplayName = "" | 
					
						
							|  |  |  | 	account.EmojiIDs = nil | 
					
						
							|  |  |  | 	account.Emojis = nil | 
					
						
							|  |  |  | 	account.Fields = nil | 
					
						
							|  |  |  | 	account.Note = "" | 
					
						
							|  |  |  | 	account.NoteRaw = "" | 
					
						
							| 
									
										
										
										
											2023-08-07 19:38:11 +02:00
										 |  |  | 	account.Memorial = util.Ptr(false) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	account.AlsoKnownAs = "" | 
					
						
							|  |  |  | 	account.MovedToAccountID = "" | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 	account.Reason = "" | 
					
						
							| 
									
										
										
										
											2023-08-07 19:38:11 +02:00
										 |  |  | 	account.Discoverable = util.Ptr(false) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 	account.StatusContentType = "" | 
					
						
							|  |  |  | 	account.CustomCSS = "" | 
					
						
							|  |  |  | 	account.SuspendedAt = now | 
					
						
							| 
									
										
										
										
											2021-07-06 13:29:11 +02:00
										 |  |  | 	account.SuspensionOrigin = origin | 
					
						
							| 
									
										
										
										
											2023-08-07 19:38:11 +02:00
										 |  |  | 	account.HideCollections = util.Ptr(true) | 
					
						
							|  |  |  | 	account.EnableRSS = util.Ptr(false) | 
					
						
							| 
									
										
										
										
											2023-03-20 19:10:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return []string{ | 
					
						
							|  |  |  | 		"fetched_at", | 
					
						
							|  |  |  | 		"avatar_media_attachment_id", | 
					
						
							|  |  |  | 		"avatar_remote_url", | 
					
						
							|  |  |  | 		"header_media_attachment_id", | 
					
						
							|  |  |  | 		"header_remote_url", | 
					
						
							|  |  |  | 		"display_name", | 
					
						
							|  |  |  | 		"emojis", | 
					
						
							|  |  |  | 		"fields", | 
					
						
							|  |  |  | 		"note", | 
					
						
							|  |  |  | 		"note_raw", | 
					
						
							|  |  |  | 		"memorial", | 
					
						
							|  |  |  | 		"also_known_as", | 
					
						
							|  |  |  | 		"moved_to_account_id", | 
					
						
							|  |  |  | 		"reason", | 
					
						
							|  |  |  | 		"discoverable", | 
					
						
							|  |  |  | 		"status_content_type", | 
					
						
							|  |  |  | 		"custom_css", | 
					
						
							|  |  |  | 		"suspended_at", | 
					
						
							|  |  |  | 		"suspension_origin", | 
					
						
							|  |  |  | 		"hide_collections", | 
					
						
							|  |  |  | 		"enable_rss", | 
					
						
							| 
									
										
										
										
											2022-03-15 16:12:35 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-03-31 15:01:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // stubbifyUser renders the given user as a stub, | 
					
						
							|  |  |  | // removing sensitive information like IP addresses | 
					
						
							|  |  |  | // and sign-in times, but keeping email addresses to | 
					
						
							|  |  |  | // prevent the same email address from creating another | 
					
						
							|  |  |  | // account on this instance. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // `encrypted_password` is set to the bcrypt hash of a | 
					
						
							|  |  |  | // random uuid, so if the action is reversed, the user | 
					
						
							|  |  |  | // will have to reset their password via email. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // For caller's convenience, this function returns the db | 
					
						
							|  |  |  | // names of all columns that are updated by it. | 
					
						
							|  |  |  | func stubbifyUser(user *gtsmodel.User) ([]string, error) { | 
					
						
							|  |  |  | 	uuid, err := uuid.New().MarshalBinary() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dummyPassword, err := bcrypt.GenerateFromPassword(uuid, bcrypt.DefaultCost) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-31 11:25:29 +01:00
										 |  |  | 	never := time.Time{} | 
					
						
							| 
									
										
										
										
											2023-03-31 15:01:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	user.EncryptedPassword = string(dummyPassword) | 
					
						
							|  |  |  | 	user.SignUpIP = net.IPv4zero | 
					
						
							|  |  |  | 	user.CurrentSignInAt = never | 
					
						
							|  |  |  | 	user.CurrentSignInIP = net.IPv4zero | 
					
						
							|  |  |  | 	user.LastSignInAt = never | 
					
						
							|  |  |  | 	user.LastSignInIP = net.IPv4zero | 
					
						
							|  |  |  | 	user.SignInCount = 1 | 
					
						
							|  |  |  | 	user.Locale = "" | 
					
						
							|  |  |  | 	user.CreatedByApplicationID = "" | 
					
						
							|  |  |  | 	user.LastEmailedAt = never | 
					
						
							|  |  |  | 	user.ConfirmationToken = "" | 
					
						
							|  |  |  | 	user.ConfirmationSentAt = never | 
					
						
							|  |  |  | 	user.ResetPasswordToken = "" | 
					
						
							|  |  |  | 	user.ResetPasswordSentAt = never | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return []string{ | 
					
						
							|  |  |  | 		"encrypted_password", | 
					
						
							|  |  |  | 		"sign_up_ip", | 
					
						
							|  |  |  | 		"current_sign_in_at", | 
					
						
							|  |  |  | 		"current_sign_in_ip", | 
					
						
							|  |  |  | 		"last_sign_in_at", | 
					
						
							|  |  |  | 		"last_sign_in_ip", | 
					
						
							|  |  |  | 		"sign_in_count", | 
					
						
							|  |  |  | 		"locale", | 
					
						
							|  |  |  | 		"created_by_application_id", | 
					
						
							|  |  |  | 		"last_emailed_at", | 
					
						
							|  |  |  | 		"confirmation_token", | 
					
						
							|  |  |  | 		"confirmation_sent_at", | 
					
						
							|  |  |  | 		"reset_password_token", | 
					
						
							|  |  |  | 		"reset_password_sent_at", | 
					
						
							|  |  |  | 	}, nil | 
					
						
							|  |  |  | } |