Allow multiple bundles, change n devices & bundle refresh (#1331)

Change to support sending multiple bundles, as needed for group chats,
limit number of devices to 3 as already done in the UI and refresh
bundle daily.
This commit is contained in:
Andrea Maria Piana 2018-12-21 11:07:25 +01:00 committed by GitHub
parent 5e1f4631b1
commit 3292538b41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 92 additions and 78 deletions

View File

@ -488,29 +488,19 @@ func (api *PublicAPI) SendGroupMessage(ctx context.Context, msg chat.SendGroupMe
}
func (api *PublicAPI) processPFSMessage(msg *whisper.Message) error {
var privateKey *ecdsa.PrivateKey
var publicKey *ecdsa.PublicKey
// Msg.Dst is empty is a public message, nothing to do
if msg.Dst != nil {
// There's probably a better way to do this
keyBytes, err := hexutil.Bytes(msg.Dst).MarshalText()
if err != nil {
return err
}
privateKey, err = api.service.w.GetPrivateKey(string(keyBytes))
if err != nil {
return err
}
// This needs to be pushed down in the protocol message
publicKey, err = crypto.UnmarshalPubkey(msg.Sig)
if err != nil {
return err
}
privateKeyID := api.service.w.SelectedKeyPairID()
if privateKeyID == "" {
return errors.New("no key selected")
}
privateKey, err := api.service.w.GetPrivateKey(privateKeyID)
if err != nil {
return err
}
var publicKey *ecdsa.PublicKey
response, err := api.service.protocol.HandleMessage(privateKey, publicKey, msg.Payload)
// Notify that someone tried to contact us using an invalid bundle

View File

@ -50,11 +50,11 @@ type IdentityAndIDPair [2]string
// DefaultEncryptionServiceConfig returns the default values used by the encryption service
func DefaultEncryptionServiceConfig(installationID string) EncryptionServiceConfig {
return EncryptionServiceConfig{
MaxInstallations: 5,
MaxInstallations: 3,
MaxSkip: 1000,
MaxKeep: 3000,
MaxMessageKeysPerSession: 2000,
BundleRefreshInterval: 6 * 60 * 60 * 1000,
BundleRefreshInterval: 24 * 60 * 60 * 1000,
InstallationID: installationID,
}
}

View File

@ -411,6 +411,8 @@ type ProtocolMessage struct {
Bundle *Bundle `protobuf:"bytes,1,opt,name=bundle,proto3" json:"bundle,omitempty"`
// The device id of the sender
InstallationId string `protobuf:"bytes,2,opt,name=installation_id,json=installationId,proto3" json:"installation_id,omitempty"`
// List of bundles
Bundles []*Bundle `protobuf:"bytes,3,rep,name=bundles,proto3" json:"bundles,omitempty"`
// One to one message, encrypted, indexed by installation_id
DirectMessage map[string]*DirectMessageProtocol `protobuf:"bytes,101,rep,name=direct_message,json=directMessage,proto3" json:"direct_message,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
// Public chats, not encrypted
@ -459,6 +461,13 @@ func (m *ProtocolMessage) GetInstallationId() string {
return ""
}
func (m *ProtocolMessage) GetBundles() []*Bundle {
if m != nil {
return m.Bundles
}
return nil
}
func (m *ProtocolMessage) GetDirectMessage() map[string]*DirectMessageProtocol {
if m != nil {
return m.DirectMessage
@ -489,39 +498,40 @@ func init() {
func init() { proto.RegisterFile("encryption.proto", fileDescriptor_8293a649ce9418c6) }
var fileDescriptor_8293a649ce9418c6 = []byte{
// 535 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0x5d, 0x8b, 0xd3, 0x40,
0x14, 0x25, 0x69, 0xb7, 0xdb, 0xde, 0xa6, 0x69, 0x19, 0x51, 0x42, 0x5d, 0xb0, 0x84, 0x15, 0x03,
0x42, 0x61, 0x5b, 0x1f, 0xc4, 0x47, 0xad, 0x58, 0x57, 0xd4, 0x65, 0xf4, 0xc1, 0x17, 0x09, 0xd3,
0xe6, 0xba, 0x3b, 0x98, 0x4e, 0xc2, 0x64, 0x5a, 0xe8, 0x2f, 0xf3, 0xcd, 0xbf, 0xa6, 0x64, 0x26,
0x69, 0xa7, 0xdd, 0x5d, 0xd8, 0xb7, 0xde, 0x8f, 0x39, 0xe7, 0xdc, 0x73, 0x7b, 0x03, 0x03, 0x14,
0x4b, 0xb9, 0xcd, 0x15, 0xcf, 0xc4, 0x38, 0x97, 0x99, 0xca, 0x48, 0x73, 0x79, 0xc3, 0x54, 0xf8,
0x05, 0xbc, 0x6f, 0xfc, 0x5a, 0x60, 0x72, 0x25, 0xf1, 0x13, 0x6e, 0xc9, 0x39, 0xf8, 0x85, 0x8e,
0xe3, 0x5c, 0x62, 0xfc, 0x1b, 0xb7, 0x81, 0x33, 0x72, 0x22, 0x8f, 0x7a, 0x85, 0xdd, 0x15, 0xc0,
0xe9, 0x06, 0x65, 0xc1, 0x33, 0x11, 0xb8, 0x23, 0x27, 0xea, 0xd1, 0x3a, 0x0c, 0xff, 0x39, 0xd0,
0x7a, 0xbb, 0x16, 0x49, 0x8a, 0x64, 0x08, 0x6d, 0x9e, 0xa0, 0x50, 0x5c, 0xd5, 0x20, 0xbb, 0x98,
0x7c, 0x80, 0xfe, 0x21, 0x4d, 0x11, 0xb8, 0xa3, 0x46, 0xd4, 0x9d, 0x3c, 0x1b, 0x97, 0xb2, 0xc6,
0x06, 0x62, 0x6c, 0x4b, 0x2b, 0xde, 0x0b, 0x25, 0xb7, 0xb4, 0x67, 0x0b, 0x29, 0xc8, 0x19, 0x74,
0xca, 0x04, 0x53, 0x6b, 0x89, 0x41, 0x53, 0xb3, 0xec, 0x13, 0x65, 0x55, 0xf1, 0x15, 0x16, 0x8a,
0xad, 0xf2, 0xe0, 0x64, 0xe4, 0x44, 0x0d, 0xba, 0x4f, 0x0c, 0xbf, 0x03, 0xb9, 0x4d, 0x40, 0x06,
0xd0, 0xa8, 0xc7, 0xee, 0xd0, 0xf2, 0x27, 0x89, 0xe0, 0x64, 0xc3, 0xd2, 0x35, 0xea, 0x59, 0xbb,
0x13, 0x62, 0x24, 0xda, 0x4f, 0xa9, 0x69, 0x78, 0xe3, 0xbe, 0x76, 0x42, 0x09, 0x7d, 0xa3, 0xfe,
0x5d, 0x26, 0x14, 0xe3, 0x02, 0x25, 0x39, 0x87, 0xd6, 0x42, 0xa7, 0x34, 0x6a, 0x77, 0xe2, 0xd9,
0x43, 0xd2, 0xaa, 0x46, 0xa6, 0xf0, 0x24, 0x97, 0x7c, 0xc3, 0x14, 0xc6, 0x47, 0x2b, 0x70, 0xf5,
0x5c, 0x8f, 0xaa, 0xaa, 0x4d, 0x7c, 0xd9, 0x6c, 0x37, 0x06, 0xcd, 0xf0, 0x12, 0xda, 0x33, 0x3a,
0x47, 0x96, 0xa0, 0xb4, 0xf5, 0x7b, 0x46, 0xbf, 0x07, 0x4e, 0xbd, 0x27, 0x47, 0x10, 0x1f, 0xdc,
0x5c, 0x04, 0x0d, 0x1d, 0xba, 0xb9, 0x8e, 0x79, 0x52, 0x59, 0xe7, 0xf2, 0x24, 0x3c, 0x83, 0xf6,
0x6c, 0x7e, 0x1f, 0x56, 0xf8, 0x0a, 0xe0, 0xc7, 0xf4, 0xfe, 0xfa, 0x31, 0x5a, 0xa5, 0xef, 0xaf,
0x03, 0x8f, 0x67, 0x5c, 0xe2, 0x52, 0x7d, 0xc6, 0xa2, 0x60, 0xd7, 0x78, 0x55, 0xfe, 0x05, 0x97,
0x59, 0x4a, 0x2e, 0xa0, 0x5b, 0xe2, 0xc5, 0x37, 0x1a, 0xb0, 0xf2, 0x67, 0x60, 0xfc, 0xd9, 0x13,
0x51, 0x9b, 0xf4, 0x25, 0x74, 0x66, 0xb4, 0x7e, 0x60, 0x56, 0xe2, 0x9b, 0x07, 0xb5, 0x07, 0x74,
0xef, 0x46, 0xd9, 0xbc, 0x43, 0xc7, 0x83, 0xe6, 0xf9, 0xae, 0xb9, 0x46, 0x0e, 0xe0, 0x34, 0x67,
0xdb, 0x34, 0x63, 0x89, 0xf6, 0xc7, 0xa3, 0x75, 0x18, 0xfe, 0x71, 0xa1, 0x5f, 0x6b, 0xae, 0x46,
0x78, 0xe0, 0x56, 0x5f, 0x40, 0x9f, 0x8b, 0x42, 0xb1, 0x34, 0x65, 0xe5, 0xf1, 0xc5, 0x3c, 0xd1,
0x9a, 0x3b, 0xd4, 0xb7, 0xd3, 0x1f, 0x13, 0xf2, 0x15, 0xfc, 0x44, 0x5b, 0x14, 0xaf, 0x0c, 0x41,
0x80, 0xfa, 0x22, 0x22, 0x03, 0x7b, 0xc4, 0x3e, 0x3e, 0xb0, 0xb3, 0x3a, 0x8d, 0xc4, 0xce, 0x91,
0xe7, 0xe0, 0xe7, 0xeb, 0x45, 0xca, 0x97, 0x3b, 0xc0, 0x5f, 0x7a, 0xa8, 0x9e, 0xc9, 0x56, 0x6d,
0xc3, 0x9f, 0x40, 0x6e, 0x63, 0xdd, 0x71, 0x05, 0x17, 0x87, 0x57, 0xf0, 0xb4, 0x72, 0xf1, 0xae,
0xad, 0x5a, 0xe7, 0xb0, 0x68, 0xe9, 0xaf, 0xcd, 0xf4, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xed,
0x53, 0xaf, 0x00, 0x81, 0x04, 0x00, 0x00,
// 548 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0x51, 0x8b, 0xd3, 0x40,
0x10, 0x26, 0x49, 0xef, 0xae, 0x9d, 0xe6, 0xd2, 0xb2, 0xa2, 0x84, 0x7a, 0x60, 0x09, 0xa7, 0x06,
0x84, 0xc2, 0xb5, 0x3e, 0x88, 0x8f, 0x5a, 0xb1, 0x9e, 0xa8, 0xc7, 0xea, 0x83, 0x2f, 0x12, 0xb6,
0xdd, 0xf5, 0x6e, 0x31, 0xdd, 0x84, 0xdd, 0x6d, 0xa1, 0x7f, 0xce, 0xbf, 0xe2, 0x4f, 0x51, 0xb2,
0x9b, 0xb4, 0xdb, 0xde, 0x1d, 0xf8, 0xd6, 0x99, 0xf9, 0xf6, 0x9b, 0x6f, 0xbe, 0xe9, 0x04, 0xfa,
0x4c, 0x2c, 0xe4, 0xa6, 0xd4, 0xbc, 0x10, 0xa3, 0x52, 0x16, 0xba, 0x40, 0xad, 0xc5, 0x0d, 0xd1,
0xc9, 0x67, 0x08, 0xbf, 0xf2, 0x6b, 0xc1, 0xe8, 0x95, 0x64, 0x1f, 0xd9, 0x06, 0x9d, 0x43, 0xa4,
0x4c, 0x9c, 0x95, 0x92, 0x65, 0xbf, 0xd8, 0x26, 0xf6, 0x86, 0x5e, 0x1a, 0xe2, 0x50, 0xb9, 0xa8,
0x18, 0x4e, 0xd6, 0x4c, 0x2a, 0x5e, 0x88, 0xd8, 0x1f, 0x7a, 0xe9, 0x29, 0x6e, 0xc2, 0xe4, 0xaf,
0x07, 0xc7, 0x6f, 0x56, 0x82, 0xe6, 0x0c, 0x0d, 0xa0, 0xcd, 0x29, 0x13, 0x9a, 0xeb, 0x86, 0x64,
0x1b, 0xa3, 0xf7, 0xd0, 0xdb, 0x6f, 0xa3, 0x62, 0x7f, 0x18, 0xa4, 0xdd, 0xf1, 0x93, 0x51, 0x25,
0x6b, 0x64, 0x29, 0x46, 0xae, 0x34, 0xf5, 0x4e, 0x68, 0xb9, 0xc1, 0xa7, 0xae, 0x10, 0x85, 0xce,
0xa0, 0x53, 0x25, 0x88, 0x5e, 0x49, 0x16, 0xb7, 0x4c, 0x97, 0x5d, 0xa2, 0xaa, 0x6a, 0xbe, 0x64,
0x4a, 0x93, 0x65, 0x19, 0x1f, 0x0d, 0xbd, 0x34, 0xc0, 0xbb, 0xc4, 0xe0, 0x1b, 0xa0, 0xdb, 0x0d,
0x50, 0x1f, 0x82, 0x66, 0xec, 0x0e, 0xae, 0x7e, 0xa2, 0x14, 0x8e, 0xd6, 0x24, 0x5f, 0x31, 0x33,
0x6b, 0x77, 0x8c, 0xac, 0x44, 0xf7, 0x29, 0xb6, 0x80, 0xd7, 0xfe, 0x2b, 0x2f, 0x91, 0xd0, 0xb3,
0xea, 0xdf, 0x16, 0x42, 0x13, 0x2e, 0x98, 0x44, 0xe7, 0x70, 0x3c, 0x37, 0x29, 0xc3, 0xda, 0x1d,
0x87, 0xee, 0x90, 0xb8, 0xae, 0xa1, 0x09, 0x3c, 0x2a, 0x25, 0x5f, 0x13, 0xcd, 0xb2, 0x83, 0x15,
0xf8, 0x66, 0xae, 0x07, 0x75, 0xd5, 0x6d, 0x7c, 0xd9, 0x6a, 0x07, 0xfd, 0x56, 0x72, 0x09, 0xed,
0x29, 0x9e, 0x31, 0x42, 0x99, 0x74, 0xf5, 0x87, 0x56, 0x7f, 0x08, 0x5e, 0xb3, 0x27, 0x4f, 0xa0,
0x08, 0xfc, 0x52, 0xc4, 0x81, 0x09, 0xfd, 0xd2, 0xc4, 0x9c, 0xd6, 0xd6, 0xf9, 0x9c, 0x26, 0x67,
0xd0, 0x9e, 0xce, 0xee, 0xe3, 0x4a, 0x5e, 0x02, 0x7c, 0x9f, 0xdc, 0x5f, 0x3f, 0x64, 0xab, 0xf5,
0xfd, 0xf6, 0xe0, 0xe1, 0x94, 0x4b, 0xb6, 0xd0, 0x9f, 0x98, 0x52, 0xe4, 0x9a, 0x5d, 0x55, 0x7f,
0xc1, 0x45, 0x91, 0xa3, 0x0b, 0xe8, 0x56, 0x7c, 0xd9, 0x8d, 0x21, 0xac, 0xfd, 0xe9, 0x5b, 0x7f,
0x76, 0x8d, 0xb0, 0xdb, 0xf4, 0x05, 0x74, 0xa6, 0xb8, 0x79, 0x60, 0x57, 0x12, 0xd9, 0x07, 0x8d,
0x07, 0x78, 0xe7, 0x46, 0x05, 0xde, 0xb2, 0xb3, 0x3d, 0xf0, 0x6c, 0x0b, 0x6e, 0x98, 0x63, 0x38,
0x29, 0xc9, 0x26, 0x2f, 0x08, 0x35, 0xfe, 0x84, 0xb8, 0x09, 0x93, 0x3f, 0x3e, 0xf4, 0x1a, 0xcd,
0xf5, 0x08, 0xff, 0xb9, 0xd5, 0xe7, 0xd0, 0xe3, 0x42, 0x69, 0x92, 0xe7, 0xa4, 0x3a, 0xbe, 0x8c,
0x53, 0xa3, 0xb9, 0x83, 0x23, 0x37, 0xfd, 0x81, 0xa2, 0x67, 0x70, 0x62, 0x9f, 0xa8, 0x38, 0x30,
0xa7, 0xb0, 0xcf, 0xd7, 0x14, 0xd1, 0x17, 0x88, 0xa8, 0xb1, 0x32, 0x5b, 0x5a, 0x21, 0x31, 0x33,
0xf0, 0xd4, 0xc2, 0x0f, 0x54, 0x8e, 0xf6, 0x6c, 0xaf, 0x4f, 0x88, 0xba, 0x39, 0xf4, 0x14, 0xa2,
0x72, 0x35, 0xcf, 0xf9, 0x62, 0x4b, 0xf8, 0xd3, 0x0c, 0x7f, 0x6a, 0xb3, 0x35, 0x6c, 0xf0, 0x03,
0xd0, 0x6d, 0xae, 0x3b, 0xae, 0xe5, 0x62, 0xff, 0x5a, 0x1e, 0xd7, 0x6e, 0xdf, 0xb5, 0x7d, 0xe7,
0x6c, 0xe6, 0xc7, 0xe6, 0xab, 0x34, 0xf9, 0x17, 0x00, 0x00, 0xff, 0xff, 0x54, 0xd8, 0xdf, 0x09,
0xa9, 0x04, 0x00, 0x00,
}

View File

@ -69,6 +69,9 @@ message ProtocolMessage {
// The device id of the sender
string installation_id = 2;
// List of bundles
repeated Bundle bundles = 3;
// One to one message, encrypted, indexed by installation_id
map<string,DirectMessageProtocol> direct_message = 101;

View File

@ -91,7 +91,7 @@ func _1536754952_initial_schemaDownSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1536754952_initial_schema.down.sql", size: 83, mode: os.FileMode(420), modTime: time.Unix(1539606161, 0)}
info := bindataFileInfo{name: "1536754952_initial_schema.down.sql", size: 83, mode: os.FileMode(420), modTime: time.Unix(1541418081, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -111,7 +111,7 @@ func _1536754952_initial_schemaUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1536754952_initial_schema.up.sql", size: 962, mode: os.FileMode(420), modTime: time.Unix(1539606161, 0)}
info := bindataFileInfo{name: "1536754952_initial_schema.up.sql", size: 962, mode: os.FileMode(420), modTime: time.Unix(1541418081, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -131,7 +131,7 @@ func _1539249977_update_ratchet_infoDownSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1539249977_update_ratchet_info.down.sql", size: 311, mode: os.FileMode(420), modTime: time.Unix(1540738831, 0)}
info := bindataFileInfo{name: "1539249977_update_ratchet_info.down.sql", size: 311, mode: os.FileMode(420), modTime: time.Unix(1543402727, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -151,7 +151,7 @@ func _1539249977_update_ratchet_infoUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1539249977_update_ratchet_info.up.sql", size: 368, mode: os.FileMode(420), modTime: time.Unix(1540738831, 0)}
info := bindataFileInfo{name: "1539249977_update_ratchet_info.up.sql", size: 368, mode: os.FileMode(420), modTime: time.Unix(1543402727, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -171,7 +171,7 @@ func _1540715431_add_versionDownSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1540715431_add_version.down.sql", size: 127, mode: os.FileMode(420), modTime: time.Unix(1541170185, 0)}
info := bindataFileInfo{name: "1540715431_add_version.down.sql", size: 127, mode: os.FileMode(420), modTime: time.Unix(1543402867, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -191,7 +191,7 @@ func _1540715431_add_versionUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1540715431_add_version.up.sql", size: 265, mode: os.FileMode(420), modTime: time.Unix(1541170185, 0)}
info := bindataFileInfo{name: "1540715431_add_version.up.sql", size: 265, mode: os.FileMode(420), modTime: time.Unix(1543402867, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -211,7 +211,7 @@ func _1541164797_add_installationsDownSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1541164797_add_installations.down.sql", size: 26, mode: os.FileMode(420), modTime: time.Unix(1541165366, 0)}
info := bindataFileInfo{name: "1541164797_add_installations.down.sql", size: 26, mode: os.FileMode(420), modTime: time.Unix(1543402888, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -231,7 +231,7 @@ func _1541164797_add_installationsUpSql() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "1541164797_add_installations.up.sql", size: 216, mode: os.FileMode(420), modTime: time.Unix(1541165467, 0)}
info := bindataFileInfo{name: "1541164797_add_installations.up.sql", size: 216, mode: os.FileMode(420), modTime: time.Unix(1543402888, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -251,7 +251,7 @@ func staticGo() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "static.go", size: 188, mode: os.FileMode(420), modTime: time.Unix(1539606161, 0)}
info := bindataFileInfo{name: "static.go", size: 188, mode: os.FileMode(420), modTime: time.Unix(1541418081, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}

View File

@ -32,7 +32,7 @@ func (p *ProtocolService) addBundleAndMarshal(myIdentityKey *ecdsa.PrivateKey, m
return nil, err
}
msg.Bundle = bundle
msg.Bundles = []*Bundle{bundle}
// marshal for sending to wire
marshaledMessage, err := proto.Marshal(msg)
@ -135,7 +135,7 @@ func (p *ProtocolService) HandleMessage(myIdentityKey *ecdsa.PrivateKey, theirPu
return nil, err
}
// Process bundle
// Process bundle, deprecated, here for backward compatibility
if bundle := protocolMessage.GetBundle(); bundle != nil {
// Should we stop processing if the bundle cannot be verified?
addedBundles, err := p.encryption.ProcessPublicBundle(myIdentityKey, bundle)
@ -146,6 +146,17 @@ func (p *ProtocolService) HandleMessage(myIdentityKey *ecdsa.PrivateKey, theirPu
p.addedBundlesHandler(addedBundles)
}
// Process bundles
for _, bundle := range protocolMessage.GetBundles() {
// Should we stop processing if the bundle cannot be verified?
addedBundles, err := p.encryption.ProcessPublicBundle(myIdentityKey, bundle)
if err != nil {
return nil, err
}
p.addedBundlesHandler(addedBundles)
}
// Check if it's a public message
if publicMessage := protocolMessage.GetPublicMessage(); publicMessage != nil {
// Nothing to do, as already in cleartext

View File

@ -69,7 +69,7 @@ func (s *ProtocolServiceTestSuite) TestBuildDirectMessage() {
s.NoError(err)
s.NotNilf(unmarshaledMsg.GetBundle(), "It adds a bundle to the message")
s.NotNilf(unmarshaledMsg.GetBundles(), "It adds a bundle to the message")
directMessage := unmarshaledMsg.GetDirectMessage()

File diff suppressed because one or more lines are too long