diff options
Diffstat (limited to 'internal/db/bundb')
| -rw-r--r-- | internal/db/bundb/account.go | 67 | ||||
| -rw-r--r-- | internal/db/bundb/migrations/20240906144432_unauthed_visibility.go.go | 69 | 
2 files changed, 129 insertions, 7 deletions
| diff --git a/internal/db/bundb/account.go b/internal/db/bundb/account.go index d8ec26291..1569af9cb 100644 --- a/internal/db/bundb/account.go +++ b/internal/db/bundb/account.go @@ -1047,7 +1047,18 @@ func (a *accountDB) GetAccountPinnedStatuses(ctx context.Context, accountID stri  	return a.state.DB.GetStatusesByIDs(ctx, statusIDs)  } -func (a *accountDB) GetAccountWebStatuses(ctx context.Context, accountID string, limit int, maxID string) ([]*gtsmodel.Status, error) { +func (a *accountDB) GetAccountWebStatuses( +	ctx context.Context, +	account *gtsmodel.Account, +	limit int, +	maxID string, +) ([]*gtsmodel.Status, error) { +	// Check for an easy case: account exposes no statuses via the web. +	webVisibility := account.Settings.WebVisibility +	if webVisibility == gtsmodel.VisibilityNone { +		return nil, db.ErrNoEntries +	} +  	// Ensure reasonable  	if limit < 0 {  		limit = 0 @@ -1061,14 +1072,36 @@ func (a *accountDB) GetAccountWebStatuses(ctx context.Context, accountID string,  		TableExpr("? AS ?", bun.Ident("statuses"), bun.Ident("status")).  		// Select only IDs from table  		Column("status.id"). -		Where("? = ?", bun.Ident("status.account_id"), accountID). +		Where("? = ?", bun.Ident("status.account_id"), account.ID).  		// Don't show replies or boosts.  		Where("? IS NULL", bun.Ident("status.in_reply_to_uri")). -		Where("? IS NULL", bun.Ident("status.boost_of_id")). +		Where("? IS NULL", bun.Ident("status.boost_of_id")) + +	// Select statuses for this account according +	// to their web visibility preference. +	switch webVisibility { + +	case gtsmodel.VisibilityPublic:  		// Only Public statuses. -		Where("? = ?", bun.Ident("status.visibility"), gtsmodel.VisibilityPublic). -		// Don't show local-only statuses on the web view. -		Where("? = ?", bun.Ident("status.federated"), true) +		q = q.Where("? = ?", bun.Ident("status.visibility"), gtsmodel.VisibilityPublic) + +	case gtsmodel.VisibilityUnlocked: +		// Public or Unlocked. +		visis := []gtsmodel.Visibility{ +			gtsmodel.VisibilityPublic, +			gtsmodel.VisibilityUnlocked, +		} +		q = q.Where("? IN (?)", bun.Ident("status.visibility"), bun.In(visis)) + +	default: +		return nil, gtserror.Newf( +			"unrecognized web visibility for account %s: %s", +			account.ID, webVisibility, +		) +	} + +	// Don't show local-only statuses on the web view. +	q = q.Where("? = ?", bun.Ident("status.federated"), true)  	// return only statuses LOWER (ie., older) than maxID  	if maxID == "" { @@ -1145,10 +1178,30 @@ func (a *accountDB) UpdateAccountSettings(  ) error {  	return a.state.Caches.DB.AccountSettings.Store(settings, func() error {  		settings.UpdatedAt = time.Now() -		if len(columns) > 0 { + +		switch { + +		case len(columns) != 0:  			// If we're updating by column,  			// ensure "updated_at" is included.  			columns = append(columns, "updated_at") + +			// If we're updating web_visibility we should +			// fall through + invalidate visibility cache. +			if !slices.Contains(columns, "web_visibility") { +				break // No need to invalidate. +			} + +			// Fallthrough +			// to invalidate. +			fallthrough + +		case len(columns) == 0: +			// Status visibility may be changing for this account. +			// Clear the visibility cache for unauthed requesters. +			// +			// todo: invalidate JUST this account's statuses. +			defer a.state.Caches.Visibility.Clear()  		}  		if _, err := a.db. diff --git a/internal/db/bundb/migrations/20240906144432_unauthed_visibility.go.go b/internal/db/bundb/migrations/20240906144432_unauthed_visibility.go.go new file mode 100644 index 000000000..473783790 --- /dev/null +++ b/internal/db/bundb/migrations/20240906144432_unauthed_visibility.go.go @@ -0,0 +1,69 @@ +// 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/>. + +package migrations + +import ( +	"context" + +	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" +	"github.com/uptrace/bun" +) + +func init() { +	up := func(ctx context.Context, db *bun.DB) error { +		return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { + +			// If column already exists we don't need to do anything. +			exists, err := doesColumnExist(ctx, tx, +				"account_settings", "web_visibility", +			) + +			if err != nil { +				// Real error. +				return err +			} else if exists { +				// Nothing to do. +				return nil +			} + +			// Create the new column. +			if _, err := tx.NewAddColumn(). +				Table("account_settings"). +				ColumnExpr( +					"? TEXT NOT NULL DEFAULT ?", +					bun.Ident("web_visibility"), +					gtsmodel.VisibilityPublic, +				). +				Exec(ctx); err != nil { +				return err +			} + +			return nil +		}) +	} + +	down := func(ctx context.Context, db *bun.DB) error { +		return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { +			return nil +		}) +	} + +	if err := Migrations.Register(up, down); err != nil { +		panic(err) +	} +} | 
