| 
									
										
										
										
											2023-03-12 16:00:57 +01:00
										 |  |  | // GoToSocial | 
					
						
							|  |  |  | // Copyright (C) GoToSocial Authors admin@gotosocial.org | 
					
						
							|  |  |  | // SPDX-License-Identifier: AGPL-3.0-or-later | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU Affero General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | // GNU Affero General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  | // along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2021-09-09 16:15:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | package trans | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							|  |  |  | 	"crypto/x509" | 
					
						
							|  |  |  | 	"encoding/json" | 
					
						
							|  |  |  | 	"encoding/pem" | 
					
						
							|  |  |  | 	"errors" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"os" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	transmodel "github.com/superseriousbusiness/gotosocial/internal/trans/model" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // accountEncode handles special fields like private + public keys on accounts | 
					
						
							|  |  |  | func (e *exporter) accountEncode(ctx context.Context, f *os.File, a *transmodel.Account) error { | 
					
						
							|  |  |  | 	a.Type = transmodel.TransAccount | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// marshal public key | 
					
						
							|  |  |  | 	encodedPublicKey := x509.MarshalPKCS1PublicKey(a.PublicKey) | 
					
						
							|  |  |  | 	if encodedPublicKey == nil { | 
					
						
							|  |  |  | 		return errors.New("could not MarshalPKCS1PublicKey") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	publicKeyBytes := pem.EncodeToMemory(&pem.Block{ | 
					
						
							|  |  |  | 		Type:  "RSA PUBLIC KEY", | 
					
						
							|  |  |  | 		Bytes: encodedPublicKey, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	a.PublicKeyString = string(publicKeyBytes) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if a.Domain == "" { | 
					
						
							|  |  |  | 		// marshal private key for local account | 
					
						
							|  |  |  | 		encodedPrivateKey := x509.MarshalPKCS1PrivateKey(a.PrivateKey) | 
					
						
							|  |  |  | 		if encodedPrivateKey == nil { | 
					
						
							|  |  |  | 			return errors.New("could not MarshalPKCS1PrivateKey") | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		privateKeyBytes := pem.EncodeToMemory(&pem.Block{ | 
					
						
							|  |  |  | 			Type:  "RSA PRIVATE KEY", | 
					
						
							|  |  |  | 			Bytes: encodedPrivateKey, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 		a.PrivateKeyString = string(privateKeyBytes) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return e.simpleEncode(ctx, f, a, a.ID) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // simpleEncode can be used for any type that doesn't have special keys which need handling differently, | 
					
						
							|  |  |  | // or for types where special keys have already been handled. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Beware, the 'type' key on the passed interface should already have been set, since simpleEncode won't know | 
					
						
							|  |  |  | // what type it is! If you try to decode stuff you've encoded with a missing type key, you're going to have a bad time. | 
					
						
							|  |  |  | func (e *exporter) simpleEncode(ctx context.Context, file *os.File, i interface{}, id string) error { | 
					
						
							|  |  |  | 	_, alreadyWritten := e.writtenIDs[id] | 
					
						
							|  |  |  | 	if alreadyWritten { | 
					
						
							|  |  |  | 		// this exporter has already exported an entry with this ID, no need to do it twice | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := json.NewEncoder(file).Encode(i) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return fmt.Errorf("simpleEncode: error encoding entry with id %s: %s", id, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	e.writtenIDs[id] = true | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } |