summaryrefslogtreecommitdiff
path: root/internal/processing
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2024-09-23 14:42:19 +0200
committerLibravatar GitHub <noreply@github.com>2024-09-23 14:42:19 +0200
commit1ce854358def5f04b7c3b73418ab56bb58512634 (patch)
tree94d827b90e435c88367d080f53b63ee2285905d6 /internal/processing
parent[chore] add nometrics build tagging to metrics API endpoint (#3331) (diff)
downloadgotosocial-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.go2
-rw-r--r--internal/processing/status/boost.go18
-rw-r--r--internal/processing/status/create.go17
-rw-r--r--internal/processing/status/fave.go22
-rw-r--r--internal/processing/status/status.go6
-rw-r--r--internal/processing/status/status_test.go3
-rw-r--r--internal/processing/status/util.go72
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
+}