github.com/status-im/status-go@v1.1.0/server/pairing/payload_mounter.go (about) 1 package pairing 2 3 import ( 4 "fmt" 5 "strings" 6 7 "go.uber.org/zap" 8 9 "github.com/status-im/status-go/api" 10 "github.com/status-im/status-go/multiaccounts" 11 "github.com/status-im/status-go/multiaccounts/accounts" 12 ) 13 14 type PayloadMounter interface { 15 PayloadLocker 16 17 // Mount Loads the payload into the PayloadManager's state 18 Mount() error 19 20 // ToSend returns an outbound safe (encrypted) payload 21 ToSend() []byte 22 } 23 24 type PayloadLoader interface { 25 Load() error 26 } 27 28 type BasePayloadMounter struct { 29 *PayloadLockPayload 30 *PayloadToSend 31 32 loader PayloadLoader 33 marshaller ProtobufMarshaller 34 encryptor *PayloadEncryptor 35 } 36 37 func NewBasePayloadMounter(loader PayloadLoader, marshaller ProtobufMarshaller, e *PayloadEncryptor) *BasePayloadMounter { 38 return &BasePayloadMounter{ 39 PayloadLockPayload: &PayloadLockPayload{e}, 40 PayloadToSend: &PayloadToSend{e}, 41 loader: loader, 42 marshaller: marshaller, 43 encryptor: e, 44 } 45 } 46 47 // Mount loads and prepares the payload to be stored in the PayloadLoader's state ready for later access 48 func (bpm *BasePayloadMounter) Mount() error { 49 err := bpm.loader.Load() 50 if err != nil { 51 return err 52 } 53 54 p, err := bpm.marshaller.MarshalProtobuf() 55 if err != nil { 56 return err 57 } 58 59 return bpm.encryptor.encrypt(p) 60 } 61 62 /* 63 |-------------------------------------------------------------------------- 64 | AccountPayload 65 |-------------------------------------------------------------------------- 66 | 67 | AccountPayloadMounter, AccountPayloadLoader and AccountPayloadMarshaller 68 | 69 */ 70 71 // NewAccountPayloadMounter generates a new and initialised AccountPayload flavoured BasePayloadMounter 72 // responsible for the whole lifecycle of an AccountPayload 73 func NewAccountPayloadMounter(pe *PayloadEncryptor, config *SenderConfig, logger *zap.Logger) (*BasePayloadMounter, error) { 74 l := logger.Named("AccountPayloadLoader") 75 l.Debug("fired", zap.Any("config", config)) 76 77 pe = pe.Renew() 78 79 // A new SHARED AccountPayload 80 p := new(AccountPayload) 81 apl, err := NewAccountPayloadLoader(p, config) 82 if err != nil { 83 return nil, err 84 } 85 86 return NewBasePayloadMounter( 87 apl, 88 NewPairingPayloadMarshaller(p, l), 89 pe, 90 ), nil 91 } 92 93 // AccountPayloadLoader is responsible for loading, parsing and validating AccountPayload data 94 type AccountPayloadLoader struct { 95 *AccountPayload 96 97 multiaccountsDB *multiaccounts.Database 98 keystorePath string 99 keyUID string 100 } 101 102 func NewAccountPayloadLoader(p *AccountPayload, config *SenderConfig) (*AccountPayloadLoader, error) { 103 ppr := &AccountPayloadLoader{ 104 AccountPayload: p, 105 } 106 107 if config == nil { 108 return ppr, nil 109 } 110 111 ppr.multiaccountsDB = config.DB 112 ppr.keyUID = config.KeyUID 113 ppr.password = config.Password 114 ppr.chatKey = config.ChatKey 115 ppr.keystorePath = config.KeystorePath 116 return ppr, nil 117 } 118 119 func (apl *AccountPayloadLoader) Load() error { 120 apl.keys = make(map[string][]byte) 121 err := loadKeys(apl.keys, apl.keystorePath) 122 if err != nil { 123 return err 124 } 125 126 err = validateKeys(apl.keys, apl.password) 127 if err != nil { 128 return err 129 } 130 131 apl.multiaccount, err = apl.multiaccountsDB.GetAccount(apl.keyUID) 132 if err != nil { 133 return err 134 } 135 136 return nil 137 } 138 139 /* 140 |-------------------------------------------------------------------------- 141 | RawMessagePayload 142 |-------------------------------------------------------------------------- 143 | 144 | RawMessagePayloadMounter and RawMessageLoader 145 | 146 */ 147 148 // NewRawMessagePayloadMounter generates a new and initialised RawMessagePayload flavoured BasePayloadMounter 149 // responsible for the whole lifecycle of an RawMessagePayload 150 func NewRawMessagePayloadMounter(logger *zap.Logger, pe *PayloadEncryptor, backend *api.GethStatusBackend, config *SenderConfig) *BasePayloadMounter { 151 pe = pe.Renew() 152 payload := NewRawMessagesPayload() 153 154 return NewBasePayloadMounter( 155 NewRawMessageLoader(backend, payload, config), 156 NewRawMessagePayloadMarshaller(payload), 157 pe, 158 ) 159 } 160 161 type RawMessageLoader struct { 162 payload *RawMessagesPayload 163 syncRawMessageHandler *SyncRawMessageHandler 164 keyUID string 165 deviceType string 166 } 167 168 func NewRawMessageLoader(backend *api.GethStatusBackend, payload *RawMessagesPayload, config *SenderConfig) *RawMessageLoader { 169 return &RawMessageLoader{ 170 syncRawMessageHandler: NewSyncRawMessageHandler(backend), 171 payload: payload, 172 keyUID: config.KeyUID, 173 deviceType: config.DeviceType, 174 } 175 } 176 177 func (r *RawMessageLoader) Load() (err error) { 178 r.payload.rawMessages, r.payload.profileKeypair, r.payload.setting, err = r.syncRawMessageHandler.PrepareRawMessage(r.keyUID, r.deviceType) 179 return err 180 } 181 182 /* 183 |-------------------------------------------------------------------------- 184 | InstallationPayload 185 |-------------------------------------------------------------------------- 186 | 187 | InstallationPayloadMounter and InstallationPayloadLoader 188 | 189 */ 190 191 // NewInstallationPayloadMounter generates a new and initialised InstallationPayload flavoured BasePayloadMounter 192 // responsible for the whole lifecycle of an InstallationPayload 193 func NewInstallationPayloadMounter(pe *PayloadEncryptor, backend *api.GethStatusBackend, deviceType string) *BasePayloadMounter { 194 pe = pe.Renew() 195 payload := NewRawMessagesPayload() 196 197 return NewBasePayloadMounter( 198 NewInstallationPayloadLoader(backend, payload, deviceType), 199 NewRawMessagePayloadMarshaller(payload), 200 pe, 201 ) 202 } 203 204 type InstallationPayloadLoader struct { 205 payload *RawMessagesPayload 206 syncRawMessageHandler *SyncRawMessageHandler 207 deviceType string 208 } 209 210 func NewInstallationPayloadLoader(backend *api.GethStatusBackend, payload *RawMessagesPayload, deviceType string) *InstallationPayloadLoader { 211 return &InstallationPayloadLoader{ 212 payload: payload, 213 syncRawMessageHandler: NewSyncRawMessageHandler(backend), 214 deviceType: deviceType, 215 } 216 } 217 218 func (r *InstallationPayloadLoader) Load() error { 219 rawMessageCollector := new(RawMessageCollector) 220 err := r.syncRawMessageHandler.CollectInstallationData(rawMessageCollector, r.deviceType) 221 if err != nil { 222 return err 223 } 224 rms := rawMessageCollector.convertToSyncRawMessage() 225 r.payload.rawMessages = rms.RawMessages 226 return nil 227 } 228 229 /* 230 |-------------------------------------------------------------------------- 231 | PayloadMounters 232 |-------------------------------------------------------------------------- 233 | 234 | Funcs for all PayloadMounters AccountPayloadMounter, RawMessagePayloadMounter and InstallationPayloadMounter 235 | 236 */ 237 238 // NewPayloadMounters returns PayloadMounter s configured to handle local pairing transfers of: 239 // - AccountPayload, RawMessagePayload and InstallationPayload 240 func NewPayloadMounters(logger *zap.Logger, pe *PayloadEncryptor, backend *api.GethStatusBackend, config *SenderConfig) (PayloadMounter, PayloadMounter, PayloadMounterReceiver, error) { 241 am, err := NewAccountPayloadMounter(pe, config, logger) 242 if err != nil { 243 return nil, nil, nil, err 244 } 245 rmm := NewRawMessagePayloadMounter(logger, pe, backend, config) 246 imr := NewInstallationPayloadMounterReceiver(pe, backend, config.DeviceType) 247 return am, rmm, imr, nil 248 } 249 250 /* 251 |-------------------------------------------------------------------------- 252 | KeystoreFilesPayload 253 |-------------------------------------------------------------------------- 254 */ 255 256 func NewKeystoreFilesPayloadMounter(backend *api.GethStatusBackend, pe *PayloadEncryptor, config *KeystoreFilesSenderConfig, logger *zap.Logger) (*BasePayloadMounter, error) { 257 l := logger.Named("KeystoreFilesPayloadLoader") 258 l.Debug("fired", zap.Any("config", config)) 259 260 pe = pe.Renew() 261 262 // A new SHARED AccountPayload 263 p := new(AccountPayload) 264 kfpl, err := NewKeystoreFilesPayloadLoader(backend, p, config) 265 if err != nil { 266 return nil, err 267 } 268 269 return NewBasePayloadMounter( 270 kfpl, 271 NewPairingPayloadMarshaller(p, l), 272 pe, 273 ), nil 274 } 275 276 type KeystoreFilesPayloadLoader struct { 277 *AccountPayload 278 279 keystorePath string 280 loggedInKeyUID string 281 keystoreFilesToTransfer []string 282 } 283 284 func NewKeystoreFilesPayloadLoader(backend *api.GethStatusBackend, p *AccountPayload, config *KeystoreFilesSenderConfig) (*KeystoreFilesPayloadLoader, error) { 285 if config == nil { 286 return nil, fmt.Errorf("empty keystore files sender config") 287 } 288 289 kfpl := &KeystoreFilesPayloadLoader{ 290 AccountPayload: p, 291 keystorePath: config.KeystorePath, 292 loggedInKeyUID: config.LoggedInKeyUID, 293 } 294 295 kfpl.password = config.Password 296 297 accountService := backend.StatusNode().AccountService() 298 299 for _, keyUID := range config.KeypairsToExport { 300 kp, err := accountService.GetKeypairByKeyUID(keyUID) 301 if err != nil { 302 return nil, err 303 } 304 305 if kp.Type == accounts.KeypairTypeSeed { 306 kfpl.keystoreFilesToTransfer = append(kfpl.keystoreFilesToTransfer, kp.DerivedFrom[2:]) 307 } 308 309 for _, acc := range kp.Accounts { 310 kfpl.keystoreFilesToTransfer = append(kfpl.keystoreFilesToTransfer, acc.Address.Hex()[2:]) 311 } 312 } 313 314 return kfpl, nil 315 } 316 317 func (kfpl *KeystoreFilesPayloadLoader) Load() error { 318 kfpl.keys = make(map[string][]byte) 319 err := loadKeys(kfpl.keys, kfpl.keystorePath) 320 if err != nil { 321 return err 322 } 323 324 // Create a new map to filter keys 325 filteredMap := make(map[string][]byte) 326 for _, searchKey := range kfpl.keystoreFilesToTransfer { 327 for key, value := range kfpl.keys { 328 if strings.Contains(key, strings.ToLower(searchKey)) { 329 filteredMap[key] = value 330 break 331 } 332 } 333 } 334 335 kfpl.keys = filteredMap 336 337 return validateKeys(kfpl.keys, kfpl.password) 338 }