federate status deletes properly

This commit is contained in:
tsmethurst
2021-06-04 16:35:58 +02:00
parent 5d2b69c256
commit 197ef03ead
19 changed files with 154 additions and 143 deletions

View File

@ -227,7 +227,7 @@ func (p *processor) AccountStatusesGet(authed *oauth.Auth, targetAccountID strin
return nil, gtserror.NewErrorInternalError(fmt.Errorf("error getting relevant statuses: %s", err))
}
visible, err := p.db.StatusVisible(&s, targetAccount, authed.Account, relevantAccounts)
visible, err := p.db.StatusVisible(&s, authed.Account, relevantAccounts)
if err != nil {
return nil, gtserror.NewErrorInternalError(fmt.Errorf("error checking status visibility: %s", err))
}
@ -246,7 +246,7 @@ func (p *processor) AccountStatusesGet(authed *oauth.Auth, targetAccountID strin
return nil, gtserror.NewErrorInternalError(fmt.Errorf("error getting relevant accounts from boosted status: %s", err))
}
boostedVisible, err := p.db.StatusVisible(bs, relevantAccounts.BoostedAccount, authed.Account, boostedRelevantAccounts)
boostedVisible, err := p.db.StatusVisible(bs, authed.Account, boostedRelevantAccounts)
if err != nil {
return nil, gtserror.NewErrorInternalError(fmt.Errorf("error checking boosted status visibility: %s", err))
}

View File

@ -135,6 +135,22 @@ func (p *processor) processFromClientAPI(clientMsg gtsmodel.FromClientAPI) error
}
return p.federateUnfave(fave, clientMsg.OriginAccount, clientMsg.TargetAccount)
}
case gtsmodel.ActivityStreamsDelete:
// DELETE
switch clientMsg.APObjectType {
case gtsmodel.ActivityStreamsNote:
// DELETE STATUS/NOTE
statusToDelete, ok := clientMsg.GTSModel.(*gtsmodel.Status)
if !ok {
return errors.New("note was not parseable as *gtsmodel.Status")
}
if err := p.deleteStatusFromTimelines(statusToDelete); err != nil {
return err
}
return p.federateStatusDelete(statusToDelete, clientMsg.OriginAccount)
}
}
return nil
}
@ -154,6 +170,43 @@ func (p *processor) federateStatus(status *gtsmodel.Status) error {
return err
}
func (p *processor) federateStatusDelete(status *gtsmodel.Status, originAccount *gtsmodel.Account) error {
asStatus, err := p.tc.StatusToAS(status)
if err != nil {
return fmt.Errorf("federateStatusDelete: error converting status to as format: %s", err)
}
outboxIRI, err := url.Parse(originAccount.OutboxURI)
if err != nil {
return fmt.Errorf("federateStatusDelete: error parsing outboxURI %s: %s", originAccount.OutboxURI, err)
}
actorIRI, err := url.Parse(originAccount.URI)
if err != nil {
return fmt.Errorf("federateStatusDelete: error parsing actorIRI %s: %s", originAccount.URI, err)
}
// create a delete and set the appropriate actor on it
delete := streams.NewActivityStreamsDelete()
// set the actor for the delete
deleteActor := streams.NewActivityStreamsActorProperty()
deleteActor.AppendIRI(actorIRI)
delete.SetActivityStreamsActor(deleteActor)
// Set the status as the 'object' property.
deleteObject := streams.NewActivityStreamsObjectProperty()
deleteObject.AppendActivityStreamsNote(asStatus)
delete.SetActivityStreamsObject(deleteObject)
// set the to and cc as the original to/cc of the original status
delete.SetActivityStreamsTo(asStatus.GetActivityStreamsTo())
delete.SetActivityStreamsCc(asStatus.GetActivityStreamsCc())
_, err = p.federator.FederatingActor().Send(context.Background(), outboxIRI, delete)
return err
}
func (p *processor) federateFollow(followRequest *gtsmodel.FollowRequest, originAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) error {
// if both accounts are local there's nothing to do here
if originAccount.Domain == "" && targetAccount.Domain == "" {

View File

@ -286,7 +286,7 @@ func (p *processor) timelineStatusForAccount(status *gtsmodel.Status, accountID
}
// make sure the status is visible
visible, err := p.db.StatusVisible(status, status.GTSAuthorAccount, timelineAccount, relevantAccounts)
visible, err := p.db.StatusVisible(status, timelineAccount, relevantAccounts)
if err != nil {
errors <- fmt.Errorf("timelineStatus: error getting visibility for status for timeline with id %s: %s", accountID, err)
return
@ -301,6 +301,6 @@ func (p *processor) timelineStatusForAccount(status *gtsmodel.Status, accountID
}
}
func (p *processor) fullyDeleteStatus(status *gtsmodel.Status, accountID string) error {
return nil
func (p *processor) deleteStatusFromTimelines(status *gtsmodel.Status) error {
return p.timelineManager.WipeStatusFromAllTimelines(status.ID)
}

View File

@ -146,6 +146,11 @@ func (p *processor) processFromFederator(federatorMsg gtsmodel.FromFederator) er
// 1. delete all media associated with status
// 2. delete boosts of status
// 3. etc etc etc
statusToDelete, ok := federatorMsg.GTSModel.(*gtsmodel.Status)
if !ok {
return errors.New("note was not parseable as *gtsmodel.Status")
}
return p.deleteStatusFromTimelines(statusToDelete)
case gtsmodel.ActivityStreamsProfile:
// DELETE A PROFILE/ACCOUNT
// TODO: handle side effects of account deletion here: delete all objects, statuses, media etc associated with account

View File

@ -109,7 +109,7 @@ func (p *processor) SearchGet(authed *oauth.Auth, searchQuery *apimodel.SearchQu
if err != nil {
continue
}
if visible, err := p.db.StatusVisible(foundStatus, statusOwner, authed.Account, relevantAccounts); !visible || err != nil {
if visible, err := p.db.StatusVisible(foundStatus, authed.Account, relevantAccounts); !visible || err != nil {
continue
}

View File

@ -31,7 +31,7 @@ func (p *processor) Boost(account *gtsmodel.Account, application *gtsmodel.Appli
}
l.Trace("going to see if status is visible")
visible, err := p.db.StatusVisible(targetStatus, targetAccount, account, relevantAccounts) // requestingAccount might well be nil here, but StatusVisible knows how to take care of that
visible, err := p.db.StatusVisible(targetStatus, account, relevantAccounts)
if err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("error seeing if status %s is visible: %s", targetStatus.ID, err))
}

View File

@ -31,7 +31,7 @@ func (p *processor) BoostedBy(account *gtsmodel.Account, targetStatusID string)
}
l.Trace("going to see if status is visible")
visible, err := p.db.StatusVisible(targetStatus, targetAccount, account, relevantAccounts) // requestingAccount might well be nil here, but StatusVisible knows how to take care of that
visible, err := p.db.StatusVisible(targetStatus, account, relevantAccounts)
if err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("StatusBoostedBy: error seeing if status %s is visible: %s", targetStatus.ID, err))
}

