[chore] Move local account settings to separate db table (#2770)

* [chore] Move local account settings to separate database model

* don't use separate settings_id
This commit is contained in:
tobi
2024-03-22 14:03:46 +01:00
committed by GitHub
parent 0767647056
commit 7f4a0a1aeb
36 changed files with 525 additions and 191 deletions

View File

@@ -518,14 +518,9 @@ func stubbifyAccount(account *gtsmodel.Account, origin string) []string {
account.Memorial = util.Ptr(false)
account.AlsoKnownAsURIs = nil
account.MovedToURI = ""
account.Reason = ""
account.Discoverable = util.Ptr(false)
account.StatusContentType = ""
account.CustomCSS = ""
account.SuspendedAt = now
account.SuspensionOrigin = origin
account.HideCollections = util.Ptr(true)
account.EnableRSS = util.Ptr(false)
return []string{
"fetched_at",
@@ -541,14 +536,9 @@ func stubbifyAccount(account *gtsmodel.Account, origin string) []string {
"memorial",
"also_known_as_uris",
"moved_to_uri",
"reason",
"discoverable",
"status_content_type",
"custom_css",
"suspended_at",
"suspension_origin",
"hide_collections",
"enable_rss",
}
}

View File

@@ -66,14 +66,9 @@ func (suite *AccountDeleteTestSuite) TestAccountDeleteLocal() {
suite.Zero(updatedAccount.NoteRaw)
suite.False(*updatedAccount.Memorial)
suite.Empty(updatedAccount.AlsoKnownAsURIs)
suite.Zero(updatedAccount.Reason)
suite.False(*updatedAccount.Discoverable)
suite.Zero(updatedAccount.StatusContentType)
suite.Zero(updatedAccount.CustomCSS)
suite.WithinDuration(time.Now(), updatedAccount.SuspendedAt, 1*time.Minute)
suite.Equal(suspensionOrigin, updatedAccount.SuspensionOrigin)
suite.True(*updatedAccount.HideCollections)
suite.False(*updatedAccount.EnableRSS)
updatedUser, err := suite.db.GetUserByAccountID(ctx, testAccount.ID)
if err != nil {

View File

@@ -64,7 +64,7 @@ func (p *Processor) GetRSSFeedForUsername(ctx context.Context, username string)
}
// Ensure account has rss feed enabled.
if !*account.EnableRSS {
if !*account.Settings.EnableRSS {
err = gtserror.New("account RSS feed not enabled")
return nil, never, gtserror.NewErrorNotFound(err)
}

View File

@@ -47,6 +47,11 @@ func (p *Processor) selectNoteFormatter(contentType string) text.FormatFunc {
// Update processes the update of an account with the given form.
func (p *Processor) Update(ctx context.Context, account *gtsmodel.Account, form *apimodel.UpdateCredentialsRequest) (*apimodel.Account, gtserror.WithCode) {
// Ensure account populated; we'll need settings.
if err := p.state.DB.PopulateAccount(ctx, account); err != nil {
log.Errorf(ctx, "error(s) populating account, will continue: %s", err)
}
if form.Discoverable != nil {
account.Discoverable = form.Discoverable
}
@@ -146,7 +151,7 @@ func (p *Processor) Update(ctx context.Context, account *gtsmodel.Account, form
}
// Format + set note according to user prefs.
f := p.selectNoteFormatter(account.StatusContentType)
f := p.selectNoteFormatter(account.Settings.StatusContentType)
formatNoteResult := f(ctx, p.parseMention, account.ID, "", account.NoteRaw)
account.Note = formatNoteResult.HTML
@@ -227,11 +232,11 @@ func (p *Processor) Update(ctx context.Context, account *gtsmodel.Account, form
if err != nil {
return nil, gtserror.NewErrorBadRequest(err)
}
account.Language = language
account.Settings.Language = language
}
if form.Source.Sensitive != nil {
account.Sensitive = form.Source.Sensitive
account.Settings.Sensitive = form.Source.Sensitive
}
if form.Source.Privacy != nil {
@@ -239,7 +244,7 @@ func (p *Processor) Update(ctx context.Context, account *gtsmodel.Account, form
return nil, gtserror.NewErrorBadRequest(err)
}
privacy := typeutils.APIVisToVis(apimodel.Visibility(*form.Source.Privacy))
account.Privacy = privacy
account.Settings.Privacy = privacy
}
if form.Source.StatusContentType != nil {
@@ -247,7 +252,7 @@ func (p *Processor) Update(ctx context.Context, account *gtsmodel.Account, form
return nil, gtserror.NewErrorBadRequest(err, err.Error())
}
account.StatusContentType = *form.Source.StatusContentType
account.Settings.StatusContentType = *form.Source.StatusContentType
}
}
@@ -256,18 +261,21 @@ func (p *Processor) Update(ctx context.Context, account *gtsmodel.Account, form
if err := validate.CustomCSS(customCSS); err != nil {
return nil, gtserror.NewErrorBadRequest(err, err.Error())
}
account.CustomCSS = text.SanitizeToPlaintext(customCSS)
account.Settings.CustomCSS = text.SanitizeToPlaintext(customCSS)
}
if form.EnableRSS != nil {
account.EnableRSS = form.EnableRSS
account.Settings.EnableRSS = form.EnableRSS
}
err := p.state.DB.UpdateAccount(ctx, account)
if err != nil {
if err := p.state.DB.UpdateAccount(ctx, account); err != nil {
return nil, gtserror.NewErrorInternalError(fmt.Errorf("could not update account %s: %s", account.ID, err))
}
if err := p.state.DB.UpdateAccountSettings(ctx, account.Settings); err != nil {
return nil, gtserror.NewErrorInternalError(fmt.Errorf("could not update account settings %s: %s", account.ID, err))
}
p.state.Workers.EnqueueClientAPI(ctx, messages.FromClientAPI{
APObjectType: ap.ObjectProfile,
APActivityType: ap.ActivityUpdate,

View File

@@ -126,9 +126,15 @@ func (suite *AccountUpdateTestSuite) TestAccountUpdateWithMention() {
}
func (suite *AccountUpdateTestSuite) TestAccountUpdateWithMarkdownNote() {
// Copy zork.
testAccount := &gtsmodel.Account{}
*testAccount = *suite.testAccounts["local_account_1"]
// Copy zork's settings.
settings := &gtsmodel.AccountSettings{}
*settings = *suite.testAccounts["local_account_1"].Settings
testAccount.Settings = settings
var (
ctx = context.Background()
note = "*hello* ~~here~~ i am!"
@@ -136,8 +142,8 @@ func (suite *AccountUpdateTestSuite) TestAccountUpdateWithMarkdownNote() {
)
// Set status content type of account 1 to markdown for this test.
testAccount.StatusContentType = "text/markdown"
if err := suite.db.UpdateAccount(ctx, testAccount, "status_content_type"); err != nil {
testAccount.Settings.StatusContentType = "text/markdown"
if err := suite.db.UpdateAccountSettings(ctx, testAccount.Settings, "status_content_type"); err != nil {
suite.FailNow(err.Error())
}

View File

@@ -32,9 +32,9 @@ func (p *Processor) PreferencesGet(ctx context.Context, accountID string) (*apim
}
return &apimodel.Preferences{
PostingDefaultVisibility: mastoPrefVisibility(act.Privacy),
PostingDefaultSensitive: *act.Sensitive,
PostingDefaultLanguage: act.Language,
PostingDefaultVisibility: mastoPrefVisibility(act.Settings.Privacy),
PostingDefaultSensitive: *act.Settings.Sensitive,
PostingDefaultLanguage: act.Settings.Language,
// The Reading* preferences don't appear to actually be settable by the
// client, so forcing some sensible defaults here
ReadingExpandMedia: "default",

View File

@@ -50,6 +50,11 @@ func (p *Processor) Create(
*apimodel.Status,
gtserror.WithCode,
) {
// Ensure account populated; we'll need settings.
if err := p.state.DB.PopulateAccount(ctx, requester); err != nil {
log.Errorf(ctx, "error(s) populating account, will continue: %s", err)
}
// Generate new ID for status.
statusID := id.NewULID()
@@ -112,11 +117,11 @@ func (p *Processor) Create(
return nil, errWithCode
}
if err := processVisibility(form, requester.Privacy, status); err != nil {
if err := processVisibility(form, requester.Settings.Privacy, status); err != nil {
return nil, gtserror.NewErrorInternalError(err)
}
if err := processLanguage(form, requester.Language, status); err != nil {
if err := processLanguage(form, requester.Settings.Language, status); err != nil {
return nil, gtserror.NewErrorInternalError(err)
}
@@ -369,7 +374,7 @@ func processLanguage(form *apimodel.AdvancedStatusCreateForm, accountDefaultLang
func (p *Processor) processContent(ctx context.Context, parseMention gtsmodel.ParseMentionFunc, form *apimodel.AdvancedStatusCreateForm, status *gtsmodel.Status) error {
if form.ContentType == "" {
// If content type wasn't specified, use the author's preferred content-type.
contentType := apimodel.StatusContentType(status.Account.StatusContentType)
contentType := apimodel.StatusContentType(status.Account.Settings.StatusContentType)
form.ContentType = contentType
}

View File

@@ -362,9 +362,7 @@ func (suite *FromFediAPITestSuite) TestProcessAccountDelete() {
suite.Empty(dbAccount.AvatarRemoteURL)
suite.Empty(dbAccount.HeaderMediaAttachmentID)
suite.Empty(dbAccount.HeaderRemoteURL)
suite.Empty(dbAccount.Reason)
suite.Empty(dbAccount.Fields)
suite.True(*dbAccount.HideCollections)
suite.False(*dbAccount.Discoverable)
suite.WithinDuration(time.Now(), dbAccount.SuspendedAt, 30*time.Second)
suite.Equal(dbAccount.ID, dbAccount.SuspensionOrigin)