diff options
| author | 2022-08-15 12:35:05 +0200 | |
|---|---|---|
| committer | 2022-08-15 11:35:05 +0100 | |
| commit | ac6ed3d939fe9dad81aadbd04541e905c625ca82 (patch) | |
| tree | 6116baf25675837dc99f69c49b9fec2ff112ce5c /internal/processing | |
| parent | [frontend] Sensitive media spoilers (#752) (diff) | |
| download | gotosocial-ac6ed3d939fe9dad81aadbd04541e905c625ca82.tar.xz | |
[chore] Update bun / sqlite versions; update gtsmodels (#754)
* upstep bun and sqlite versions
* allow specific columns to be updated in the db
* only update necessary columns for user
* bit tidier
* only update necessary fields of media_attachment
* only update relevant instance fields
* update tests
* update only specific account columns
* use bool pointers on gtsmodels
includes attachment, status, account, user
* update columns more selectively
* test all default fields on new account insert
* updating remaining bools on gtsmodels
* initialize pointer fields when extracting AP emoji
* copy bools properly
* add copyBoolPtr convenience function + test it
* initialize false bool ptrs a bit more neatly
Diffstat (limited to 'internal/processing')
24 files changed, 152 insertions, 84 deletions
| diff --git a/internal/processing/account/createfollow.go b/internal/processing/account/createfollow.go index 49430b9fb..7e7692135 100644 --- a/internal/processing/account/createfollow.go +++ b/internal/processing/account/createfollow.go @@ -76,19 +76,21 @@ func (p *processor) FollowCreate(ctx context.Context, requestingAccount *gtsmode  		return nil, gtserror.NewErrorInternalError(err)  	} +	showReblogs := true +	notify := false  	fr := >smodel.FollowRequest{  		ID:              newFollowID,  		AccountID:       requestingAccount.ID,  		TargetAccountID: form.ID, -		ShowReblogs:     true, +		ShowReblogs:     &showReblogs,  		URI:             uris.GenerateURIForFollow(requestingAccount.Username, newFollowID), -		Notify:          false, +		Notify:          ¬ify,  	}  	if form.Reblogs != nil { -		fr.ShowReblogs = *form.Reblogs +		fr.ShowReblogs = form.Reblogs  	}  	if form.Notify != nil { -		fr.Notify = *form.Notify +		fr.Notify = form.Notify  	}  	// whack it in the database @@ -97,7 +99,7 @@ func (p *processor) FollowCreate(ctx context.Context, requestingAccount *gtsmode  	}  	// if it's a local account that's not locked we can just straight up accept the follow request -	if !targetAcct.Locked && targetAcct.Domain == "" { +	if !*targetAcct.Locked && targetAcct.Domain == "" {  		if _, err := p.db.AcceptFollowRequest(ctx, requestingAccount.ID, form.ID); err != nil {  			return nil, gtserror.NewErrorInternalError(fmt.Errorf("accountfollowcreate: error accepting folow request for local unlocked account: %s", err))  		} diff --git a/internal/processing/account/delete.go b/internal/processing/account/delete.go index 7b382f17c..f71f08954 100644 --- a/internal/processing/account/delete.go +++ b/internal/processing/account/delete.go @@ -285,8 +285,10 @@ selectStatusesLoop:  	account.HeaderRemoteURL = ""  	account.Reason = ""  	account.Fields = []gtsmodel.Field{} -	account.HideCollections = true -	account.Discoverable = false +	hideCollections := true +	account.HideCollections = &hideCollections +	discoverable := false +	account.Discoverable = &discoverable  	account.SuspendedAt = time.Now()  	account.SuspensionOrigin = origin diff --git a/internal/processing/account/update.go b/internal/processing/account/update.go index 804e7ba7e..3b844a160 100644 --- a/internal/processing/account/update.go +++ b/internal/processing/account/update.go @@ -39,11 +39,11 @@ import (  func (p *processor) Update(ctx context.Context, account *gtsmodel.Account, form *apimodel.UpdateCredentialsRequest) (*apimodel.Account, gtserror.WithCode) {  	if form.Discoverable != nil { -		account.Discoverable = *form.Discoverable +		account.Discoverable = form.Discoverable  	}  	if form.Bot != nil { -		account.Bot = *form.Bot +		account.Bot = form.Bot  	}  	if form.DisplayName != nil { @@ -92,7 +92,7 @@ func (p *processor) Update(ctx context.Context, account *gtsmodel.Account, form  	}  	if form.Locked != nil { -		account.Locked = *form.Locked +		account.Locked = form.Locked  	}  	if form.Source != nil { @@ -104,7 +104,7 @@ func (p *processor) Update(ctx context.Context, account *gtsmodel.Account, form  		}  		if form.Source.Sensitive != nil { -			account.Sensitive = *form.Source.Sensitive +			account.Sensitive = form.Source.Sensitive  		}  		if form.Source.Privacy != nil { diff --git a/internal/processing/account/update_test.go b/internal/processing/account/update_test.go index 7e4ca818e..0483154c6 100644 --- a/internal/processing/account/update_test.go +++ b/internal/processing/account/update_test.go @@ -65,7 +65,7 @@ func (suite *AccountUpdateTestSuite) TestAccountUpdateSimple() {  	// fields should be updated in the database as well  	dbAccount, err := suite.db.GetAccountByID(context.Background(), testAccount.ID)  	suite.NoError(err) -	suite.True(dbAccount.Locked) +	suite.True(*dbAccount.Locked)  	suite.Equal(displayName, dbAccount.DisplayName)  	suite.Equal(`<p><a href="http://localhost:8080/tags/hello" class="mention hashtag" rel="tag nofollow noreferrer noopener" target="_blank">#<span>hello</span></a> here i am!</p>`, dbAccount.Note)  } @@ -107,7 +107,7 @@ func (suite *AccountUpdateTestSuite) TestAccountUpdateWithMention() {  	// fields should be updated in the database as well  	dbAccount, err := suite.db.GetAccountByID(context.Background(), testAccount.ID)  	suite.NoError(err) -	suite.True(dbAccount.Locked) +	suite.True(*dbAccount.Locked)  	suite.Equal(displayName, dbAccount.DisplayName)  	suite.Equal(noteExpected, dbAccount.Note)  } diff --git a/internal/processing/admin/createdomainblock.go b/internal/processing/admin/createdomainblock.go index b42445380..969cb52de 100644 --- a/internal/processing/admin/createdomainblock.go +++ b/internal/processing/admin/createdomainblock.go @@ -62,7 +62,7 @@ func (p *processor) DomainBlockCreate(ctx context.Context, account *gtsmodel.Acc  			CreatedByAccountID: account.ID,  			PrivateComment:     text.SanitizePlaintext(privateComment),  			PublicComment:      text.SanitizePlaintext(publicComment), -			Obfuscate:          obfuscate, +			Obfuscate:          &obfuscate,  			SubscriptionID:     subscriptionID,  		} @@ -101,6 +101,19 @@ func (p *processor) initiateDomainBlockSideEffects(ctx context.Context, account  	// if we have an instance entry for this domain, update it with the new block ID and clear all fields  	instance := >smodel.Instance{}  	if err := p.db.GetWhere(ctx, []db.Where{{Key: "domain", Value: block.Domain}}, instance); err == nil { +		updatingColumns := []string{ +			"title", +			"updated_at", +			"suspended_at", +			"domain_block_id", +			"short_description", +			"description", +			"terms", +			"contact_email", +			"contact_account_username", +			"contact_account_id", +			"version", +		}  		instance.Title = ""  		instance.UpdatedAt = time.Now()  		instance.SuspendedAt = time.Now() @@ -112,7 +125,7 @@ func (p *processor) initiateDomainBlockSideEffects(ctx context.Context, account  		instance.ContactAccountUsername = ""  		instance.ContactAccountID = ""  		instance.Version = "" -		if err := p.db.UpdateByPrimaryKey(ctx, instance); err != nil { +		if err := p.db.UpdateByPrimaryKey(ctx, instance, updatingColumns...); err != nil {  			l.Errorf("domainBlockProcessSideEffects: db error updating instance: %s", err)  		}  		l.Debug("domainBlockProcessSideEffects: instance entry updated") diff --git a/internal/processing/admin/deletedomainblock.go b/internal/processing/admin/deletedomainblock.go index 832b9256e..29e911888 100644 --- a/internal/processing/admin/deletedomainblock.go +++ b/internal/processing/admin/deletedomainblock.go @@ -58,9 +58,11 @@ func (p *processor) DomainBlockDelete(ctx context.Context, account *gtsmodel.Acc  		{Key: "domain", Value: domainBlock.Domain, CaseInsensitive: true},  		{Key: "domain_block_id", Value: id},  	}, i); err == nil { +		updatingColumns := []string{"suspended_at", "domain_block_id", "updated_at"}  		i.SuspendedAt = time.Time{}  		i.DomainBlockID = "" -		if err := p.db.UpdateByPrimaryKey(ctx, i); err != nil { +		i.UpdatedAt = time.Now() +		if err := p.db.UpdateByPrimaryKey(ctx, i, updatingColumns...); err != nil {  			return nil, gtserror.NewErrorInternalError(fmt.Errorf("couldn't update database entry for instance %s: %s", domainBlock.Domain, err))  		}  	} diff --git a/internal/processing/admin/emoji.go b/internal/processing/admin/emoji.go index f91f972a8..36657a6aa 100644 --- a/internal/processing/admin/emoji.go +++ b/internal/processing/admin/emoji.go @@ -33,7 +33,7 @@ import (  )  func (p *processor) EmojiCreate(ctx context.Context, account *gtsmodel.Account, user *gtsmodel.User, form *apimodel.EmojiCreateRequest) (*apimodel.Emoji, gtserror.WithCode) { -	if !user.Admin { +	if !*user.Admin {  		return nil, gtserror.NewErrorUnauthorized(fmt.Errorf("user %s not an admin", user.ID), "user is not an admin")  	} diff --git a/internal/processing/fromclientapi.go b/internal/processing/fromclientapi.go index 0f684f200..2c4f20d81 100644 --- a/internal/processing/fromclientapi.go +++ b/internal/processing/fromclientapi.go @@ -392,7 +392,7 @@ func (p *processor) federateAccountDelete(ctx context.Context, account *gtsmodel  func (p *processor) federateStatus(ctx context.Context, status *gtsmodel.Status) error {  	// do nothing if the status shouldn't be federated -	if !status.Federated { +	if !*status.Federated {  		return nil  	} diff --git a/internal/processing/fromclientapi_test.go b/internal/processing/fromclientapi_test.go index 014266b37..0e620c9e9 100644 --- a/internal/processing/fromclientapi_test.go +++ b/internal/processing/fromclientapi_test.go @@ -66,20 +66,21 @@ func (suite *FromClientAPITestSuite) TestProcessStreamNewStatus() {  		EmojiIDs:                 []string{},  		CreatedAt:                testrig.TimeMustParse("2021-10-20T11:36:45Z"),  		UpdatedAt:                testrig.TimeMustParse("2021-10-20T11:36:45Z"), -		Local:                    true, +		Local:                    testrig.TrueBool(),  		AccountURI:               "http://localhost:8080/users/admin",  		AccountID:                "01F8MH17FWEB39HZJ76B6VXSKF",  		InReplyToID:              "",  		BoostOfID:                "",  		ContentWarning:           "",  		Visibility:               gtsmodel.VisibilityFollowersOnly, -		Sensitive:                false, +		Sensitive:                testrig.FalseBool(),  		Language:                 "en",  		CreatedWithApplicationID: "01F8MGXQRHYF5QPMTMXP78QC2F", -		Federated:                false, // set federated as false for this one, since we're not testing federation stuff now -		Boostable:                true, -		Replyable:                true, -		Likeable:                 true, +		Pinned:                   testrig.FalseBool(), +		Federated:                testrig.FalseBool(), +		Boostable:                testrig.TrueBool(), +		Replyable:                testrig.TrueBool(), +		Likeable:                 testrig.TrueBool(),  		ActivityStreamsType:      ap.ObjectNote,  	} diff --git a/internal/processing/fromfederator.go b/internal/processing/fromfederator.go index 132b33f4c..ad8273869 100644 --- a/internal/processing/fromfederator.go +++ b/internal/processing/fromfederator.go @@ -259,7 +259,7 @@ func (p *processor) processCreateFollowRequestFromFederator(ctx context.Context,  		followRequest.TargetAccount = a  	} -	if followRequest.TargetAccount.Locked { +	if *followRequest.TargetAccount.Locked {  		// if the account is locked just notify the follow request and nothing else  		return p.notifyFollowRequest(ctx, followRequest)  	} diff --git a/internal/processing/fromfederator_test.go b/internal/processing/fromfederator_test.go index 4d339cb18..86b63dade 100644 --- a/internal/processing/fromfederator_test.go +++ b/internal/processing/fromfederator_test.go @@ -84,13 +84,14 @@ func (suite *FromFederatorTestSuite) TestProcessFederationAnnounce() {  	suite.Equal(boostedStatus.AccountID, notif.TargetAccountID)  	suite.Equal(announceStatus.AccountID, notif.OriginAccountID)  	suite.Equal(announceStatus.ID, notif.StatusID) -	suite.False(notif.Read) +	suite.False(*notif.Read)  }  func (suite *FromFederatorTestSuite) TestProcessReplyMention() {  	repliedAccount := suite.testAccounts["local_account_1"]  	repliedStatus := suite.testStatuses["local_account_1_status_1"]  	replyingAccount := suite.testAccounts["remote_account_1"] +  	replyingStatus := >smodel.Status{  		CreatedAt: time.Now(),  		UpdatedAt: time.Now(), @@ -110,10 +111,10 @@ func (suite *FromFederatorTestSuite) TestProcessReplyMention() {  		InReplyToAccountID:  repliedAccount.ID,  		Visibility:          gtsmodel.VisibilityUnlocked,  		ActivityStreamsType: ap.ObjectNote, -		Federated:           true, -		Boostable:           true, -		Replyable:           true, -		Likeable:            true, +		Federated:           testrig.TrueBool(), +		Boostable:           testrig.TrueBool(), +		Replyable:           testrig.TrueBool(), +		Likeable:            testrig.FalseBool(),  	}  	wssStream, errWithCode := suite.processor.OpenStreamForAccount(context.Background(), repliedAccount, stream.TimelineHome) @@ -156,10 +157,17 @@ func (suite *FromFederatorTestSuite) TestProcessReplyMention() {  	suite.Equal(replyingStatus.InReplyToAccountID, notif.TargetAccountID)  	suite.Equal(replyingStatus.AccountID, notif.OriginAccountID)  	suite.Equal(replyingStatus.ID, notif.StatusID) -	suite.False(notif.Read) +	suite.False(*notif.Read) + +	// the notification should be streamed +	var msg *stream.Message +	select { +	case msg = <-wssStream.Messages: +		// fine +	case <-time.After(5 * time.Second): +		suite.FailNow("no message from wssStream") +	} -	// the notification should also be streamed -	msg := <-wssStream.Messages  	suite.Equal(stream.EventTypeNotification, msg.Event)  	suite.NotEmpty(msg.Payload)  	suite.EqualValues([]string{stream.TimelineHome}, msg.Stream) @@ -222,10 +230,16 @@ func (suite *FromFederatorTestSuite) TestProcessFave() {  	suite.Equal(fave.TargetAccountID, notif.TargetAccountID)  	suite.Equal(fave.AccountID, notif.OriginAccountID)  	suite.Equal(fave.StatusID, notif.StatusID) -	suite.False(notif.Read) +	suite.False(*notif.Read)  	// 2. a notification should be streamed -	msg := <-wssStream.Messages +	var msg *stream.Message +	select { +	case msg = <-wssStream.Messages: +		// fine +	case <-time.After(5 * time.Second): +		suite.FailNow("no message from wssStream") +	}  	suite.Equal(stream.EventTypeNotification, msg.Event)  	suite.NotEmpty(msg.Payload)  	suite.EqualValues([]string{stream.TimelineNotifications}, msg.Stream) @@ -289,7 +303,7 @@ func (suite *FromFederatorTestSuite) TestProcessFaveWithDifferentReceivingAccoun  	suite.Equal(fave.TargetAccountID, notif.TargetAccountID)  	suite.Equal(fave.AccountID, notif.OriginAccountID)  	suite.Equal(fave.StatusID, notif.StatusID) -	suite.False(notif.Read) +	suite.False(*notif.Read)  	// 2. no notification should be streamed to the account that received the fave message, because they weren't the target  	suite.Empty(wssStream.Messages) @@ -309,9 +323,9 @@ func (suite *FromFederatorTestSuite) TestProcessAccountDelete() {  		UpdatedAt:       time.Now().Add(-1 * time.Hour),  		AccountID:       deletedAccount.ID,  		TargetAccountID: receivingAccount.ID, -		ShowReblogs:     true, +		ShowReblogs:     testrig.TrueBool(),  		URI:             fmt.Sprintf("%s/follows/01FGRY72ASHBSET64353DPHK9T", deletedAccount.URI), -		Notify:          false, +		Notify:          testrig.FalseBool(),  	}  	err := suite.db.Put(ctx, zorkFollowSatan)  	suite.NoError(err) @@ -322,9 +336,9 @@ func (suite *FromFederatorTestSuite) TestProcessAccountDelete() {  		UpdatedAt:       time.Now().Add(-1 * time.Hour),  		AccountID:       receivingAccount.ID,  		TargetAccountID: deletedAccount.ID, -		ShowReblogs:     true, +		ShowReblogs:     testrig.TrueBool(),  		URI:             fmt.Sprintf("%s/follows/01FGRYAVAWWPP926J175QGM0WV", receivingAccount.URI), -		Notify:          false, +		Notify:          testrig.FalseBool(),  	}  	err = suite.db.Put(ctx, satanFollowZork)  	suite.NoError(err) @@ -369,8 +383,8 @@ func (suite *FromFederatorTestSuite) TestProcessAccountDelete() {  	suite.Empty(dbAccount.HeaderRemoteURL)  	suite.Empty(dbAccount.Reason)  	suite.Empty(dbAccount.Fields) -	suite.True(dbAccount.HideCollections) -	suite.False(dbAccount.Discoverable) +	suite.True(*dbAccount.HideCollections) +	suite.False(*dbAccount.Discoverable)  	suite.WithinDuration(time.Now(), dbAccount.SuspendedAt, 30*time.Second)  	suite.Equal(dbAccount.ID, dbAccount.SuspensionOrigin)  } @@ -395,9 +409,9 @@ func (suite *FromFederatorTestSuite) TestProcessFollowRequestLocked() {  		Account:         originAccount,  		TargetAccountID: targetAccount.ID,  		TargetAccount:   targetAccount, -		ShowReblogs:     true, +		ShowReblogs:     testrig.TrueBool(),  		URI:             fmt.Sprintf("%s/follows/01FGRYAVAWWPP926J175QGM0WV", originAccount.URI), -		Notify:          false, +		Notify:          testrig.FalseBool(),  	}  	err := suite.db.Put(ctx, satanFollowRequestTurtle) @@ -412,7 +426,13 @@ func (suite *FromFederatorTestSuite) TestProcessFollowRequestLocked() {  	suite.NoError(err)  	// a notification should be streamed -	msg := <-wssStream.Messages +	var msg *stream.Message +	select { +	case msg = <-wssStream.Messages: +		// fine +	case <-time.After(5 * time.Second): +		suite.FailNow("no message from wssStream") +	}  	suite.Equal(stream.EventTypeNotification, msg.Event)  	suite.NotEmpty(msg.Payload)  	suite.EqualValues([]string{stream.TimelineHome}, msg.Stream) @@ -446,9 +466,9 @@ func (suite *FromFederatorTestSuite) TestProcessFollowRequestUnlocked() {  		Account:         originAccount,  		TargetAccountID: targetAccount.ID,  		TargetAccount:   targetAccount, -		ShowReblogs:     true, +		ShowReblogs:     testrig.TrueBool(),  		URI:             fmt.Sprintf("%s/follows/01FGRYAVAWWPP926J175QGM0WV", originAccount.URI), -		Notify:          false, +		Notify:          testrig.FalseBool(),  	}  	err := suite.db.Put(ctx, satanFollowRequestTurtle) @@ -463,7 +483,13 @@ func (suite *FromFederatorTestSuite) TestProcessFollowRequestUnlocked() {  	suite.NoError(err)  	// a notification should be streamed -	msg := <-wssStream.Messages +	var msg *stream.Message +	select { +	case msg = <-wssStream.Messages: +		// fine +	case <-time.After(5 * time.Second): +		suite.FailNow("no message from wssStream") +	}  	suite.Equal(stream.EventTypeNotification, msg.Event)  	suite.NotEmpty(msg.Payload)  	suite.EqualValues([]string{stream.TimelineHome}, msg.Stream) diff --git a/internal/processing/instance.go b/internal/processing/instance.go index 4d1e8b8fd..0a13917ea 100644 --- a/internal/processing/instance.go +++ b/internal/processing/instance.go @@ -81,7 +81,7 @@ func (p *processor) InstancePeersGet(ctx context.Context, authed *oauth.Auth, in  		}  		for _, d := range domainBlocks { -			if d.Obfuscate { +			if *d.Obfuscate {  				d.Domain = obfuscate(d.Domain)  			} @@ -123,11 +123,14 @@ func (p *processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSe  		return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error fetching instance account %s: %s", host, err))  	} +	updatingColumns := []string{} +  	// validate & update site title if it's set on the form  	if form.Title != nil {  		if err := validate.SiteTitle(*form.Title); err != nil {  			return nil, gtserror.NewErrorBadRequest(err, fmt.Sprintf("site title invalid: %s", err))  		} +		updatingColumns = append(updatingColumns, "title")  		i.Title = text.SanitizePlaintext(*form.Title) // don't allow html in site title  	} @@ -153,15 +156,16 @@ func (p *processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSe  			err := fmt.Errorf("user of selected contact account %s is not confirmed", contactAccount.Username)  			return nil, gtserror.NewErrorBadRequest(err, err.Error())  		} -		if !contactUser.Approved { +		if !*contactUser.Approved {  			err := fmt.Errorf("user of selected contact account %s is not approved", contactAccount.Username)  			return nil, gtserror.NewErrorBadRequest(err, err.Error())  		}  		// contact account user must be admin or moderator otherwise what's the point of contacting them -		if !contactUser.Admin && !contactUser.Moderator { +		if !*contactUser.Admin && !*contactUser.Moderator {  			err := fmt.Errorf("user of selected contact account %s is neither admin nor moderator", contactAccount.Username)  			return nil, gtserror.NewErrorBadRequest(err, err.Error())  		} +		updatingColumns = append(updatingColumns, "contact_account_id")  		i.ContactAccountID = contactAccount.ID  	} @@ -173,6 +177,7 @@ func (p *processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSe  				return nil, gtserror.NewErrorBadRequest(err, err.Error())  			}  		} +		updatingColumns = append(updatingColumns, "contact_email")  		i.ContactEmail = contactEmail  	} @@ -181,6 +186,7 @@ func (p *processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSe  		if err := validate.SiteShortDescription(*form.ShortDescription); err != nil {  			return nil, gtserror.NewErrorBadRequest(err, err.Error())  		} +		updatingColumns = append(updatingColumns, "short_description")  		i.ShortDescription = text.SanitizeHTML(*form.ShortDescription) // html is OK in site description, but we should sanitize it  	} @@ -189,6 +195,7 @@ func (p *processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSe  		if err := validate.SiteDescription(*form.Description); err != nil {  			return nil, gtserror.NewErrorBadRequest(err, err.Error())  		} +		updatingColumns = append(updatingColumns, "description")  		i.Description = text.SanitizeHTML(*form.Description) // html is OK in site description, but we should sanitize it  	} @@ -197,6 +204,7 @@ func (p *processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSe  		if err := validate.SiteTerms(*form.Terms); err != nil {  			return nil, gtserror.NewErrorBadRequest(err, err.Error())  		} +		updatingColumns = append(updatingColumns, "terms")  		i.Terms = text.SanitizeHTML(*form.Terms) // html is OK in site terms, but we should sanitize it  	} @@ -216,7 +224,7 @@ func (p *processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSe  		}  	} -	if err := p.db.UpdateByPrimaryKey(ctx, i); err != nil { +	if err := p.db.UpdateByPrimaryKey(ctx, i, updatingColumns...); err != nil {  		return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error updating instance %s: %s", host, err))  	} diff --git a/internal/processing/media/getfile.go b/internal/processing/media/getfile.go index 3227cb8c8..52cdcc052 100644 --- a/internal/processing/media/getfile.go +++ b/internal/processing/media/getfile.go @@ -112,7 +112,7 @@ func (p *processor) getAttachmentContent(ctx context.Context, requestingAccount  	}  	// if we have the media cached on our server already, we can now simply return it from storage -	if a.Cached { +	if *a.Cached {  		return p.retrieveFromStorage(ctx, storagePath, attachmentContent)  	} @@ -236,7 +236,7 @@ func (p *processor) getEmojiContent(ctx context.Context, wantedEmojiID string, e  		return nil, gtserror.NewErrorNotFound(fmt.Errorf("emoji %s could not be taken from the db: %s", wantedEmojiID, err))  	} -	if e.Disabled { +	if *e.Disabled {  		return nil, gtserror.NewErrorNotFound(fmt.Errorf("emoji %s has been disabled", wantedEmojiID))  	} diff --git a/internal/processing/media/getfile_test.go b/internal/processing/media/getfile_test.go index 7c6525abe..6ba06426f 100644 --- a/internal/processing/media/getfile_test.go +++ b/internal/processing/media/getfile_test.go @@ -28,6 +28,7 @@ import (  	"github.com/stretchr/testify/suite"  	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"  	"github.com/superseriousbusiness/gotosocial/internal/media" +	"github.com/superseriousbusiness/gotosocial/testrig"  )  type GetFileTestSuite struct { @@ -67,8 +68,8 @@ func (suite *GetFileTestSuite) TestGetRemoteFileUncached() {  	// uncache the file from local  	testAttachment := suite.testAttachments["remote_account_1_status_1_attachment_1"] -	testAttachment.Cached = false -	err := suite.db.UpdateByPrimaryKey(ctx, testAttachment) +	testAttachment.Cached = testrig.FalseBool() +	err := suite.db.UpdateByPrimaryKey(ctx, testAttachment, "cached")  	suite.NoError(err)  	err = suite.storage.Delete(ctx, testAttachment.File.Path)  	suite.NoError(err) @@ -103,7 +104,7 @@ func (suite *GetFileTestSuite) TestGetRemoteFileUncached() {  	// the attachment should be updated in the database  	dbAttachment, err := suite.db.GetAttachmentByID(ctx, testAttachment.ID)  	suite.NoError(err) -	suite.True(dbAttachment.Cached) +	suite.True(*dbAttachment.Cached)  	// the file should be back in storage at the same path as before  	refreshedBytes, err := suite.storage.Get(ctx, testAttachment.File.Path) @@ -116,8 +117,8 @@ func (suite *GetFileTestSuite) TestGetRemoteFileUncachedInterrupted() {  	// uncache the file from local  	testAttachment := suite.testAttachments["remote_account_1_status_1_attachment_1"] -	testAttachment.Cached = false -	err := suite.db.UpdateByPrimaryKey(ctx, testAttachment) +	testAttachment.Cached = testrig.FalseBool() +	err := suite.db.UpdateByPrimaryKey(ctx, testAttachment, "cached")  	suite.NoError(err)  	err = suite.storage.Delete(ctx, testAttachment.File.Path)  	suite.NoError(err) @@ -153,7 +154,7 @@ func (suite *GetFileTestSuite) TestGetRemoteFileUncachedInterrupted() {  	// the attachment should still be updated in the database even though the caller hung up  	dbAttachment, err := suite.db.GetAttachmentByID(ctx, testAttachment.ID)  	suite.NoError(err) -	suite.True(dbAttachment.Cached) +	suite.True(*dbAttachment.Cached)  	// the file should be back in storage at the same path as before  	refreshedBytes, err := suite.storage.Get(ctx, testAttachment.File.Path) @@ -170,8 +171,8 @@ func (suite *GetFileTestSuite) TestGetRemoteFileThumbnailUncached() {  	suite.NoError(err)  	// uncache the file from local -	testAttachment.Cached = false -	err = suite.db.UpdateByPrimaryKey(ctx, testAttachment) +	testAttachment.Cached = testrig.FalseBool() +	err = suite.db.UpdateByPrimaryKey(ctx, testAttachment, "cached")  	suite.NoError(err)  	err = suite.storage.Delete(ctx, testAttachment.File.Path)  	suite.NoError(err) diff --git a/internal/processing/media/unattach.go b/internal/processing/media/unattach.go index bb09525fe..5ef8f81f4 100644 --- a/internal/processing/media/unattach.go +++ b/internal/processing/media/unattach.go @@ -43,10 +43,11 @@ func (p *processor) Unattach(ctx context.Context, account *gtsmodel.Account, med  		return nil, gtserror.NewErrorNotFound(errors.New("attachment not owned by requesting account"))  	} +	updatingColumns := []string{"updated_at", "status_id"}  	attachment.UpdatedAt = time.Now()  	attachment.StatusID = "" -	if err := p.db.UpdateByPrimaryKey(ctx, attachment); err != nil { +	if err := p.db.UpdateByPrimaryKey(ctx, attachment, updatingColumns...); err != nil {  		return nil, gtserror.NewErrorNotFound(fmt.Errorf("db error updating attachment: %s", err))  	} diff --git a/internal/processing/media/unattach_test.go b/internal/processing/media/unattach_test.go index 60efc2688..7572741ac 100644 --- a/internal/processing/media/unattach_test.go +++ b/internal/processing/media/unattach_test.go @@ -30,7 +30,7 @@ type UnattachTestSuite struct {  	MediaStandardTestSuite  } -func (suite *GetFileTestSuite) TestUnattachMedia() { +func (suite *UnattachTestSuite) TestUnattachMedia() {  	ctx := context.Background()  	testAttachment := suite.testAttachments["admin_account_status_1_attachment_1"] diff --git a/internal/processing/media/update.go b/internal/processing/media/update.go index 116588a48..b8177eeb4 100644 --- a/internal/processing/media/update.go +++ b/internal/processing/media/update.go @@ -44,11 +44,11 @@ func (p *processor) Update(ctx context.Context, account *gtsmodel.Account, media  		return nil, gtserror.NewErrorNotFound(errors.New("attachment not owned by requesting account"))  	} +	updatingColumns := []string{} +  	if form.Description != nil {  		attachment.Description = text.SanitizePlaintext(*form.Description) -		if err := p.db.UpdateByPrimaryKey(ctx, attachment); err != nil { -			return nil, gtserror.NewErrorInternalError(fmt.Errorf("database error updating description: %s", err)) -		} +		updatingColumns = append(updatingColumns, "description")  	}  	if form.Focus != nil { @@ -58,9 +58,11 @@ func (p *processor) Update(ctx context.Context, account *gtsmodel.Account, media  		}  		attachment.FileMeta.Focus.X = focusx  		attachment.FileMeta.Focus.Y = focusy -		if err := p.db.UpdateByPrimaryKey(ctx, attachment); err != nil { -			return nil, gtserror.NewErrorInternalError(fmt.Errorf("database error updating focus: %s", err)) -		} +		updatingColumns = append(updatingColumns, "focus_x", "focus_y") +	} + +	if err := p.db.UpdateByPrimaryKey(ctx, attachment, updatingColumns...); err != nil { +		return nil, gtserror.NewErrorInternalError(fmt.Errorf("database error updating media: %s", err))  	}  	a, err := p.tc.AttachmentToAPIAttachment(ctx, attachment) diff --git a/internal/processing/status/create.go b/internal/processing/status/create.go index 2c509809a..fef857c7c 100644 --- a/internal/processing/status/create.go +++ b/internal/processing/status/create.go @@ -40,18 +40,21 @@ func (p *processor) Create(ctx context.Context, account *gtsmodel.Account, appli  		return nil, gtserror.NewErrorInternalError(err)  	} +	local := true +	sensitive := form.Sensitive +  	newStatus := >smodel.Status{  		ID:                       thisStatusID,  		URI:                      accountURIs.StatusesURI + "/" + thisStatusID,  		URL:                      accountURIs.StatusesURL + "/" + thisStatusID,  		CreatedAt:                time.Now(),  		UpdatedAt:                time.Now(), -		Local:                    true, +		Local:                    &local,  		AccountID:                account.ID,  		AccountURI:               account.URI,  		ContentWarning:           text.SanitizePlaintext(form.SpoilerText),  		ActivityStreamsType:      ap.ObjectNote, -		Sensitive:                form.Sensitive, +		Sensitive:                &sensitive,  		Language:                 form.Language,  		CreatedWithApplicationID: application.ID,  		Text:                     form.Status, diff --git a/internal/processing/status/fave.go b/internal/processing/status/fave.go index 1b40d9da1..f80d65358 100644 --- a/internal/processing/status/fave.go +++ b/internal/processing/status/fave.go @@ -49,7 +49,7 @@ func (p *processor) Fave(ctx context.Context, requestingAccount *gtsmodel.Accoun  	if !visible {  		return nil, gtserror.NewErrorNotFound(errors.New("status is not visible"))  	} -	if !targetStatus.Likeable { +	if !*targetStatus.Likeable {  		return nil, gtserror.NewErrorForbidden(errors.New("status is not faveable"))  	} diff --git a/internal/processing/status/util.go b/internal/processing/status/util.go index 64b496673..5e961e2ea 100644 --- a/internal/processing/status/util.go +++ b/internal/processing/status/util.go @@ -98,10 +98,10 @@ func (p *processor) ProcessVisibility(ctx context.Context, form *apimodel.Advanc  	}  	status.Visibility = vis -	status.Federated = federated -	status.Boostable = boostable -	status.Replyable = replyable -	status.Likeable = likeable +	status.Federated = &federated +	status.Boostable = &boostable +	status.Replyable = &replyable +	status.Likeable = &likeable  	return nil  } @@ -128,7 +128,7 @@ func (p *processor) ProcessReplyToID(ctx context.Context, form *apimodel.Advance  		err := fmt.Errorf("db error fetching status with id %s: %s", form.InReplyToID, err)  		return gtserror.NewErrorInternalError(err)  	} -	if !repliedStatus.Replyable { +	if !*repliedStatus.Replyable {  		err := fmt.Errorf("status with id %s is marked as not replyable", form.InReplyToID)  		return gtserror.NewErrorForbidden(err, err.Error())  	} diff --git a/internal/processing/user/changepassword.go b/internal/processing/user/changepassword.go index 50c7a7517..ddfec6898 100644 --- a/internal/processing/user/changepassword.go +++ b/internal/processing/user/changepassword.go @@ -20,6 +20,7 @@ package user  import (  	"context" +	"time"  	"github.com/superseriousbusiness/gotosocial/internal/gtserror"  	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" @@ -42,7 +43,9 @@ func (p *processor) ChangePassword(ctx context.Context, user *gtsmodel.User, old  	}  	user.EncryptedPassword = string(newPasswordHash) -	if err := p.db.UpdateByPrimaryKey(ctx, user); err != nil { +	user.UpdatedAt = time.Now() + +	if err := p.db.UpdateByPrimaryKey(ctx, user, "encrypted_password", "updated_at"); err != nil {  		return gtserror.NewErrorInternalError(err, "database error")  	} diff --git a/internal/processing/user/emailconfirm.go b/internal/processing/user/emailconfirm.go index eccaae5ec..6bffce7d9 100644 --- a/internal/processing/user/emailconfirm.go +++ b/internal/processing/user/emailconfirm.go @@ -71,12 +71,13 @@ func (p *processor) SendConfirmEmail(ctx context.Context, user *gtsmodel.User, u  	}  	// email sent, now we need to update the user entry with the token we just sent them +	updatingColumns := []string{"confirmation_sent_at", "confirmation_token", "last_emailed_at", "updated_at"}  	user.ConfirmationSentAt = time.Now()  	user.ConfirmationToken = confirmationToken  	user.LastEmailedAt = time.Now()  	user.UpdatedAt = time.Now() -	if err := p.db.UpdateByPrimaryKey(ctx, user); err != nil { +	if err := p.db.UpdateByPrimaryKey(ctx, user, updatingColumns...); err != nil {  		return fmt.Errorf("SendConfirmEmail: error updating user entry after email sent: %s", err)  	} @@ -118,13 +119,14 @@ func (p *processor) ConfirmEmail(ctx context.Context, token string) (*gtsmodel.U  	}  	// mark the user's email address as confirmed + remove the unconfirmed address and the token +	updatingColumns := []string{"email", "unconfirmed_email", "confirmed_at", "confirmation_token", "updated_at"}  	user.Email = user.UnconfirmedEmail  	user.UnconfirmedEmail = ""  	user.ConfirmedAt = time.Now()  	user.ConfirmationToken = ""  	user.UpdatedAt = time.Now() -	if err := p.db.UpdateByPrimaryKey(ctx, user); err != nil { +	if err := p.db.UpdateByPrimaryKey(ctx, user, updatingColumns...); err != nil {  		return nil, gtserror.NewErrorInternalError(err)  	} diff --git a/internal/processing/user/emailconfirm_test.go b/internal/processing/user/emailconfirm_test.go index 6f22306a1..87aff9756 100644 --- a/internal/processing/user/emailconfirm_test.go +++ b/internal/processing/user/emailconfirm_test.go @@ -67,13 +67,14 @@ func (suite *EmailConfirmTestSuite) TestConfirmEmail() {  	user := suite.testUsers["local_account_1"]  	// set a bunch of stuff on the user as though zork hasn't been confirmed yet, but has had an email sent 5 minutes ago +	updatingColumns := []string{"unconfirmed_email", "email", "confirmed_at", "confirmation_sent_at", "confirmation_token"}  	user.UnconfirmedEmail = "some.email@example.org"  	user.Email = ""  	user.ConfirmedAt = time.Time{}  	user.ConfirmationSentAt = time.Now().Add(-5 * time.Minute)  	user.ConfirmationToken = "1d1aa44b-afa4-49c8-ac4b-eceb61715cc6" -	err := suite.db.UpdateByPrimaryKey(ctx, user) +	err := suite.db.UpdateByPrimaryKey(ctx, user, updatingColumns...)  	suite.NoError(err)  	// confirm with the token set above @@ -94,13 +95,14 @@ func (suite *EmailConfirmTestSuite) TestConfirmEmailOldToken() {  	user := suite.testUsers["local_account_1"]  	// set a bunch of stuff on the user as though zork hasn't been confirmed yet, but has had an email sent 8 days ago +	updatingColumns := []string{"unconfirmed_email", "email", "confirmed_at", "confirmation_sent_at", "confirmation_token"}  	user.UnconfirmedEmail = "some.email@example.org"  	user.Email = ""  	user.ConfirmedAt = time.Time{}  	user.ConfirmationSentAt = time.Now().Add(-192 * time.Hour)  	user.ConfirmationToken = "1d1aa44b-afa4-49c8-ac4b-eceb61715cc6" -	err := suite.db.UpdateByPrimaryKey(ctx, user) +	err := suite.db.UpdateByPrimaryKey(ctx, user, updatingColumns...)  	suite.NoError(err)  	// confirm with the token set above diff --git a/internal/processing/user/user_test.go b/internal/processing/user/user_test.go index 007a5f8ce..56947f69a 100644 --- a/internal/processing/user/user_test.go +++ b/internal/processing/user/user_test.go @@ -40,8 +40,8 @@ type UserStandardTestSuite struct {  }  func (suite *UserStandardTestSuite) SetupTest() { -	testrig.InitTestLog()  	testrig.InitTestConfig() +	testrig.InitTestLog()  	suite.db = testrig.NewTestDB()  	suite.sentEmails = make(map[string]string) | 