View File

@ -5,6 +5,7 @@ import (
"fmt"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
)
@ -14,7 +15,11 @@ func (p *processor) Delete(account *gtsmodel.Account, targetStatusID string) (*a
l.Tracef("going to search for target status %s", targetStatusID)
targetStatus := &gtsmodel.Status{}
if err := p.db.GetByID(targetStatusID, targetStatus); err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("error fetching status %s: %s", targetStatusID, err))
if _, ok := err.(db.ErrNoEntries); !ok {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("error fetching status %s: %s", targetStatusID, err))
}
// status is already gone
return nil, nil
}
if targetStatus.AccountID != account.ID {
@ -40,10 +45,10 @@ func (p *processor) Delete(account *gtsmodel.Account, targetStatusID string) (*a
return nil, gtserror.NewErrorInternalError(fmt.Errorf("error converting status %s to frontend representation: %s", targetStatus.ID, err))
}
if err := p.db.DeleteByID(targetStatus.ID, targetStatus); err != nil {
if err := p.db.DeleteByID(targetStatus.ID, &gtsmodel.Status{}); err != nil {
return nil, gtserror.NewErrorInternalError(fmt.Errorf("error deleting status from the database: %s", err))
}
// send it back to the processor for async processing
p.fromClientAPI <- gtsmodel.FromClientAPI{
APObjectType: gtsmodel.ActivityStreamsNote,

View File

@ -41,7 +41,7 @@ func (p *processor) Fave(account *gtsmodel.Account, targetStatusID string) (*api
}
l.Trace("going to see if status is visible")
visible, err := p.db.StatusVisible(targetStatus, targetAccount, account, relevantAccounts) // requestingAccount might well be nil here, but StatusVisible knows how to take care of that
visible, err := p.db.StatusVisible(targetStatus, account, relevantAccounts) // requestingAccount might well be nil here, but StatusVisible knows how to take care of that
if err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("error seeing if status %s is visible: %s", targetStatus.ID, err))
}

View File

@ -31,7 +31,7 @@ func (p *processor) FavedBy(account *gtsmodel.Account, targetStatusID string) ([
}
l.Trace("going to see if status is visible")
visible, err := p.db.StatusVisible(targetStatus, targetAccount, account, relevantAccounts) // requestingAccount might well be nil here, but StatusVisible knows how to take care of that
visible, err := p.db.StatusVisible(targetStatus, account, relevantAccounts) // requestingAccount might well be nil here, but StatusVisible knows how to take care of that
if err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("error seeing if status %s is visible: %s", targetStatus.ID, err))
}

