github.com/status-im/status-go@v1.1.0/server/pairing/payload_management.go (about)

     1  package pairing
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  
     7  	"github.com/golang/protobuf/proto"
     8  	"go.uber.org/zap"
     9  
    10  	"github.com/status-im/status-go/api"
    11  	"github.com/status-im/status-go/multiaccounts"
    12  	"github.com/status-im/status-go/multiaccounts/accounts"
    13  	"github.com/status-im/status-go/multiaccounts/settings"
    14  	"github.com/status-im/status-go/protocol/protobuf"
    15  )
    16  
    17  var (
    18  	ErrKeyFileAlreadyExists   = errors.New("key file already exists")
    19  	ErrLoggedInKeyUIDConflict = errors.New("logged in keyUID not same as keyUID in payload")
    20  )
    21  
    22  // AccountPayload represents the payload structure a Server handles
    23  type AccountPayload struct {
    24  	keys         map[string][]byte // nolint: structcheck
    25  	multiaccount *multiaccounts.Account
    26  	password     string
    27  	chatKey      string
    28  	//flag if account already exist before sync account
    29  	exist bool
    30  }
    31  
    32  // AccountPayloadMarshaller is responsible for marshalling and unmarshalling Server payload data
    33  type AccountPayloadMarshaller struct {
    34  	logger *zap.Logger
    35  	*AccountPayload
    36  }
    37  
    38  func NewPairingPayloadMarshaller(ap *AccountPayload, logger *zap.Logger) *AccountPayloadMarshaller {
    39  	return &AccountPayloadMarshaller{logger: logger, AccountPayload: ap}
    40  }
    41  
    42  func (ppm *AccountPayloadMarshaller) MarshalProtobuf() ([]byte, error) {
    43  	lpp := &protobuf.LocalPairingPayload{
    44  		Keys:     ppm.accountKeysToProtobuf(),
    45  		Password: ppm.password,
    46  		ChatKey:  ppm.chatKey,
    47  	}
    48  	if ppm.multiaccount != nil {
    49  		lpp.Multiaccount = ppm.multiaccount.ToProtobuf()
    50  	}
    51  	return proto.Marshal(lpp)
    52  }
    53  
    54  func (ppm *AccountPayloadMarshaller) accountKeysToProtobuf() []*protobuf.LocalPairingPayload_Key {
    55  	var keys []*protobuf.LocalPairingPayload_Key
    56  	for name, data := range ppm.keys {
    57  		keys = append(keys, &protobuf.LocalPairingPayload_Key{Name: name, Data: data})
    58  	}
    59  	return keys
    60  }
    61  
    62  func (ppm *AccountPayloadMarshaller) UnmarshalProtobuf(data []byte) error {
    63  	l := ppm.logger.Named("UnmarshalProtobuf()")
    64  	l.Debug("fired")
    65  
    66  	pb := new(protobuf.LocalPairingPayload)
    67  	err := proto.Unmarshal(data, pb)
    68  	l.Debug(
    69  		"after protobuf.LocalPairingPayload",
    70  		zap.Any("pb", pb),
    71  		zap.Any("pb.Multiaccount", pb.Multiaccount),
    72  		zap.Any("pb.Keys", pb.Keys),
    73  	)
    74  	if err != nil {
    75  		return err
    76  	}
    77  
    78  	ppm.accountKeysFromProtobuf(pb.Keys)
    79  	if pb.Multiaccount != nil {
    80  		ppm.multiaccountFromProtobuf(pb.Multiaccount)
    81  	}
    82  	ppm.password = pb.Password
    83  	ppm.chatKey = pb.ChatKey
    84  
    85  	return nil
    86  }
    87  
    88  func (ppm *AccountPayloadMarshaller) accountKeysFromProtobuf(pbKeys []*protobuf.LocalPairingPayload_Key) {
    89  	l := ppm.logger.Named("accountKeysFromProtobuf()")
    90  	l.Debug("fired")
    91  
    92  	if ppm.keys == nil {
    93  		ppm.keys = make(map[string][]byte)
    94  	}
    95  
    96  	for _, key := range pbKeys {
    97  		ppm.keys[key.Name] = key.Data
    98  	}
    99  	l.Debug(
   100  		"after for _, key := range pbKeys",
   101  		zap.Any("pbKeys", pbKeys),
   102  		zap.Any("accountPayloadMarshaller.keys", ppm.keys),
   103  	)
   104  }
   105  
   106  func (ppm *AccountPayloadMarshaller) multiaccountFromProtobuf(pbMultiAccount *protobuf.MultiAccount) {
   107  	ppm.multiaccount = new(multiaccounts.Account)
   108  	ppm.multiaccount.FromProtobuf(pbMultiAccount)
   109  }
   110  
   111  type RawMessagesPayload struct {
   112  	rawMessages    []*protobuf.RawMessage
   113  	profileKeypair *accounts.Keypair
   114  	setting        *settings.Settings
   115  }
   116  
   117  func NewRawMessagesPayload() *RawMessagesPayload {
   118  	return &RawMessagesPayload{
   119  		setting: new(settings.Settings),
   120  	}
   121  }
   122  
   123  // RawMessagePayloadMarshaller is responsible for marshalling and unmarshalling raw message data
   124  type RawMessagePayloadMarshaller struct {
   125  	payload *RawMessagesPayload
   126  }
   127  
   128  func NewRawMessagePayloadMarshaller(payload *RawMessagesPayload) *RawMessagePayloadMarshaller {
   129  	return &RawMessagePayloadMarshaller{
   130  		payload: payload,
   131  	}
   132  }
   133  
   134  func (rmm *RawMessagePayloadMarshaller) MarshalProtobuf() (data []byte, err error) {
   135  	syncRawMessage := new(protobuf.SyncRawMessage)
   136  
   137  	syncRawMessage.RawMessages = rmm.payload.rawMessages
   138  	if rmm.payload.profileKeypair != nil && len(rmm.payload.profileKeypair.KeyUID) > 0 {
   139  		syncRawMessage.SubAccountsJsonBytes, err = json.Marshal(rmm.payload.profileKeypair)
   140  		if err != nil {
   141  			return nil, err
   142  		}
   143  	}
   144  	if !rmm.payload.setting.IsEmpty() {
   145  		syncRawMessage.SettingsJsonBytes, err = json.Marshal(rmm.payload.setting)
   146  		if err != nil {
   147  			return nil, err
   148  		}
   149  	}
   150  
   151  	return proto.Marshal(syncRawMessage)
   152  }
   153  
   154  func (rmm *RawMessagePayloadMarshaller) UnmarshalProtobuf(data []byte) error {
   155  	syncRawMessage := new(protobuf.SyncRawMessage)
   156  	err := proto.Unmarshal(data, syncRawMessage)
   157  	if err != nil {
   158  		return err
   159  	}
   160  	if syncRawMessage.SubAccountsJsonBytes != nil {
   161  		err = json.Unmarshal(syncRawMessage.SubAccountsJsonBytes, &rmm.payload.profileKeypair)
   162  		if err != nil {
   163  			return err
   164  		}
   165  	}
   166  	if syncRawMessage.SettingsJsonBytes != nil {
   167  		err = json.Unmarshal(syncRawMessage.SettingsJsonBytes, rmm.payload.setting)
   168  		if err != nil {
   169  			return err
   170  		}
   171  	}
   172  
   173  	rmm.payload.rawMessages = syncRawMessage.RawMessages
   174  	return nil
   175  }
   176  
   177  // InstallationPayloadMounterReceiver represents an InstallationPayload Repository
   178  type InstallationPayloadMounterReceiver struct {
   179  	PayloadMounter
   180  	PayloadReceiver
   181  }
   182  
   183  func NewInstallationPayloadMounterReceiver(encryptor *PayloadEncryptor, backend *api.GethStatusBackend, deviceType string) *InstallationPayloadMounterReceiver {
   184  	return &InstallationPayloadMounterReceiver{
   185  		NewInstallationPayloadMounter(encryptor, backend, deviceType),
   186  		NewInstallationPayloadReceiver(encryptor, backend, deviceType),
   187  	}
   188  }
   189  
   190  func (i *InstallationPayloadMounterReceiver) LockPayload() {
   191  	i.PayloadMounter.LockPayload()
   192  	i.PayloadReceiver.LockPayload()
   193  }