| 
									
										
										
										
											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-17 19:06:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-30 13:12:00 +02:00
										 |  |  | package processing | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 	"errors" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2022-01-24 13:12:17 +01:00
										 |  |  | 	"net/url" | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-19 09:47:55 +01:00
										 |  |  | 	"codeberg.org/gruf/go-kv" | 
					
						
							|  |  |  | 	"codeberg.org/gruf/go-logger/v2/level" | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/ap" | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 
					
						
							| 
									
										
										
										
											2021-06-13 18:42:28 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/id" | 
					
						
							| 
									
										
										
										
											2022-07-19 09:47:55 +01:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/log" | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/messages" | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | // ProcessFromFederator reads the APActivityType and APObjectType of an incoming message from the federator, | 
					
						
							|  |  |  | // and directs the message into the appropriate side effect handler function, or simply does nothing if there's | 
					
						
							|  |  |  | // no handler function defined for the combination of Activity and Object. | 
					
						
							| 
									
										
										
										
											2023-02-22 16:05:26 +01:00
										 |  |  | func (p *Processor) ProcessFromFederator(ctx context.Context, federatorMsg messages.FromFederator) error { | 
					
						
							| 
									
										
										
										
											2022-07-19 09:47:55 +01:00
										 |  |  | 	// Allocate new log fields slice | 
					
						
							|  |  |  | 	fields := make([]kv.Field, 3, 5) | 
					
						
							|  |  |  | 	fields[0] = kv.Field{"activityType", federatorMsg.APActivityType} | 
					
						
							|  |  |  | 	fields[1] = kv.Field{"objectType", federatorMsg.APObjectType} | 
					
						
							|  |  |  | 	fields[2] = kv.Field{"toAccount", federatorMsg.ReceivingAccount.Username} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if federatorMsg.APIri != nil { | 
					
						
							|  |  |  | 		// An IRI was supplied, append to log | 
					
						
							|  |  |  | 		fields = append(fields, kv.Field{ | 
					
						
							|  |  |  | 			"iri", federatorMsg.APIri, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if federatorMsg.GTSModel != nil && | 
					
						
							|  |  |  | 		log.Level() >= level.DEBUG { | 
					
						
							|  |  |  | 		// Append converted model to log | 
					
						
							|  |  |  | 		fields = append(fields, kv.Field{ | 
					
						
							|  |  |  | 			"model", federatorMsg.GTSModel, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Log this federated message | 
					
						
							| 
									
										
										
										
											2023-02-17 12:02:29 +01:00
										 |  |  | 	l := log.WithContext(ctx).WithFields(fields...) | 
					
						
							| 
									
										
										
										
											2022-07-19 09:47:55 +01:00
										 |  |  | 	l.Info("processing from federator") | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 	switch federatorMsg.APActivityType { | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 	case ap.ActivityCreate: | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 		// CREATE SOMETHING | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 		switch federatorMsg.APObjectType { | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		case ap.ObjectNote: | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 			// CREATE A STATUS | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 			return p.processCreateStatusFromFederator(ctx, federatorMsg) | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		case ap.ActivityLike: | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 			// CREATE A FAVE | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 			return p.processCreateFaveFromFederator(ctx, federatorMsg) | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		case ap.ActivityFollow: | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 			// CREATE A FOLLOW REQUEST | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 			return p.processCreateFollowRequestFromFederator(ctx, federatorMsg) | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		case ap.ActivityAnnounce: | 
					
						
							| 
									
										
										
										
											2021-05-28 19:57:04 +02:00
										 |  |  | 			// CREATE AN ANNOUNCE | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 			return p.processCreateAnnounceFromFederator(ctx, federatorMsg) | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		case ap.ActivityBlock: | 
					
						
							| 
									
										
										
										
											2021-07-11 16:22:21 +02:00
										 |  |  | 			// CREATE A BLOCK | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 			return p.processCreateBlockFromFederator(ctx, federatorMsg) | 
					
						
							| 
									
										
										
										
											2023-01-25 11:12:27 +01:00
										 |  |  | 		case ap.ActivityFlag: | 
					
						
							|  |  |  | 			// CREATE A FLAG / REPORT | 
					
						
							|  |  |  | 			return p.processCreateFlagFromFederator(ctx, federatorMsg) | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 	case ap.ActivityUpdate: | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 		// UPDATE SOMETHING | 
					
						
							| 
									
										
										
										
											2021-11-22 08:46:19 +01:00
										 |  |  | 		if federatorMsg.APObjectType == ap.ObjectProfile { | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 			// UPDATE AN ACCOUNT | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 			return p.processUpdateAccountFromFederator(ctx, federatorMsg) | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 	case ap.ActivityDelete: | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 		// DELETE SOMETHING | 
					
						
							| 
									
										
										
										
											2021-05-23 18:07:04 +02:00
										 |  |  | 		switch federatorMsg.APObjectType { | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		case ap.ObjectNote: | 
					
						
							| 
									
										
										
										
											2021-05-23 18:07:04 +02:00
										 |  |  | 			// DELETE A STATUS | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 			return p.processDeleteStatusFromFederator(ctx, federatorMsg) | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		case ap.ObjectProfile: | 
					
						
							| 
									
										
										
										
											2021-05-23 18:07:04 +02:00
										 |  |  | 			// DELETE A PROFILE/ACCOUNT | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 			return p.processDeleteAccountFromFederator(ctx, federatorMsg) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-09-30 10:56:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	// not a combination we can/need to process | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // processCreateStatusFromFederator handles Activity Create and Object Note | 
					
						
							| 
									
										
										
										
											2023-02-22 16:05:26 +01:00
										 |  |  | func (p *Processor) processCreateStatusFromFederator(ctx context.Context, federatorMsg messages.FromFederator) error { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	// check for either an IRI that we still need to dereference, OR an already dereferenced | 
					
						
							|  |  |  | 	// and converted status pinned to the message. | 
					
						
							| 
									
										
										
										
											2023-05-12 10:15:54 +01:00
										 |  |  | 	var ( | 
					
						
							|  |  |  | 		status *gtsmodel.Status | 
					
						
							|  |  |  | 		err    error | 
					
						
							|  |  |  | 	) | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if federatorMsg.GTSModel != nil { | 
					
						
							|  |  |  | 		var ok bool | 
					
						
							| 
									
										
										
										
											2023-05-12 10:15:54 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// there's a gts model already pinned to the message, it should be a status | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 		if status, ok = federatorMsg.GTSModel.(*gtsmodel.Status); !ok { | 
					
						
							|  |  |  | 			return errors.New("ProcessFromFederator: note was not parseable as *gtsmodel.Status") | 
					
						
							| 
									
										
										
										
											2021-05-23 18:07:04 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-12 10:15:54 +01:00
										 |  |  | 		// Since this was a create originating AP object | 
					
						
							|  |  |  | 		// statusable may have been set on message (no problem if not). | 
					
						
							|  |  |  | 		statusable, _ := federatorMsg.APObjectModel.(ap.Statusable) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Call refresh on status to deref if necessary etc. | 
					
						
							|  |  |  | 		status, _, err = p.federator.RefreshStatus(ctx, | 
					
						
							|  |  |  | 			federatorMsg.ReceivingAccount.Username, | 
					
						
							|  |  |  | 			status, | 
					
						
							|  |  |  | 			statusable, | 
					
						
							|  |  |  | 			false, | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		// no model pinned, we need to dereference based on the IRI | 
					
						
							|  |  |  | 		if federatorMsg.APIri == nil { | 
					
						
							|  |  |  | 			return errors.New("ProcessFromFederator: status was not pinned to federatorMsg, and neither was an IRI for us to dereference") | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-12 10:15:54 +01:00
										 |  |  | 		status, _, err = p.federator.GetStatusByURI(ctx, federatorMsg.ReceivingAccount.Username, federatorMsg.APIri) | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-12 10:15:54 +01:00
										 |  |  | 	if status.Account == nil || status.Account.IsRemote() { | 
					
						
							|  |  |  | 		// Either no account attached yet, or a remote account. | 
					
						
							|  |  |  | 		// Both situations we need to parse account URI to fetch it. | 
					
						
							|  |  |  | 		remoteAccURI, err := url.Parse(status.AccountURI) | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-12 10:15:54 +01:00
										 |  |  | 		// Ensure that account for this status has been deref'd. | 
					
						
							|  |  |  | 		status.Account, _, err = p.federator.GetAccountByURI(ctx, | 
					
						
							| 
									
										
										
										
											2023-02-03 20:03:05 +00:00
										 |  |  | 			federatorMsg.ReceivingAccount.Username, | 
					
						
							| 
									
										
										
										
											2023-05-12 10:15:54 +01:00
										 |  |  | 			remoteAccURI, | 
					
						
							| 
									
										
										
										
											2023-02-03 20:03:05 +00:00
										 |  |  | 		) | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 21:56:02 +02:00
										 |  |  | 	if err := p.timelineAndNotifyStatus(ctx, status); err != nil { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // processCreateFaveFromFederator handles Activity Create and Object Like | 
					
						
							| 
									
										
										
										
											2023-02-22 16:05:26 +01:00
										 |  |  | func (p *Processor) processCreateFaveFromFederator(ctx context.Context, federatorMsg messages.FromFederator) error { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	incomingFave, ok := federatorMsg.GTSModel.(*gtsmodel.StatusFave) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		return errors.New("like was not parseable as *gtsmodel.StatusFave") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 	// make sure the account is pinned | 
					
						
							|  |  |  | 	if incomingFave.Account == nil { | 
					
						
							| 
									
										
										
										
											2023-03-01 18:26:53 +00:00
										 |  |  | 		a, err := p.state.DB.GetAccountByID(ctx, incomingFave.AccountID) | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		incomingFave.Account = a | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-09 12:16:10 +02:00
										 |  |  | 	// Get the remote account to make sure the avi and header are cached. | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 	if incomingFave.Account.Domain != "" { | 
					
						
							|  |  |  | 		remoteAccountID, err := url.Parse(incomingFave.Account.URI) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-12 10:15:54 +01:00
										 |  |  | 		a, _, err := p.federator.GetAccountByURI(ctx, | 
					
						
							| 
									
										
										
										
											2023-02-03 20:03:05 +00:00
										 |  |  | 			federatorMsg.ReceivingAccount.Username, | 
					
						
							|  |  |  | 			remoteAccountID, | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		incomingFave.Account = a | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	if err := p.notifyFave(ctx, incomingFave); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // processCreateFollowRequestFromFederator handles Activity Create and Object Follow | 
					
						
							| 
									
										
										
										
											2023-02-22 16:05:26 +01:00
										 |  |  | func (p *Processor) processCreateFollowRequestFromFederator(ctx context.Context, federatorMsg messages.FromFederator) error { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	followRequest, ok := federatorMsg.GTSModel.(*gtsmodel.FollowRequest) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		return errors.New("incomingFollowRequest was not parseable as *gtsmodel.FollowRequest") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 	// make sure the account is pinned | 
					
						
							|  |  |  | 	if followRequest.Account == nil { | 
					
						
							| 
									
										
										
										
											2023-03-01 18:26:53 +00:00
										 |  |  | 		a, err := p.state.DB.GetAccountByID(ctx, followRequest.AccountID) | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		followRequest.Account = a | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-09 12:16:10 +02:00
										 |  |  | 	// Get the remote account to make sure the avi and header are cached. | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 	if followRequest.Account.Domain != "" { | 
					
						
							|  |  |  | 		remoteAccountID, err := url.Parse(followRequest.Account.URI) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-12 10:15:54 +01:00
										 |  |  | 		a, _, err := p.federator.GetAccountByURI(ctx, | 
					
						
							| 
									
										
										
										
											2023-02-03 20:03:05 +00:00
										 |  |  | 			federatorMsg.ReceivingAccount.Username, | 
					
						
							|  |  |  | 			remoteAccountID, | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		followRequest.Account = a | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	if followRequest.TargetAccount == nil { | 
					
						
							| 
									
										
										
										
											2023-03-01 18:26:53 +00:00
										 |  |  | 		a, err := p.state.DB.GetAccountByID(ctx, followRequest.TargetAccountID) | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		followRequest.TargetAccount = a | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-15 12:35:05 +02:00
										 |  |  | 	if *followRequest.TargetAccount.Locked { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 		// if the account is locked just notify the follow request and nothing else | 
					
						
							|  |  |  | 		return p.notifyFollowRequest(ctx, followRequest) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// if the target account isn't locked, we should already accept the follow and notify about the new follower instead | 
					
						
							| 
									
										
										
										
											2023-03-01 18:26:53 +00:00
										 |  |  | 	follow, err := p.state.DB.AcceptFollowRequest(ctx, followRequest.AccountID, followRequest.TargetAccountID) | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-16 13:27:43 +02:00
										 |  |  | 	if err := p.federateAcceptFollowRequest(ctx, follow); err != nil { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 	return p.notifyFollow(ctx, follow, followRequest.TargetAccount) | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // processCreateAnnounceFromFederator handles Activity Create and Object Announce | 
					
						
							| 
									
										
										
										
											2023-02-22 16:05:26 +01:00
										 |  |  | func (p *Processor) processCreateAnnounceFromFederator(ctx context.Context, federatorMsg messages.FromFederator) error { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	incomingAnnounce, ok := federatorMsg.GTSModel.(*gtsmodel.Status) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		return errors.New("announce was not parseable as *gtsmodel.Status") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 	// make sure the account is pinned | 
					
						
							|  |  |  | 	if incomingAnnounce.Account == nil { | 
					
						
							| 
									
										
										
										
											2023-03-01 18:26:53 +00:00
										 |  |  | 		a, err := p.state.DB.GetAccountByID(ctx, incomingAnnounce.AccountID) | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		incomingAnnounce.Account = a | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-09 12:16:10 +02:00
										 |  |  | 	// Get the remote account to make sure the avi and header are cached. | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 	if incomingAnnounce.Account.Domain != "" { | 
					
						
							|  |  |  | 		remoteAccountID, err := url.Parse(incomingAnnounce.Account.URI) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-12 10:15:54 +01:00
										 |  |  | 		a, _, err := p.federator.GetAccountByURI(ctx, | 
					
						
							| 
									
										
										
										
											2023-02-03 20:03:05 +00:00
										 |  |  | 			federatorMsg.ReceivingAccount.Username, | 
					
						
							|  |  |  | 			remoteAccountID, | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2022-01-25 13:48:13 +01:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		incomingAnnounce.Account = a | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	if err := p.federator.DereferenceAnnounce(ctx, incomingAnnounce, federatorMsg.ReceivingAccount.Username); err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("error dereferencing announce from federator: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	incomingAnnounceID, err := id.NewULIDFromTime(incomingAnnounce.CreatedAt) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	incomingAnnounce.ID = incomingAnnounceID | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-01 18:26:53 +00:00
										 |  |  | 	if err := p.state.DB.PutStatus(ctx, incomingAnnounce); err != nil { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 		return fmt.Errorf("error adding dereferenced announce to the db: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 21:56:02 +02:00
										 |  |  | 	if err := p.timelineAndNotifyStatus(ctx, incomingAnnounce); err != nil { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := p.notifyAnnounce(ctx, incomingAnnounce); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // processCreateBlockFromFederator handles Activity Create and Object Block | 
					
						
							| 
									
										
										
										
											2023-02-22 16:05:26 +01:00
										 |  |  | func (p *Processor) processCreateBlockFromFederator(ctx context.Context, federatorMsg messages.FromFederator) error { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	block, ok := federatorMsg.GTSModel.(*gtsmodel.Block) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		return errors.New("block was not parseable as *gtsmodel.Block") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// remove any of the blocking account's statuses from the blocked account's timeline, and vice versa | 
					
						
							| 
									
										
										
										
											2023-05-25 10:37:38 +02:00
										 |  |  | 	if err := p.state.Timelines.Home.WipeItemsFromAccountID(ctx, block.AccountID, block.TargetAccountID); err != nil { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-05-25 10:37:38 +02:00
										 |  |  | 	if err := p.state.Timelines.Home.WipeItemsFromAccountID(ctx, block.TargetAccountID, block.AccountID); err != nil { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// TODO: same with notifications | 
					
						
							|  |  |  | 	// TODO: same with bookmarks | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 16:05:26 +01:00
										 |  |  | func (p *Processor) processCreateFlagFromFederator(ctx context.Context, federatorMsg messages.FromFederator) error { | 
					
						
							| 
									
										
										
										
											2023-03-19 13:11:46 +01:00
										 |  |  | 	incomingReport, ok := federatorMsg.GTSModel.(*gtsmodel.Report) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		return errors.New("flag was not parseable as *gtsmodel.Report") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// TODO: handle additional side effects of flag creation: | 
					
						
							|  |  |  | 	// - notify admins by dm / notification | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-10 21:56:02 +02:00
										 |  |  | 	return p.emailReport(ctx, incomingReport) | 
					
						
							| 
									
										
										
										
											2023-01-25 11:12:27 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | // processUpdateAccountFromFederator handles Activity Update and Object Profile | 
					
						
							| 
									
										
										
										
											2023-02-22 16:05:26 +01:00
										 |  |  | func (p *Processor) processUpdateAccountFromFederator(ctx context.Context, federatorMsg messages.FromFederator) error { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	incomingAccount, ok := federatorMsg.GTSModel.(*gtsmodel.Account) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							| 
									
										
										
										
											2023-05-09 12:16:10 +02:00
										 |  |  | 		return errors.New("*gtsmodel.Account was not parseable on update account message") | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-09 12:16:10 +02:00
										 |  |  | 	// Because this was an Update, the new AP Object should be set on the message. | 
					
						
							|  |  |  | 	incomingAccountable, ok := federatorMsg.APObjectModel.(ap.Accountable) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		return errors.New("Accountable was not parseable on update account message") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Call RefreshAccount to fetch up-to-date bio, avatar, header, etc. | 
					
						
							| 
									
										
										
										
											2023-05-12 10:15:54 +01:00
										 |  |  | 	updatedAccount, _, err := p.federator.RefreshAccount( | 
					
						
							| 
									
										
										
										
											2023-05-09 12:16:10 +02:00
										 |  |  | 		ctx, | 
					
						
							| 
									
										
										
										
											2023-02-03 20:03:05 +00:00
										 |  |  | 		federatorMsg.ReceivingAccount.Username, | 
					
						
							| 
									
										
										
										
											2023-04-26 17:17:22 +02:00
										 |  |  | 		incomingAccount, | 
					
						
							| 
									
										
										
										
											2023-05-12 10:15:54 +01:00
										 |  |  | 		incomingAccountable, | 
					
						
							|  |  |  | 		true, | 
					
						
							| 
									
										
										
										
											2023-05-09 12:16:10 +02:00
										 |  |  | 	) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("error enriching updated account from federator: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// RefreshAccount doesn't make DB update calls, so do that here. | 
					
						
							|  |  |  | 	if err := p.state.DB.UpdateAccount(ctx, updatedAccount); err != nil { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 		return fmt.Errorf("error enriching updated account from federator: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // processDeleteStatusFromFederator handles Activity Delete and Object Note | 
					
						
							| 
									
										
										
										
											2023-02-22 16:05:26 +01:00
										 |  |  | func (p *Processor) processDeleteStatusFromFederator(ctx context.Context, federatorMsg messages.FromFederator) error { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	statusToDelete, ok := federatorMsg.GTSModel.(*gtsmodel.Status) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		return errors.New("note was not parseable as *gtsmodel.Status") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-24 17:17:40 +02:00
										 |  |  | 	// delete attachments from this status since this request | 
					
						
							|  |  |  | 	// comes from the federating API, and there's no way the | 
					
						
							|  |  |  | 	// poster can do a delete + redraft for it on our instance | 
					
						
							|  |  |  | 	deleteAttachments := true | 
					
						
							|  |  |  | 	return p.wipeStatus(ctx, statusToDelete, deleteAttachments) | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // processDeleteAccountFromFederator handles Activity Delete and Object Profile | 
					
						
							| 
									
										
										
										
											2023-02-22 16:05:26 +01:00
										 |  |  | func (p *Processor) processDeleteAccountFromFederator(ctx context.Context, federatorMsg messages.FromFederator) error { | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | 	account, ok := federatorMsg.GTSModel.(*gtsmodel.Account) | 
					
						
							|  |  |  | 	if !ok { | 
					
						
							|  |  |  | 		return errors.New("account delete was not parseable as *gtsmodel.Account") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-22 16:05:26 +01:00
										 |  |  | 	return p.account.Delete(ctx, account, account.ID) | 
					
						
							| 
									
										
										
										
											2021-10-10 12:39:25 +02:00
										 |  |  | } |