| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | /* | 
					
						
							|  |  |  |    GoToSocial | 
					
						
							|  |  |  |    Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    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-30 13:12:00 +02:00
										 |  |  | package processing | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 	"errors" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 	"net/url" | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 	"github.com/go-fed/activity/streams" | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (p *processor) processFromClientAPI(clientMsg gtsmodel.FromClientAPI) error { | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 	switch clientMsg.APActivityType { | 
					
						
							|  |  |  | 	case gtsmodel.ActivityStreamsCreate: | 
					
						
							|  |  |  | 		// CREATE | 
					
						
							|  |  |  | 		switch clientMsg.APObjectType { | 
					
						
							|  |  |  | 		case gtsmodel.ActivityStreamsNote: | 
					
						
							|  |  |  | 			// CREATE NOTE | 
					
						
							|  |  |  | 			status, ok := clientMsg.GTSModel.(*gtsmodel.Status) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return errors.New("note was not parseable as *gtsmodel.Status") | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 18:42:28 +02:00
										 |  |  | 			if err := p.timelineStatus(status); err != nil { | 
					
						
							|  |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 			if err := p.notifyStatus(status); err != nil { | 
					
						
							|  |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-24 18:49:48 +02:00
										 |  |  | 			if status.VisibilityAdvanced != nil && status.VisibilityAdvanced.Federated { | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 				return p.federateStatus(status) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		case gtsmodel.ActivityStreamsFollow: | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 			// CREATE FOLLOW REQUEST | 
					
						
							|  |  |  | 			followRequest, ok := clientMsg.GTSModel.(*gtsmodel.FollowRequest) | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 			if !ok { | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 				return errors.New("followrequest was not parseable as *gtsmodel.FollowRequest") | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 			if err := p.notifyFollowRequest(followRequest, clientMsg.TargetAccount); err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 			return p.federateFollow(followRequest, clientMsg.OriginAccount, clientMsg.TargetAccount) | 
					
						
							| 
									
										
										
										
											2021-05-24 18:49:48 +02:00
										 |  |  | 		case gtsmodel.ActivityStreamsLike: | 
					
						
							|  |  |  | 			// CREATE LIKE/FAVE | 
					
						
							|  |  |  | 			fave, ok := clientMsg.GTSModel.(*gtsmodel.StatusFave) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return errors.New("fave was not parseable as *gtsmodel.StatusFave") | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 			if err := p.notifyFave(fave, clientMsg.TargetAccount); err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-24 18:49:48 +02:00
										 |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return p.federateFave(fave, clientMsg.OriginAccount, clientMsg.TargetAccount) | 
					
						
							| 
									
										
										
										
											2021-05-28 19:57:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		case gtsmodel.ActivityStreamsAnnounce: | 
					
						
							|  |  |  | 			// CREATE BOOST/ANNOUNCE | 
					
						
							|  |  |  | 			boostWrapperStatus, ok := clientMsg.GTSModel.(*gtsmodel.Status) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return errors.New("boost was not parseable as *gtsmodel.Status") | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-17 18:02:33 +02:00
										 |  |  | 			if err := p.timelineStatus(boostWrapperStatus); err != nil { | 
					
						
							|  |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-28 19:57:04 +02:00
										 |  |  | 			if err := p.notifyAnnounce(boostWrapperStatus); err != nil { | 
					
						
							|  |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return p.federateAnnounce(boostWrapperStatus, clientMsg.OriginAccount, clientMsg.TargetAccount) | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	case gtsmodel.ActivityStreamsUpdate: | 
					
						
							|  |  |  | 		// UPDATE | 
					
						
							| 
									
										
										
										
											2021-05-28 22:47:18 +02:00
										 |  |  | 		switch clientMsg.APObjectType { | 
					
						
							|  |  |  | 		case gtsmodel.ActivityStreamsProfile, gtsmodel.ActivityStreamsPerson: | 
					
						
							|  |  |  | 			// UPDATE ACCOUNT/PROFILE | 
					
						
							|  |  |  | 			account, ok := clientMsg.GTSModel.(*gtsmodel.Account) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return errors.New("account was not parseable as *gtsmodel.Account") | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return p.federateAccountUpdate(account, clientMsg.OriginAccount) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 	case gtsmodel.ActivityStreamsAccept: | 
					
						
							|  |  |  | 		// ACCEPT | 
					
						
							|  |  |  | 		switch clientMsg.APObjectType { | 
					
						
							|  |  |  | 		case gtsmodel.ActivityStreamsFollow: | 
					
						
							|  |  |  | 			// ACCEPT FOLLOW | 
					
						
							|  |  |  | 			follow, ok := clientMsg.GTSModel.(*gtsmodel.Follow) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return errors.New("accept was not parseable as *gtsmodel.Follow") | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if err := p.notifyFollow(follow, clientMsg.TargetAccount); err != nil { | 
					
						
							|  |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 			return p.federateAcceptFollowRequest(follow, clientMsg.OriginAccount, clientMsg.TargetAccount) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	case gtsmodel.ActivityStreamsUndo: | 
					
						
							|  |  |  | 		// UNDO | 
					
						
							|  |  |  | 		switch clientMsg.APObjectType { | 
					
						
							|  |  |  | 		case gtsmodel.ActivityStreamsFollow: | 
					
						
							|  |  |  | 			// UNDO FOLLOW | 
					
						
							|  |  |  | 			follow, ok := clientMsg.GTSModel.(*gtsmodel.Follow) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return errors.New("undo was not parseable as *gtsmodel.Follow") | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return p.federateUnfollow(follow, clientMsg.OriginAccount, clientMsg.TargetAccount) | 
					
						
							| 
									
										
										
										
											2021-06-13 18:42:28 +02:00
										 |  |  | 		case gtsmodel.ActivityStreamsLike: | 
					
						
							|  |  |  | 			// UNDO LIKE/FAVE | 
					
						
							|  |  |  | 			fave, ok := clientMsg.GTSModel.(*gtsmodel.StatusFave) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return errors.New("undo was not parseable as *gtsmodel.StatusFave") | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return p.federateUnfave(fave, clientMsg.OriginAccount, clientMsg.TargetAccount) | 
					
						
							| 
									
										
										
										
											2021-06-21 15:56:00 +02:00
										 |  |  | 		case gtsmodel.ActivityStreamsAnnounce: | 
					
						
							|  |  |  | 			// UNDO ANNOUNCE/BOOST | 
					
						
							|  |  |  | 			boost, ok := clientMsg.GTSModel.(*gtsmodel.Status) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return errors.New("undo was not parseable as *gtsmodel.Status") | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if err := p.deleteStatusFromTimelines(boost); err != nil { | 
					
						
							|  |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return p.federateUnannounce(boost, clientMsg.OriginAccount, clientMsg.TargetAccount) | 
					
						
							| 
									
										
										
										
											2021-06-13 18:42:28 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	case gtsmodel.ActivityStreamsDelete: | 
					
						
							|  |  |  | 		// DELETE | 
					
						
							|  |  |  | 		switch clientMsg.APObjectType { | 
					
						
							|  |  |  | 		case gtsmodel.ActivityStreamsNote: | 
					
						
							|  |  |  | 			// DELETE STATUS/NOTE | 
					
						
							|  |  |  | 			statusToDelete, ok := clientMsg.GTSModel.(*gtsmodel.Status) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return errors.New("note was not parseable as *gtsmodel.Status") | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if err := p.deleteStatusFromTimelines(statusToDelete); err != nil { | 
					
						
							|  |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return p.federateStatusDelete(statusToDelete, clientMsg.OriginAccount) | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (p *processor) federateStatus(status *gtsmodel.Status) error { | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 	asStatus, err := p.tc.StatusToAS(status) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateStatus: error converting status to as format: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 	outboxIRI, err := url.Parse(status.GTSAuthorAccount.OutboxURI) | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 		return fmt.Errorf("federateStatus: error parsing outboxURI %s: %s", status.GTSAuthorAccount.OutboxURI, err) | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, err = p.federator.FederatingActor().Send(context.Background(), outboxIRI, asStatus) | 
					
						
							|  |  |  | 	return err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 18:42:28 +02:00
										 |  |  | func (p *processor) federateStatusDelete(status *gtsmodel.Status, originAccount *gtsmodel.Account) error { | 
					
						
							|  |  |  | 	asStatus, err := p.tc.StatusToAS(status) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateStatusDelete: error converting status to as format: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	outboxIRI, err := url.Parse(originAccount.OutboxURI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateStatusDelete: error parsing outboxURI %s: %s", originAccount.OutboxURI, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	actorIRI, err := url.Parse(originAccount.URI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateStatusDelete: error parsing actorIRI %s: %s", originAccount.URI, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// create a delete and set the appropriate actor on it | 
					
						
							|  |  |  | 	delete := streams.NewActivityStreamsDelete() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// set the actor for the delete | 
					
						
							|  |  |  | 	deleteActor := streams.NewActivityStreamsActorProperty() | 
					
						
							|  |  |  | 	deleteActor.AppendIRI(actorIRI) | 
					
						
							|  |  |  | 	delete.SetActivityStreamsActor(deleteActor) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Set the status as the 'object' property. | 
					
						
							|  |  |  | 	deleteObject := streams.NewActivityStreamsObjectProperty() | 
					
						
							|  |  |  | 	deleteObject.AppendActivityStreamsNote(asStatus) | 
					
						
							|  |  |  | 	delete.SetActivityStreamsObject(deleteObject) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// set the to and cc as the original to/cc of the original status | 
					
						
							|  |  |  | 	delete.SetActivityStreamsTo(asStatus.GetActivityStreamsTo()) | 
					
						
							|  |  |  | 	delete.SetActivityStreamsCc(asStatus.GetActivityStreamsCc()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, err = p.federator.FederatingActor().Send(context.Background(), outboxIRI, delete) | 
					
						
							|  |  |  | 	return err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | func (p *processor) federateFollow(followRequest *gtsmodel.FollowRequest, originAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) error { | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 	// if both accounts are local there's nothing to do here | 
					
						
							|  |  |  | 	if originAccount.Domain == "" && targetAccount.Domain == "" { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 	follow := p.tc.FollowRequestToFollow(followRequest) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 	asFollow, err := p.tc.FollowToAS(follow, originAccount, targetAccount) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateFollow: error converting follow to as format: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	outboxIRI, err := url.Parse(originAccount.OutboxURI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateFollow: error parsing outboxURI %s: %s", originAccount.OutboxURI, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, err = p.federator.FederatingActor().Send(context.Background(), outboxIRI, asFollow) | 
					
						
							|  |  |  | 	return err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (p *processor) federateUnfollow(follow *gtsmodel.Follow, originAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) error { | 
					
						
							|  |  |  | 	// if both accounts are local there's nothing to do here | 
					
						
							|  |  |  | 	if originAccount.Domain == "" && targetAccount.Domain == "" { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// recreate the follow | 
					
						
							|  |  |  | 	asFollow, err := p.tc.FollowToAS(follow, originAccount, targetAccount) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateUnfollow: error converting follow to as format: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	targetAccountURI, err := url.Parse(targetAccount.URI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("error parsing uri %s: %s", targetAccount.URI, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// create an Undo and set the appropriate actor on it | 
					
						
							|  |  |  | 	undo := streams.NewActivityStreamsUndo() | 
					
						
							|  |  |  | 	undo.SetActivityStreamsActor(asFollow.GetActivityStreamsActor()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Set the recreated follow as the 'object' property. | 
					
						
							|  |  |  | 	undoObject := streams.NewActivityStreamsObjectProperty() | 
					
						
							|  |  |  | 	undoObject.AppendActivityStreamsFollow(asFollow) | 
					
						
							|  |  |  | 	undo.SetActivityStreamsObject(undoObject) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Set the To of the undo as the target of the recreated follow | 
					
						
							|  |  |  | 	undoTo := streams.NewActivityStreamsToProperty() | 
					
						
							|  |  |  | 	undoTo.AppendIRI(targetAccountURI) | 
					
						
							|  |  |  | 	undo.SetActivityStreamsTo(undoTo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	outboxIRI, err := url.Parse(originAccount.OutboxURI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateUnfollow: error parsing outboxURI %s: %s", originAccount.OutboxURI, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// send off the Undo | 
					
						
							|  |  |  | 	_, err = p.federator.FederatingActor().Send(context.Background(), outboxIRI, undo) | 
					
						
							|  |  |  | 	return err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 18:42:28 +02:00
										 |  |  | func (p *processor) federateUnfave(fave *gtsmodel.StatusFave, originAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) error { | 
					
						
							|  |  |  | 	// if both accounts are local there's nothing to do here | 
					
						
							|  |  |  | 	if originAccount.Domain == "" && targetAccount.Domain == "" { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// create the AS fave | 
					
						
							|  |  |  | 	asFave, err := p.tc.FaveToAS(fave) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateFave: error converting fave to as format: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	targetAccountURI, err := url.Parse(targetAccount.URI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("error parsing uri %s: %s", targetAccount.URI, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// create an Undo and set the appropriate actor on it | 
					
						
							|  |  |  | 	undo := streams.NewActivityStreamsUndo() | 
					
						
							|  |  |  | 	undo.SetActivityStreamsActor(asFave.GetActivityStreamsActor()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Set the fave as the 'object' property. | 
					
						
							|  |  |  | 	undoObject := streams.NewActivityStreamsObjectProperty() | 
					
						
							|  |  |  | 	undoObject.AppendActivityStreamsLike(asFave) | 
					
						
							|  |  |  | 	undo.SetActivityStreamsObject(undoObject) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Set the To of the undo as the target of the fave | 
					
						
							|  |  |  | 	undoTo := streams.NewActivityStreamsToProperty() | 
					
						
							|  |  |  | 	undoTo.AppendIRI(targetAccountURI) | 
					
						
							|  |  |  | 	undo.SetActivityStreamsTo(undoTo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	outboxIRI, err := url.Parse(originAccount.OutboxURI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateFave: error parsing outboxURI %s: %s", originAccount.OutboxURI, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	_, err = p.federator.FederatingActor().Send(context.Background(), outboxIRI, undo) | 
					
						
							|  |  |  | 	return err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-21 15:56:00 +02:00
										 |  |  | func (p *processor) federateUnannounce(boost *gtsmodel.Status, originAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) error { | 
					
						
							|  |  |  | 	asAnnounce, err := p.tc.BoostToAS(boost, originAccount, targetAccount) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateUnannounce: error converting status to announce: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// create an Undo and set the appropriate actor on it | 
					
						
							|  |  |  | 	undo := streams.NewActivityStreamsUndo() | 
					
						
							|  |  |  | 	undo.SetActivityStreamsActor(asAnnounce.GetActivityStreamsActor()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Set the boost as the 'object' property. | 
					
						
							|  |  |  | 	undoObject := streams.NewActivityStreamsObjectProperty() | 
					
						
							|  |  |  | 	undoObject.AppendActivityStreamsAnnounce(asAnnounce) | 
					
						
							|  |  |  | 	undo.SetActivityStreamsObject(undoObject) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// set the to | 
					
						
							|  |  |  | 	undo.SetActivityStreamsTo(asAnnounce.GetActivityStreamsTo()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// set the cc | 
					
						
							|  |  |  | 	undo.SetActivityStreamsCc(asAnnounce.GetActivityStreamsCc()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	outboxIRI, err := url.Parse(originAccount.OutboxURI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateUnannounce: error parsing outboxURI %s: %s", originAccount.OutboxURI, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, err = p.federator.FederatingActor().Send(context.Background(), outboxIRI, undo) | 
					
						
							|  |  |  | 	return err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | func (p *processor) federateAcceptFollowRequest(follow *gtsmodel.Follow, originAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) error { | 
					
						
							|  |  |  | 	// if both accounts are local there's nothing to do here | 
					
						
							|  |  |  | 	if originAccount.Domain == "" && targetAccount.Domain == "" { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// recreate the AS follow | 
					
						
							|  |  |  | 	asFollow, err := p.tc.FollowToAS(follow, originAccount, targetAccount) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateUnfollow: error converting follow to as format: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	acceptingAccountURI, err := url.Parse(targetAccount.URI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("error parsing uri %s: %s", targetAccount.URI, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	requestingAccountURI, err := url.Parse(originAccount.URI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("error parsing uri %s: %s", targetAccount.URI, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// create an Accept | 
					
						
							|  |  |  | 	accept := streams.NewActivityStreamsAccept() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// set the accepting actor on it | 
					
						
							|  |  |  | 	acceptActorProp := streams.NewActivityStreamsActorProperty() | 
					
						
							|  |  |  | 	acceptActorProp.AppendIRI(acceptingAccountURI) | 
					
						
							|  |  |  | 	accept.SetActivityStreamsActor(acceptActorProp) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Set the recreated follow as the 'object' property. | 
					
						
							|  |  |  | 	acceptObject := streams.NewActivityStreamsObjectProperty() | 
					
						
							|  |  |  | 	acceptObject.AppendActivityStreamsFollow(asFollow) | 
					
						
							|  |  |  | 	accept.SetActivityStreamsObject(acceptObject) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Set the To of the accept as the originator of the follow | 
					
						
							|  |  |  | 	acceptTo := streams.NewActivityStreamsToProperty() | 
					
						
							|  |  |  | 	acceptTo.AppendIRI(requestingAccountURI) | 
					
						
							|  |  |  | 	accept.SetActivityStreamsTo(acceptTo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	outboxIRI, err := url.Parse(targetAccount.OutboxURI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateAcceptFollowRequest: error parsing outboxURI %s: %s", originAccount.OutboxURI, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// send off the accept using the accepter's outbox | 
					
						
							|  |  |  | 	_, err = p.federator.FederatingActor().Send(context.Background(), outboxIRI, accept) | 
					
						
							|  |  |  | 	return err | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2021-05-24 18:49:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | func (p *processor) federateFave(fave *gtsmodel.StatusFave, originAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) error { | 
					
						
							|  |  |  | 	// if both accounts are local there's nothing to do here | 
					
						
							|  |  |  | 	if originAccount.Domain == "" && targetAccount.Domain == "" { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// create the AS fave | 
					
						
							|  |  |  | 	asFave, err := p.tc.FaveToAS(fave) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateFave: error converting fave to as format: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	outboxIRI, err := url.Parse(originAccount.OutboxURI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateFave: error parsing outboxURI %s: %s", originAccount.OutboxURI, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	_, err = p.federator.FederatingActor().Send(context.Background(), outboxIRI, asFave) | 
					
						
							|  |  |  | 	return err | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-05-28 19:57:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | func (p *processor) federateAnnounce(boostWrapperStatus *gtsmodel.Status, boostingAccount *gtsmodel.Account, boostedAccount *gtsmodel.Account) error { | 
					
						
							|  |  |  | 	announce, err := p.tc.BoostToAS(boostWrapperStatus, boostingAccount, boostedAccount) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateAnnounce: error converting status to announce: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	outboxIRI, err := url.Parse(boostingAccount.OutboxURI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateAnnounce: error parsing outboxURI %s: %s", boostingAccount.OutboxURI, err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-28 22:47:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-28 19:57:04 +02:00
										 |  |  | 	_, err = p.federator.FederatingActor().Send(context.Background(), outboxIRI, announce) | 
					
						
							|  |  |  | 	return err | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-05-28 22:47:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | func (p *processor) federateAccountUpdate(updatedAccount *gtsmodel.Account, originAccount *gtsmodel.Account) error { | 
					
						
							|  |  |  | 	person, err := p.tc.AccountToAS(updatedAccount) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateAccountUpdate: error converting account to person: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	update, err := p.tc.WrapPersonInUpdate(person, originAccount) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateAccountUpdate: error wrapping person in update: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	outboxIRI, err := url.Parse(originAccount.OutboxURI) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("federateAnnounce: error parsing outboxURI %s: %s", originAccount.OutboxURI, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, err = p.federator.FederatingActor().Send(context.Background(), outboxIRI, update) | 
					
						
							|  |  |  | 	return err | 
					
						
							|  |  |  | } |