2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   GoToSocial 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 18:42:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   Copyright  ( C )  2021 - 2022  GoToSocial  Authors  admin @ gotosocial . org 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   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/>. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* /  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  dereferencing  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"encoding/json" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-16 18:52:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"io" 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"net/url" 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-25 15:34:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"sync" 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 18:12:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-23 21:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/miekg/dns" 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-13 17:29:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/activity/streams" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/activity/streams/vocab" 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/ap" 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/config" 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/db" 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/id" 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 09:47:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/log" 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-09 18:41:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/media" 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/transport" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  webfingerInterval  =  - 48  *  time . Hour  // 2 days in the past  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-25 15:34:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  instanceAccount ( account  * gtsmodel . Account )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  strings . EqualFold ( account . Username ,  account . Domain )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account . FollowersURI  ==  ""  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										account . FollowingURI  ==  ""  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										( account . Username  ==  "internal.fetch"  &&  strings . Contains ( account . Note ,  "internal service actor" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// GetRemoteAccountParams wraps parameters for a remote account lookup.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  GetRemoteAccountParams  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The username of the user doing the lookup request (optional). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If not set, then the GtS instance account will be used to do the lookup. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RequestingUsername  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The ActivityPub URI of the remote account (optional). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If not set (nil), the ActivityPub URI of the remote account will be discovered 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// via webfinger, so you must set RemoteAccountUsername and RemoteAccountHost 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// if this parameter is not set. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RemoteAccountID  * url . URL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The username of the remote account (optional). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If RemoteAccountID is not set, then this value must be set. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RemoteAccountUsername  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The host of the remote account (optional). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If RemoteAccountID is not set, then this value must be set. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RemoteAccountHost  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Whether to do a blocking call to the remote instance. If true, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// then the account's media and other fields will be fully dereferenced before it is returned. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If false, then the account's media and other fields will be dereferenced in the background, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// so only a minimal account representation will be returned by GetRemoteAccount. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Blocking  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Whether to skip making calls to remote instances. This is useful when you want to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// quickly fetch a remote account from the database or fail, and don't want to cause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// http requests to go flying around. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SkipResolve  bool 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// PartialAccount can be used if the GetRemoteAccount call results from a federated/ap 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// account update. In this case, we will already have a partial representation of the account, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// derived from converting the AP representation to a gtsmodel representation. If this field 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// is provided, then GetRemoteAccount will use this as a basis for building the full account. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									PartialAccount  * gtsmodel . Account 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// GetRemoteAccount completely dereferences a remote account, converts it to a GtS model account,  
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// puts or updates it in the database (if necessary), and returns it to a caller.  
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// If a local account is passed into this function for whatever reason (hey, it happens!), then it  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// will be returned from the database without making any remote calls.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( d  * deref )  GetRemoteAccount ( ctx  context . Context ,  params  GetRemoteAccountParams )  ( foundAccount  * gtsmodel . Account ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/ * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										In  this  function  we  want  to  retrieve  a  gtsmodel  representation  of  a  remote  account ,  with  its  proper 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										accountDomain  set ,  while  making  as  few  calls  to  remote  instances  as  possible  to  save  time  and  bandwidth . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										There  are  a  few  different  paths  through  this  function ,  and  the  path  taken  depends  on  how  much 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										initial  information  we  are  provided  with  via  parameters ,  how  much  information  we  already  have  stored , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										and  what  we ' re  allowed  to  do  according  to  the  parameters  we ' ve  been  passed . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Scenario  1 :  We ' re  not  allowed  to  resolve  remotely ,  but  we ' ve  got  either  the  account  URI  or  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										            account  username  +  host ,  so  we  can  check  in  our  database  and  return  if  possible . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Scenario  2 :  We  are  allowed  to  resolve  remotely ,  and  we  have  an  account  URI  but  no  username  or  host . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										            In  this  case ,  we  can  use  the  URI  to  resolve  the  remote  account  and  find  the  username , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													and  then  we  can  webfinger  the  account  to  discover  the  accountDomain  if  necessary . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Scenario  3 :  We  are  allowed  to  resolve  remotely ,  and  we  have  the  username  and  host  but  no  URI . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										            In  this  case ,  we  can  webfinger  the  account  to  discover  the  URI ,  and  then  dereference 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													from  that . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									skipResolve  :=  params . SkipResolve 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// this first step checks if we have the 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// account in the database somewhere already, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// or if we've been provided it as a partial 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  params . PartialAccount  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										foundAccount  =  params . PartialAccount 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  foundAccount . Domain  ==  ""  ||  foundAccount . Domain  ==  config . GetHost ( )  ||  foundAccount . Domain  ==  config . GetAccountDomain ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// this is actually a local account, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// make sure we don't try to resolve 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											skipResolve  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  params . RemoteAccountID  !=  nil : 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										uri  :=  params . RemoteAccountID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										host  :=  uri . Host 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  host  ==  config . GetHost ( )  ||  host  ==  config . GetAccountDomain ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// this is actually a local account, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// make sure we don't try to resolve 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											skipResolve  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  a ,  dbErr  :=  d . db . GetAccountByURI ( ctx ,  uri . String ( ) ) ;  dbErr  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											foundAccount  =  a 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  dbErr  !=  db . ErrNoEntries  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  fmt . Errorf ( "GetRemoteAccount: database error looking for account with uri %s: %s" ,  uri ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  params . RemoteAccountUsername  !=  ""  &&  ( params . RemoteAccountHost  ==  ""  ||  params . RemoteAccountHost  ==  config . GetHost ( )  ||  params . RemoteAccountHost  ==  config . GetAccountDomain ( ) ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// either no domain is provided or this seems 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// to be a local account, so don't resolve 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										skipResolve  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-02 10:56:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  a ,  dbErr  :=  d . db . GetAccountByUsernameDomain ( ctx ,  params . RemoteAccountUsername ,  "" ) ;  dbErr  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											foundAccount  =  a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  dbErr  !=  db . ErrNoEntries  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  fmt . Errorf ( "GetRemoteAccount: database error looking for local account with username %s: %s" ,  params . RemoteAccountUsername ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  params . RemoteAccountUsername  !=  ""  &&  params . RemoteAccountHost  !=  "" : 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  a ,  dbErr  :=  d . db . GetAccountByUsernameDomain ( ctx ,  params . RemoteAccountUsername ,  params . RemoteAccountHost ) ;  dbErr  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											foundAccount  =  a 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  dbErr  !=  db . ErrNoEntries  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  fmt . Errorf ( "GetRemoteAccount: database error looking for account with username %s and domain %s: %s" ,  params . RemoteAccountUsername ,  params . RemoteAccountHost ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  errors . New ( "GetRemoteAccount: no identifying parameters were set so we cannot get account" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  skipResolve  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// if we can't resolve, return already 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// since there's nothing more we can do 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  foundAccount  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  errors . New ( "GetRemoteAccount: couldn't retrieve account locally and won't try to resolve it" ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  accountable  ap . Accountable 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  params . RemoteAccountUsername  ==  ""  ||  params . RemoteAccountHost  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// try to populate the missing params 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// the first one is easy ... 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										params . RemoteAccountHost  =  params . RemoteAccountID . Host 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// ... but we still need the username so we can do a finger for the accountDomain 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// check if we got the account earlier 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  foundAccount  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											params . RemoteAccountUsername  =  foundAccount . Username 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// if we didn't already have it, we have dereference it from remote and just... 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accountable ,  err  =  d . dereferenceAccountable ( ctx ,  params . RequestingUsername ,  params . RemoteAccountID ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												err  =  fmt . Errorf ( "GetRemoteAccount: error dereferencing accountable: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 18:12:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// ... take the username (for now) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											params . RemoteAccountUsername ,  err  =  ap . ExtractPreferredUsername ( accountable ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  fmt . Errorf ( "GetRemoteAccount: error extracting accountable username: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 18:12:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// if we reach this point, params.RemoteAccountHost and params.RemoteAccountUsername must be set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// params.RemoteAccountID may or may not be set, but we have enough information to fetch it if we need it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// we finger to fetch the account domain but just in case we're not fingering, make a best guess 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// already about what the account domain might be; this var will be overwritten later if necessary 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  accountDomain  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  foundAccount  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										accountDomain  =  foundAccount . Domain 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  params . RemoteAccountID  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										accountDomain  =  params . RemoteAccountID . Host 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										accountDomain  =  params . RemoteAccountHost 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-23 21:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// to save on remote calls, only webfinger if: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// - we don't know the remote account ActivityPub ID yet OR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// - we haven't found the account yet in some other way OR 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// - we were passed a partial account in params OR 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-23 21:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// - we haven't webfingered the account for two days AND the account isn't an instance account 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  fingered  time . Time 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  params . RemoteAccountID  ==  nil  ||  foundAccount  ==  nil  ||  params . PartialAccount  !=  nil  ||  ( foundAccount . LastWebfingeredAt . Before ( time . Now ( ) . Add ( webfingerInterval ) )  &&  ! instanceAccount ( foundAccount ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										accountDomain ,  params . RemoteAccountID ,  err  =  d . fingerRemoteAccount ( ctx ,  params . RequestingUsername ,  params . RemoteAccountUsername ,  params . RemoteAccountHost ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  fmt . Errorf ( "GetRemoteAccount: error while fingering: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fingered  =  time . Now ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! fingered . IsZero ( )  &&  foundAccount  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// if we just fingered and now have a discovered account domain but still no account, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// we should do a final lookup in the database with the discovered username + accountDomain 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// to make absolutely sure we don't already have this account 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										a  :=  & gtsmodel . Account { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										where  :=  [ ] db . Where { { Key :  "username" ,  Value :  params . RemoteAccountUsername } ,  { Key :  "domain" ,  Value :  accountDomain } } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  dbErr  :=  d . db . GetWhere ( ctx ,  where ,  a ) ;  dbErr  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											foundAccount  =  a 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  dbErr  !=  db . ErrNoEntries  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  fmt . Errorf ( "GetRemoteAccount: database error looking for account with username %s and host %s: %s" ,  params . RemoteAccountUsername ,  params . RemoteAccountHost ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// we may also have some extra information already, like the account we had in the db, or the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// accountable representation that we dereferenced from remote 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  foundAccount  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// we still don't have the account, so deference it if we didn't earlier 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  accountable  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accountable ,  err  =  d . dereferenceAccountable ( ctx ,  params . RequestingUsername ,  params . RemoteAccountID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  fmt . Errorf ( "GetRemoteAccount: error dereferencing accountable: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// then convert 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										foundAccount ,  err  =  d . typeConverter . ASRepresentationToAccount ( ctx ,  accountable ,  accountDomain ,  false ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  fmt . Errorf ( "GetRemoteAccount: error converting accountable to account: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// this is a new account so we need to generate a new ID for it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  ulid  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ulid ,  err  =  id . NewRandomULID ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  fmt . Errorf ( "GetRemoteAccount: error generating new id for account: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										foundAccount . ID  =  ulid 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  d . populateAccountFields ( ctx ,  foundAccount ,  params . RequestingUsername ,  params . Blocking ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  fmt . Errorf ( "GetRemoteAccount: error populating further account fields: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										foundAccount . LastWebfingeredAt  =  fingered 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										foundAccount . UpdatedAt  =  time . Now ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										foundAccount ,  err  =  d . db . PutAccount ( ctx ,  foundAccount ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  fmt . Errorf ( "GetRemoteAccount: error putting new account: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  // the new account 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// we had the account already, but now we know the account domain, so update it if it's different 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  accountDomainChanged  bool 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! strings . EqualFold ( foundAccount . Domain ,  accountDomain )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										accountDomainChanged  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										foundAccount . Domain  =  accountDomain 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-23 21:27:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// if SharedInboxURI is nil, that means we don't know yet if this account has 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// a shared inbox available for it, so we need to check this here 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  sharedInboxChanged  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  foundAccount . SharedInboxURI  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// we need the accountable for this, so get it if we don't have it yet 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  accountable  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accountable ,  err  =  d . dereferenceAccountable ( ctx ,  params . RequestingUsername ,  params . RemoteAccountID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  fmt . Errorf ( "GetRemoteAccount: error dereferencing accountable: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// This can be: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// - an empty string (we know it doesn't have a shared inbox) OR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// - a string URL (we know it does a shared inbox). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Set it either way! 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  sharedInbox  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  sharedInboxURI  :=  ap . ExtractSharedInbox ( accountable ) ;  sharedInboxURI  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// only trust shared inbox if it has at least two domains, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// from the right, in common with the domain of the account 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  dns . CompareDomainName ( foundAccount . Domain ,  sharedInboxURI . Host )  >=  2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sharedInbox  =  sharedInboxURI . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sharedInboxChanged  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										foundAccount . SharedInboxURI  =  & sharedInbox 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// make sure the account fields are populated before returning: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// the caller might want to block until everything is loaded 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  fieldsChanged  bool 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									fieldsChanged ,  err  =  d . populateAccountFields ( ctx ,  foundAccount ,  params . RequestingUsername ,  params . Blocking ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "GetRemoteAccount: error populating remoteAccount fields: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  fingeredChanged  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! fingered . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fingeredChanged  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										foundAccount . LastWebfingeredAt  =  fingered 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  accountDomainChanged  ||  sharedInboxChanged  ||  fieldsChanged  ||  fingeredChanged  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-20 22:47:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										foundAccount ,  err  =  d . db . UpdateAccount ( ctx ,  foundAccount ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  fmt . Errorf ( "GetRemoteAccount: error updating remoteAccount: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  // the account we already had + possibly updated 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// dereferenceAccountable calls remoteAccountID with a GET request, and tries to parse whatever  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// it finds as something that an account model can be constructed out of.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Will work for Person, Application, or Service models.  
						 
					
						
							
								
									
										
										
										
											2021-08-25 15:34:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( d  * deref )  dereferenceAccountable ( ctx  context . Context ,  username  string ,  remoteAccountID  * url . URL )  ( ap . Accountable ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									d . startHandshake ( username ,  remoteAccountID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  d . stopHandshake ( username ,  remoteAccountID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-25 15:34:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  blocked ,  err  :=  d . db . IsDomainBlocked ( ctx ,  remoteAccountID . Host ) ;  blocked  ||  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "DereferenceAccountable: domain %s is blocked" ,  remoteAccountID . Host ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-25 15:34:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									transport ,  err  :=  d . transportController . NewTransportForUsername ( ctx ,  username ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "DereferenceAccountable: transport err: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-04 15:24:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									b ,  err  :=  transport . Dereference ( ctx ,  remoteAccountID ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "DereferenceAccountable: error deferencing %s: %s" ,  remoteAccountID . String ( ) ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m  :=  make ( map [ string ] interface { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  json . Unmarshal ( b ,  & m ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "DereferenceAccountable: error unmarshalling bytes into json: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-04 15:24:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									t ,  err  :=  streams . ToType ( ctx ,  m ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "DereferenceAccountable: error resolving json into ap vocab type: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  t . GetTypeName ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 10:30:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ap . ActorApplication : 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										p ,  ok  :=  t . ( vocab . ActivityStreamsApplication ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  errors . New ( "DereferenceAccountable: error resolving type as activitystreams application" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  p ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-30 12:27:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ap . ActorGroup : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p ,  ok  :=  t . ( vocab . ActivityStreamsGroup ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  errors . New ( "DereferenceAccountable: error resolving type as activitystreams group" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  p ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ap . ActorOrganization : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p ,  ok  :=  t . ( vocab . ActivityStreamsOrganization ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  errors . New ( "DereferenceAccountable: error resolving type as activitystreams organization" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  p ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ap . ActorPerson : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p ,  ok  :=  t . ( vocab . ActivityStreamsPerson ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  errors . New ( "DereferenceAccountable: error resolving type as activitystreams person" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  p ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-03 10:30:40 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ap . ActorService : 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										p ,  ok  :=  t . ( vocab . ActivityStreamsService ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  errors . New ( "DereferenceAccountable: error resolving type as activitystreams service" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  p ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil ,  fmt . Errorf ( "DereferenceAccountable: type name %s not supported" ,  t . GetTypeName ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// populateAccountFields populates any fields on the given account that weren't populated by the initial  
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// dereferencing. This includes things like header and avatar etc.  
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( d  * deref )  populateAccountFields ( ctx  context . Context ,  account  * gtsmodel . Account ,  requestingUsername  string ,  blocking  bool )  ( bool ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// if we're dealing with an instance account, just bail, we don't need to do anything 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  instanceAccount ( account )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  false ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									accountURI ,  err  :=  url . Parse ( account . URI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  false ,  fmt . Errorf ( "populateAccountFields: couldn't parse account URI %s: %s" ,  account . URI ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-25 15:34:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  blocked ,  err  :=  d . db . IsDomainBlocked ( ctx ,  accountURI . Host ) ;  blocked  ||  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  false ,  fmt . Errorf ( "populateAccountFields: domain %s is blocked" ,  accountURI . Host ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  changed  bool 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// fetch the header and avatar 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  mediaChanged ,  err  :=  d . fetchRemoteAccountMedia ( ctx ,  account ,  requestingUsername ,  blocking ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  false ,  fmt . Errorf ( "populateAccountFields: error fetching header/avi for account: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  mediaChanged  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										changed  =  mediaChanged 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// fetch any emojis used in note, fields, display name, etc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  emojisChanged ,  err  :=  d . fetchRemoteAccountEmojis ( ctx ,  account ,  requestingUsername ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ,  fmt . Errorf ( "populateAccountFields: error fetching emojis for account: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  emojisChanged  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										changed  =  emojisChanged 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  changed ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// fetchRemoteAccountMedia fetches and stores the header and avatar for a remote account,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// using a transport on behalf of requestingUsername.  
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The returned boolean indicates whether anything changed -- in other words, whether the  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// account should be updated in the database.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// targetAccount's AvatarMediaAttachmentID and HeaderMediaAttachmentID will be updated as necessary.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// If refresh is true, then the media will be fetched again even if it's already been fetched before.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// If blocking is true, then the calls to the media manager made by this function will be blocking:  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// in other words, the function won't return until the header and the avatar have been fully processed.  
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( d  * deref )  fetchRemoteAccountMedia ( ctx  context . Context ,  targetAccount  * gtsmodel . Account ,  requestingUsername  string ,  blocking  bool )  ( bool ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										changed  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t        transport . Transport 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  targetAccount . AvatarRemoteURL  !=  ""  &&  ( targetAccount . AvatarMediaAttachmentID  ==  "" )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  processingMedia  * media . ProcessingMedia 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-08 17:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 13:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										d . dereferencingAvatarsLock . Lock ( )  // LOCK HERE 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// first check if we're already processing this media 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  alreadyProcessing ,  ok  :=  d . dereferencingAvatars [ targetAccount . ID ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// we're already on it, no worries 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											processingMedia  =  alreadyProcessing 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-08 17:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  processingMedia  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// we're not already processing it so start now 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											avatarIRI ,  err  :=  url . Parse ( targetAccount . AvatarRemoteURL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 13:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												d . dereferencingAvatarsLock . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  changed ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  t  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t ,  err  =  d . transportController . NewTransportForUsername ( ctx ,  requestingUsername ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  false ,  fmt . Errorf ( "fetchRemoteAccountMedia: error getting transport for user: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											data  :=  func ( innerCtx  context . Context )  ( io . Reader ,  int ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  t . DereferenceMedia ( innerCtx ,  avatarIRI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											avatar  :=  true 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 13:50:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											newProcessing ,  err  :=  d . mediaManager . ProcessMedia ( ctx ,  data ,  nil ,  targetAccount . ID ,  & media . AdditionalMediaInfo { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												RemoteURL :  & targetAccount . AvatarRemoteURL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Avatar :     & avatar , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 13:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												d . dereferencingAvatarsLock . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  changed ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// store it in our map to indicate it's in process 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											d . dereferencingAvatars [ targetAccount . ID ]  =  newProcessing 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											processingMedia  =  newProcessing 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-08 17:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 13:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										d . dereferencingAvatarsLock . Unlock ( )  // UNLOCK HERE 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-08 17:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// block until loaded if required... 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  blocking  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  lockAndLoad ( ctx ,  d . dereferencingAvatarsLock ,  processingMedia ,  d . dereferencingAvatars ,  targetAccount . ID ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  changed ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// ...otherwise do it async 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											go  func ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 18:12:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dlCtx ,  done  :=  context . WithDeadline ( context . Background ( ) ,  time . Now ( ) . Add ( 1 * time . Minute ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  :=  lockAndLoad ( dlCtx ,  d . dereferencingAvatarsLock ,  processingMedia ,  d . dereferencingAvatars ,  targetAccount . ID ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 09:47:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													log . Errorf ( "fetchRemoteAccountMedia: error during async lock and load of avatar: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 18:12:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												done ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 18:12:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										targetAccount . AvatarMediaAttachmentID  =  processingMedia . AttachmentID ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										changed  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-11 11:01:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  targetAccount . HeaderRemoteURL  !=  ""  &&  ( targetAccount . HeaderMediaAttachmentID  ==  "" )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  processingMedia  * media . ProcessingMedia 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-08 17:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 13:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										d . dereferencingHeadersLock . Lock ( )  // LOCK HERE 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// first check if we're already processing this media 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  alreadyProcessing ,  ok  :=  d . dereferencingHeaders [ targetAccount . ID ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// we're already on it, no worries 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											processingMedia  =  alreadyProcessing 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-08 17:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  processingMedia  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// we're not already processing it so start now 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											headerIRI ,  err  :=  url . Parse ( targetAccount . HeaderRemoteURL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 13:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												d . dereferencingAvatarsLock . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  changed ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  t  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t ,  err  =  d . transportController . NewTransportForUsername ( ctx ,  requestingUsername ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  false ,  fmt . Errorf ( "fetchRemoteAccountMedia: error getting transport for user: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											data  :=  func ( innerCtx  context . Context )  ( io . Reader ,  int ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  t . DereferenceMedia ( innerCtx ,  headerIRI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											header  :=  true 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 13:50:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											newProcessing ,  err  :=  d . mediaManager . ProcessMedia ( ctx ,  data ,  nil ,  targetAccount . ID ,  & media . AdditionalMediaInfo { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												RemoteURL :  & targetAccount . HeaderRemoteURL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Header :     & header , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 13:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												d . dereferencingAvatarsLock . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  changed ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// store it in our map to indicate it's in process 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											d . dereferencingHeaders [ targetAccount . ID ]  =  newProcessing 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											processingMedia  =  newProcessing 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-08 17:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 13:17:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										d . dereferencingHeadersLock . Unlock ( )  // UNLOCK HERE 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-08 17:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// block until loaded if required... 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  blocking  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  lockAndLoad ( ctx ,  d . dereferencingHeadersLock ,  processingMedia ,  d . dereferencingHeaders ,  targetAccount . ID ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  changed ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// ...otherwise do it async 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											go  func ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 18:12:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dlCtx ,  done  :=  context . WithDeadline ( context . Background ( ) ,  time . Now ( ) . Add ( 1 * time . Minute ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  :=  lockAndLoad ( dlCtx ,  d . dereferencingHeadersLock ,  processingMedia ,  d . dereferencingHeaders ,  targetAccount . ID ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 09:47:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													log . Errorf ( "fetchRemoteAccountMedia: error during async lock and load of header: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 18:12:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												done ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 18:12:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										targetAccount . HeaderMediaAttachmentID  =  processingMedia . AttachmentID ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										changed  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 11:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  changed ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:32:39 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-26 11:56:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( d  * deref )  fetchRemoteAccountEmojis ( ctx  context . Context ,  targetAccount  * gtsmodel . Account ,  requestingUsername  string )  ( bool ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									maybeEmojis  :=  targetAccount . Emojis 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									maybeEmojiIDs  :=  targetAccount . EmojiIDs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// It's possible that the account had emoji IDs set on it, but not Emojis 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// themselves, depending on how it was fetched before being passed to us. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If we only have IDs, fetch the emojis from the db. We know they're in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// there or else they wouldn't have IDs. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( maybeEmojiIDs )  >  len ( maybeEmojis )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										maybeEmojis  =  [ ] * gtsmodel . Emoji { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  emojiID  :=  range  maybeEmojiIDs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											maybeEmoji ,  err  :=  d . db . GetEmojiByID ( ctx ,  emojiID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  false ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											maybeEmojis  =  append ( maybeEmojis ,  maybeEmoji ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// For all the maybe emojis we have, we either fetch them from the database 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// (if we haven't already), or dereference them from the remote instance. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									gotEmojis ,  err  :=  d . populateEmojis ( ctx ,  maybeEmojis ,  requestingUsername ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Extract the ID of each fetched or dereferenced emoji, so we can attach 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// this to the account if necessary. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									gotEmojiIDs  :=  make ( [ ] string ,  0 ,  len ( gotEmojis ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  e  :=  range  gotEmojis  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										gotEmojiIDs  =  append ( gotEmojiIDs ,  e . ID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										changed   =  false  // have the emojis for this account changed? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										maybeLen  =  len ( maybeEmojis ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										gotLen    =  len ( gotEmojis ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// if the length of everything is zero, this is simple: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// nothing has changed and there's nothing to do 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  maybeLen  ==  0  &&  gotLen  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  changed ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// if the *amount* of emojis on the account has changed, then the got emojis 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// are definitely different from the previous ones (if there were any) -- 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// the account has either more or fewer emojis set on it now, so take the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// discovered emojis as the new correct ones. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  maybeLen  !=  gotLen  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										changed  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										targetAccount . Emojis  =  gotEmojis 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										targetAccount . EmojiIDs  =  gotEmojiIDs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  changed ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// if the lengths are the same but not all of the slices are 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// zero, something *might* have changed, so we have to check 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 1. did we have emojis before that we don't have now? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  maybeEmoji  :=  range  maybeEmojis  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  stillPresent  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  gotEmoji  :=  range  gotEmojis  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  maybeEmoji . URI  ==  gotEmoji . URI  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// the emoji we maybe had is still present now, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// so we can stop checking gotEmojis 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												stillPresent  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! stillPresent  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// at least one maybeEmoji is no longer present in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// the got emojis, so we can stop checking now 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											changed  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											targetAccount . Emojis  =  gotEmojis 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											targetAccount . EmojiIDs  =  gotEmojiIDs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  changed ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 2. do we have emojis now that we didn't have before? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  gotEmoji  :=  range  gotEmojis  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  wasPresent  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  maybeEmoji  :=  range  maybeEmojis  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// check emoji IDs here as well, because unreferenced 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// maybe emojis we didn't already have would not have 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// had IDs set on them yet 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  gotEmoji . URI  ==  maybeEmoji . URI  &&  gotEmoji . ID  ==  maybeEmoji . ID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// this got emoji was present already in the maybeEmoji, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// so we can stop checking through maybeEmojis 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												wasPresent  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! wasPresent  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// at least one gotEmojis was not present in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// the maybeEmojis, so we can stop checking now 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											changed  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											targetAccount . Emojis  =  gotEmojis 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											targetAccount . EmojiIDs  =  gotEmojiIDs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  changed ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  changed ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-24 13:12:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  lockAndLoad ( ctx  context . Context ,  lock  * sync . Mutex ,  processing  * media . ProcessingMedia ,  processingMap  map [ string ] * media . ProcessingMedia ,  accountID  string )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// whatever happens, remove the in-process media from the map 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lock . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delete ( processingMap ,  accountID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lock . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// try and load it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_ ,  err  :=  processing . LoadAttachment ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}