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) |