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 }