encoders.go (2790B)
1 // GoToSocial 2 // Copyright (C) GoToSocial Authors admin@gotosocial.org 3 // SPDX-License-Identifier: AGPL-3.0-or-later 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package trans 19 20 import ( 21 "context" 22 "crypto/x509" 23 "encoding/json" 24 "encoding/pem" 25 "errors" 26 "fmt" 27 "os" 28 29 transmodel "github.com/superseriousbusiness/gotosocial/internal/trans/model" 30 ) 31 32 // accountEncode handles special fields like private + public keys on accounts 33 func (e *exporter) accountEncode(ctx context.Context, f *os.File, a *transmodel.Account) error { 34 a.Type = transmodel.TransAccount 35 36 // marshal public key 37 encodedPublicKey := x509.MarshalPKCS1PublicKey(a.PublicKey) 38 if encodedPublicKey == nil { 39 return errors.New("could not MarshalPKCS1PublicKey") 40 } 41 publicKeyBytes := pem.EncodeToMemory(&pem.Block{ 42 Type: "RSA PUBLIC KEY", 43 Bytes: encodedPublicKey, 44 }) 45 a.PublicKeyString = string(publicKeyBytes) 46 47 if a.Domain == "" { 48 // marshal private key for local account 49 encodedPrivateKey := x509.MarshalPKCS1PrivateKey(a.PrivateKey) 50 if encodedPrivateKey == nil { 51 return errors.New("could not MarshalPKCS1PrivateKey") 52 } 53 privateKeyBytes := pem.EncodeToMemory(&pem.Block{ 54 Type: "RSA PRIVATE KEY", 55 Bytes: encodedPrivateKey, 56 }) 57 a.PrivateKeyString = string(privateKeyBytes) 58 } 59 60 return e.simpleEncode(ctx, f, a, a.ID) 61 } 62 63 // simpleEncode can be used for any type that doesn't have special keys which need handling differently, 64 // or for types where special keys have already been handled. 65 // 66 // Beware, the 'type' key on the passed interface should already have been set, since simpleEncode won't know 67 // 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. 68 func (e *exporter) simpleEncode(ctx context.Context, file *os.File, i interface{}, id string) error { 69 _, alreadyWritten := e.writtenIDs[id] 70 if alreadyWritten { 71 // this exporter has already exported an entry with this ID, no need to do it twice 72 return nil 73 } 74 75 err := json.NewEncoder(file).Encode(i) 76 if err != nil { 77 return fmt.Errorf("simpleEncode: error encoding entry with id %s: %s", id, err) 78 } 79 80 e.writtenIDs[id] = true 81 return nil 82 }