| 
									
										
										
										
											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-08-25 15:34:33 +02:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 	"errors" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2021-08-10 13:32:39 +02:00
										 |  |  | 	"net/url" | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/sirupsen/logrus" | 
					
						
							| 
									
										
										
										
											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/db" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 
					
						
							| 
									
										
										
										
											2021-06-13 18:42:28 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/id" | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/messages" | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | func (p *processor) ProcessFromFederator(ctx context.Context, federatorMsg messages.FromFederator) error { | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 	l := p.log.WithFields(logrus.Fields{ | 
					
						
							|  |  |  | 		"func":         "processFromFederator", | 
					
						
							|  |  |  | 		"federatorMsg": fmt.Sprintf("%+v", federatorMsg), | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-11 16:22:21 +02:00
										 |  |  | 	l.Trace("entering function PROCESS 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-05-21 15:48:26 +02:00
										 |  |  | 		// CREATE | 
					
						
							|  |  |  | 		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 | 
					
						
							|  |  |  | 			incomingStatus, ok := federatorMsg.GTSModel.(*gtsmodel.Status) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return errors.New("note was not parseable as *gtsmodel.Status") | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-01 10:08:21 +01:00
										 |  |  | 			status, err := p.federator.EnrichRemoteStatus(ctx, federatorMsg.ReceivingAccount.Username, incomingStatus, false, false) | 
					
						
							| 
									
										
										
										
											2021-08-10 13:32:39 +02:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return err | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 			if err := p.timelineStatus(ctx, status); err != nil { | 
					
						
							| 
									
										
										
										
											2021-06-13 18:42:28 +02:00
										 |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 			if err := p.notifyStatus(ctx, status); err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		case ap.ObjectProfile: | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 			// CREATE AN ACCOUNT | 
					
						
							| 
									
										
										
										
											2021-08-10 13:32:39 +02:00
										 |  |  | 			// nothing to do here | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		case ap.ActivityLike: | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 			// CREATE A FAVE | 
					
						
							|  |  |  | 			incomingFave, ok := federatorMsg.GTSModel.(*gtsmodel.StatusFave) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return errors.New("like was not parseable as *gtsmodel.StatusFave") | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 			if err := p.notifyFave(ctx, incomingFave, federatorMsg.ReceivingAccount); err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		case ap.ActivityFollow: | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 			// CREATE A FOLLOW REQUEST | 
					
						
							|  |  |  | 			incomingFollowRequest, ok := federatorMsg.GTSModel.(*gtsmodel.FollowRequest) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							| 
									
										
										
										
											2021-05-28 19:57:04 +02:00
										 |  |  | 				return errors.New("incomingFollowRequest was not parseable as *gtsmodel.FollowRequest") | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 			if err := p.notifyFollowRequest(ctx, incomingFollowRequest, federatorMsg.ReceivingAccount); err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		case ap.ActivityAnnounce: | 
					
						
							| 
									
										
										
										
											2021-05-28 19:57:04 +02:00
										 |  |  | 			// CREATE AN ANNOUNCE | 
					
						
							|  |  |  | 			incomingAnnounce, ok := federatorMsg.GTSModel.(*gtsmodel.Status) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return errors.New("announce was not parseable as *gtsmodel.Status") | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 			if err := p.federator.DereferenceAnnounce(ctx, incomingAnnounce, federatorMsg.ReceivingAccount.Username); err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-28 19:57:04 +02:00
										 |  |  | 				return fmt.Errorf("error dereferencing announce from federator: %s", err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 18:42:28 +02:00
										 |  |  | 			incomingAnnounceID, err := id.NewULIDFromTime(incomingAnnounce.CreatedAt) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			incomingAnnounce.ID = incomingAnnounceID | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 			if err := p.db.PutStatus(ctx, incomingAnnounce); err != nil { | 
					
						
							| 
									
										
										
										
											2021-09-04 13:29:56 +02:00
										 |  |  | 				return fmt.Errorf("error adding dereferenced announce to the db: %s", err) | 
					
						
							| 
									
										
										
										
											2021-05-28 19:57:04 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 			if err := p.timelineStatus(ctx, incomingAnnounce); err != nil { | 
					
						
							| 
									
										
										
										
											2021-06-17 18:02:33 +02:00
										 |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 			if err := p.notifyAnnounce(ctx, incomingAnnounce); err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-28 19:57:04 +02:00
										 |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		case ap.ActivityBlock: | 
					
						
							| 
									
										
										
										
											2021-07-11 16:22:21 +02:00
										 |  |  | 			// CREATE A BLOCK | 
					
						
							|  |  |  | 			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 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 			if err := p.timelineManager.WipeStatusesFromAccountID(ctx, block.AccountID, block.TargetAccountID); err != nil { | 
					
						
							| 
									
										
										
										
											2021-07-11 16:22:21 +02:00
										 |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 			if err := p.timelineManager.WipeStatusesFromAccountID(ctx, block.TargetAccountID, block.AccountID); err != nil { | 
					
						
							| 
									
										
										
										
											2021-07-11 16:22:21 +02:00
										 |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			// TODO: same with notifications | 
					
						
							|  |  |  | 			// TODO: same with bookmarks | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 	case ap.ActivityUpdate: | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 		// UPDATE | 
					
						
							|  |  |  | 		switch federatorMsg.APObjectType { | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		case ap.ObjectProfile: | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 			// UPDATE AN ACCOUNT | 
					
						
							|  |  |  | 			incomingAccount, ok := federatorMsg.GTSModel.(*gtsmodel.Account) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return errors.New("profile was not parseable as *gtsmodel.Account") | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-10 13:32:39 +02:00
										 |  |  | 			incomingAccountURI, err := url.Parse(incomingAccount.URI) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return err | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-08-10 13:32:39 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 			if _, _, err := p.federator.GetRemoteAccount(ctx, federatorMsg.ReceivingAccount.Username, incomingAccountURI, true); err != nil { | 
					
						
							| 
									
										
										
										
											2021-08-10 13:32:39 +02:00
										 |  |  | 				return fmt.Errorf("error dereferencing account from federator: %s", err) | 
					
						
							| 
									
										
										
										
											2021-05-21 15:48:26 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 	case ap.ActivityDelete: | 
					
						
							| 
									
										
										
										
											2021-05-23 18:07:04 +02:00
										 |  |  | 		// DELETE | 
					
						
							|  |  |  | 		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 | 
					
						
							|  |  |  | 			// TODO: handle side effects of status deletion here: | 
					
						
							|  |  |  | 			// 1. delete all media associated with status | 
					
						
							|  |  |  | 			// 2. delete boosts of status | 
					
						
							|  |  |  | 			// 3. etc etc etc | 
					
						
							| 
									
										
										
										
											2021-06-13 18:42:28 +02:00
										 |  |  | 			statusToDelete, ok := federatorMsg.GTSModel.(*gtsmodel.Status) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return errors.New("note was not parseable as *gtsmodel.Status") | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// delete all attachments for this status | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 			for _, a := range statusToDelete.AttachmentIDs { | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 				if err := p.mediaProcessor.Delete(ctx, a); err != nil { | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 					return err | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// delete all mentions for this status | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 			for _, m := range statusToDelete.MentionIDs { | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 				if err := p.db.DeleteByID(ctx, m, >smodel.Mention{}); err != nil { | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 					return err | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// delete all notifications for this status | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 			if err := p.db.DeleteWhere(ctx, []db.Where{{Key: "status_id", Value: statusToDelete.ID}}, &[]*gtsmodel.Notification{}); err != nil { | 
					
						
							| 
									
										
										
										
											2021-07-05 13:23:03 +02:00
										 |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// remove this status from any and all timelines | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 			return p.deleteStatusFromTimelines(ctx, statusToDelete) | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		case ap.ObjectProfile: | 
					
						
							| 
									
										
										
										
											2021-05-23 18:07:04 +02:00
										 |  |  | 			// DELETE A PROFILE/ACCOUNT | 
					
						
							|  |  |  | 			// TODO: handle side effects of account deletion here: delete all objects, statuses, media etc associated with account | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 	case ap.ActivityAccept: | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 		// ACCEPT | 
					
						
							|  |  |  | 		switch federatorMsg.APObjectType { | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		case ap.ActivityFollow: | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 			// ACCEPT A FOLLOW | 
					
						
							|  |  |  | 			follow, ok := federatorMsg.GTSModel.(*gtsmodel.Follow) | 
					
						
							|  |  |  | 			if !ok { | 
					
						
							|  |  |  | 				return errors.New("follow was not parseable as *gtsmodel.Follow") | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 			if err := p.notifyFollow(ctx, follow, federatorMsg.ReceivingAccount); err != nil { | 
					
						
							| 
									
										
										
										
											2021-05-27 16:06:24 +02:00
										 |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-05-17 19:06:58 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } |