| 
									
										
										
										
											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-03-07 13:05:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | package federation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"net/url" | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +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" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/activity/streams/vocab" | 
					
						
							| 
									
										
										
										
											2021-12-20 15:19:53 +01:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/ap" | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/config" | 
					
						
							| 
									
										
										
										
											2021-04-01 20:46:45 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/db" | 
					
						
							| 
									
										
										
										
											2023-04-28 16:45:21 +01:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/gtscontext" | 
					
						
							| 
									
										
										
										
											2023-03-06 09:38:43 +00:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | 
					
						
							| 
									
										
										
										
											2022-07-19 09:47:55 +01:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/log" | 
					
						
							| 
									
										
										
										
											2021-12-20 15:19:53 +01:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/uris" | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/util" | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | type errOtherIRIBlocked struct { | 
					
						
							|  |  |  | 	account     string | 
					
						
							|  |  |  | 	domainBlock bool | 
					
						
							|  |  |  | 	iriStrs     []string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-11 10:45:35 +01:00
										 |  |  | func (e *errOtherIRIBlocked) Error() string { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	iriStrsNice := "[" + strings.Join(e.iriStrs, ", ") + "]" | 
					
						
							|  |  |  | 	if e.domainBlock { | 
					
						
							|  |  |  | 		return "domain block exists for one or more of " + iriStrsNice | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return "block exists between " + e.account + " and one or more of " + iriStrsNice | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func newErrOtherIRIBlocked( | 
					
						
							|  |  |  | 	account string, | 
					
						
							|  |  |  | 	domainBlock bool, | 
					
						
							|  |  |  | 	otherIRIs []*url.URL, | 
					
						
							|  |  |  | ) error { | 
					
						
							|  |  |  | 	e := errOtherIRIBlocked{ | 
					
						
							|  |  |  | 		account:     account, | 
					
						
							|  |  |  | 		domainBlock: domainBlock, | 
					
						
							|  |  |  | 		iriStrs:     make([]string, 0, len(otherIRIs)), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, iri := range otherIRIs { | 
					
						
							|  |  |  | 		e.iriStrs = append(e.iriStrs, iri.String()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-11 10:45:35 +01:00
										 |  |  | 	return &e | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-20 18:14:23 +02:00
										 |  |  | /* | 
					
						
							|  |  |  | 	GO FED FEDERATING PROTOCOL INTERFACE | 
					
						
							|  |  |  | 	FederatingProtocol contains behaviors an application needs to satisfy for the | 
					
						
							|  |  |  | 	full ActivityPub S2S implementation to be supported by this library. | 
					
						
							|  |  |  | 	It is only required if the client application wants to support the server-to- | 
					
						
							|  |  |  | 	server, or federating, protocol. | 
					
						
							|  |  |  | 	It is passed to the library as a dependency injection from the client | 
					
						
							|  |  |  | 	application. | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | // PostInboxRequestBodyHook callback after parsing the request body for a | 
					
						
							|  |  |  | // federated request to the Actor's inbox. | 
					
						
							| 
									
										
										
										
											2021-04-20 18:14:23 +02:00
										 |  |  | // | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | // Can be used to set contextual information based on the Activity received. | 
					
						
							| 
									
										
										
										
											2021-04-20 18:14:23 +02:00
										 |  |  | // | 
					
						
							|  |  |  | // Warning: Neither authentication nor authorization has taken place at | 
					
						
							|  |  |  | // this time. Doing anything beyond setting contextual information is | 
					
						
							|  |  |  | // strongly discouraged. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | // If an error is returned, it is passed back to the caller of PostInbox. | 
					
						
							|  |  |  | // In this case, the DelegateActor implementation must not write a response | 
					
						
							|  |  |  | // to the ResponseWriter as is expected that the caller to PostInbox will | 
					
						
							|  |  |  | // do so when handling the error. | 
					
						
							| 
									
										
										
										
											2023-10-23 10:58:13 +01:00
										 |  |  | func (f *Federator) PostInboxRequestBodyHook(ctx context.Context, r *http.Request, activity pub.Activity) (context.Context, error) { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	// Extract any other IRIs involved in this activity. | 
					
						
							|  |  |  | 	otherIRIs := []*url.URL{} | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	// Get the ID of the Activity itslf. | 
					
						
							|  |  |  | 	activityID, err := pub.GetId(activity) | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		otherIRIs = append(otherIRIs, activityID) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check if the Activity has an 'inReplyTo'. | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 	if replyToable, ok := activity.(ap.ReplyToable); ok { | 
					
						
							|  |  |  | 		if inReplyToURI := ap.ExtractInReplyToURI(replyToable); inReplyToURI != nil { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 			otherIRIs = append(otherIRIs, inReplyToURI) | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-17 17:49:11 +02:00
										 |  |  | 	// Check for TO and CC URIs on the Activity. | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	if addressable, ok := activity.(ap.Addressable); ok { | 
					
						
							| 
									
										
										
										
											2023-06-17 17:49:11 +02:00
										 |  |  | 		otherIRIs = append(otherIRIs, ap.ExtractToURIs(addressable)...) | 
					
						
							|  |  |  | 		otherIRIs = append(otherIRIs, ap.ExtractCcURIs(addressable)...) | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	// Now perform the same checks, but for the Object(s) of the Activity. | 
					
						
							|  |  |  | 	objectProp := activity.GetActivityStreamsObject() | 
					
						
							|  |  |  | 	for iter := objectProp.Begin(); iter != objectProp.End(); iter = iter.Next() { | 
					
						
							|  |  |  | 		if iter.IsIRI() { | 
					
						
							|  |  |  | 			otherIRIs = append(otherIRIs, iter.GetIRI()) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		t := iter.GetType() | 
					
						
							|  |  |  | 		if t == nil { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		objectID, err := pub.GetId(t) | 
					
						
							|  |  |  | 		if err == nil { | 
					
						
							|  |  |  | 			otherIRIs = append(otherIRIs, objectID) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if replyToable, ok := t.(ap.ReplyToable); ok { | 
					
						
							|  |  |  | 			if inReplyToURI := ap.ExtractInReplyToURI(replyToable); inReplyToURI != nil { | 
					
						
							|  |  |  | 				otherIRIs = append(otherIRIs, inReplyToURI) | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if addressable, ok := t.(ap.Addressable); ok { | 
					
						
							| 
									
										
										
										
											2023-06-17 17:49:11 +02:00
										 |  |  | 			otherIRIs = append(otherIRIs, ap.ExtractToURIs(addressable)...) | 
					
						
							|  |  |  | 			otherIRIs = append(otherIRIs, ap.ExtractCcURIs(addressable)...) | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	// Clean any instances of the public URI, since | 
					
						
							|  |  |  | 	// we don't care about that in this context. | 
					
						
							|  |  |  | 	otherIRIs = func(iris []*url.URL) []*url.URL { | 
					
						
							|  |  |  | 		np := make([]*url.URL, 0, len(iris)) | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		for _, i := range iris { | 
					
						
							|  |  |  | 			if !pub.IsPublic(i.String()) { | 
					
						
							|  |  |  | 				np = append(np, i) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		return np | 
					
						
							|  |  |  | 	}(otherIRIs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// OtherIRIs will likely contain some | 
					
						
							|  |  |  | 	// duplicate entries now, so remove them. | 
					
						
							|  |  |  | 	otherIRIs = util.UniqueURIs(otherIRIs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Finished, set other IRIs on the context | 
					
						
							|  |  |  | 	// so they can be checked for blocks later. | 
					
						
							|  |  |  | 	ctx = gtscontext.SetOtherIRIs(ctx, otherIRIs) | 
					
						
							|  |  |  | 	return ctx, nil | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-20 18:14:23 +02:00
										 |  |  | // AuthenticatePostInbox delegates the authentication of a POST to an | 
					
						
							|  |  |  | // inbox. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // If an error is returned, it is passed back to the caller of | 
					
						
							|  |  |  | // PostInbox. In this case, the implementation must not write a | 
					
						
							|  |  |  | // response to the ResponseWriter as is expected that the client will | 
					
						
							|  |  |  | // do so when handling the error. The 'authenticated' is ignored. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // If no error is returned, but authentication or authorization fails, | 
					
						
							|  |  |  | // then authenticated must be false and error nil. It is expected that | 
					
						
							|  |  |  | // the implementation handles writing to the ResponseWriter in this | 
					
						
							|  |  |  | // case. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Finally, if the authentication and authorization succeeds, then | 
					
						
							|  |  |  | // authenticated must be true and error nil. The request will continue | 
					
						
							|  |  |  | // to be processed. | 
					
						
							| 
									
										
										
										
											2023-10-23 10:58:13 +01:00
										 |  |  | func (f *Federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool, error) { | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	log.Tracef(ctx, "received request to authenticate inbox %s", r.URL.String()) | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	// Ensure this is an inbox path, and fetch the inbox owner | 
					
						
							|  |  |  | 	// account by parsing username from `/users/{username}/inbox`. | 
					
						
							| 
									
										
										
										
											2021-12-20 15:19:53 +01:00
										 |  |  | 	username, err := uris.ParseInboxPath(r.URL) | 
					
						
							| 
									
										
										
										
											2021-05-15 11:58:11 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		err = gtserror.Newf("could not parse %s as inbox path: %w", r.URL.String(), err) | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 		return nil, false, err | 
					
						
							| 
									
										
										
										
											2021-05-15 11:58:11 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if username == "" { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		err = gtserror.New("inbox username was empty") | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 		return nil, false, err | 
					
						
							| 
									
										
										
										
											2021-05-15 11:58:11 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-02 10:56:33 +01:00
										 |  |  | 	receivingAccount, err := f.db.GetAccountByUsernameDomain(ctx, username, "") | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		err = gtserror.Newf("could not fetch receiving account %s: %w", username, err) | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 		return nil, false, err | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	// Check who's trying to deliver to us by inspecting the http signature. | 
					
						
							| 
									
										
										
										
											2023-09-12 11:43:12 +02:00
										 |  |  | 	pubKeyAuth, errWithCode := f.AuthenticateFederatedRequest(ctx, receivingAccount.Username) | 
					
						
							| 
									
										
										
										
											2022-04-26 18:10:11 +02:00
										 |  |  | 	if errWithCode != nil { | 
					
						
							|  |  |  | 		switch errWithCode.Code() { | 
					
						
							|  |  |  | 		case http.StatusUnauthorized, http.StatusForbidden, http.StatusBadRequest: | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 			// If codes 400, 401, or 403, obey the go-fed | 
					
						
							|  |  |  | 			// interface by writing the header and bailing. | 
					
						
							| 
									
										
										
										
											2022-04-26 18:10:11 +02:00
										 |  |  | 			w.WriteHeader(errWithCode.Code()) | 
					
						
							| 
									
										
										
										
											2022-11-11 12:18:38 +01:00
										 |  |  | 		case http.StatusGone: | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 			// If the requesting account's key has gone | 
					
						
							|  |  |  | 			// (410) then likely inbox post was a delete. | 
					
						
							|  |  |  | 			// | 
					
						
							|  |  |  | 			// We can just write 202 and leave: we didn't | 
					
						
							|  |  |  | 			// know about the account anyway, so we can't | 
					
						
							|  |  |  | 			// do any further processing. | 
					
						
							| 
									
										
										
										
											2022-11-11 12:18:38 +01:00
										 |  |  | 			w.WriteHeader(http.StatusAccepted) | 
					
						
							| 
									
										
										
										
											2022-04-26 18:10:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-04-03 13:57:07 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// We still return the error | 
					
						
							|  |  |  | 		// for later request logging. | 
					
						
							|  |  |  | 		return ctx, false, errWithCode | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-21 10:35:30 +00:00
										 |  |  | 	if pubKeyAuth.Handshaking { | 
					
						
							|  |  |  | 		// There is a mutal handshake occurring between us and | 
					
						
							|  |  |  | 		// the owner URI. Return 202 and leave as we can't do | 
					
						
							|  |  |  | 		// much else until the handshake procedure has finished. | 
					
						
							|  |  |  | 		w.WriteHeader(http.StatusAccepted) | 
					
						
							| 
									
										
										
										
											2023-11-10 17:16:58 +01:00
										 |  |  | 		return ctx, false, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	// We have everything we need now, set the requesting | 
					
						
							|  |  |  | 	// and receiving accounts on the context for later use. | 
					
						
							| 
									
										
										
										
											2023-11-21 10:35:30 +00:00
										 |  |  | 	ctx = gtscontext.SetRequestingAccount(ctx, pubKeyAuth.Owner) | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	ctx = gtscontext.SetReceivingAccount(ctx, receivingAccount) | 
					
						
							|  |  |  | 	return ctx, true, nil | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-20 18:14:23 +02:00
										 |  |  | // Blocked should determine whether to permit a set of actors given by | 
					
						
							|  |  |  | // their ids are able to interact with this particular end user due to | 
					
						
							|  |  |  | // being blocked or other application-specific logic. | 
					
						
							| 
									
										
										
										
											2023-10-23 10:58:13 +01:00
										 |  |  | func (f *Federator) Blocked(ctx context.Context, actorIRIs []*url.URL) (bool, error) { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	// Fetch relevant items from request context. | 
					
						
							|  |  |  | 	// These should have been set further up the flow. | 
					
						
							|  |  |  | 	receivingAccount := gtscontext.ReceivingAccount(ctx) | 
					
						
							|  |  |  | 	if receivingAccount == nil { | 
					
						
							|  |  |  | 		err := gtserror.New("couldn't determine blocks (receiving account not set on request context)") | 
					
						
							|  |  |  | 		return false, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	requestingAccount := gtscontext.RequestingAccount(ctx) | 
					
						
							|  |  |  | 	if requestingAccount == nil { | 
					
						
							|  |  |  | 		err := gtserror.New("couldn't determine blocks (requesting account not set on request context)") | 
					
						
							|  |  |  | 		return false, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	otherIRIs := gtscontext.OtherIRIs(ctx) | 
					
						
							|  |  |  | 	if otherIRIs == nil { | 
					
						
							|  |  |  | 		err := gtserror.New("couldn't determine blocks (otherIRIs not set on request context)") | 
					
						
							|  |  |  | 		return false, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-15 11:58:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	l := log. | 
					
						
							|  |  |  | 		WithContext(ctx). | 
					
						
							|  |  |  | 		WithFields(kv.Fields{ | 
					
						
							|  |  |  | 			{"actorIRIs", actorIRIs}, | 
					
						
							|  |  |  | 			{"receivingAccount", receivingAccount.URI}, | 
					
						
							|  |  |  | 			{"requestingAccount", requestingAccount.URI}, | 
					
						
							|  |  |  | 			{"otherIRIs", otherIRIs}, | 
					
						
							|  |  |  | 		}...) | 
					
						
							|  |  |  | 	l.Trace("checking blocks") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Start broad by checking domain-level blocks first for | 
					
						
							|  |  |  | 	// the given actor IRIs; if any of them are domain blocked | 
					
						
							|  |  |  | 	// then we can save some work. | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 	blocked, err := f.db.AreURIsBlocked(ctx, actorIRIs) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		err = gtserror.Newf("error checking domain blocks of actorIRIs: %w", err) | 
					
						
							|  |  |  | 		return false, err | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 	if blocked { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		l.Trace("one or more actorIRIs are domain blocked") | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 		return blocked, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	// Now user level blocks. Receiver should not block requester. | 
					
						
							|  |  |  | 	blocked, err = f.db.IsBlocked(ctx, receivingAccount.ID, requestingAccount.ID) | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		err = gtserror.Newf("db error checking block between receiver and requester: %w", err) | 
					
						
							|  |  |  | 		return false, err | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 	if blocked { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		l.Trace("receiving account blocks requesting account") | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 		return blocked, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	// We've established that no blocks exist between directly | 
					
						
							|  |  |  | 	// involved actors, but what about IRIs of other actors and | 
					
						
							|  |  |  | 	// objects which are tangentially involved in the activity | 
					
						
							|  |  |  | 	// (ie., replied to, boosted)? | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// If one or more of these other IRIs is domain blocked, or | 
					
						
							|  |  |  | 	// blocked by the receiving account, this shouldn't return | 
					
						
							|  |  |  | 	// blocked=true to send a 403, since that would be rather | 
					
						
							|  |  |  | 	// silly behavior. Instead, we should indicate to the caller | 
					
						
							|  |  |  | 	// that we should stop processing the activity and just write | 
					
						
							|  |  |  | 	// 202 Accepted instead. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// For this, we can use the errOtherIRIBlocked type, which | 
					
						
							|  |  |  | 	// will be checked for | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Check high-level domain blocks first. | 
					
						
							|  |  |  | 	blocked, err = f.db.AreURIsBlocked(ctx, otherIRIs) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		err := gtserror.Newf("error checking domain block of otherIRIs: %w", err) | 
					
						
							|  |  |  | 		return false, err | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	if blocked { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		err := newErrOtherIRIBlocked(receivingAccount.URI, true, otherIRIs) | 
					
						
							|  |  |  | 		l.Trace(err.Error()) | 
					
						
							|  |  |  | 		return false, err | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	// For each other IRI, check whether the IRI points to an | 
					
						
							|  |  |  | 	// account or a status, and try to get (an) accountID(s) | 
					
						
							|  |  |  | 	// from it to do further checks on. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// We use a map for this instead of a slice in order to | 
					
						
							|  |  |  | 	// deduplicate entries and avoid doing the same check twice. | 
					
						
							|  |  |  | 	// The map value is the host of the otherIRI. | 
					
						
							|  |  |  | 	accountIDs := make(map[string]string, len(otherIRIs)) | 
					
						
							|  |  |  | 	for _, iri := range otherIRIs { | 
					
						
							|  |  |  | 		// Assemble iri string just once. | 
					
						
							|  |  |  | 		iriStr := iri.String() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		account, err := f.db.GetAccountByURI( | 
					
						
							|  |  |  | 			// We're on a hot path, fetch bare minimum. | 
					
						
							|  |  |  | 			gtscontext.SetBarebones(ctx), | 
					
						
							|  |  |  | 			iriStr, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		if err != nil && !errors.Is(err, db.ErrNoEntries) { | 
					
						
							|  |  |  | 			// Real db error. | 
					
						
							|  |  |  | 			err = gtserror.Newf("db error trying to get %s as account: %w", iriStr, err) | 
					
						
							|  |  |  | 			return false, err | 
					
						
							|  |  |  | 		} else if err == nil { | 
					
						
							|  |  |  | 			// IRI is for an account. | 
					
						
							|  |  |  | 			accountIDs[account.ID] = iri.Host | 
					
						
							|  |  |  | 			continue | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		status, err := f.db.GetStatusByURI( | 
					
						
							|  |  |  | 			// We're on a hot path, fetch bare minimum. | 
					
						
							|  |  |  | 			gtscontext.SetBarebones(ctx), | 
					
						
							|  |  |  | 			iriStr, | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		if err != nil && !errors.Is(err, db.ErrNoEntries) { | 
					
						
							|  |  |  | 			// Real db error. | 
					
						
							|  |  |  | 			err = gtserror.Newf("db error trying to get %s as status: %w", iriStr, err) | 
					
						
							|  |  |  | 			return false, err | 
					
						
							|  |  |  | 		} else if err == nil { | 
					
						
							|  |  |  | 			// IRI is for a status. | 
					
						
							|  |  |  | 			accountIDs[status.AccountID] = iri.Host | 
					
						
							|  |  |  | 			continue | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 	// Get our own host value just once outside the loop. | 
					
						
							|  |  |  | 	ourHost := config.GetHost() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for accountID, iriHost := range accountIDs { | 
					
						
							|  |  |  | 		// Receiver shouldn't block other IRI owner. | 
					
						
							|  |  |  | 		// | 
					
						
							|  |  |  | 		// This check protects against cases where someone on our | 
					
						
							|  |  |  | 		// instance is receiving a boost from someone they don't | 
					
						
							|  |  |  | 		// block, but the boost target is the status of an account | 
					
						
							|  |  |  | 		// they DO have blocked, or the boosted status mentions an | 
					
						
							|  |  |  | 		// account they have blocked. In this case, it's v. unlikely | 
					
						
							|  |  |  | 		// they care to see the boost in their timeline, so there's | 
					
						
							|  |  |  | 		// no point in us processing it. | 
					
						
							|  |  |  | 		blocked, err = f.db.IsBlocked(ctx, receivingAccount.ID, accountID) | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 			err = gtserror.Newf("db error checking block between receiver and other account: %w", err) | 
					
						
							|  |  |  | 			return false, err | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-23 11:46:50 +02:00
										 |  |  | 		if blocked { | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 			l.Trace("receiving account blocks one or more otherIRIs") | 
					
						
							|  |  |  | 			err := newErrOtherIRIBlocked(receivingAccount.URI, false, otherIRIs) | 
					
						
							|  |  |  | 			return false, err | 
					
						
							| 
									
										
										
										
											2021-05-15 11:58:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-07-11 16:22:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-13 16:47:56 +02:00
										 |  |  | 		// If other account is from our instance (indicated by the | 
					
						
							|  |  |  | 		// host of the URI stored in the map), ensure they don't block | 
					
						
							|  |  |  | 		// the requester. | 
					
						
							|  |  |  | 		// | 
					
						
							|  |  |  | 		// This check protects against cases where one of our users | 
					
						
							|  |  |  | 		// might be mentioned by the requesting account, and therefore | 
					
						
							|  |  |  | 		// appear in otherIRIs, but the activity itself has been sent | 
					
						
							|  |  |  | 		// to a different account on our instance. In other words, two | 
					
						
							|  |  |  | 		// accounts are gossiping about + trying to tag a third account | 
					
						
							|  |  |  | 		// who has one or the other of them blocked. | 
					
						
							|  |  |  | 		if iriHost == ourHost { | 
					
						
							|  |  |  | 			blocked, err = f.db.IsBlocked(ctx, accountID, requestingAccount.ID) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				err = gtserror.Newf("db error checking block between other account and requester: %w", err) | 
					
						
							|  |  |  | 				return false, err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if blocked { | 
					
						
							|  |  |  | 				l.Trace("one or more otherIRIs belonging to us blocks requesting account") | 
					
						
							|  |  |  | 				err := newErrOtherIRIBlocked(requestingAccount.URI, false, otherIRIs) | 
					
						
							|  |  |  | 				return false, err | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-05-15 11:58:11 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-09-24 17:56:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | 	return false, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-20 18:14:23 +02:00
										 |  |  | // FederatingCallbacks returns the application logic that handles | 
					
						
							|  |  |  | // ActivityStreams received from federating peers. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Note that certain types of callbacks will be 'wrapped' with default | 
					
						
							|  |  |  | // behaviors supported natively by the library. Other callbacks | 
					
						
							|  |  |  | // compatible with streams.TypeResolver can be specified by 'other'. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // For example, setting the 'Create' field in the | 
					
						
							|  |  |  | // FederatingWrappedCallbacks lets an application dependency inject | 
					
						
							|  |  |  | // additional behaviors they want to take place, including the default | 
					
						
							|  |  |  | // behavior supplied by this library. This is guaranteed to be compliant | 
					
						
							|  |  |  | // with the ActivityPub Social protocol. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // To override the default behavior, instead supply the function in | 
					
						
							|  |  |  | // 'other', which does not guarantee the application will be compliant | 
					
						
							|  |  |  | // with the ActivityPub Social Protocol. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Applications are not expected to handle every single ActivityStreams | 
					
						
							|  |  |  | // type and extension. The unhandled ones are passed to DefaultCallback. | 
					
						
							| 
									
										
										
										
											2024-03-12 15:34:08 +01:00
										 |  |  | func (f *Federator) FederatingCallbacks(ctx context.Context) ( | 
					
						
							|  |  |  | 	wrapped pub.FederatingWrappedCallbacks, | 
					
						
							|  |  |  | 	other []any, | 
					
						
							|  |  |  | 	err error, | 
					
						
							|  |  |  | ) { | 
					
						
							| 
									
										
										
										
											2021-05-15 11:58:11 +02:00
										 |  |  | 	wrapped = pub.FederatingWrappedCallbacks{ | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 		// OnFollow determines what action to take for this | 
					
						
							|  |  |  | 		// particular callback if a Follow Activity is handled. | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 		// | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 		// For our implementation, we always want to do nothing | 
					
						
							|  |  |  | 		// because we have internal logic for handling follows. | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 		OnFollow: pub.OnFollowDoNothing, | 
					
						
							| 
									
										
										
										
											2021-05-15 11:58:11 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	// Override some default behaviors to trigger our own side effects. | 
					
						
							| 
									
										
										
										
											2024-03-12 15:34:08 +01:00
										 |  |  | 	other = []any{ | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 		func(ctx context.Context, undo vocab.ActivityStreamsUndo) error { | 
					
						
							|  |  |  | 			return f.FederatingDB().Undo(ctx, undo) | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		func(ctx context.Context, accept vocab.ActivityStreamsAccept) error { | 
					
						
							|  |  |  | 			return f.FederatingDB().Accept(ctx, accept) | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2021-10-16 13:27:43 +02:00
										 |  |  | 		func(ctx context.Context, reject vocab.ActivityStreamsReject) error { | 
					
						
							|  |  |  | 			return f.FederatingDB().Reject(ctx, reject) | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2021-05-28 19:57:04 +02:00
										 |  |  | 		func(ctx context.Context, announce vocab.ActivityStreamsAnnounce) error { | 
					
						
							|  |  |  | 			return f.FederatingDB().Announce(ctx, announce) | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-12 15:34:08 +01:00
										 |  |  | 	// Define some of our own behaviors which are not | 
					
						
							|  |  |  | 	// overrides of the default pub.FederatingWrappedCallbacks. | 
					
						
							|  |  |  | 	other = append(other, []any{ | 
					
						
							|  |  |  | 		func(ctx context.Context, move vocab.ActivityStreamsMove) error { | 
					
						
							|  |  |  | 			return f.FederatingDB().Move(ctx, move) | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	}...) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-15 11:58:11 +02:00
										 |  |  | 	return | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-20 18:14:23 +02:00
										 |  |  | // DefaultCallback is called for types that go-fed can deserialize but | 
					
						
							|  |  |  | // are not handled by the application's callbacks returned in the | 
					
						
							|  |  |  | // Callbacks method. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Applications are not expected to handle every single ActivityStreams | 
					
						
							|  |  |  | // type and extension, so the unhandled ones are passed to | 
					
						
							|  |  |  | // DefaultCallback. | 
					
						
							| 
									
										
										
										
											2023-10-23 10:58:13 +01:00
										 |  |  | func (f *Federator) DefaultCallback(ctx context.Context, activity pub.Activity) error { | 
					
						
							| 
									
										
										
										
											2023-04-06 13:19:55 +02:00
										 |  |  | 	log.Debugf(ctx, "received unhandle-able activity type (%s) so ignoring it", activity.GetTypeName()) | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-20 18:14:23 +02:00
										 |  |  | // MaxInboxForwardingRecursionDepth determines how deep to search within | 
					
						
							|  |  |  | // an activity to determine if inbox forwarding needs to occur. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Zero or negative numbers indicate infinite recursion. | 
					
						
							| 
									
										
										
										
											2023-10-23 10:58:13 +01:00
										 |  |  | func (f *Federator) MaxInboxForwardingRecursionDepth(ctx context.Context) int { | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | 	// TODO | 
					
						
							| 
									
										
										
										
											2021-05-15 11:58:11 +02:00
										 |  |  | 	return 4 | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-20 18:14:23 +02:00
										 |  |  | // MaxDeliveryRecursionDepth determines how deep to search within | 
					
						
							|  |  |  | // collections owned by peers when they are targeted to receive a | 
					
						
							|  |  |  | // delivery. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Zero or negative numbers indicate infinite recursion. | 
					
						
							| 
									
										
										
										
											2023-10-23 10:58:13 +01:00
										 |  |  | func (f *Federator) MaxDeliveryRecursionDepth(ctx context.Context) int { | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | 	// TODO | 
					
						
							| 
									
										
										
										
											2021-05-15 11:58:11 +02:00
										 |  |  | 	return 4 | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-20 18:14:23 +02:00
										 |  |  | // FilterForwarding allows the implementation to apply business logic | 
					
						
							|  |  |  | // such as blocks, spam filtering, and so on to a list of potential | 
					
						
							|  |  |  | // Collections and OrderedCollections of recipients when inbox | 
					
						
							|  |  |  | // forwarding has been triggered. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The activity is provided as a reference for more intelligent | 
					
						
							|  |  |  | // logic to be used, but the implementation must not modify it. | 
					
						
							| 
									
										
										
										
											2023-10-23 10:58:13 +01:00
										 |  |  | func (f *Federator) FilterForwarding(ctx context.Context, potentialRecipients []*url.URL, a pub.Activity) ([]*url.URL, error) { | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | 	// TODO | 
					
						
							| 
									
										
										
										
											2021-05-29 19:36:54 +02:00
										 |  |  | 	return []*url.URL{}, nil | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-20 18:14:23 +02:00
										 |  |  | // GetInbox returns the OrderedCollection inbox of the actor for this | 
					
						
							|  |  |  | // context. It is up to the implementation to provide the correct | 
					
						
							|  |  |  | // collection for the kind of authorization given in the request. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // AuthenticateGetInbox will be called prior to this. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Always called, regardless whether the Federated Protocol or Social | 
					
						
							|  |  |  | // API is enabled. | 
					
						
							| 
									
										
										
										
											2023-10-23 10:58:13 +01:00
										 |  |  | func (f *Federator) GetInbox(ctx context.Context, r *http.Request) (vocab.ActivityStreamsOrderedCollectionPage, error) { | 
					
						
							| 
									
										
										
										
											2021-05-15 11:58:11 +02:00
										 |  |  | 	// IMPLEMENTATION NOTE: For GoToSocial, we serve GETS to outboxes and inboxes through | 
					
						
							| 
									
										
										
										
											2021-05-08 14:25:55 +02:00
										 |  |  | 	// the CLIENT API, not through the federation API, so we just do nothing here. | 
					
						
							| 
									
										
										
										
											2021-05-29 19:36:54 +02:00
										 |  |  | 	return streams.NewActivityStreamsOrderedCollectionPage(), nil | 
					
						
							| 
									
										
										
										
											2021-03-07 13:05:33 +01:00
										 |  |  | } |