mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-05-31 22:58:32 +00:00
use redirectFollowers func for clientAPI as well
This commit is contained in:
parent
d9f1e0e458
commit
6e111c3f4a
|
@ -39,12 +39,13 @@ import (
|
|||
// specifically for messages originating
|
||||
// from the client/REST API.
|
||||
type clientAPI struct {
|
||||
state *state.State
|
||||
converter *typeutils.Converter
|
||||
surface *surface
|
||||
federate *federate
|
||||
wipeStatus wipeStatus
|
||||
account *account.Processor
|
||||
state *state.State
|
||||
converter *typeutils.Converter
|
||||
surface *surface
|
||||
federate *federate
|
||||
wipeStatus wipeStatus
|
||||
redirectFollowers redirectFollowers
|
||||
account *account.Processor
|
||||
}
|
||||
|
||||
func (p *Processor) EnqueueClientAPI(cctx context.Context, msgs ...messages.FromClientAPI) {
|
||||
|
@ -652,12 +653,18 @@ func (p *clientAPI) ReportAccount(ctx context.Context, cMsg messages.FromClientA
|
|||
}
|
||||
|
||||
func (p *clientAPI) MoveAccount(ctx context.Context, cMsg messages.FromClientAPI) error {
|
||||
// Redirect each local follower of
|
||||
// OriginAccount to follow move target.
|
||||
p.redirectFollowers(ctx, cMsg.OriginAccount, cMsg.TargetAccount)
|
||||
|
||||
// At this point, we know OriginAccount has the
|
||||
// Move set on it. Just make sure it's populated.
|
||||
if err := p.state.DB.PopulateMove(ctx, cMsg.OriginAccount.Move); err != nil {
|
||||
return gtserror.Newf("error populating Move: %w", err)
|
||||
}
|
||||
|
||||
// Now send the Move message out to
|
||||
// OriginAccount's (remote) followers.
|
||||
if err := p.federate.MoveAccount(ctx, cMsg.OriginAccount); err != nil {
|
||||
return gtserror.Newf("error federating account move: %w", err)
|
||||
}
|
||||
|
|
|
@ -39,11 +39,12 @@ import (
|
|||
// specifically for messages originating
|
||||
// from the federation/ActivityPub API.
|
||||
type fediAPI struct {
|
||||
state *state.State
|
||||
surface *surface
|
||||
federate *federate
|
||||
wipeStatus wipeStatus
|
||||
account *account.Processor
|
||||
state *state.State
|
||||
surface *surface
|
||||
federate *federate
|
||||
wipeStatus wipeStatus
|
||||
redirectFollowers redirectFollowers
|
||||
account *account.Processor
|
||||
}
|
||||
|
||||
func (p *Processor) EnqueueFediAPI(cctx context.Context, msgs ...messages.FromFediAPI) {
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
"errors"
|
||||
"time"
|
||||
|
||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtscontext"
|
||||
|
@ -380,7 +379,7 @@ func (p *fediAPI) MoveAccount(ctx context.Context, fMsg messages.FromFediAPI) er
|
|||
|
||||
// Transfer originAcct's followers
|
||||
// on this instance to targetAcct.
|
||||
redirectOK := p.RedirectAccountFollowers(
|
||||
redirectOK := p.redirectFollowers(
|
||||
ctx,
|
||||
originAcct,
|
||||
targetAcct,
|
||||
|
@ -422,98 +421,6 @@ func (p *fediAPI) MoveAccount(ctx context.Context, fMsg messages.FromFediAPI) er
|
|||
return nil
|
||||
}
|
||||
|
||||
// RedirectAccountFollowers redirects all local
|
||||
// followers of originAcct to targetAcct.
|
||||
//
|
||||
// Both accounts must be fully dereferenced
|
||||
// already, and the Move must be valid.
|
||||
//
|
||||
// Callers to this function MUST have obtained
|
||||
// a lock already by calling FedLocks.Lock.
|
||||
//
|
||||
// Return bool will be true if all goes OK.
|
||||
func (p *fediAPI) RedirectAccountFollowers(
|
||||
ctx context.Context,
|
||||
originAcct *gtsmodel.Account,
|
||||
targetAcct *gtsmodel.Account,
|
||||
) bool {
|
||||
// Any local followers of originAcct should
|
||||
// send follow requests to targetAcct instead,
|
||||
// and have followers of originAcct removed.
|
||||
//
|
||||
// Select local followers with barebones, since
|
||||
// we only need follow.Account and we can get
|
||||
// that ourselves.
|
||||
followers, err := p.state.DB.GetAccountLocalFollowers(
|
||||
gtscontext.SetBarebones(ctx),
|
||||
originAcct.ID,
|
||||
)
|
||||
if err != nil && !errors.Is(err, db.ErrNoEntries) {
|
||||
log.Errorf(ctx,
|
||||
"db error getting follows targeting originAcct: %v",
|
||||
err,
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
for _, follow := range followers {
|
||||
// Fetch the local account that
|
||||
// owns the follow targeting originAcct.
|
||||
if follow.Account, err = p.state.DB.GetAccountByID(
|
||||
gtscontext.SetBarebones(ctx),
|
||||
follow.AccountID,
|
||||
); err != nil {
|
||||
log.Errorf(ctx,
|
||||
"db error getting follow account %s: %v",
|
||||
follow.AccountID, err,
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
// Use the account processor FollowCreate
|
||||
// function to send off the new follow,
|
||||
// carrying over the Reblogs and Notify
|
||||
// values from the old follow to the new.
|
||||
//
|
||||
// This will also handle cases where our
|
||||
// account has already followed the target
|
||||
// account, by just updating the existing
|
||||
// follow of target account.
|
||||
if _, err := p.account.FollowCreate(
|
||||
ctx,
|
||||
follow.Account,
|
||||
&apimodel.AccountFollowRequest{
|
||||
ID: targetAcct.ID,
|
||||
Reblogs: follow.ShowReblogs,
|
||||
Notify: follow.Notify,
|
||||
},
|
||||
); err != nil {
|
||||
log.Errorf(ctx,
|
||||
"error creating new follow for account %s: %v",
|
||||
follow.AccountID, err,
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
// New follow is in the process of
|
||||
// sending, remove the existing follow.
|
||||
// This will send out an Undo Activity for each Follow.
|
||||
if _, err := p.account.FollowRemove(
|
||||
ctx,
|
||||
follow.Account,
|
||||
follow.TargetAccountID,
|
||||
); err != nil {
|
||||
log.Errorf(ctx,
|
||||
"error removing old follow for account %s: %v",
|
||||
follow.AccountID, err,
|
||||
)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// RemoveAccountFollowing removes all
|
||||
// follows owned by the move originAcct.
|
||||
//
|
||||
|
|
129
internal/processing/workers/redirectfollowers.go
Normal file
129
internal/processing/workers/redirectfollowers.go
Normal file
|
@ -0,0 +1,129 @@
|
|||
// 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 workers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtscontext"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/log"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing/account"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/state"
|
||||
)
|
||||
|
||||
// redirectFollowers redirects all local
|
||||
// followers of originAcct to targetAcct.
|
||||
//
|
||||
// Both accounts must be fully dereferenced
|
||||
// already, and the Move must be valid.
|
||||
//
|
||||
// Return bool will be true if all goes OK.
|
||||
type redirectFollowers func(
|
||||
ctx context.Context,
|
||||
originAcct *gtsmodel.Account,
|
||||
targetAcct *gtsmodel.Account,
|
||||
) bool
|
||||
|
||||
// redirectFollowersF returns a redirectFollowers util function.
|
||||
func redirectFollowersF(state *state.State, account *account.Processor) redirectFollowers {
|
||||
return func(
|
||||
ctx context.Context,
|
||||
originAcct *gtsmodel.Account,
|
||||
targetAcct *gtsmodel.Account,
|
||||
) bool {
|
||||
// Any local followers of originAcct should
|
||||
// send follow requests to targetAcct instead,
|
||||
// and have followers of originAcct removed.
|
||||
//
|
||||
// Select local followers with barebones, since
|
||||
// we only need follow.Account and we can get
|
||||
// that ourselves.
|
||||
followers, err := state.DB.GetAccountLocalFollowers(
|
||||
gtscontext.SetBarebones(ctx),
|
||||
originAcct.ID,
|
||||
)
|
||||
if err != nil && !errors.Is(err, db.ErrNoEntries) {
|
||||
log.Errorf(ctx,
|
||||
"db error getting follows targeting originAcct: %v",
|
||||
err,
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
for _, follow := range followers {
|
||||
// Fetch the local account that
|
||||
// owns the follow targeting originAcct.
|
||||
if follow.Account, err = state.DB.GetAccountByID(
|
||||
gtscontext.SetBarebones(ctx),
|
||||
follow.AccountID,
|
||||
); err != nil {
|
||||
log.Errorf(ctx,
|
||||
"db error getting follow account %s: %v",
|
||||
follow.AccountID, err,
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
// Use the account processor FollowCreate
|
||||
// function to send off the new follow,
|
||||
// carrying over the Reblogs and Notify
|
||||
// values from the old follow to the new.
|
||||
//
|
||||
// This will also handle cases where our
|
||||
// account has already followed the target
|
||||
// account, by just updating the existing
|
||||
// follow of target account.
|
||||
if _, err := account.FollowCreate(
|
||||
ctx,
|
||||
follow.Account,
|
||||
&apimodel.AccountFollowRequest{
|
||||
ID: targetAcct.ID,
|
||||
Reblogs: follow.ShowReblogs,
|
||||
Notify: follow.Notify,
|
||||
},
|
||||
); err != nil {
|
||||
log.Errorf(ctx,
|
||||
"error creating new follow for account %s: %v",
|
||||
follow.AccountID, err,
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
// New follow is in the process of
|
||||
// sending, remove the existing follow.
|
||||
// This will send out an Undo Activity for each Follow.
|
||||
if _, err := account.FollowRemove(
|
||||
ctx,
|
||||
follow.Account,
|
||||
follow.TargetAccountID,
|
||||
); err != nil {
|
||||
log.Errorf(ctx,
|
||||
"error removing old follow for account %s: %v",
|
||||
follow.AccountID, err,
|
||||
)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -71,22 +71,31 @@ func New(
|
|||
surface,
|
||||
)
|
||||
|
||||
// Init shared redirect
|
||||
// followers func.
|
||||
redirectFollowers := redirectFollowersF(
|
||||
state,
|
||||
account,
|
||||
)
|
||||
|
||||
return Processor{
|
||||
workers: &state.Workers,
|
||||
clientAPI: &clientAPI{
|
||||
state: state,
|
||||
converter: converter,
|
||||
surface: surface,
|
||||
federate: federate,
|
||||
wipeStatus: wipeStatus,
|
||||
account: account,
|
||||
state: state,
|
||||
converter: converter,
|
||||
surface: surface,
|
||||
federate: federate,
|
||||
wipeStatus: wipeStatus,
|
||||
redirectFollowers: redirectFollowers,
|
||||
account: account,
|
||||
},
|
||||
fediAPI: &fediAPI{
|
||||
state: state,
|
||||
surface: surface,
|
||||
federate: federate,
|
||||
wipeStatus: wipeStatus,
|
||||
account: account,
|
||||
state: state,
|
||||
surface: surface,
|
||||
federate: federate,
|
||||
wipeStatus: wipeStatus,
|
||||
redirectFollowers: redirectFollowers,
|
||||
account: account,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue