| 
									
										
										
										
											2023-03-12 16:00:57 +01:00
										 |  |  | // 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/>. | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | package federation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"net/url" | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-11 15:17:36 +02:00
										 |  |  | 	errorsv2 "codeberg.org/gruf/go-errors/v2" | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	"codeberg.org/gruf/go-kv" | 
					
						
							| 
									
										
										
										
											2021-11-13 17:29:43 +01:00
										 |  |  | 	"github.com/superseriousbusiness/activity/pub" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/activity/streams/vocab" | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/ap" | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/db" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | 
					
						
							| 
									
										
										
										
											2022-07-19 09:47:55 +01:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/log" | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | // IsASMediaType will return whether the given content-type string | 
					
						
							|  |  |  | // matches one of the 2 possible ActivityStreams incoming content types: | 
					
						
							|  |  |  | // - application/activity+json | 
					
						
							|  |  |  | // - application/ld+json;profile=https://w3.org/ns/activitystreams | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Where for the above we are leniant with whitespace and quotes. | 
					
						
							|  |  |  | func IsASMediaType(ct string) bool { | 
					
						
							|  |  |  | 	var ( | 
					
						
							|  |  |  | 		// First content-type part, | 
					
						
							|  |  |  | 		// contains the application/... | 
					
						
							|  |  |  | 		p1 string = ct //nolint:revive | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Second content-type part, | 
					
						
							|  |  |  | 		// contains AS IRI if provided | 
					
						
							|  |  |  | 		p2 string | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Split content-type by semi-colon. | 
					
						
							|  |  |  | 	sep := strings.IndexByte(ct, ';') | 
					
						
							|  |  |  | 	if sep >= 0 { | 
					
						
							|  |  |  | 		p1 = ct[:sep] | 
					
						
							|  |  |  | 		p2 = ct[sep+1:] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Trim any ending space from the | 
					
						
							|  |  |  | 	// main content-type part of string. | 
					
						
							|  |  |  | 	p1 = strings.TrimRight(p1, " ") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch p1 { | 
					
						
							|  |  |  | 	case "application/activity+json": | 
					
						
							|  |  |  | 		return p2 == "" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	case "application/ld+json": | 
					
						
							|  |  |  | 		// Trim all start/end space. | 
					
						
							|  |  |  | 		p2 = strings.Trim(p2, " ") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Drop any quotes around the URI str. | 
					
						
							|  |  |  | 		p2 = strings.ReplaceAll(p2, "\"", "") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// End part must be a ref to the main AS namespace IRI. | 
					
						
							|  |  |  | 		return p2 == "profile=https://www.w3.org/ns/activitystreams" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | // federatingActor wraps the pub.FederatingActor | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | // with some custom GoToSocial-specific logic. | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | type federatingActor struct { | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	sideEffectActor pub.DelegateActor | 
					
						
							|  |  |  | 	wrapped         pub.FederatingActor | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | // newFederatingActor returns a federatingActor. | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | func newFederatingActor(c pub.CommonBehavior, s2s pub.FederatingProtocol, db pub.Database, clock pub.Clock) pub.FederatingActor { | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	sideEffectActor := pub.NewSideEffectActor(c, s2s, nil, db, clock) | 
					
						
							| 
									
										
										
										
											2023-05-09 12:16:10 +02:00
										 |  |  | 	sideEffectActor.Serialize = ap.Serialize // hook in our own custom Serialize function | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return &federatingActor{ | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 		sideEffectActor: sideEffectActor, | 
					
						
							| 
									
										
										
										
											2023-05-09 12:16:10 +02:00
										 |  |  | 		wrapped:         pub.NewCustomActor(sideEffectActor, false, true, clock), | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | // PostInboxScheme is a reimplementation of the default baseActor | 
					
						
							|  |  |  | // implementation of PostInboxScheme in pub/base_actor.go. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Key differences from that implementation: | 
					
						
							|  |  |  | //   - More explicit debug logging when a request is not processed. | 
					
						
							|  |  |  | //   - Normalize content of activity object. | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | //   - *ALWAYS* return gtserror.WithCode if there's an issue, to | 
					
						
							|  |  |  | //     provide more helpful messages to remote callers. | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | //   - Return code 202 instead of 200 on successful POST, to reflect | 
					
						
							|  |  |  | //     that we process most side effects asynchronously. | 
					
						
							|  |  |  | func (f *federatingActor) PostInboxScheme(ctx context.Context, w http.ResponseWriter, r *http.Request, scheme string) (bool, error) { | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 	l := log.WithContext(ctx). | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 		WithFields([]kv.Field{ | 
					
						
							|  |  |  | 			{"userAgent", r.UserAgent()}, | 
					
						
							|  |  |  | 			{"path", r.URL.Path}, | 
					
						
							|  |  |  | 		}...) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 	// Ensure valid ActivityPub Content-Type. | 
					
						
							|  |  |  | 	// https://www.w3.org/TR/activitypub/#server-to-server-interactions | 
					
						
							|  |  |  | 	if ct := r.Header.Get("Content-Type"); !IsASMediaType(ct) { | 
					
						
							|  |  |  | 		const ct1 = "application/activity+json" | 
					
						
							|  |  |  | 		const ct2 = "application/ld+json;profile=https://w3.org/ns/activitystreams" | 
					
						
							|  |  |  | 		err := fmt.Errorf("Content-Type %s not acceptable, this endpoint accepts: [%q %q]", ct, ct1, ct2) | 
					
						
							|  |  |  | 		return false, gtserror.NewErrorNotAcceptable(err) | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 	// Authenticate request by checking http signature. | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	ctx, authenticated, err := f.sideEffectActor.AuthenticatePostInbox(ctx, w, r) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-10-03 14:59:30 +01:00
										 |  |  | 		err := gtserror.Newf("error authenticating post inbox: %w", err) | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 		return false, gtserror.NewErrorInternalError(err) | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !authenticated { | 
					
						
							| 
									
										
										
										
											2023-10-03 14:59:30 +01:00
										 |  |  | 		const text = "not authenticated" | 
					
						
							|  |  |  | 		return false, gtserror.NewErrorUnauthorized(errors.New(text), text) | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* | 
					
						
							|  |  |  | 		Begin processing the request, but note that we | 
					
						
							|  |  |  | 		have not yet applied authorization (ie., blocks). | 
					
						
							|  |  |  | 	*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-18 16:11:13 +00:00
										 |  |  | 	// Resolve the activity, rejecting badly formatted / transient. | 
					
						
							|  |  |  | 	activity, ok, errWithCode := ap.ResolveIncomingActivity(r) | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 	if errWithCode != nil { | 
					
						
							|  |  |  | 		return false, errWithCode | 
					
						
							| 
									
										
										
										
											2024-01-18 16:11:13 +00:00
										 |  |  | 	} else if !ok { // transient | 
					
						
							|  |  |  | 		return false, nil | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	// Set additional context data. Primarily this means | 
					
						
							|  |  |  | 	// looking at the Activity and seeing which IRIs are | 
					
						
							|  |  |  | 	// involved in it tangentially. | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 	ctx, err = f.sideEffectActor.PostInboxRequestBodyHook(ctx, r, activity) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-10-03 14:59:30 +01:00
										 |  |  | 		err := gtserror.Newf("error during post inbox request body hook: %w", err) | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 		return false, gtserror.NewErrorInternalError(err) | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	// Check authorization of the activity; this will include blocks. | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 	authorized, err := f.sideEffectActor.AuthorizePostInbox(ctx, w, activity) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		if errors.As(err, new(errOtherIRIBlocked)) { | 
					
						
							|  |  |  | 			// There's no direct block between requester(s) and | 
					
						
							|  |  |  | 			// receiver. However, one or more of the other IRIs | 
					
						
							|  |  |  | 			// involved in the request (account replied to, note | 
					
						
							|  |  |  | 			// boosted, etc) is blocked either at domain level or | 
					
						
							|  |  |  | 			// by the receiver. We don't need to return 403 here, | 
					
						
							|  |  |  | 			// instead, just return 202 accepted but don't do any | 
					
						
							|  |  |  | 			// further processing of the activity. | 
					
						
							|  |  |  | 			return true, nil | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Real error has occurred. | 
					
						
							| 
									
										
										
										
											2023-10-03 14:59:30 +01:00
										 |  |  | 		err := gtserror.Newf("error authorizing post inbox: %w", err) | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 		return false, gtserror.NewErrorInternalError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !authorized { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		// Block exists either from this instance against | 
					
						
							|  |  |  | 		// one or more directly involved actors, or between | 
					
						
							|  |  |  | 		// receiving account and one of those actors. | 
					
						
							| 
									
										
										
										
											2023-10-03 14:59:30 +01:00
										 |  |  | 		const text = "blocked" | 
					
						
							|  |  |  | 		return false, gtserror.NewErrorForbidden(errors.New(text), text) | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Copy existing URL + add request host and scheme. | 
					
						
							|  |  |  | 	inboxID := func() *url.URL { | 
					
						
							|  |  |  | 		u := new(url.URL) | 
					
						
							|  |  |  | 		*u = *r.URL | 
					
						
							|  |  |  | 		u.Host = r.Host | 
					
						
							|  |  |  | 		u.Scheme = scheme | 
					
						
							|  |  |  | 		return u | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// At this point we have everything we need, and have verified that | 
					
						
							|  |  |  | 	// the POST request is authentic (properly signed) and authorized | 
					
						
							|  |  |  | 	// (permitted to interact with the target inbox). | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	// | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 	// Post the activity to the Actor's inbox and trigger side effects . | 
					
						
							|  |  |  | 	if err := f.sideEffectActor.PostInbox(ctx, inboxID, activity); err != nil { | 
					
						
							| 
									
										
										
										
											2023-11-30 16:22:34 +00:00
										 |  |  | 		// Special case: We know it is a bad request if the object or target | 
					
						
							|  |  |  | 		// props needed to be populated, or we failed parsing activity details. | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 		// Send the rejection to the peer. | 
					
						
							| 
									
										
										
										
											2023-11-30 16:22:34 +00:00
										 |  |  | 		if errors.Is(err, pub.ErrObjectRequired) || | 
					
						
							|  |  |  | 			errors.Is(err, pub.ErrTargetRequired) || | 
					
						
							|  |  |  | 			gtserror.IsMalformed(err) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// Log malformed activities to help debug. | 
					
						
							|  |  |  | 			l = l.WithField("activity", activity) | 
					
						
							|  |  |  | 			l.Warnf("malformed incoming activity: %v", err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			const text = "malformed incoming activity" | 
					
						
							| 
									
										
										
										
											2023-10-03 14:59:30 +01:00
										 |  |  | 			return false, gtserror.NewErrorBadRequest(errors.New(text), text) | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// There's been some real error. | 
					
						
							| 
									
										
										
										
											2023-10-03 14:59:30 +01:00
										 |  |  | 		err := gtserror.Newf("error calling sideEffectActor.PostInbox: %w", err) | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 		return false, gtserror.NewErrorInternalError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Side effects are complete. Now delegate determining whether | 
					
						
							|  |  |  | 	// to do inbox forwarding, as well as the action to do it. | 
					
						
							|  |  |  | 	if err := f.sideEffectActor.InboxForwarding(ctx, inboxID, activity); err != nil { | 
					
						
							|  |  |  | 		// As a not-ideal side-effect, InboxForwarding will try | 
					
						
							|  |  |  | 		// to create entries if the federatingDB returns `false` | 
					
						
							|  |  |  | 		// when calling `Exists()` to determine whether the Activity | 
					
						
							|  |  |  | 		// is in the database. | 
					
						
							|  |  |  | 		// | 
					
						
							|  |  |  | 		// Since our `Exists()` function currently *always* | 
					
						
							| 
									
										
										
										
											2023-08-11 15:17:36 +02:00
										 |  |  | 		// returns false, it will *always* attempt to parse | 
					
						
							|  |  |  | 		// out and insert the Activity, trying to fetch other | 
					
						
							|  |  |  | 		// items from the DB in the process, which may or may | 
					
						
							|  |  |  | 		// not exist yet. Therefore, we should expect some | 
					
						
							|  |  |  | 		// errors coming from this function, and only warn log | 
					
						
							|  |  |  | 		// on certain ones. | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 		// | 
					
						
							|  |  |  | 		// This check may be removed when the `Exists()` func | 
					
						
							|  |  |  | 		// is updated, and/or federating callbacks are handled | 
					
						
							|  |  |  | 		// properly. | 
					
						
							| 
									
										
										
										
											2023-11-30 16:22:34 +00:00
										 |  |  | 		if !errorsv2.IsV2( | 
					
						
							| 
									
										
										
										
											2023-08-11 15:17:36 +02:00
										 |  |  | 			err, | 
					
						
							|  |  |  | 			db.ErrAlreadyExists, | 
					
						
							|  |  |  | 			db.ErrNoEntries, | 
					
						
							|  |  |  | 		) { | 
					
						
							| 
									
										
										
										
											2023-06-14 15:08:31 +02:00
										 |  |  | 			// Failed inbox forwarding is not a show-stopper, | 
					
						
							|  |  |  | 			// and doesn't even necessarily denote a real error. | 
					
						
							| 
									
										
										
										
											2023-10-03 14:59:30 +01:00
										 |  |  | 			l.Warnf("error calling sideEffectActor.InboxForwarding: %v", err) | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Request is now undergoing processing. Caller | 
					
						
							|  |  |  | 	// of this function will handle writing Accepted. | 
					
						
							|  |  |  | 	return true, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  | 	Functions below are just lightly wrapped versions | 
					
						
							|  |  |  | 	of the original go-fed federatingActor functions. | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | func (f *federatingActor) PostInbox(c context.Context, w http.ResponseWriter, r *http.Request) (bool, error) { | 
					
						
							|  |  |  | 	return f.PostInboxScheme(c, w, r, "https") | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-28 21:05:15 +02:00
										 |  |  | func (f *federatingActor) Send(c context.Context, outbox *url.URL, t vocab.Type) (pub.Activity, error) { | 
					
						
							|  |  |  | 	log.Infof(c, "send activity %s via outbox %s", t.GetTypeName(), outbox) | 
					
						
							|  |  |  | 	return f.wrapped.Send(c, outbox, t) | 
					
						
							| 
									
										
										
										
											2021-05-15 11:58:11 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | func (f *federatingActor) GetInbox(c context.Context, w http.ResponseWriter, r *http.Request) (bool, error) { | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	return f.wrapped.GetInbox(c, w, r) | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (f *federatingActor) PostOutbox(c context.Context, w http.ResponseWriter, r *http.Request) (bool, error) { | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	return f.wrapped.PostOutbox(c, w, r) | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-15 11:58:11 +02:00
										 |  |  | func (f *federatingActor) PostOutboxScheme(c context.Context, w http.ResponseWriter, r *http.Request, scheme string) (bool, error) { | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	return f.wrapped.PostOutboxScheme(c, w, r, scheme) | 
					
						
							| 
									
										
										
										
											2021-05-15 11:58:11 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | func (f *federatingActor) GetOutbox(c context.Context, w http.ResponseWriter, r *http.Request) (bool, error) { | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	return f.wrapped.GetOutbox(c, w, r) | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | } |