You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
4.5 KiB
152 lines
4.5 KiB
// 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 federatingdb |
|
|
|
import ( |
|
"context" |
|
"net/http" |
|
"time" |
|
|
|
"codeberg.org/superseriousbusiness/activity/streams/vocab" |
|
"github.com/superseriousbusiness/gotosocial/internal/ap" |
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror" |
|
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" |
|
"github.com/superseriousbusiness/gotosocial/internal/id" |
|
"github.com/superseriousbusiness/gotosocial/internal/log" |
|
"github.com/superseriousbusiness/gotosocial/internal/messages" |
|
) |
|
|
|
func (f *federatingDB) LikeRequest( |
|
ctx context.Context, |
|
likeReq vocab.GoToSocialLikeRequest, |
|
) error { |
|
log.DebugKV(ctx, "LikeRequest", serialize{likeReq}) |
|
|
|
// Mark activity as handled. |
|
f.storeActivityID(likeReq) |
|
|
|
// Extract relevant values from passed ctx. |
|
activityContext := getActivityContext(ctx) |
|
if activityContext.internal { |
|
return nil // Already processed. |
|
} |
|
|
|
requesting := activityContext.requestingAcct |
|
receiving := activityContext.receivingAcct |
|
|
|
if receiving.IsMoving() { |
|
// A Moving account |
|
// can't accept a Like. |
|
return nil |
|
} |
|
|
|
// Convert received LikeRequest type to dummy |
|
// fave, so that we can check against policies. |
|
// This dummy won't be stored in the database, |
|
// it's used purely for doing permission checks. |
|
dummyFave, err := f.converter.ASLikeToFave(ctx, likeReq) |
|
if err != nil { |
|
err := gtserror.Newf("error converting from AS type: %w", err) |
|
return gtserror.WrapWithCode(http.StatusBadRequest, err) |
|
} |
|
|
|
if !*dummyFave.Status.Local { |
|
// Only process like requests for local statuses. |
|
// |
|
// If the remote has sent us a like request for a |
|
// status that's not ours, we should ignore it. |
|
return nil |
|
} |
|
|
|
// Ensure fave would be enacted by correct account. |
|
if dummyFave.AccountID != requesting.ID { |
|
return gtserror.NewfWithCode(http.StatusForbidden, "requester %s is not expected actor %s", |
|
requesting.URI, dummyFave.Account.URI) |
|
} |
|
|
|
// Ensure fave would be received by correct account. |
|
if dummyFave.TargetAccountID != receiving.ID { |
|
return gtserror.NewfWithCode(http.StatusForbidden, "receiver %s is not expected object %s", |
|
receiving.URI, dummyFave.TargetAccount.URI) |
|
} |
|
|
|
// Check how we should handle this request. |
|
policyResult, err := f.intFilter.StatusLikeable(ctx, |
|
requesting, |
|
dummyFave.Status, |
|
) |
|
if err != nil { |
|
return gtserror.Newf("error seeing if status %s is likeable: %w", dummyFave.Status.URI, err) |
|
} |
|
|
|
// Determine whether to automatically accept, |
|
// automatically reject, or pend approval. |
|
var ( |
|
acceptedAt time.Time |
|
rejectedAt time.Time |
|
) |
|
if policyResult.AutomaticApproval() { |
|
acceptedAt = time.Now() |
|
} else if policyResult.Forbidden() { |
|
rejectedAt = time.Now() |
|
} |
|
|
|
interactionReq := >smodel.InteractionRequest{ |
|
ID: id.NewULID(), |
|
StatusID: dummyFave.Status.ID, |
|
Status: dummyFave.Status, |
|
TargetAccountID: receiving.ID, |
|
TargetAccount: receiving, |
|
InteractingAccountID: requesting.ID, |
|
InteractingAccount: requesting, |
|
InteractionURI: dummyFave.URI, |
|
InteractionType: gtsmodel.InteractionLikeRequest, |
|
AcceptedAt: acceptedAt, |
|
RejectedAt: rejectedAt, |
|
|
|
// Empty as reject/accept |
|
// response not yet sent. |
|
ResponseURI: "", |
|
} |
|
|
|
// Send the interactionReq through to |
|
// the processor to handle side effects. |
|
f.state.Workers.Federator.Queue.Push(&messages.FromFediAPI{ |
|
APObjectType: ap.ActivityLikeRequest, |
|
APActivityType: ap.ActivityCreate, |
|
GTSModel: interactionReq, |
|
Receiving: receiving, |
|
Requesting: requesting, |
|
}) |
|
|
|
return nil |
|
} |
|
|
|
func (f *federatingDB) ReplyRequest( |
|
ctx context.Context, |
|
replyReq vocab.GoToSocialReplyRequest, |
|
) error { |
|
return nil |
|
} |
|
|
|
func (f *federatingDB) AnnounceRequest( |
|
ctx context.Context, |
|
announceReq vocab.GoToSocialAnnounceRequest, |
|
) error { |
|
return nil |
|
}
|
|
|