2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   GoToSocial 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   Copyright  ( C )  2021  GoToSocial  Authors  admin @ gotosocial . org 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   This  program  is  free  software :  you  can  redistribute  it  and / or  modify 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   it  under  the  terms  of  the  GNU  Affero  General  Public  License  as  published  by 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   the  Free  Software  Foundation ,  either  version  3  of  the  License ,  or 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   ( at  your  option )  any  later  version . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   This  program  is  distributed  in  the  hope  that  it  will  be  useful , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   but  WITHOUT  ANY  WARRANTY ;  without  even  the  implied  warranty  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   MERCHANTABILITY  or  FITNESS  FOR  A  PARTICULAR  PURPOSE .   See  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   GNU  Affero  General  Public  License  for  more  details . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   You  should  have  received  a  copy  of  the  GNU  Affero  General  Public  License 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   along  with  this  program .   If  not ,  see  < http : //www.gnu.org/licenses/>. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* /  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								package  pg  
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"crypto/rand" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"crypto/rsa" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"net" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"net/mail" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 14:38:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"regexp" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 18:12:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 22:52:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-05 18:31:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/go-pg/pg/extra/pgdebug" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/go-pg/pg/v10" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/go-pg/pg/v10/orm" 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/google/uuid" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 22:52:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/sirupsen/logrus" 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/config" 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/db" 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/superseriousbusiness/gotosocial/internal/util" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"golang.org/x/crypto/bcrypt" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 22:26:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// postgresService satisfies the DB interface  
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								type  postgresService  struct  {  
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									config  * config . Config 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									conn    * pg . DB 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									log     * logrus . Logger 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cancel  context . CancelFunc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// federationDB pub.Database 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// NewPostgresService returns a postgresService derived from the provided config, which implements the go-fed DB interface.  
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Under the hood, it uses https://github.com/go-pg/pg to create and maintain a database connection.  
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  NewPostgresService ( ctx  context . Context ,  c  * config . Config ,  log  * logrus . Logger )  ( db . DB ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2021-03-04 14:38:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									opts ,  err  :=  derivePGOptions ( c ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "could not create postgres service: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-05 18:31:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									log . Debugf ( "using pg options: %+v" ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 22:52:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// create a connection 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pgCtx ,  cancel  :=  context . WithCancel ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									conn  :=  pg . Connect ( opts ) . WithContext ( pgCtx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-05 18:31:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// this will break the logfmt format we normally log in, 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since we can't choose where pg outputs to and it defaults to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// stdout. So use this option with care! 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  log . GetLevel ( )  >=  logrus . TraceLevel  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-05 18:31:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										conn . AddQueryHook ( pgdebug . DebugHook { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Print all queries. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Verbose :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// actually *begin* the connection so that we can tell if the db is there and listening 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-05 18:31:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  conn . Ping ( ctx ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 22:52:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cancel ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "db connection error: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-05 18:31:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// print out discovered postgres version 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  version  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  _ ,  err  =  conn . QueryOneContext ( ctx ,  pg . Scan ( & version ) ,  "SELECT version()" ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 22:52:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cancel ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "db connection error: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-05 18:31:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									log . Infof ( "connected to postgres version: %s" ,  version ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 22:52:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ps  :=  & postgresService { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										config :  c , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										conn :    conn , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										log :     log , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cancel :  cancel , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// we can confidently return this useable postgres service now 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ps ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 22:26:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDY  STUFF 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* /  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// derivePGOptions takes an application config and returns either a ready-to-use *pg.Options  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// with sensible defaults, or an error if it's not satisfied by the provided config.  
						 
					
						
							
								
									
										
										
										
											2021-03-04 14:38:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  derivePGOptions ( c  * config . Config )  ( * pg . Options ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  strings . ToUpper ( c . DBConfig . Type )  !=  db . DBTypePostgres  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "expected db type of %s but got %s" ,  db . DBTypePostgres ,  c . DBConfig . Type ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 12:07:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// validate port 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 14:38:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  c . DBConfig . Port  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 12:07:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  errors . New ( "no port set" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// validate address 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 14:38:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  c . DBConfig . Address  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 12:07:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  errors . New ( "no address set" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 22:52:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 14:38:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ipv4Regex  :=  regexp . MustCompile ( ` ^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.) { 3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ ` ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hostnameRegex  :=  regexp . MustCompile ( ` ^(?:[a-z0-9]+(?:-[a-z0-9]+)*\.)+[a-z] { 2,}$ ` ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! hostnameRegex . MatchString ( c . DBConfig . Address )  &&  ! ipv4Regex . MatchString ( c . DBConfig . Address )  &&  c . DBConfig . Address  !=  "localhost"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "address %s was neither an ipv4 address nor a valid hostname" ,  c . DBConfig . Address ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 22:52:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// validate username 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 14:38:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  c . DBConfig . User  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 12:07:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  errors . New ( "no user set" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 22:52:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// validate that there's a password 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 14:38:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  c . DBConfig . Password  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 22:52:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  errors . New ( "no password set" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// validate database 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 14:38:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  c . DBConfig . Database  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 12:07:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  errors . New ( "no database set" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 22:52:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// We can rely on the pg library we're using to set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// sensible defaults for everything we don't set here. 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									options  :=  & pg . Options { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 14:38:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Addr :             fmt . Sprintf ( "%s:%d" ,  c . DBConfig . Address ,  c . DBConfig . Port ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										User :             c . DBConfig . User , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Password :         c . DBConfig . Password , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Database :         c . DBConfig . Database , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ApplicationName :  c . ApplicationName , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  options ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BASIC  DB  FUNCTIONALITY 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* /  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  CreateTable ( i  interface { } )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ps . conn . Model ( i ) . CreateTable ( & orm . CreateTableOptions { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										IfNotExists :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  DropTable ( i  interface { } )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ps . conn . Model ( i ) . DropTable ( & orm . DropTableOptions { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										IfExists :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 22:52:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  Stop ( ctx  context . Context )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ps . log . Info ( "closing db connection" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Close ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// only cancel if there's a problem closing the db 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ps . cancel ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 18:26:30 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-03-05 18:31:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  IsHealthy ( ctx  context . Context )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ps . conn . Ping ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-05 18:31:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  CreateSchema ( ctx  context . Context )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									models  :=  [ ] interface { } { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										( * gtsmodel . Account ) ( nil ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										( * gtsmodel . Status ) ( nil ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										( * gtsmodel . User ) ( nil ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-05 18:31:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ps . log . Info ( "creating db schema" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  model  :=  range  models  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  :=  ps . conn . Model ( model ) . CreateTable ( & orm . CreateTableOptions { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											IfNotExists :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ps . log . Info ( "db schema created" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 22:26:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetByID ( id  string ,  i  interface { } )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( i ) . Where ( "id = ?" ,  id ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 22:26:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetWhere ( where  [ ] db . Where ,  i  interface { } )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( where )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errors . New ( "no queries provided" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									q  :=  ps . conn . Model ( i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  w  :=  range  where  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-02 19:52:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  w . Value  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											q  =  q . Where ( "? IS NULL" ,  pg . Ident ( w . Key ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 19:39:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-02 19:52:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  w . CaseInsensitive  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												q  =  q . Where ( "LOWER(?) = LOWER(?)" ,  pg . Safe ( w . Key ) ,  w . Value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												q  =  q . Where ( "? = ?" ,  pg . Safe ( w . Key ) ,  w . Value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-29 19:39:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  q . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 22:26:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// func (ps *postgresService) GetWhereMany(i interface{}, where ...model.Where) error {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 	return nil  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// }  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 22:26:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetAll ( i  interface { } )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( i ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 22:26:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  Put ( i  interface { } )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_ ,  err  :=  ps . conn . Model ( i ) . Insert ( i ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  &&  strings . Contains ( err . Error ( ) ,  "duplicate key value violates unique constraint" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  db . ErrAlreadyExists { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 22:26:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  Upsert ( i  interface { } ,  conflictColumn  string )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  _ ,  err  :=  ps . conn . Model ( i ) . OnConflict ( fmt . Sprintf ( "(%s) DO UPDATE" ,  conflictColumn ) ) . Insert ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 22:26:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  UpdateByID ( id  string ,  i  interface { } )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  err  :=  ps . conn . Model ( i ) . Where ( "id = ?" ,  id ) . OnConflict ( "(id) DO UPDATE" ) . Insert ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  UpdateOneByID ( id  string ,  key  string ,  value  interface { } ,  i  interface { } )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_ ,  err  :=  ps . conn . Model ( i ) . Set ( "? = ?" ,  pg . Safe ( key ) ,  value ) . Where ( "id = ?" ,  id ) . Update ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 22:26:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  DeleteByID ( id  string ,  i  interface { } )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  err  :=  ps . conn . Model ( i ) . Where ( "id = ?" ,  id ) . Delete ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// if there are no rows *anyway* then that's fine 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// just return err if there's an actual error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 22:26:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  DeleteWhere ( where  [ ] db . Where ,  i  interface { } )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( where )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errors . New ( "no queries provided" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									q  :=  ps . conn . Model ( i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  w  :=  range  where  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Where ( "? = ?" ,  pg . Safe ( w . Key ) ,  w . Value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  _ ,  err  :=  q . Delete ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// if there are no rows *anyway* then that's fine 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// just return err if there's an actual error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDY  SHORTCUTS 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* /  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  AcceptFollowRequest ( originAccountID  string ,  targetAccountID  string )  ( * gtsmodel . Follow ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// make sure the original follow request exists 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									fr  :=  & gtsmodel . FollowRequest { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( fr ) . Where ( "account_id = ?" ,  originAccountID ) . Where ( "target_account_id = ?" ,  targetAccountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrMultiRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// create a new follow to 'replace' the request with 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									follow  :=  & gtsmodel . Follow { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AccountID :        originAccountID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										TargetAccountID :  targetAccountID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										URI :              fr . URI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// if the follow already exists, just update the URI -- we don't need to do anything else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  _ ,  err  :=  ps . conn . Model ( follow ) . OnConflict ( "ON CONSTRAINT follows_account_id_target_account_id_key DO UPDATE set uri = ?" ,  follow . URI ) . Insert ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// now remove the follow request 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  err  :=  ps . conn . Model ( & gtsmodel . FollowRequest { } ) . Where ( "account_id = ?" ,  originAccountID ) . Where ( "target_account_id = ?" ,  targetAccountID ) . Delete ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  follow ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  CreateInstanceAccount ( )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									username  :=  ps . config . Host 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 14:06:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									key ,  err  :=  rsa . GenerateKey ( rand . Reader ,  2048 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ps . log . Errorf ( "error creating new rsa key: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newAccountURIs  :=  util . GenerateURIsForAccount ( username ,  ps . config . Protocol ,  ps . config . Host ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a  :=  & gtsmodel . Account { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Username :               ps . config . Host , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DisplayName :            username , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										URL :                    newAccountURIs . UserURL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PrivateKey :             key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PublicKey :              & key . PublicKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PublicKeyURI :           newAccountURIs . PublicKeyURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ActorType :              gtsmodel . ActivityStreamsPerson , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										URI :                    newAccountURIs . UserURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										InboxURI :               newAccountURIs . InboxURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										OutboxURI :              newAccountURIs . OutboxURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										FollowersURI :           newAccountURIs . FollowersURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										FollowingURI :           newAccountURIs . FollowingURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										FeaturedCollectionURI :  newAccountURIs . CollectionURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									inserted ,  err  :=  ps . conn . Model ( a ) . Where ( "username = ?" ,  username ) . SelectOrInsert ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  inserted  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ps . log . Infof ( "created instance account %s with id %s" ,  username ,  a . ID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ps . log . Infof ( "instance account %s already exists with id %s" ,  username ,  a . ID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  CreateInstanceInstance ( )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									i  :=  & gtsmodel . Instance { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Domain :  ps . config . Host , 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 20:34:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Title :   ps . config . Host , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										URI :     fmt . Sprintf ( "%s://%s" ,  ps . config . Protocol ,  ps . config . Host ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 14:06:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									inserted ,  err  :=  ps . conn . Model ( i ) . Where ( "domain = ?" ,  ps . config . Host ) . SelectOrInsert ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  inserted  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 14:06:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ps . log . Infof ( "created instance instance %s with id %s" ,  ps . config . Host ,  i . ID ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 20:34:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ps . log . Infof ( "instance instance %s already exists with id %s" ,  ps . config . Host ,  i . ID ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetAccountByUserID ( userID  string ,  account  * gtsmodel . Account )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									user  :=  & gtsmodel . User { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ID :  userID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( user ) . Where ( "id = ?" ,  userID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( account ) . Where ( "id = ?" ,  user . AccountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetLocalAccountByUsername ( username  string ,  account  * gtsmodel . Account )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( account ) . Where ( "username = ?" ,  username ) . Where ( "? IS NULL" ,  pg . Ident ( "domain" ) ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetFollowRequestsForAccountID ( accountID  string ,  followRequests  * [ ] gtsmodel . FollowRequest )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( followRequests ) . Where ( "target_account_id = ?" ,  accountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetFollowingByAccountID ( accountID  string ,  following  * [ ] gtsmodel . Follow )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( following ) . Where ( "account_id = ?" ,  accountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:57:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetFollowersByAccountID ( accountID  string ,  followers  * [ ] gtsmodel . Follow ,  localOnly  bool )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 18:11:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									q  :=  ps . conn . Model ( followers ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:57:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 18:11:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  localOnly  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 21:13:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// for local accounts let's get where domain is null OR where domain is an empty string, just to be safe 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										whereGroup  :=  func ( q  * pg . Query )  ( * pg . Query ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											q  =  q . 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 14:39:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												WhereOr ( "? IS NULL" ,  pg . Ident ( "a.domain" ) ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												WhereOr ( "a.domain = ?" ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 21:13:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  q ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 18:11:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										q  =  q . ColumnExpr ( "follow.*" ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Join ( "JOIN accounts AS a ON follow.account_id = TEXT(a.id)" ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Where ( "follow.target_account_id = ?" ,  accountID ) . 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 21:13:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											WhereGroup ( whereGroup ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 18:11:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Where ( "target_account_id = ?" ,  accountID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 10:57:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 18:11:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  q . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetFavesByAccountID ( accountID  string ,  faves  * [ ] gtsmodel . StatusFave )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( faves ) . Where ( "account_id = ?" ,  accountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  CountStatusesByAccountID ( accountID  string )  ( int ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									count ,  err  :=  ps . conn . Model ( & gtsmodel . Status { } ) . Where ( "account_id = ?" ,  accountID ) . Count ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  0 ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  count ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetStatusesByTimeDescending ( accountID  string ,  statuses  * [ ] gtsmodel . Status ,  limit  int ,  excludeReplies  bool ,  maxID  string ,  pinned  bool ,  mediaOnly  bool )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									q  :=  ps . conn . Model ( statuses ) . Order ( "created_at DESC" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  accountID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Where ( "account_id = ?" ,  accountID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  limit  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Limit ( limit ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  excludeReplies  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Where ( "? IS NULL" ,  pg . Ident ( "in_reply_to_id" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  pinned  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Where ( "pinned = ?" ,  true ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  mediaOnly  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . WhereGroup ( func ( q  * pg . Query )  ( * pg . Query ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  q . Where ( "? IS NOT NULL" ,  pg . Ident ( "attachments" ) ) . Where ( "attachments != '{}'" ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-23 18:07:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  maxID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  :=  & gtsmodel . Status { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( s ) . Where ( "id = ?" ,  maxID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Where ( "status.created_at < ?" ,  s . CreatedAt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  q . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetLastStatusForAccountID ( accountID  string ,  status  * gtsmodel . Status )  error  {  
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( status ) . Order ( "created_at DESC" ) . Limit ( 1 ) . Where ( "account_id = ?" ,  accountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  IsUsernameAvailable ( username  string )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// if no error we fail because it means we found something 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// if error but it's not pg.ErrNoRows then we fail 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// if err is pg.ErrNoRows we're good, we found nothing so continue 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( & gtsmodel . Account { } ) . Where ( "username = ?" ,  username ) . Where ( "domain = ?" ,  nil ) . Select ( ) ;  err  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  fmt . Errorf ( "username %s already in use" ,  username ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  err  !=  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Errorf ( "db error: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  IsEmailAvailable ( email  string )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// parse the domain from the email 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									m ,  err  :=  mail . ParseAddress ( email ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Errorf ( "error parsing email address %s: %s" ,  email ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									domain  :=  strings . Split ( m . Address ,  "@" ) [ 1 ]  // domain will always be the second part after @ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check if the email domain is blocked 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( & gtsmodel . EmailDomainBlock { } ) . Where ( "domain = ?" ,  domain ) . Select ( ) ;  err  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// fail because we found something 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Errorf ( "email domain %s is blocked" ,  domain ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  err  !=  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// fail because we got an unexpected error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Errorf ( "db error: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check if this email is associated with a user already 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( & gtsmodel . User { } ) . Where ( "email = ?" ,  email ) . WhereOr ( "unconfirmed_email = ?" ,  email ) . Select ( ) ;  err  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// fail because we found something 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Errorf ( "email %s already in use" ,  email ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  err  !=  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// fail because we got an unexpected error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Errorf ( "db error: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  NewSignup ( username  string ,  reason  string ,  requireApproval  bool ,  email  string ,  password  string ,  signUpIP  net . IP ,  locale  string ,  appID  string )  ( * gtsmodel . User ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									key ,  err  :=  rsa . GenerateKey ( rand . Reader ,  2048 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ps . log . Errorf ( "error creating new rsa key: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newAccountURIs  :=  util . GenerateURIsForAccount ( username ,  ps . config . Protocol ,  ps . config . Host ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									a  :=  & gtsmodel . Account { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Username :               username , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DisplayName :            username , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Reason :                 reason , 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										URL :                    newAccountURIs . UserURL , 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										PrivateKey :             key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PublicKey :              & key . PublicKey , 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										PublicKeyURI :           newAccountURIs . PublicKeyURI , 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ActorType :              gtsmodel . ActivityStreamsPerson , 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										URI :                    newAccountURIs . UserURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										InboxURI :               newAccountURIs . InboxURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										OutboxURI :              newAccountURIs . OutboxURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										FollowersURI :           newAccountURIs . FollowersURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										FollowingURI :           newAccountURIs . FollowingURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										FeaturedCollectionURI :  newAccountURIs . CollectionURI , 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  _ ,  err  =  ps . conn . Model ( a ) . Insert ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pw ,  err  :=  bcrypt . GenerateFromPassword ( [ ] byte ( password ) ,  bcrypt . DefaultCost ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "error hashing password: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									u  :=  & gtsmodel . User { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										AccountID :               a . ID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										EncryptedPassword :       string ( pw ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SignUpIP :                signUpIP , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Locale :                  locale , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UnconfirmedEmail :        email , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CreatedByApplicationID :  appID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Approved :                ! requireApproval ,  // if we don't require moderator approval, just pre-approve the user 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  _ ,  err  =  ps . conn . Model ( u ) . Insert ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  u ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  SetHeaderOrAvatarForAccountID ( mediaAttachment  * gtsmodel . MediaAttachment ,  accountID  string )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  mediaAttachment . Avatar  &&  mediaAttachment . Header  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errors . New ( "one media attachment cannot be both header and avatar" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  headerOrAVI  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  mediaAttachment . Avatar  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										headerOrAVI  =  "avatar" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  mediaAttachment . Header  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										headerOrAVI  =  "header" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errors . New ( "given media attachment was neither a header nor an avatar" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// TODO: there are probably more side effects here that need to be handled 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  _ ,  err  :=  ps . conn . Model ( mediaAttachment ) . OnConflict ( "(id) DO UPDATE" ) . Insert ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  _ ,  err  :=  ps . conn . Model ( & gtsmodel . Account { } ) . Set ( fmt . Sprintf ( "%s_media_attachment_id = ?" ,  headerOrAVI ) ,  mediaAttachment . ID ) . Where ( "id = ?" ,  accountID ) . Update ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-14 17:56:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetHeaderForAccountID ( header  * gtsmodel . MediaAttachment ,  accountID  string )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									acct  :=  & gtsmodel . Account { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( acct ) . Where ( "id = ?" ,  accountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  acct . HeaderMediaAttachmentID  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( header ) . Where ( "id = ?" ,  acct . HeaderMediaAttachmentID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetAvatarForAccountID ( avatar  * gtsmodel . MediaAttachment ,  accountID  string )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									acct  :=  & gtsmodel . Account { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( acct ) . Where ( "id = ?" ,  accountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  acct . AvatarMediaAttachmentID  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( avatar ) . Where ( "id = ?" ,  acct . AvatarMediaAttachmentID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 11:58:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  db . ErrNoEntries { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  Blocked ( account1  string ,  account2  string )  ( bool ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2021-05-08 14:25:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// TODO: check domain blocks as well 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  blocked  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( & gtsmodel . Block { } ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Where ( "account_id = ?" ,  account1 ) . Where ( "target_account_id = ?" ,  account2 ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										WhereOr ( "target_account_id = ?" ,  account1 ) . Where ( "account_id = ?" ,  account2 ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											blocked  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  blocked ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-20 18:14:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  blocked ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									blocked  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  blocked ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetRelationship ( requestingAccount  string ,  targetAccount  string )  ( * gtsmodel . Relationship ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r  :=  & gtsmodel . Relationship { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ID :  targetAccount , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check if the requesting account follows the target account 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									follow  :=  & gtsmodel . Follow { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( follow ) . Where ( "account_id = ?" ,  requestingAccount ) . Where ( "target_account_id = ?" ,  targetAccount ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// a proper error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  fmt . Errorf ( "getrelationship: error checking follow existence: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// no follow exists so these are all false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . Following  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . ShowingReblogs  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . Notifying  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// follow exists so we can fill these fields out... 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . Following  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . ShowingReblogs  =  follow . ShowReblogs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . Notifying  =  follow . Notify 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check if the target account follows the requesting account 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									followedBy ,  err  :=  ps . conn . Model ( & gtsmodel . Follow { } ) . Where ( "account_id = ?" ,  targetAccount ) . Where ( "target_account_id = ?" ,  requestingAccount ) . Exists ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "getrelationship: error checking followed_by existence: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r . FollowedBy  =  followedBy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check if the requesting account blocks the target account 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									blocking ,  err  :=  ps . conn . Model ( & gtsmodel . Block { } ) . Where ( "account_id = ?" ,  requestingAccount ) . Where ( "target_account_id = ?" ,  targetAccount ) . Exists ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "getrelationship: error checking blocking existence: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r . Blocking  =  blocking 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check if the target account blocks the requesting account 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									blockedBy ,  err  :=  ps . conn . Model ( & gtsmodel . Block { } ) . Where ( "account_id = ?" ,  targetAccount ) . Where ( "target_account_id = ?" ,  requestingAccount ) . Exists ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "getrelationship: error checking blocked existence: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r . BlockedBy  =  blockedBy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check if there's a pending following request from requesting account to target account 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									requested ,  err  :=  ps . conn . Model ( & gtsmodel . FollowRequest { } ) . Where ( "account_id = ?" ,  requestingAccount ) . Where ( "target_account_id = ?" ,  targetAccount ) . Exists ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "getrelationship: error checking blocked existence: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r . Requested  =  requested 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  r ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 16:35:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  StatusVisible ( targetStatus  * gtsmodel . Status ,  requestingAccount  * gtsmodel . Account ,  relevantAccounts  * gtsmodel . RelevantAccounts )  ( bool ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									l  :=  ps . log . WithField ( "func" ,  "StatusVisible" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 16:35:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									targetAccount  :=  relevantAccounts . StatusAuthor 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// if target account is suspended then don't show the status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! targetAccount . SuspendedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										l . Debug ( "target account suspended at is not zero" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// if the target user doesn't exist (anymore) then the status also shouldn't be visible 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// note: we only do this for local users 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  targetAccount . Domain  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										targetUser  :=  & gtsmodel . User { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( targetUser ) . Where ( "account_id = ?" ,  targetAccount . ID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											l . Debug ( "target user could not be selected" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  false ,  db . ErrNoEntries { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// if target user is disabled, not yet approved, or not confirmed then don't show the status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// (although in the latter two cases it's unlikely they posted a status yet anyway, but you never know!) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  targetUser . Disabled  ||  ! targetUser . Approved  ||  targetUser . ConfirmedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											l . Debug ( "target user is disabled, not approved, or not confirmed" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If requesting account is nil, that means whoever requested the status didn't auth, or their auth failed. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// In this case, we can still serve the status if it's public, otherwise we definitely shouldn't. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  requestingAccount  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  targetStatus . Visibility  ==  gtsmodel . VisibilityPublic  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  true ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										l . Debug ( "requesting account is nil but the target status isn't public" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// if requesting account is suspended then don't show the status -- although they probably shouldn't have gotten 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// this far (ie., been authed) in the first place: this is just for safety. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! requestingAccount . SuspendedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										l . Debug ( "requesting account is suspended" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// check if we have a local account -- if so we can check the user for that account in the DB 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  requestingAccount . Domain  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										requestingUser  :=  & gtsmodel . User { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( requestingUser ) . Where ( "account_id = ?" ,  requestingAccount . ID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// if the requesting account is local but doesn't have a corresponding user in the db this is a problem 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												l . Debug ( "requesting account is local but there's no corresponding user" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  false ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-20 18:14:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											l . Debugf ( "requesting account is local but there was an error getting the corresponding user: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// okay, user exists, so make sure it has full privileges/is confirmed/approved 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  requestingUser . Disabled  ||  ! requestingUser . Approved  ||  requestingUser . ConfirmedAt . IsZero ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											l . Debug ( "requesting account is local but corresponding user is either disabled, not approved, or not confirmed" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// if the target status belongs to the requesting account, they should always be able to view it at this point 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  targetStatus . AccountID  ==  requestingAccount . ID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// At this point we have a populated targetAccount, targetStatus, and requestingAccount, so we can check for blocks and whathaveyou 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// First check if a block exists directly between the target account (which authored the status) and the requesting account. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  blocked ,  err  :=  ps . Blocked ( targetAccount . ID ,  requestingAccount . ID ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										l . Debugf ( "something went wrong figuring out if the accounts have a block: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  blocked  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// don't allow the status to be viewed if a block exists in *either* direction between these two accounts, no creepy stalking please 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										l . Debug ( "a block exists between requesting account and target account" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// check other accounts mentioned/boosted by/replied to by the status, if they exist 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  relevantAccounts  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// status replies to account id 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 16:35:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  relevantAccounts . ReplyToAccount  !=  nil  &&  relevantAccounts . ReplyToAccount . ID  !=  requestingAccount . ID  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  blocked ,  err  :=  ps . Blocked ( relevantAccounts . ReplyToAccount . ID ,  requestingAccount . ID ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  false ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  blocked  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												l . Debug ( "a block exists between requesting account and reply to account" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  false ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-03 18:11:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// check reply to ID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  targetStatus . InReplyToID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												followsRepliedAccount ,  err  :=  ps . Follows ( requestingAccount ,  relevantAccounts . ReplyToAccount ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  false ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! followsRepliedAccount  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													l . Debug ( "target status is a followers-only reply to an account that is not followed by the requesting account" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  false ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// status boosts accounts id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  relevantAccounts . BoostedAccount  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  blocked ,  err  :=  ps . Blocked ( relevantAccounts . BoostedAccount . ID ,  requestingAccount . ID ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  false ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  blocked  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												l . Debug ( "a block exists between requesting account and boosted account" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  false ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// status boosts a reply to account id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  relevantAccounts . BoostedReplyToAccount  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  blocked ,  err  :=  ps . Blocked ( relevantAccounts . BoostedReplyToAccount . ID ,  requestingAccount . ID ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  false ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  blocked  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												l . Debug ( "a block exists between requesting account and boosted reply to account" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  false ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// status mentions accounts 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  a  :=  range  relevantAccounts . MentionedAccounts  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  blocked ,  err  :=  ps . Blocked ( a . ID ,  requestingAccount . ID ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  false ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  blocked  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												l . Debug ( "a block exists between requesting account and a mentioned account" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  false ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// if the requesting account is mentioned in the status it should always be visible 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  acct  :=  range  relevantAccounts . MentionedAccounts  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  acct . ID  ==  requestingAccount . ID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  true ,  nil  // yep it's mentioned! 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// at this point we know neither account blocks the other, or another account mentioned or otherwise referred to in the status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// that means it's now just a matter of checking the visibility settings of the status itself 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  targetStatus . Visibility  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  gtsmodel . VisibilityPublic ,  gtsmodel . VisibilityUnlocked : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// no problem here, just return OK 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  gtsmodel . VisibilityFollowersOnly : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// check one-way follow 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										follows ,  err  :=  ps . Follows ( requestingAccount ,  targetAccount ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! follows  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											l . Debug ( "requested status is followers only but requesting account is not a follower" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  false ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  gtsmodel . VisibilityMutualsOnly : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// check mutual follow 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mutuals ,  err  :=  ps . Mutuals ( requestingAccount ,  targetAccount ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! mutuals  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											l . Debug ( "requested status is mutuals only but accounts aren't mufos" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  false ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  gtsmodel . VisibilityDirect : 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										l . Debug ( "requesting account requests a status it's not mentioned in" ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  false ,  nil  // it's not mentioned -_- 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false ,  errors . New ( "reached the end of StatusVisible with no result" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  Follows ( sourceAccount  * gtsmodel . Account ,  targetAccount  * gtsmodel . Account )  ( bool ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ps . conn . Model ( & gtsmodel . Follow { } ) . Where ( "account_id = ?" ,  sourceAccount . ID ) . Where ( "target_account_id = ?" ,  targetAccount . ID ) . Exists ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  FollowRequested ( sourceAccount  * gtsmodel . Account ,  targetAccount  * gtsmodel . Account )  ( bool ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ps . conn . Model ( & gtsmodel . FollowRequest { } ) . Where ( "account_id = ?" ,  sourceAccount . ID ) . Where ( "target_account_id = ?" ,  targetAccount . ID ) . Exists ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  Mutuals ( account1  * gtsmodel . Account ,  account2  * gtsmodel . Account )  ( bool ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// make sure account 1 follows account 2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									f1 ,  err  :=  ps . conn . Model ( & gtsmodel . Follow { } ) . Where ( "account_id = ?" ,  account1 . ID ) . Where ( "target_account_id = ?" ,  account2 . ID ) . Exists ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-20 18:14:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  false ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// make sure account 2 follows account 1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									f2 ,  err  :=  ps . conn . Model ( & gtsmodel . Follow { } ) . Where ( "account_id = ?" ,  account2 . ID ) . Where ( "target_account_id = ?" ,  account1 . ID ) . Exists ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  false ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-20 18:14:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  false ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  f1  &&  f2 ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  PullRelevantAccountsFromStatus ( targetStatus  * gtsmodel . Status )  ( * gtsmodel . RelevantAccounts ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									accounts  :=  & gtsmodel . RelevantAccounts { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										MentionedAccounts :  [ ] * gtsmodel . Account { } , 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-02 19:52:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// get the author account 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  targetStatus . GTSAuthorAccount  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										statusAuthor  :=  & gtsmodel . Account { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( statusAuthor ) . Where ( "id = ?" ,  targetStatus . AccountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  accounts ,  fmt . Errorf ( "PullRelevantAccountsFromStatus: error getting statusAuthor with id %s: %s" ,  targetStatus . AccountID ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										targetStatus . GTSAuthorAccount  =  statusAuthor 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									accounts . StatusAuthor  =  targetStatus . GTSAuthorAccount 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// get the replied to account from the status and add it to the pile 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  targetStatus . InReplyToAccountID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										repliedToAccount  :=  & gtsmodel . Account { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( repliedToAccount ) . Where ( "id = ?" ,  targetStatus . InReplyToAccountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-28 19:57:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  accounts ,  fmt . Errorf ( "PullRelevantAccountsFromStatus: error getting repliedToAcount with id %s: %s" ,  targetStatus . InReplyToAccountID ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										accounts . ReplyToAccount  =  repliedToAccount 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// get the boosted account from the status and add it to the pile 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  targetStatus . BoostOfID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// retrieve the boosted status first 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										boostedStatus  :=  & gtsmodel . Status { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( boostedStatus ) . Where ( "id = ?" ,  targetStatus . BoostOfID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-28 19:57:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  accounts ,  fmt . Errorf ( "PullRelevantAccountsFromStatus: error getting boostedStatus with id %s: %s" ,  targetStatus . BoostOfID ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										boostedAccount  :=  & gtsmodel . Account { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( boostedAccount ) . Where ( "id = ?" ,  boostedStatus . AccountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-28 19:57:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  accounts ,  fmt . Errorf ( "PullRelevantAccountsFromStatus: error getting boostedAccount with id %s: %s" ,  boostedStatus . AccountID ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										accounts . BoostedAccount  =  boostedAccount 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// the boosted status might be a reply to another account so we should get that too 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  boostedStatus . InReplyToAccountID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											boostedStatusRepliedToAccount  :=  & gtsmodel . Account { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  ps . conn . Model ( boostedStatusRepliedToAccount ) . Where ( "id = ?" ,  boostedStatus . InReplyToAccountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-28 19:57:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  accounts ,  fmt . Errorf ( "PullRelevantAccountsFromStatus: error getting boostedStatusRepliedToAccount with id %s: %s" ,  boostedStatus . InReplyToAccountID ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accounts . BoostedReplyToAccount  =  boostedStatusRepliedToAccount 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// now get all accounts with IDs that are mentioned in the status 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  mentionID  :=  range  targetStatus . Mentions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mention  :=  & gtsmodel . Mention { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( mention ) . Where ( "id = ?" ,  mentionID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-28 19:57:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  accounts ,  fmt . Errorf ( "PullRelevantAccountsFromStatus: error getting mention with id %s: %s" ,  mentionID ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										mentionedAccount  :=  & gtsmodel . Account { } 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-17 19:06:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( mentionedAccount ) . Where ( "id = ?" ,  mention . TargetAccountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-28 19:57:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  accounts ,  fmt . Errorf ( "PullRelevantAccountsFromStatus: error getting mentioned account: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										accounts . MentionedAccounts  =  append ( accounts . MentionedAccounts ,  mentionedAccount ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  accounts ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetReplyCountForStatus ( status  * gtsmodel . Status )  ( int ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ps . conn . Model ( & gtsmodel . Status { } ) . Where ( "in_reply_to_id = ?" ,  status . ID ) . Count ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetReblogCountForStatus ( status  * gtsmodel . Status )  ( int ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ps . conn . Model ( & gtsmodel . Status { } ) . Where ( "boost_of_id = ?" ,  status . ID ) . Count ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetFaveCountForStatus ( status  * gtsmodel . Status )  ( int ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ps . conn . Model ( & gtsmodel . StatusFave { } ) . Where ( "status_id = ?" ,  status . ID ) . Count ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  StatusFavedBy ( status  * gtsmodel . Status ,  accountID  string )  ( bool ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ps . conn . Model ( & gtsmodel . StatusFave { } ) . Where ( "status_id = ?" ,  status . ID ) . Where ( "account_id = ?" ,  accountID ) . Exists ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  StatusRebloggedBy ( status  * gtsmodel . Status ,  accountID  string )  ( bool ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ps . conn . Model ( & gtsmodel . Status { } ) . Where ( "boost_of_id = ?" ,  status . ID ) . Where ( "account_id = ?" ,  accountID ) . Exists ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  StatusMutedBy ( status  * gtsmodel . Status ,  accountID  string )  ( bool ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ps . conn . Model ( & gtsmodel . StatusMute { } ) . Where ( "status_id = ?" ,  status . ID ) . Where ( "account_id = ?" ,  accountID ) . Exists ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  StatusBookmarkedBy ( status  * gtsmodel . Status ,  accountID  string )  ( bool ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ps . conn . Model ( & gtsmodel . StatusBookmark { } ) . Where ( "status_id = ?" ,  status . ID ) . Where ( "account_id = ?" ,  accountID ) . Exists ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  WhoFavedStatus ( status  * gtsmodel . Status )  ( [ ] * gtsmodel . Account ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									accounts  :=  [ ] * gtsmodel . Account { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									faves  :=  [ ] * gtsmodel . StatusFave { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( & faves ) . Where ( "status_id = ?" ,  status . ID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  accounts ,  nil  // no rows just means nobody has faved this status, so that's fine 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  err  // an actual error has occurred 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  f  :=  range  faves  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										acc  :=  & gtsmodel . Account { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( acc ) . Where ( "id = ?" ,  f . AccountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue  // the account doesn't exist for some reason??? but this isn't the place to worry about that so just skip it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err  // an actual error has occurred 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										accounts  =  append ( accounts ,  acc ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  accounts ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 17:36:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  WhoBoostedStatus ( status  * gtsmodel . Status )  ( [ ] * gtsmodel . Account ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									accounts  :=  [ ] * gtsmodel . Account { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									boosts  :=  [ ] * gtsmodel . Status { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( & boosts ) . Where ( "boost_of_id = ?" ,  status . ID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  accounts ,  nil  // no rows just means nobody has boosted this status, so that's fine 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err  // an actual error has occurred 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  f  :=  range  boosts  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										acc  :=  & gtsmodel . Account { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( acc ) . Where ( "id = ?" ,  f . AccountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue  // the account doesn't exist for some reason??? but this isn't the place to worry about that so just skip it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err  // an actual error has occurred 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										accounts  =  append ( accounts ,  acc ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  accounts ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-02 19:52:15 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetStatusesWhereFollowing ( accountID  string ,  limit  int ,  offsetStatusID  string )  ( [ ] * gtsmodel . Status ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									statuses  :=  [ ] * gtsmodel . Status { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									q  :=  ps . conn . Model ( & statuses ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									q  =  q . ColumnExpr ( "status.*" ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Join ( "JOIN follows AS f ON f.target_account_id = status.account_id" ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Where ( "f.account_id = ?" ,  accountID ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Order ( "status.created_at DESC" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  offsetStatusID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  :=  & gtsmodel . Status { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( s ) . Where ( "id = ?" ,  offsetStatusID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Where ( "status.created_at < ?" ,  s . CreatedAt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  limit  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Limit ( limit ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  :=  q . Select ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  statuses ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 17:36:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetPublicTimelineForAccount ( accountID  string ,  maxID  string ,  sinceID  string ,  minID  string ,  limit  int ,  local  bool )  ( [ ] * gtsmodel . Status ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									statuses  :=  [ ] * gtsmodel . Status { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									q  :=  ps . conn . Model ( & statuses ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Where ( "visibility = ?" ,  gtsmodel . VisibilityPublic ) . 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-04 16:35:58 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Where ( "? IS NULL" ,  pg . Ident ( "in_reply_to_id" ) ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Where ( "? IS NULL" ,  pg . Ident ( "boost_of_id" ) ) . 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 17:36:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Limit ( limit ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Order ( "created_at DESC" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  maxID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  :=  & gtsmodel . Status { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( s ) . Where ( "id = ?" ,  maxID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Where ( "created_at < ?" ,  s . CreatedAt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  minID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  :=  & gtsmodel . Status { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( s ) . Where ( "id = ?" ,  minID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Where ( "created_at > ?" ,  s . CreatedAt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  sinceID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  :=  & gtsmodel . Status { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( s ) . Where ( "id = ?" ,  sinceID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Where ( "created_at > ?" ,  s . CreatedAt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  local  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Where ( "local = ?" ,  local ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 23:04:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  :=  q . Select ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  statuses ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 17:36:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  GetNotificationsForAccount ( accountID  string ,  limit  int ,  maxID  string ,  sinceID  string )  ( [ ] * gtsmodel . Notification ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2021-05-27 16:06:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									notifications  :=  [ ] * gtsmodel . Notification { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									q  :=  ps . conn . Model ( & notifications ) . Where ( "target_account_id = ?" ,  accountID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  maxID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										n  :=  & gtsmodel . Notification { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( n ) . Where ( "id = ?" ,  maxID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Where ( "created_at < ?" ,  n . CreatedAt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-31 17:36:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  sinceID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										n  :=  & gtsmodel . Notification { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( n ) . Where ( "id = ?" ,  sinceID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Where ( "created_at > ?" ,  n . CreatedAt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-27 16:06:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  limit  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										q  =  q . Limit ( limit ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									q  =  q . Order ( "created_at DESC" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  q . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  notifications ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CONVERSION  FUNCTIONS 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* /  
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  MentionStringsToMentions ( targetAccounts  [ ] string ,  originAccountID  string ,  statusID  string )  ( [ ] * gtsmodel . Mention ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ogAccount  :=  & gtsmodel . Account { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  ps . conn . Model ( ogAccount ) . Where ( "id = ?" ,  originAccountID ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									menchies  :=  [ ] * gtsmodel . Mention { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  a  :=  range  targetAccounts  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// A mentioned account looks like "@test@example.org" or just "@test" for a local account 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// -- we can guarantee this from the regex that targetAccounts should have been derived from. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// But we still need to do a bit of fiddling to get what we need here -- the username and domain (if given). 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 1.  trim off the first @ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t  :=  strings . TrimPrefix ( a ,  "@" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 2. split the username and domain 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  :=  strings . Split ( t ,  "@" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 3. if it's length 1 it's a local account, length 2 means remote, anything else means something is wrong 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  local  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  len ( s )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											local  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											local  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  fmt . Errorf ( "mentioned account format '%s' was not valid" ,  a ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  username ,  domain  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										username  =  s [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! local  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											domain  =  s [ 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 4. check we now have a proper username and domain 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  username  ==  ""  ||  ( ! local  &&  domain  ==  "" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  fmt . Errorf ( "username or domain for '%s' was nil" ,  a ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// okay we're good now, we can start pulling accounts out of the database 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mentionedAccount  :=  & gtsmodel . Account { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 12:47:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// match username + account, case insensitive 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  local  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// local user -- should have a null domain 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 12:47:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  ps . conn . Model ( mentionedAccount ) . Where ( "LOWER(?) = LOWER(?)" ,  pg . Ident ( "username" ) ,  username ) . Where ( "? IS NULL" ,  pg . Ident ( "domain" ) ) . Select ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// remote user -- should have domain defined 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 12:47:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  ps . conn . Model ( mentionedAccount ) . Where ( "LOWER(?) = LOWER(?)" ,  pg . Ident ( "username" ) ,  username ) . Where ( "LOWER(?) = LOWER(?)" ,  pg . Ident ( "domain" ) ,  domain ) . Select ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// no result found for this username/domain so just don't include it as a mencho and carry on about our business 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ps . log . Debugf ( "no account found with username '%s' and domain '%s', skipping it" ,  username ,  domain ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// a serious error has happened so bail 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  fmt . Errorf ( "error getting account with username '%s' and domain '%s': %s" ,  username ,  domain ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// id, createdAt and updatedAt will be populated by the db, so we have everything we need! 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										menchies  =  append ( menchies ,  & gtsmodel . Mention { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											StatusID :             statusID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											OriginAccountID :      ogAccount . ID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											OriginAccountURI :     ogAccount . URI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											TargetAccountID :      mentionedAccount . ID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											NameString :           a , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											MentionedAccountURI :  mentionedAccount . URI , 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-05 12:47:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											MentionedAccountURL :  mentionedAccount . URL , 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 15:48:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											GTSAccount :           mentionedAccount , 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  menchies ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-19 19:42:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  TagStringsToTags ( tags  [ ] string ,  originAccountID  string ,  statusID  string )  ( [ ] * gtsmodel . Tag ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newTags  :=  [ ] * gtsmodel . Tag { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  t  :=  range  tags  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tag  :=  & gtsmodel . Tag { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// we can use selectorinsert here to create the new tag if it doesn't exist already 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// inserted will be true if this is a new tag we just created 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  ps . conn . Model ( tag ) . Where ( "name = ?" ,  t ) . Select ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// tag doesn't exist yet so populate it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tag . ID  =  uuid . NewString ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tag . Name  =  t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tag . FirstSeenFromAccountID  =  originAccountID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tag . CreatedAt  =  time . Now ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tag . UpdatedAt  =  time . Now ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tag . Useable  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tag . Listable  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  fmt . Errorf ( "error getting tag with name %s: %s" ,  t ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// bail already if the tag isn't useable 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! tag . Useable  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tag . LastStatusAt  =  time . Now ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newTags  =  append ( newTags ,  tag ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  newTags ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( ps  * postgresService )  EmojiStringsToEmojis ( emojis  [ ] string ,  originAccountID  string ,  statusID  string )  ( [ ] * gtsmodel . Emoji ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newEmojis  :=  [ ] * gtsmodel . Emoji { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  e  :=  range  emojis  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										emoji  :=  & gtsmodel . Emoji { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  :=  ps . conn . Model ( emoji ) . Where ( "shortcode = ?" ,  e ) . Where ( "visible_in_picker = true" ) . Where ( "disabled = false" ) . Select ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  pg . ErrNoRows  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// no result found for this username/domain so just don't include it as an emoji and carry on about our business 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ps . log . Debugf ( "no emoji found with shortcode %s, skipping it" ,  e ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// a serious error has happened so bail 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  fmt . Errorf ( "error getting emoji with shortcode %s: %s" ,  e ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newEmojis  =  append ( newEmojis ,  emoji ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  newEmojis ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-01 20:46:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}