gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }