diff options
Diffstat (limited to 'internal/message')
-rw-r--r-- | internal/message/accountprocess.go | 10 | ||||
-rw-r--r-- | internal/message/fromclientapiprocess.go | 28 | ||||
-rw-r--r-- | internal/message/fromcommonprocess.go | 4 | ||||
-rw-r--r-- | internal/message/fromfederatorprocess.go | 138 | ||||
-rw-r--r-- | internal/message/statusprocess.go | 9 | ||||
-rw-r--r-- | internal/message/timelineprocess.go | 14 |
6 files changed, 178 insertions, 25 deletions
diff --git a/internal/message/accountprocess.go b/internal/message/accountprocess.go index 22542f0c3..8847e5789 100644 --- a/internal/message/accountprocess.go +++ b/internal/message/accountprocess.go @@ -454,13 +454,9 @@ func (p *processor) AccountFollowCreate(authed *oauth.Auth, form *apimodel.Accou p.fromClientAPI <- gtsmodel.FromClientAPI{ APObjectType: gtsmodel.ActivityStreamsFollow, APActivityType: gtsmodel.ActivityStreamsCreate, - GTSModel: >smodel.Follow{ - AccountID: authed.Account.ID, - TargetAccountID: form.TargetAccountID, - URI: fr.URI, - }, - OriginAccount: authed.Account, - TargetAccount: targetAcct, + GTSModel: fr, + OriginAccount: authed.Account, + TargetAccount: targetAcct, } // return whatever relationship results from this diff --git a/internal/message/fromclientapiprocess.go b/internal/message/fromclientapiprocess.go index 12e4bd3c0..1d30b526c 100644 --- a/internal/message/fromclientapiprocess.go +++ b/internal/message/fromclientapiprocess.go @@ -72,6 +72,19 @@ func (p *processor) processFromClientAPI(clientMsg gtsmodel.FromClientAPI) error } return p.federateFave(fave, clientMsg.OriginAccount, clientMsg.TargetAccount) + + case gtsmodel.ActivityStreamsAnnounce: + // CREATE BOOST/ANNOUNCE + boostWrapperStatus, ok := clientMsg.GTSModel.(*gtsmodel.Status) + if !ok { + return errors.New("boost was not parseable as *gtsmodel.Status") + } + + if err := p.notifyAnnounce(boostWrapperStatus); err != nil { + return err + } + + return p.federateAnnounce(boostWrapperStatus, clientMsg.OriginAccount, clientMsg.TargetAccount) } case gtsmodel.ActivityStreamsUpdate: // UPDATE @@ -253,3 +266,18 @@ func (p *processor) federateFave(fave *gtsmodel.StatusFave, originAccount *gtsmo _, err = p.federator.FederatingActor().Send(context.Background(), outboxIRI, asFave) return err } + +func (p *processor) federateAnnounce(boostWrapperStatus *gtsmodel.Status, boostingAccount *gtsmodel.Account, boostedAccount *gtsmodel.Account) error { + announce, err := p.tc.BoostToAS(boostWrapperStatus, boostingAccount, boostedAccount) + if err != nil { + return fmt.Errorf("federateAnnounce: error converting status to announce: %s", err) + } + + outboxIRI, err := url.Parse(boostingAccount.OutboxURI) + if err != nil { + return fmt.Errorf("federateAnnounce: error parsing outboxURI %s: %s", boostingAccount.OutboxURI, err) + } + + _, err = p.federator.FederatingActor().Send(context.Background(), outboxIRI, announce) + return err +} diff --git a/internal/message/fromcommonprocess.go b/internal/message/fromcommonprocess.go index 73d58f1d1..19f5829b4 100644 --- a/internal/message/fromcommonprocess.go +++ b/internal/message/fromcommonprocess.go @@ -158,3 +158,7 @@ func (p *processor) notifyFave(fave *gtsmodel.StatusFave, receivingAccount *gtsm return nil } + +func (p *processor) notifyAnnounce(status *gtsmodel.Status) error { + return nil +} diff --git a/internal/message/fromfederatorprocess.go b/internal/message/fromfederatorprocess.go index 10dbfcf6e..7fbdacbf9 100644 --- a/internal/message/fromfederatorprocess.go +++ b/internal/message/fromfederatorprocess.go @@ -27,7 +27,6 @@ import ( "github.com/sirupsen/logrus" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" - "github.com/superseriousbusiness/gotosocial/internal/transport" ) func (p *processor) processFromFederator(federatorMsg gtsmodel.FromFederator) error { @@ -50,7 +49,7 @@ func (p *processor) processFromFederator(federatorMsg gtsmodel.FromFederator) er } l.Debug("will now derefence incoming status") - if err := p.dereferenceStatusFields(incomingStatus); err != nil { + if err := p.dereferenceStatusFields(incomingStatus, federatorMsg.ReceivingAccount.Username); err != nil { return fmt.Errorf("error dereferencing status from federator: %s", err) } if err := p.db.UpdateByID(incomingStatus.ID, incomingStatus); err != nil { @@ -88,12 +87,30 @@ func (p *processor) processFromFederator(federatorMsg gtsmodel.FromFederator) er // CREATE A FOLLOW REQUEST incomingFollowRequest, ok := federatorMsg.GTSModel.(*gtsmodel.FollowRequest) if !ok { - return errors.New("like was not parseable as *gtsmodel.FollowRequest") + return errors.New("incomingFollowRequest was not parseable as *gtsmodel.FollowRequest") } if err := p.notifyFollowRequest(incomingFollowRequest, federatorMsg.ReceivingAccount); err != nil { return err } + case gtsmodel.ActivityStreamsAnnounce: + // CREATE AN ANNOUNCE + incomingAnnounce, ok := federatorMsg.GTSModel.(*gtsmodel.Status) + if !ok { + return errors.New("announce was not parseable as *gtsmodel.Status") + } + + if err := p.dereferenceAnnounce(incomingAnnounce, federatorMsg.ReceivingAccount.Username); err != nil { + return fmt.Errorf("error dereferencing announce from federator: %s", err) + } + + if err := p.db.Put(incomingAnnounce); err != nil { + return fmt.Errorf("error adding dereferenced announce to the db: %s", err) + } + + if err := p.notifyAnnounce(incomingAnnounce); err != nil { + return err + } } case gtsmodel.ActivityStreamsUpdate: // UPDATE @@ -168,18 +185,14 @@ func (p *processor) processFromFederator(federatorMsg gtsmodel.FromFederator) er // This function will deference all of the above, insert them in the database as necessary, // and attach them to the status. The status itself will not be added to the database yet, // that's up the caller to do. -func (p *processor) dereferenceStatusFields(status *gtsmodel.Status) error { +func (p *processor) dereferenceStatusFields(status *gtsmodel.Status, requestingUsername string) error { l := p.log.WithFields(logrus.Fields{ "func": "dereferenceStatusFields", "status": fmt.Sprintf("%+v", status), }) l.Debug("entering function") - var t transport.Transport - var err error - var username string - // TODO: dereference with a user that's addressed by the status - t, err = p.federator.GetTransportForUser(username) + t, err := p.federator.GetTransportForUser(requestingUsername) if err != nil { return fmt.Errorf("error creating transport: %s", err) } @@ -224,10 +237,10 @@ func (p *processor) dereferenceStatusFields(status *gtsmodel.Status) error { } l.Debugf("dereferenced attachment: %+v", deferencedAttachment) deferencedAttachment.StatusID = status.ID + deferencedAttachment.Description = a.Description if err := p.db.Put(deferencedAttachment); err != nil { return fmt.Errorf("error inserting dereferenced attachment with remote url %s: %s", a.RemoteURL, err) } - deferencedAttachment.Description = a.Description attachmentIDs = append(attachmentIDs, deferencedAttachment.ID) } status.Attachments = attachmentIDs @@ -260,7 +273,7 @@ func (p *processor) dereferenceStatusFields(status *gtsmodel.Status) error { } // we just don't have it yet, so we should go get it.... - accountable, err := p.federator.DereferenceRemoteAccount(username, uri) + accountable, err := p.federator.DereferenceRemoteAccount(requestingUsername, uri) if err != nil { // we can't dereference it so just skip it l.Debugf("error dereferencing remote account with uri %s: %s", uri.String(), err) @@ -313,3 +326,106 @@ func (p *processor) dereferenceAccountFields(account *gtsmodel.Account, requesti return nil } + +func (p *processor) dereferenceAnnounce(announce *gtsmodel.Status, requestingUsername string) error { + if announce.GTSBoostedStatus == nil || announce.GTSBoostedStatus.URI == "" { + // we can't do anything unfortunately + return errors.New("dereferenceAnnounce: no URI to dereference") + } + + // check if we already have the boosted status in the database + boostedStatus := >smodel.Status{} + err := p.db.GetWhere([]db.Where{{Key: "uri", Value: announce.GTSBoostedStatus.URI}}, boostedStatus) + if err == nil { + // nice, we already have it so we don't actually need to dereference it from remote + announce.Content = boostedStatus.Content + announce.ContentWarning = boostedStatus.ContentWarning + announce.ActivityStreamsType = boostedStatus.ActivityStreamsType + announce.Sensitive = boostedStatus.Sensitive + announce.Language = boostedStatus.Language + announce.Text = boostedStatus.Text + announce.BoostOfID = boostedStatus.ID + announce.Visibility = boostedStatus.Visibility + announce.VisibilityAdvanced = boostedStatus.VisibilityAdvanced + announce.GTSBoostedStatus = boostedStatus + return nil + } + + // we don't have it so we need to dereference it + remoteStatusID, err := url.Parse(announce.GTSBoostedStatus.URI) + if err != nil { + return fmt.Errorf("dereferenceAnnounce: error parsing url %s: %s", announce.GTSBoostedStatus.URI, err) + } + + statusable, err := p.federator.DereferenceRemoteStatus(requestingUsername, remoteStatusID) + if err != nil { + return fmt.Errorf("dereferenceAnnounce: error dereferencing remote status with id %s: %s", announce.GTSBoostedStatus.URI, err) + } + + // make sure we have the author account in the db + attributedToProp := statusable.GetActivityStreamsAttributedTo() + for iter := attributedToProp.Begin(); iter != attributedToProp.End(); iter = iter.Next() { + accountURI := iter.GetIRI() + if accountURI == nil { + continue + } + + if err := p.db.GetWhere([]db.Where{{Key: "uri", Value: accountURI.String()}}, >smodel.Account{}); err == nil { + // we already have it, fine + continue + } + + // we don't have the boosted status author account yet so dereference it + accountable, err := p.federator.DereferenceRemoteAccount(requestingUsername, accountURI) + if err != nil { + return fmt.Errorf("dereferenceAnnounce: error dereferencing remote account with id %s: %s", accountURI.String(), err) + } + account, err := p.tc.ASRepresentationToAccount(accountable, false) + if err != nil { + return fmt.Errorf("dereferenceAnnounce: error converting dereferenced account with id %s into account : %s", accountURI.String(), err) + } + + // insert the dereferenced account so it gets an ID etc + if err := p.db.Put(account); err != nil { + return fmt.Errorf("dereferenceAnnounce: error putting dereferenced account with id %s into database : %s", accountURI.String(), err) + } + + if err := p.dereferenceAccountFields(account, requestingUsername, false); err != nil { + return fmt.Errorf("dereferenceAnnounce: error dereferencing fields on account with id %s : %s", accountURI.String(), err) + } + } + + // now convert the statusable into something we can understand + boostedStatus, err = p.tc.ASStatusToStatus(statusable) + if err != nil { + return fmt.Errorf("dereferenceAnnounce: error converting dereferenced statusable with id %s into status : %s", announce.GTSBoostedStatus.URI, err) + } + + // put it in the db already so it gets an ID generated for it + if err := p.db.Put(boostedStatus); err != nil { + return fmt.Errorf("dereferenceAnnounce: error putting dereferenced status with id %s into the db: %s", announce.GTSBoostedStatus.URI, err) + } + + // now dereference additional fields straight away (we're already async here so we have time) + if err := p.dereferenceStatusFields(boostedStatus, requestingUsername); err != nil { + return fmt.Errorf("dereferenceAnnounce: error dereferencing status fields for status with id %s: %s", announce.GTSBoostedStatus.URI, err) + } + + // update with the newly dereferenced fields + if err := p.db.UpdateByID(boostedStatus.ID, boostedStatus); err != nil { + return fmt.Errorf("dereferenceAnnounce: error updating dereferenced status in the db: %s", err) + } + + // we have everything we need! + announce.Content = boostedStatus.Content + announce.ContentWarning = boostedStatus.ContentWarning + announce.ActivityStreamsType = boostedStatus.ActivityStreamsType + announce.Sensitive = boostedStatus.Sensitive + announce.Language = boostedStatus.Language + announce.Text = boostedStatus.Text + announce.BoostOfID = boostedStatus.ID + announce.Visibility = boostedStatus.Visibility + announce.VisibilityAdvanced = boostedStatus.VisibilityAdvanced + announce.GTSBoostedStatus = boostedStatus + return nil +} diff --git a/internal/message/statusprocess.go b/internal/message/statusprocess.go index f64c35948..40c7b30ca 100644 --- a/internal/message/statusprocess.go +++ b/internal/message/statusprocess.go @@ -291,6 +291,15 @@ func (p *processor) StatusBoost(authed *oauth.Auth, targetStatusID string) (*api return nil, NewErrorInternalError(err) } + // send it to the processor for async processing + p.fromClientAPI <- gtsmodel.FromClientAPI{ + APObjectType: gtsmodel.ActivityStreamsAnnounce, + APActivityType: gtsmodel.ActivityStreamsCreate, + GTSModel: boostWrapperStatus, + OriginAccount: authed.Account, + TargetAccount: targetAccount, + } + // return the frontend representation of the new status to the submitter mastoStatus, err := p.tc.StatusToMasto(boostWrapperStatus, authed.Account, authed.Account, targetAccount, nil, targetStatus) if err != nil { diff --git a/internal/message/timelineprocess.go b/internal/message/timelineprocess.go index c3f2246d5..271d19db5 100644 --- a/internal/message/timelineprocess.go +++ b/internal/message/timelineprocess.go @@ -18,17 +18,17 @@ func (p *processor) HomeTimelineGet(authed *oauth.Auth, maxID string, sinceID st for _, s := range statuses { targetAccount := >smodel.Account{} if err := p.db.GetByID(s.AccountID, targetAccount); err != nil { - return nil, NewErrorInternalError(fmt.Errorf("error getting status author: %s", err)) + return nil, NewErrorInternalError(fmt.Errorf("HomeTimelineGet: error getting status author: %s", err)) } relevantAccounts, err := p.db.PullRelevantAccountsFromStatus(s) if err != nil { - return nil, NewErrorInternalError(fmt.Errorf("error getting relevant statuses: %s", err)) + return nil, NewErrorInternalError(fmt.Errorf("HomeTimelineGet: error getting relevant statuses for status with id %s and uri %s: %s", s.ID, s.URI, err)) } visible, err := p.db.StatusVisible(s, targetAccount, authed.Account, relevantAccounts) if err != nil { - return nil, NewErrorInternalError(fmt.Errorf("error checking status visibility: %s", err)) + return nil, NewErrorInternalError(fmt.Errorf("HomeTimelineGet: error checking status visibility: %s", err)) } if !visible { continue @@ -38,16 +38,16 @@ func (p *processor) HomeTimelineGet(authed *oauth.Auth, maxID string, sinceID st if s.BoostOfID != "" { bs := >smodel.Status{} if err := p.db.GetByID(s.BoostOfID, bs); err != nil { - return nil, NewErrorInternalError(fmt.Errorf("error getting boosted status: %s", err)) + return nil, NewErrorInternalError(fmt.Errorf("HomeTimelineGet: error getting boosted status: %s", err)) } boostedRelevantAccounts, err := p.db.PullRelevantAccountsFromStatus(bs) if err != nil { - return nil, NewErrorInternalError(fmt.Errorf("error getting relevant accounts from boosted status: %s", err)) + return nil, NewErrorInternalError(fmt.Errorf("HomeTimelineGet: error getting relevant accounts from boosted status: %s", err)) } boostedVisible, err := p.db.StatusVisible(bs, relevantAccounts.BoostedAccount, authed.Account, boostedRelevantAccounts) if err != nil { - return nil, NewErrorInternalError(fmt.Errorf("error checking boosted status visibility: %s", err)) + return nil, NewErrorInternalError(fmt.Errorf("HomeTimelineGet: error checking boosted status visibility: %s", err)) } if boostedVisible { @@ -57,7 +57,7 @@ func (p *processor) HomeTimelineGet(authed *oauth.Auth, maxID string, sinceID st apiStatus, err := p.tc.StatusToMasto(s, targetAccount, authed.Account, relevantAccounts.BoostedAccount, relevantAccounts.ReplyToAccount, boostedStatus) if err != nil { - return nil, NewErrorInternalError(fmt.Errorf("error converting status to masto: %s", err)) + return nil, NewErrorInternalError(fmt.Errorf("HomeTimelineGet: error converting status to masto: %s", err)) } apiStatuses = append(apiStatuses, *apiStatus) |