diff options
author | 2024-09-23 14:42:19 +0200 | |
---|---|---|
committer | 2024-09-23 14:42:19 +0200 | |
commit | 1ce854358def5f04b7c3b73418ab56bb58512634 (patch) | |
tree | 94d827b90e435c88367d080f53b63ee2285905d6 /internal/processing | |
parent | [chore] add nometrics build tagging to metrics API endpoint (#3331) (diff) | |
download | gotosocial-1ce854358def5f04b7c3b73418ab56bb58512634.tar.xz |
[feature] Show info for pending replies, allow implicit accept of pending replies (#3322)
* [feature] Allow implicit accept of pending replies
* update wording
Diffstat (limited to 'internal/processing')
-rw-r--r-- | internal/processing/processor.go | 2 | ||||
-rw-r--r-- | internal/processing/status/boost.go | 18 | ||||
-rw-r--r-- | internal/processing/status/create.go | 17 | ||||
-rw-r--r-- | internal/processing/status/fave.go | 22 | ||||
-rw-r--r-- | internal/processing/status/status.go | 6 | ||||
-rw-r--r-- | internal/processing/status/status_test.go | 3 | ||||
-rw-r--r-- | internal/processing/status/util.go | 72 |
7 files changed, 135 insertions, 5 deletions
diff --git a/internal/processing/processor.go b/internal/processing/processor.go index 2ed13d396..ce0f1cfb8 100644 --- a/internal/processing/processor.go +++ b/internal/processing/processor.go @@ -223,7 +223,7 @@ func NewProcessor( processor.tags = tags.New(state, converter) processor.timeline = timeline.New(state, converter, visFilter) processor.search = search.New(state, federator, converter, visFilter) - processor.status = status.New(state, &common, &processor.polls, federator, converter, visFilter, intFilter, parseMentionFunc) + processor.status = status.New(state, &common, &processor.polls, &processor.interactionRequests, federator, converter, visFilter, intFilter, parseMentionFunc) processor.user = user.New(state, converter, oauthServer, emailSender) // The advanced migrations processor sequences advanced migrations from all other processors. diff --git a/internal/processing/status/boost.go b/internal/processing/status/boost.go index 1b6e8bd47..0e09a8e7b 100644 --- a/internal/processing/status/boost.go +++ b/internal/processing/status/boost.go @@ -28,6 +28,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/gtserror" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/messages" + "github.com/superseriousbusiness/gotosocial/internal/util" ) // BoostCreate processes the boost/reblog of target @@ -138,6 +139,23 @@ func (p *Processor) BoostCreate( Target: target.Account, }) + // If the boost target status replies to a status + // that we own, and has a pending interaction + // request, use the boost as an implicit accept. + implicitlyAccepted, errWithCode := p.implicitlyAccept(ctx, + requester, target, + ) + if errWithCode != nil { + return nil, errWithCode + } + + // If we ended up implicitly accepting, mark the + // target status as no longer pending approval so + // it's serialized properly via the API. + if implicitlyAccepted { + target.PendingApproval = util.Ptr(false) + } + return p.c.GetAPIStatus(ctx, requester, boost) } diff --git a/internal/processing/status/create.go b/internal/processing/status/create.go index 1513018ae..184a92680 100644 --- a/internal/processing/status/create.go +++ b/internal/processing/status/create.go @@ -164,6 +164,23 @@ func (p *Processor) Create( } } + // If the new status replies to a status that + // replies to us, use our reply as an implicit + // accept of any pending interaction. + implicitlyAccepted, errWithCode := p.implicitlyAccept(ctx, + requester, status, + ) + if errWithCode != nil { + return nil, errWithCode + } + + // If we ended up implicitly accepting, mark the + // replied-to status as no longer pending approval + // so it's serialized properly via the API. + if implicitlyAccepted { + status.InReplyTo.PendingApproval = util.Ptr(false) + } + return p.c.GetAPIStatus(ctx, requester, status) } diff --git a/internal/processing/status/fave.go b/internal/processing/status/fave.go index 497c4d465..defc59af0 100644 --- a/internal/processing/status/fave.go +++ b/internal/processing/status/fave.go @@ -31,6 +31,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/log" "github.com/superseriousbusiness/gotosocial/internal/messages" "github.com/superseriousbusiness/gotosocial/internal/uris" + "github.com/superseriousbusiness/gotosocial/internal/util" ) func (p *Processor) getFaveableStatus( @@ -138,8 +139,6 @@ func (p *Processor) FaveCreate( pendingApproval = false } - status.PendingApproval = &pendingApproval - // Create a new fave, marking it // as pending approval if necessary. faveID := id.NewULID() @@ -157,7 +156,7 @@ func (p *Processor) FaveCreate( } if err := p.state.DB.PutStatusFave(ctx, gtsFave); err != nil { - err = fmt.Errorf("FaveCreate: error putting fave in database: %w", err) + err = gtserror.Newf("db error putting fave: %w", err) return nil, gtserror.NewErrorInternalError(err) } @@ -170,6 +169,23 @@ func (p *Processor) FaveCreate( Target: status.Account, }) + // If the fave target status replies to a status + // that we own, and has a pending interaction + // request, use the fave as an implicit accept. + implicitlyAccepted, errWithCode := p.implicitlyAccept(ctx, + requester, status, + ) + if errWithCode != nil { + return nil, errWithCode + } + + // If we ended up implicitly accepting, mark the + // target status as no longer pending approval so + // it's serialized properly via the API. + if implicitlyAccepted { + status.PendingApproval = util.Ptr(false) + } + return p.c.GetAPIStatus(ctx, requester, status) } diff --git a/internal/processing/status/status.go b/internal/processing/status/status.go index 7e614cc31..26dfd0d7a 100644 --- a/internal/processing/status/status.go +++ b/internal/processing/status/status.go @@ -23,6 +23,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/filter/visibility" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/processing/common" + "github.com/superseriousbusiness/gotosocial/internal/processing/interactionrequests" "github.com/superseriousbusiness/gotosocial/internal/processing/polls" "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/superseriousbusiness/gotosocial/internal/text" @@ -42,7 +43,8 @@ type Processor struct { parseMention gtsmodel.ParseMentionFunc // other processors - polls *polls.Processor + polls *polls.Processor + intReqs *interactionrequests.Processor } // New returns a new status processor. @@ -50,6 +52,7 @@ func New( state *state.State, common *common.Processor, polls *polls.Processor, + intReqs *interactionrequests.Processor, federator *federation.Federator, converter *typeutils.Converter, visFilter *visibility.Filter, @@ -66,5 +69,6 @@ func New( formatter: text.NewFormatter(state.DB), parseMention: parseMention, polls: polls, + intReqs: intReqs, } } diff --git a/internal/processing/status/status_test.go b/internal/processing/status/status_test.go index f0b22b2c1..b3c446d14 100644 --- a/internal/processing/status/status_test.go +++ b/internal/processing/status/status_test.go @@ -27,6 +27,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/media" "github.com/superseriousbusiness/gotosocial/internal/processing" "github.com/superseriousbusiness/gotosocial/internal/processing/common" + "github.com/superseriousbusiness/gotosocial/internal/processing/interactionrequests" "github.com/superseriousbusiness/gotosocial/internal/processing/polls" "github.com/superseriousbusiness/gotosocial/internal/processing/status" "github.com/superseriousbusiness/gotosocial/internal/state" @@ -100,11 +101,13 @@ func (suite *StatusStandardTestSuite) SetupTest() { common := common.New(&suite.state, suite.mediaManager, suite.typeConverter, suite.federator, visFilter) polls := polls.New(&common, &suite.state, suite.typeConverter) + intReqs := interactionrequests.New(&common, &suite.state, suite.typeConverter) suite.status = status.New( &suite.state, &common, &polls, + &intReqs, suite.federator, suite.typeConverter, visFilter, diff --git a/internal/processing/status/util.go b/internal/processing/status/util.go new file mode 100644 index 000000000..99cff7c56 --- /dev/null +++ b/internal/processing/status/util.go @@ -0,0 +1,72 @@ +// 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 status + +import ( + "context" + "errors" + + "github.com/superseriousbusiness/gotosocial/internal/db" + "github.com/superseriousbusiness/gotosocial/internal/gtserror" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/util" +) + +func (p *Processor) implicitlyAccept( + ctx context.Context, + requester *gtsmodel.Account, + status *gtsmodel.Status, +) (bool, gtserror.WithCode) { + if status.InReplyToAccountID != requester.ID { + // Status doesn't reply to us, + // we can't accept on behalf + // of someone else. + return false, nil + } + + targetPendingApproval := util.PtrOrValue(status.PendingApproval, false) + if !targetPendingApproval { + // Status isn't pending approval, + // nothing to implicitly accept. + return false, nil + } + + // Status is pending approval, + // check for an interaction request. + intReq, err := p.state.DB.GetInteractionRequestByInteractionURI(ctx, status.URI) + if err != nil && !errors.Is(err, db.ErrNoEntries) { + // Something's gone wrong. + err := gtserror.Newf("db error getting interaction request for %s: %w", status.URI, err) + return false, gtserror.NewErrorInternalError(err) + } + + // No interaction request present + // for this status. Race condition? + if intReq == nil { + return false, nil + } + + // Accept the interaction. + if _, errWithCode := p.intReqs.Accept(ctx, + requester, intReq.ID, + ); errWithCode != nil { + return false, errWithCode + } + + return true, nil +} |