View File

@ -31,7 +31,7 @@ func (p *processor) Get(account *gtsmodel.Account, targetStatusID string) (*apim
}
l.Trace("going to see if status is visible")
visible, err := p.db.StatusVisible(targetStatus, targetAccount, account, relevantAccounts) // requestingAccount might well be nil here, but StatusVisible knows how to take care of that
visible, err := p.db.StatusVisible(targetStatus, account, relevantAccounts) // requestingAccount might well be nil here, but StatusVisible knows how to take care of that
if err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("error seeing if status %s is visible: %s", targetStatus.ID, err))
}

View File

@ -31,7 +31,7 @@ func (p *processor) Unfave(account *gtsmodel.Account, targetStatusID string) (*a
}
l.Trace("going to see if status is visible")
visible, err := p.db.StatusVisible(targetStatus, targetAccount, account, relevantAccounts) // requestingAccount might well be nil here, but StatusVisible knows how to take care of that
visible, err := p.db.StatusVisible(targetStatus, account, relevantAccounts) // requestingAccount might well be nil here, but StatusVisible knows how to take care of that
if err != nil {
return nil, gtserror.NewErrorNotFound(fmt.Errorf("error seeing if status %s is visible: %s", targetStatus.ID, err))
}
@ -60,8 +60,7 @@ func (p *processor) Unfave(account *gtsmodel.Account, targetStatusID string) (*a
if toUnfave {
// we had a fave, so take some action to get rid of it
_, err = p.db.UnfaveStatus(targetStatus, account.ID)
if err != nil {
if err := p.db.DeleteWhere([]db.Where{{Key: "status_id", Value: targetStatus.ID}, {Key: "account_id", Value: account.ID}}, gtsFave); err != nil {
return nil, gtserror.NewErrorInternalError(fmt.Errorf("error unfaveing status: %s", err))
}

View File

@ -74,7 +74,7 @@ func (p *processor) filterStatuses(authed *oauth.Auth, statuses []*gtsmodel.Stat
continue
}
visible, err := p.db.StatusVisible(s, targetAccount, authed.Account, relevantAccounts)
visible, err := p.db.StatusVisible(s, authed.Account, relevantAccounts)
if err != nil {
return nil, gtserror.NewErrorInternalError(fmt.Errorf("HomeTimelineGet: error checking status visibility: %s", err))
}
@ -98,7 +98,7 @@ func (p *processor) filterStatuses(authed *oauth.Auth, statuses []*gtsmodel.Stat
continue
}
boostedVisible, err := p.db.StatusVisible(bs, relevantAccounts.BoostedAccount, authed.Account, boostedRelevantAccounts)
boostedVisible, err := p.db.StatusVisible(bs, authed.Account, boostedRelevantAccounts)
if err != nil {
return nil, gtserror.NewErrorInternalError(fmt.Errorf("HomeTimelineGet: error checking boosted status visibility: %s", err))
}
@ -204,7 +204,7 @@ func (p *processor) indexAndIngest(statuses []*gtsmodel.Status, timelineAccount
l.Error(fmt.Errorf("initTimelineFor: error getting relevant accounts from status %s: %s", s.ID, err))
continue
}
visible, err := p.db.StatusVisible(s, relevantAccounts.StatusAuthor, timelineAccount, relevantAccounts)
visible, err := p.db.StatusVisible(s, timelineAccount, relevantAccounts)
if err != nil {
l.Error(fmt.Errorf("initTimelineFor: error checking visibility of status %s: %s", s.ID, err))
continue