From 3c6b741f71fdcb42022e97de79eb1cb700facda1 Mon Sep 17 00:00:00 2001 From: Andrea Maria Piana Date: Mon, 7 Sep 2020 10:25:57 +0200 Subject: [PATCH] Add tests for send notification & review feedback --- VERSION | 2 +- protocol/chat.go | 6 +- protocol/common/message.go | 1 + protocol/message_handler.go | 6 +- protocol/messenger.go | 6 +- .../application_metadata_message.pb.go | 4 +- protocol/protobuf/group_chat_invitation.pb.go | 4 +- protocol/protobuf/pairing.pb.go | 4 +- protocol/protobuf/push_notifications.pb.go | 135 ++++++------ protocol/protobuf/push_notifications.proto | 1 + protocol/pushnotificationclient/client.go | 7 +- protocol/pushnotificationserver/server.go | 135 ++++++++---- .../pushnotificationserver/server_test.go | 207 ++++++++++++++++++ 13 files changed, 387 insertions(+), 131 deletions(-) diff --git a/VERSION b/VERSION index aba2fdc24..0b0945503 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.60.2 +0.61.0 diff --git a/protocol/chat.go b/protocol/chat.go index b02fc23a1..120100f80 100644 --- a/protocol/chat.go +++ b/protocol/chat.go @@ -117,9 +117,9 @@ func (c *Chat) MembersAsPublicKeys() ([]*ecdsa.PublicKey, error) { func (c *Chat) JoinedMembersAsPublicKeys() ([]*ecdsa.PublicKey, error) { var publicKeys []string - for _, item := range c.Members { - if item.Joined { - publicKeys = append(publicKeys, item.ID) + for _, member := range c.Members { + if member.Joined { + publicKeys = append(publicKeys, member.ID) } } return stringSliceToPublicKeys(publicKeys, true) diff --git a/protocol/common/message.go b/protocol/common/message.go index 51a031f77..7fba8393e 100644 --- a/protocol/common/message.go +++ b/protocol/common/message.go @@ -302,6 +302,7 @@ func (m *Message) parseAudio() error { return nil } +// implement interface of https://github.com/status-im/markdown/blob/b9fe921681227b1dace4b56364e15edb3b698308/ast/node.go#L701 type MentionNodeVisitor struct { mentions []string } diff --git a/protocol/message_handler.go b/protocol/message_handler.go index 574ccb393..2be57ae2c 100644 --- a/protocol/message_handler.go +++ b/protocol/message_handler.go @@ -248,11 +248,11 @@ func (m *MessageHandler) HandleSyncInstallationContact(state *ReceivedMessageSta return nil } -func (m *MessageHandler) HandleSyncInstallationPublicChat(state *ReceivedMessageState, message protobuf.SyncInstallationPublicChat) (bool, error) { +func (m *MessageHandler) HandleSyncInstallationPublicChat(state *ReceivedMessageState, message protobuf.SyncInstallationPublicChat) bool { chatID := message.Id _, ok := state.AllChats[chatID] if ok { - return false, nil + return false } chat := CreatePublicChat(chatID, state.Timesource) @@ -260,7 +260,7 @@ func (m *MessageHandler) HandleSyncInstallationPublicChat(state *ReceivedMessage state.AllChats[chat.ID] = &chat state.ModifiedChats[chat.ID] = true - return true, nil + return true } func (m *MessageHandler) HandleContactUpdate(state *ReceivedMessageState, message protobuf.ContactUpdate) error { diff --git a/protocol/messenger.go b/protocol/messenger.go index 147c9c0ee..e8cc759c1 100644 --- a/protocol/messenger.go +++ b/protocol/messenger.go @@ -2274,11 +2274,7 @@ func (m *Messenger) handleRetrievedMessages(chatWithMessages map[transport.Filte p := msg.ParsedMessage.Interface().(protobuf.SyncInstallationPublicChat) logger.Debug("Handling SyncInstallationPublicChat", zap.Any("message", p)) - added, err := m.handler.HandleSyncInstallationPublicChat(messageState, p) - if err != nil { - logger.Warn("failed to handle SyncInstallationPublicChat", zap.Error(err)) - continue - } + added := m.handler.HandleSyncInstallationPublicChat(messageState, p) // We re-register as we want to receive mentions from the newly joined public chat if added { diff --git a/protocol/protobuf/application_metadata_message.pb.go b/protocol/protobuf/application_metadata_message.pb.go index 378b07e1d..bb849a14c 100644 --- a/protocol/protobuf/application_metadata_message.pb.go +++ b/protocol/protobuf/application_metadata_message.pb.go @@ -174,9 +174,7 @@ func init() { proto.RegisterType((*ApplicationMetadataMessage)(nil), "protobuf.ApplicationMetadataMessage") } -func init() { - proto.RegisterFile("application_metadata_message.proto", fileDescriptor_ad09a6406fcf24c7) -} +func init() { proto.RegisterFile("application_metadata_message.proto", fileDescriptor_ad09a6406fcf24c7) } var fileDescriptor_ad09a6406fcf24c7 = []byte{ // 493 bytes of a gzipped FileDescriptorProto diff --git a/protocol/protobuf/group_chat_invitation.pb.go b/protocol/protobuf/group_chat_invitation.pb.go index b44a31b8e..548bdfbfe 100644 --- a/protocol/protobuf/group_chat_invitation.pb.go +++ b/protocol/protobuf/group_chat_invitation.pb.go @@ -123,9 +123,7 @@ func init() { proto.RegisterType((*GroupChatInvitation)(nil), "protobuf.GroupChatInvitation") } -func init() { - proto.RegisterFile("group_chat_invitation.proto", fileDescriptor_a6a73333de6a8ebe) -} +func init() { proto.RegisterFile("group_chat_invitation.proto", fileDescriptor_a6a73333de6a8ebe) } var fileDescriptor_a6a73333de6a8ebe = []byte{ // 234 bytes of a gzipped FileDescriptorProto diff --git a/protocol/protobuf/pairing.pb.go b/protocol/protobuf/pairing.pb.go index 8f85ad616..f8cc82f04 100644 --- a/protocol/protobuf/pairing.pb.go +++ b/protocol/protobuf/pairing.pb.go @@ -335,9 +335,7 @@ func init() { proto.RegisterType((*SyncInstallation)(nil), "protobuf.SyncInstallation") } -func init() { - proto.RegisterFile("pairing.proto", fileDescriptor_d61ab7221f0b5518) -} +func init() { proto.RegisterFile("pairing.proto", fileDescriptor_d61ab7221f0b5518) } var fileDescriptor_d61ab7221f0b5518 = []byte{ // 397 bytes of a gzipped FileDescriptorProto diff --git a/protocol/protobuf/push_notifications.pb.go b/protocol/protobuf/push_notifications.pb.go index bd636ac53..c518c228c 100644 --- a/protocol/protobuf/push_notifications.pb.go +++ b/protocol/protobuf/push_notifications.pb.go @@ -566,6 +566,7 @@ type PushNotification struct { InstallationId string `protobuf:"bytes,4,opt,name=installation_id,json=installationId,proto3" json:"installation_id,omitempty"` Message []byte `protobuf:"bytes,5,opt,name=message,proto3" json:"message,omitempty"` Type PushNotification_PushNotificationType `protobuf:"varint,6,opt,name=type,proto3,enum=protobuf.PushNotification_PushNotificationType" json:"type,omitempty"` + Author []byte `protobuf:"bytes,7,opt,name=author,proto3" json:"author,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -638,6 +639,13 @@ func (m *PushNotification) GetType() PushNotification_PushNotificationType { return PushNotification_UNKNOWN_PUSH_NOTIFICATION_TYPE } +func (m *PushNotification) GetAuthor() []byte { + if m != nil { + return m.Author + } + return nil +} + type PushNotificationRequest struct { Requests []*PushNotification `protobuf:"bytes,1,rep,name=requests,proto3" json:"requests,omitempty"` MessageId []byte `protobuf:"bytes,2,opt,name=message_id,json=messageId,proto3" json:"message_id,omitempty"` @@ -815,67 +823,68 @@ func init() { func init() { proto.RegisterFile("push_notifications.proto", fileDescriptor_200acd86044eaa5d) } var fileDescriptor_200acd86044eaa5d = []byte{ - // 990 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x4d, 0x6f, 0xe3, 0x44, - 0x18, 0xc6, 0x4e, 0xda, 0x24, 0x6f, 0xd2, 0xd4, 0x1d, 0xf5, 0xc3, 0x14, 0xba, 0x04, 0x03, 0x22, - 0xea, 0x21, 0xa0, 0x22, 0xb1, 0x2b, 0xb8, 0x10, 0x52, 0xa7, 0x6b, 0xb5, 0xb1, 0xc3, 0xc4, 0x65, - 0xb5, 0x12, 0xd2, 0xc8, 0xb1, 0x27, 0xad, 0x55, 0xd7, 0x36, 0x1e, 0xa7, 0x28, 0x37, 0x7e, 0x00, - 0x17, 0xae, 0x9c, 0xf8, 0x0d, 0xfc, 0x0d, 0xfe, 0x14, 0xf2, 0xd8, 0xce, 0xba, 0x8d, 0x9b, 0x16, - 0x69, 0x4f, 0xc9, 0x3c, 0xef, 0xc7, 0xcc, 0xfb, 0xf1, 0x3c, 0x06, 0x39, 0x9c, 0xb3, 0x6b, 0xe2, - 0x07, 0xb1, 0x3b, 0x73, 0x6d, 0x2b, 0x76, 0x03, 0x9f, 0xf5, 0xc2, 0x28, 0x88, 0x03, 0x54, 0xe7, - 0x3f, 0xd3, 0xf9, 0x4c, 0xf9, 0x7b, 0x03, 0x3e, 0x1e, 0xcf, 0xd9, 0xb5, 0x5e, 0xf0, 0xc2, 0xf4, - 0xca, 0x65, 0x71, 0xc4, 0xff, 0x23, 0x03, 0x20, 0x0e, 0x6e, 0xa8, 0x4f, 0xe2, 0x45, 0x48, 0x65, - 0xa1, 0x23, 0x74, 0xdb, 0x27, 0x5f, 0xf7, 0xf2, 0xf8, 0xde, 0xba, 0xd8, 0x9e, 0x99, 0x04, 0x9a, - 0x8b, 0x90, 0xe2, 0x46, 0x9c, 0xff, 0x45, 0x9f, 0x42, 0xcb, 0xa1, 0x77, 0xae, 0x4d, 0x09, 0xc7, - 0x64, 0xb1, 0x23, 0x74, 0x1b, 0xb8, 0x99, 0x62, 0x3c, 0x02, 0x7d, 0x09, 0xdb, 0xae, 0xcf, 0x62, - 0xcb, 0xf3, 0x78, 0x1e, 0xe2, 0x3a, 0x72, 0x85, 0x7b, 0xb5, 0x8b, 0xb0, 0xe6, 0x24, 0xb9, 0x2c, - 0xdb, 0xa6, 0x8c, 0x65, 0xb9, 0xaa, 0x69, 0xae, 0x14, 0x4b, 0x73, 0xc9, 0x50, 0xa3, 0xbe, 0x35, - 0xf5, 0xa8, 0x23, 0x6f, 0x74, 0x84, 0x6e, 0x1d, 0xe7, 0xc7, 0xc4, 0x72, 0x47, 0x23, 0xe6, 0x06, - 0xbe, 0xbc, 0xd9, 0x11, 0xba, 0x55, 0x9c, 0x1f, 0x51, 0x17, 0x24, 0xcb, 0xf3, 0x82, 0xdf, 0xa8, - 0x43, 0x6e, 0xe8, 0x82, 0x78, 0x2e, 0x8b, 0xe5, 0x5a, 0xa7, 0xd2, 0x6d, 0xe1, 0x76, 0x86, 0x9f, - 0xd3, 0xc5, 0x85, 0xcb, 0x62, 0x74, 0x0c, 0x3b, 0x53, 0x2f, 0xb0, 0x6f, 0xa8, 0x43, 0xec, 0x6b, - 0x2b, 0x4e, 0x5d, 0xeb, 0xdc, 0x75, 0x3b, 0x33, 0x0c, 0xae, 0xad, 0x98, 0xfb, 0xbe, 0x00, 0x98, - 0xfb, 0x11, 0xef, 0x0f, 0x8d, 0xe4, 0x06, 0x7f, 0x4c, 0x01, 0x41, 0xbb, 0xb0, 0x71, 0x15, 0x59, - 0x7e, 0x2c, 0x43, 0x47, 0xe8, 0xb6, 0x70, 0x7a, 0x40, 0x2f, 0x41, 0xe6, 0x77, 0x92, 0x59, 0x14, - 0xdc, 0x12, 0x3b, 0xf0, 0x63, 0xcb, 0x8e, 0x19, 0x09, 0x7c, 0x6f, 0x21, 0x37, 0x79, 0x8e, 0x3d, - 0x6e, 0x1f, 0x46, 0xc1, 0xed, 0x20, 0xb3, 0x1a, 0xbe, 0xb7, 0x40, 0x1f, 0x41, 0xc3, 0x0a, 0x7d, - 0x12, 0x07, 0xa1, 0x6b, 0xcb, 0x2d, 0xde, 0x98, 0xba, 0x15, 0xfa, 0x66, 0x72, 0x46, 0x5f, 0x40, - 0x9b, 0x3f, 0x8f, 0xdc, 0x52, 0x9f, 0x2f, 0x86, 0xbc, 0xc5, 0x73, 0x6d, 0x71, 0x74, 0x94, 0x81, - 0xe8, 0x7b, 0x38, 0xcc, 0x1b, 0x91, 0x3b, 0x16, 0xea, 0x6c, 0xf3, 0x3a, 0x0f, 0x32, 0x8f, 0x3c, - 0x28, 0xaf, 0x57, 0x19, 0x42, 0x63, 0xb9, 0x00, 0x68, 0x1f, 0xd0, 0xa5, 0x7e, 0xae, 0x1b, 0x6f, - 0x74, 0x62, 0x1a, 0xe7, 0xaa, 0x4e, 0xcc, 0xb7, 0x63, 0x55, 0xfa, 0x00, 0x6d, 0x41, 0xa3, 0x3f, - 0xce, 0x30, 0x49, 0x40, 0x08, 0xda, 0x43, 0x0d, 0xab, 0x3f, 0xf6, 0x27, 0x6a, 0x86, 0x89, 0xca, - 0x3f, 0x22, 0x7c, 0xbe, 0x6e, 0xcd, 0x30, 0x65, 0x61, 0xe0, 0x33, 0x9a, 0x0c, 0x94, 0xcd, 0xf9, - 0xe8, 0xf9, 0x9e, 0xd6, 0x71, 0x7e, 0x44, 0x3a, 0x6c, 0xd0, 0x28, 0x0a, 0x22, 0xbe, 0x6c, 0xed, - 0x93, 0x57, 0xcf, 0xdb, 0xdf, 0x3c, 0x71, 0x4f, 0x4d, 0x62, 0xf9, 0x1e, 0xa7, 0x69, 0xd0, 0x11, - 0x40, 0x44, 0x7f, 0x9d, 0x53, 0x16, 0xe7, 0xbb, 0xd9, 0xc2, 0x8d, 0x0c, 0xd1, 0x1c, 0xe5, 0x77, - 0x01, 0x1a, 0xcb, 0x98, 0x62, 0xe9, 0x2a, 0xc6, 0x06, 0xce, 0x4b, 0xdf, 0x83, 0x9d, 0x51, 0xff, - 0x62, 0x68, 0xe0, 0x91, 0x7a, 0x4a, 0x46, 0xea, 0x64, 0xd2, 0x3f, 0x53, 0x25, 0x01, 0xed, 0x82, - 0xf4, 0xb3, 0x8a, 0x27, 0x9a, 0xa1, 0x93, 0x91, 0x36, 0x19, 0xf5, 0xcd, 0xc1, 0x6b, 0x49, 0x44, - 0x87, 0xb0, 0x7f, 0xa9, 0x4f, 0x2e, 0xc7, 0x63, 0x03, 0x9b, 0xea, 0x69, 0xb1, 0x87, 0x95, 0xa4, - 0x69, 0x9a, 0x6e, 0xaa, 0x58, 0xef, 0x5f, 0xa4, 0x37, 0x48, 0x55, 0x65, 0x0e, 0x72, 0xb6, 0x0d, - 0x83, 0xc0, 0xa1, 0x7d, 0xe7, 0x8e, 0x46, 0xb1, 0xcb, 0x68, 0x32, 0x45, 0xf4, 0x16, 0xf6, 0x57, - 0x94, 0x81, 0xb8, 0xfe, 0x2c, 0x90, 0x85, 0x4e, 0xa5, 0xdb, 0x3c, 0xf9, 0xec, 0xf1, 0xf6, 0xfc, - 0x34, 0xa7, 0xd1, 0x42, 0xf3, 0x67, 0x01, 0xde, 0x0d, 0x1f, 0x98, 0x12, 0x54, 0x79, 0x05, 0x7b, - 0xa5, 0x21, 0xe8, 0x13, 0x68, 0x86, 0xf3, 0xa9, 0xe7, 0xda, 0x09, 0xa3, 0x18, 0xbf, 0xa8, 0x85, - 0x21, 0x85, 0xce, 0xe9, 0x82, 0x29, 0x7f, 0x88, 0xf0, 0xe1, 0xa3, 0xb7, 0xad, 0x10, 0x5d, 0x58, - 0x25, 0x7a, 0x89, 0x68, 0x88, 0xa5, 0xa2, 0x71, 0x04, 0xf0, 0xee, 0x29, 0xf9, 0xf0, 0x96, 0x2f, - 0x29, 0x25, 0x7f, 0xb5, 0x94, 0xfc, 0x4b, 0xc2, 0x6e, 0x14, 0x09, 0xfb, 0xb8, 0xac, 0x1c, 0xc3, - 0x0e, 0xa3, 0xd1, 0x1d, 0x8d, 0x48, 0xe1, 0xfe, 0x1a, 0x8f, 0xdd, 0x4e, 0x0d, 0xe3, 0xfc, 0x15, - 0xca, 0x9f, 0x02, 0x1c, 0x95, 0xb6, 0x63, 0xb9, 0xed, 0x2f, 0xa1, 0xfa, 0x7f, 0x67, 0xc6, 0x03, - 0x92, 0xfa, 0x6f, 0x29, 0x63, 0xd6, 0x15, 0xcd, 0x7b, 0xd4, 0xc2, 0x8d, 0x0c, 0xd1, 0x9c, 0x22, - 0x8b, 0x2a, 0xf7, 0x58, 0xa4, 0xfc, 0x2b, 0x82, 0xf4, 0x30, 0xf9, 0x73, 0x26, 0x73, 0x00, 0x35, - 0x2e, 0x1a, 0xcb, 0xdb, 0x36, 0x93, 0xe3, 0xd3, 0x93, 0x28, 0x99, 0x68, 0xb5, 0x74, 0xa2, 0x32, - 0xd4, 0xb2, 0xf7, 0x67, 0xa3, 0xc8, 0x8f, 0x68, 0x00, 0x55, 0xfe, 0xdd, 0xda, 0xe4, 0xbc, 0xff, - 0xea, 0xf1, 0x26, 0xad, 0x00, 0x9c, 0xee, 0x3c, 0x58, 0x31, 0x61, 0xb7, 0xcc, 0x8a, 0x14, 0x78, - 0x91, 0x13, 0x7b, 0x7c, 0x39, 0x79, 0x4d, 0x74, 0xc3, 0xd4, 0x86, 0xda, 0xa0, 0x6f, 0x26, 0xdc, - 0xcd, 0x48, 0xde, 0x84, 0xda, 0x3b, 0x6a, 0xf3, 0x83, 0x9e, 0x98, 0x25, 0x51, 0x09, 0xe1, 0x60, - 0x55, 0x7c, 0xb8, 0x82, 0xa0, 0x6f, 0xa1, 0x9e, 0x89, 0x09, 0xcb, 0xc6, 0x7b, 0xb8, 0x46, 0xb1, - 0x96, 0xbe, 0x4f, 0x4c, 0x56, 0xf9, 0x4b, 0x84, 0xfd, 0xd5, 0x2b, 0xc3, 0x20, 0x8a, 0xd7, 0x48, - 0xe7, 0x0f, 0xf7, 0xa5, 0xf3, 0x78, 0x9d, 0x74, 0x26, 0xa9, 0x4a, 0xc5, 0xf2, 0x7d, 0x4c, 0x59, - 0xf9, 0xe5, 0x39, 0xa2, 0xba, 0x0d, 0xcd, 0x37, 0xd8, 0xd0, 0xcf, 0x8a, 0x5f, 0x94, 0x07, 0xe2, - 0x28, 0x26, 0x98, 0x6e, 0x98, 0x04, 0xab, 0x67, 0xda, 0xc4, 0x54, 0xb1, 0x7a, 0x2a, 0x55, 0x12, - 0xc1, 0x5c, 0x2d, 0x28, 0xa3, 0xda, 0xfd, 0xbe, 0x0a, 0x0f, 0x19, 0xf3, 0x1d, 0xd4, 0x22, 0x5e, - 0x3b, 0x93, 0x45, 0x3e, 0xad, 0xce, 0x53, 0x4d, 0xc2, 0x79, 0xc0, 0x74, 0x93, 0x7b, 0x7e, 0xf3, - 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x65, 0x07, 0x55, 0xdb, 0xac, 0x09, 0x00, 0x00, + // 1002 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xdd, 0x6e, 0xe3, 0x44, + 0x14, 0xc6, 0x4e, 0xda, 0x24, 0x27, 0x69, 0x9a, 0x8e, 0xfa, 0x63, 0x0a, 0x5d, 0x82, 0x01, 0x11, + 0xf5, 0xa2, 0xa0, 0x22, 0xb1, 0x2b, 0xb8, 0x21, 0xa4, 0x6e, 0xd7, 0x6a, 0x63, 0x87, 0x89, 0xcb, + 0x6a, 0x25, 0xa4, 0x91, 0x9b, 0x4c, 0x5b, 0xab, 0xae, 0xc7, 0x78, 0xc6, 0x45, 0xb9, 0xe3, 0x01, + 0xb8, 0xe1, 0x96, 0x2b, 0x9e, 0x81, 0x57, 0xe2, 0x45, 0x90, 0xc7, 0x76, 0xd6, 0x6d, 0xdc, 0xb4, + 0x48, 0x7b, 0x95, 0x9c, 0x6f, 0xce, 0x39, 0x33, 0xe7, 0xe7, 0xfb, 0x0c, 0x5a, 0x18, 0xf3, 0x6b, + 0x12, 0x30, 0xe1, 0x5d, 0x7a, 0x13, 0x57, 0x78, 0x2c, 0xe0, 0x07, 0x61, 0xc4, 0x04, 0x43, 0x75, + 0xf9, 0x73, 0x11, 0x5f, 0xea, 0x7f, 0xaf, 0xc0, 0xc7, 0xa3, 0x98, 0x5f, 0x5b, 0x05, 0x2f, 0x4c, + 0xaf, 0x3c, 0x2e, 0x22, 0xf9, 0x1f, 0xd9, 0x00, 0x82, 0xdd, 0xd0, 0x80, 0x88, 0x59, 0x48, 0x35, + 0xa5, 0xab, 0xf4, 0xda, 0x87, 0x5f, 0x1f, 0xe4, 0xf1, 0x07, 0xcb, 0x62, 0x0f, 0x9c, 0x24, 0xd0, + 0x99, 0x85, 0x14, 0x37, 0x44, 0xfe, 0x17, 0x7d, 0x0a, 0xad, 0x29, 0xbd, 0xf3, 0x26, 0x94, 0x48, + 0x4c, 0x53, 0xbb, 0x4a, 0xaf, 0x81, 0x9b, 0x29, 0x26, 0x23, 0xd0, 0x97, 0xb0, 0xee, 0x05, 0x5c, + 0xb8, 0xbe, 0x2f, 0xf3, 0x10, 0x6f, 0xaa, 0x55, 0xa4, 0x57, 0xbb, 0x08, 0x9b, 0xd3, 0x24, 0x97, + 0x3b, 0x99, 0x50, 0xce, 0xb3, 0x5c, 0xd5, 0x34, 0x57, 0x8a, 0xa5, 0xb9, 0x34, 0xa8, 0xd1, 0xc0, + 0xbd, 0xf0, 0xe9, 0x54, 0x5b, 0xe9, 0x2a, 0xbd, 0x3a, 0xce, 0xcd, 0xe4, 0xe4, 0x8e, 0x46, 0xdc, + 0x63, 0x81, 0xb6, 0xda, 0x55, 0x7a, 0x55, 0x9c, 0x9b, 0xa8, 0x07, 0x1d, 0xd7, 0xf7, 0xd9, 0x6f, + 0x74, 0x4a, 0x6e, 0xe8, 0x8c, 0xf8, 0x1e, 0x17, 0x5a, 0xad, 0x5b, 0xe9, 0xb5, 0x70, 0x3b, 0xc3, + 0x4f, 0xe9, 0xec, 0xcc, 0xe3, 0x02, 0xed, 0xc3, 0xc6, 0x85, 0xcf, 0x26, 0x37, 0x74, 0x4a, 0x26, + 0xd7, 0xae, 0x48, 0x5d, 0xeb, 0xd2, 0x75, 0x3d, 0x3b, 0x18, 0x5c, 0xbb, 0x42, 0xfa, 0xbe, 0x00, + 0x88, 0x83, 0x48, 0xf6, 0x87, 0x46, 0x5a, 0x43, 0x3e, 0xa6, 0x80, 0xa0, 0x4d, 0x58, 0xb9, 0x8a, + 0xdc, 0x40, 0x68, 0xd0, 0x55, 0x7a, 0x2d, 0x9c, 0x1a, 0xe8, 0x25, 0x68, 0xf2, 0x4e, 0x72, 0x19, + 0xb1, 0x5b, 0x32, 0x61, 0x81, 0x70, 0x27, 0x82, 0x13, 0x16, 0xf8, 0x33, 0xad, 0x29, 0x73, 0x6c, + 0xc9, 0xf3, 0xe3, 0x88, 0xdd, 0x0e, 0xb2, 0x53, 0x3b, 0xf0, 0x67, 0xe8, 0x23, 0x68, 0xb8, 0x61, + 0x40, 0x04, 0x0b, 0xbd, 0x89, 0xd6, 0x92, 0x8d, 0xa9, 0xbb, 0x61, 0xe0, 0x24, 0x36, 0xfa, 0x02, + 0xda, 0xf2, 0x79, 0xe4, 0x96, 0x06, 0x72, 0x31, 0xb4, 0x35, 0x99, 0x6b, 0x4d, 0xa2, 0xc3, 0x0c, + 0x44, 0xdf, 0xc3, 0x6e, 0xde, 0x88, 0xdc, 0xb1, 0x50, 0x67, 0x5b, 0xd6, 0xb9, 0x93, 0x79, 0xe4, + 0x41, 0x79, 0xbd, 0xfa, 0x31, 0x34, 0xe6, 0x0b, 0x80, 0xb6, 0x01, 0x9d, 0x5b, 0xa7, 0x96, 0xfd, + 0xc6, 0x22, 0x8e, 0x7d, 0x6a, 0x58, 0xc4, 0x79, 0x3b, 0x32, 0x3a, 0x1f, 0xa0, 0x35, 0x68, 0xf4, + 0x47, 0x19, 0xd6, 0x51, 0x10, 0x82, 0xf6, 0xb1, 0x89, 0x8d, 0x1f, 0xfb, 0x63, 0x23, 0xc3, 0x54, + 0xfd, 0x1f, 0x15, 0x3e, 0x5f, 0xb6, 0x66, 0x98, 0xf2, 0x90, 0x05, 0x9c, 0x26, 0x03, 0xe5, 0xb1, + 0x1c, 0xbd, 0xdc, 0xd3, 0x3a, 0xce, 0x4d, 0x64, 0xc1, 0x0a, 0x8d, 0x22, 0x16, 0xc9, 0x65, 0x6b, + 0x1f, 0xbe, 0x7a, 0xde, 0xfe, 0xe6, 0x89, 0x0f, 0x8c, 0x24, 0x56, 0xee, 0x71, 0x9a, 0x06, 0xed, + 0x01, 0x44, 0xf4, 0xd7, 0x98, 0x72, 0x91, 0xef, 0x66, 0x0b, 0x37, 0x32, 0xc4, 0x9c, 0xea, 0xbf, + 0x2b, 0xd0, 0x98, 0xc7, 0x14, 0x4b, 0x37, 0x30, 0xb6, 0x71, 0x5e, 0xfa, 0x16, 0x6c, 0x0c, 0xfb, + 0x67, 0xc7, 0x36, 0x1e, 0x1a, 0x47, 0x64, 0x68, 0x8c, 0xc7, 0xfd, 0x13, 0xa3, 0xa3, 0xa0, 0x4d, + 0xe8, 0xfc, 0x6c, 0xe0, 0xb1, 0x69, 0x5b, 0x64, 0x68, 0x8e, 0x87, 0x7d, 0x67, 0xf0, 0xba, 0xa3, + 0xa2, 0x5d, 0xd8, 0x3e, 0xb7, 0xc6, 0xe7, 0xa3, 0x91, 0x8d, 0x1d, 0xe3, 0xa8, 0xd8, 0xc3, 0x4a, + 0xd2, 0x34, 0xd3, 0x72, 0x0c, 0x6c, 0xf5, 0xcf, 0xd2, 0x1b, 0x3a, 0x55, 0x3d, 0x06, 0x2d, 0xdb, + 0x86, 0x01, 0x9b, 0xd2, 0xfe, 0xf4, 0x8e, 0x46, 0xc2, 0xe3, 0x34, 0x99, 0x22, 0x7a, 0x0b, 0xdb, + 0x0b, 0xca, 0x40, 0xbc, 0xe0, 0x92, 0x69, 0x4a, 0xb7, 0xd2, 0x6b, 0x1e, 0x7e, 0xf6, 0x78, 0x7b, + 0x7e, 0x8a, 0x69, 0x34, 0x33, 0x83, 0x4b, 0x86, 0x37, 0xc3, 0x07, 0x47, 0x09, 0xaa, 0xbf, 0x82, + 0xad, 0xd2, 0x10, 0xf4, 0x09, 0x34, 0xc3, 0xf8, 0xc2, 0xf7, 0x26, 0x09, 0xa3, 0xb8, 0xbc, 0xa8, + 0x85, 0x21, 0x85, 0x4e, 0xe9, 0x8c, 0xeb, 0x7f, 0xa8, 0xf0, 0xe1, 0xa3, 0xb7, 0x2d, 0x10, 0x5d, + 0x59, 0x24, 0x7a, 0x89, 0x68, 0xa8, 0xa5, 0xa2, 0xb1, 0x07, 0xf0, 0xee, 0x29, 0xf9, 0xf0, 0xe6, + 0x2f, 0x29, 0x25, 0x7f, 0xb5, 0x94, 0xfc, 0x73, 0xc2, 0xae, 0x14, 0x09, 0xfb, 0xb8, 0xac, 0xec, + 0xc3, 0x06, 0xa7, 0xd1, 0x1d, 0x8d, 0x48, 0xe1, 0xfe, 0x9a, 0x8c, 0x5d, 0x4f, 0x0f, 0x46, 0xf9, + 0x2b, 0xf4, 0x3f, 0x15, 0xd8, 0x2b, 0x6d, 0xc7, 0x7c, 0xdb, 0x5f, 0x42, 0xf5, 0xff, 0xce, 0x4c, + 0x06, 0x24, 0xf5, 0xdf, 0x52, 0xce, 0xdd, 0x2b, 0x9a, 0xf7, 0xa8, 0x85, 0x1b, 0x19, 0x62, 0x4e, + 0x8b, 0x2c, 0xaa, 0xdc, 0x63, 0x91, 0xfe, 0xaf, 0x0a, 0x9d, 0x87, 0xc9, 0x9f, 0x33, 0x99, 0x1d, + 0xa8, 0x49, 0xd1, 0x98, 0xdf, 0xb6, 0x9a, 0x98, 0x4f, 0x4f, 0xa2, 0x64, 0xa2, 0xd5, 0xd2, 0x89, + 0x6a, 0x50, 0xcb, 0xde, 0x9f, 0x8d, 0x22, 0x37, 0xd1, 0x00, 0xaa, 0xf2, 0xbb, 0xb5, 0x2a, 0x79, + 0xff, 0xd5, 0xe3, 0x4d, 0x5a, 0x00, 0x24, 0xdd, 0x65, 0x30, 0xda, 0x86, 0x55, 0x37, 0x16, 0xd7, + 0x2c, 0xca, 0x86, 0x95, 0x59, 0xba, 0x03, 0x9b, 0x65, 0x51, 0x48, 0x87, 0x17, 0x39, 0xe1, 0x47, + 0xe7, 0xe3, 0xd7, 0xc4, 0xb2, 0x1d, 0xf3, 0xd8, 0x1c, 0xf4, 0x9d, 0x84, 0xd3, 0x19, 0xf9, 0x9b, + 0x50, 0x7b, 0x47, 0x79, 0x69, 0x58, 0xc9, 0x71, 0x47, 0xd5, 0x43, 0xd8, 0x59, 0x14, 0x25, 0xa9, + 0x2c, 0xe8, 0x5b, 0xa8, 0x67, 0x22, 0xc3, 0xb3, 0xb1, 0xef, 0x2e, 0x51, 0xb2, 0xb9, 0xef, 0x13, + 0x13, 0xd7, 0xff, 0x52, 0x61, 0x7b, 0xf1, 0xca, 0x90, 0x45, 0x62, 0x89, 0xa4, 0xfe, 0x70, 0x5f, + 0x52, 0xf7, 0x97, 0x49, 0x6a, 0x92, 0xaa, 0x54, 0x44, 0xdf, 0xc7, 0xf4, 0xf5, 0x5f, 0x9e, 0x23, + 0xb6, 0xeb, 0xd0, 0x7c, 0x83, 0x6d, 0xeb, 0xa4, 0xf8, 0xa5, 0x79, 0x20, 0x9a, 0x6a, 0x82, 0x59, + 0xb6, 0x43, 0xb0, 0x71, 0x62, 0x8e, 0x1d, 0x03, 0x1b, 0x47, 0x9d, 0x4a, 0x22, 0xa4, 0x8b, 0x05, + 0x65, 0x14, 0xbc, 0xdf, 0x57, 0xe5, 0x21, 0x93, 0xbe, 0x83, 0x5a, 0x24, 0x6b, 0xe7, 0x9a, 0x2a, + 0xa7, 0xd5, 0x7d, 0xaa, 0x49, 0x38, 0x0f, 0xb8, 0x58, 0x95, 0x9e, 0xdf, 0xfc, 0x17, 0x00, 0x00, + 0xff, 0xff, 0xd4, 0x90, 0x1f, 0x72, 0xc4, 0x09, 0x00, 0x00, } diff --git a/protocol/protobuf/push_notifications.proto b/protocol/protobuf/push_notifications.proto index c92882a2d..1d801edc4 100644 --- a/protocol/protobuf/push_notifications.proto +++ b/protocol/protobuf/push_notifications.proto @@ -74,6 +74,7 @@ message PushNotification { MESSAGE = 1; MENTION = 2; } + bytes author = 7; } message PushNotificationRequest { diff --git a/protocol/pushnotificationclient/client.go b/protocol/pushnotificationclient/client.go index 7593fd6be..c22f28fd4 100644 --- a/protocol/pushnotificationclient/client.go +++ b/protocol/pushnotificationclient/client.go @@ -49,7 +49,7 @@ const encryptedPayloadKeyLength = 16 const accessTokenKeyLength = 16 const staleQueryTimeInSeconds = 86400 const mentionInstallationID = "mention" -const oneToOneChatIDLength = 65 +const oneToOneChatIDLength = 132 // maxRegistrationRetries is the maximum number of attempts we do before giving up registering with a server const maxRegistrationRetries int64 = 12 @@ -211,8 +211,6 @@ func (c *Client) Start() error { return errors.New("can't start, missing message processor") } - c.config.Logger.Debug("starting push notification client", zap.Any("config", c.config)) - err := c.loadLastPushNotificationRegistration() if err != nil { return err @@ -996,7 +994,7 @@ func (c *Client) handleDirectMessageSent(sentMessage *common.SentMessage) error // If it's a public key, we use our own public key as chatID, which correspond to the chatID used by the other peer // otherwise we use the group chat ID var chatID string - if len(chatID) == oneToOneChatIDLength { + if len(message.ChatId) == oneToOneChatIDLength { chatID = types.EncodeHex(crypto.FromECDSAPub(&c.config.Identity.PublicKey)) } else { // this is a group chat @@ -1350,6 +1348,7 @@ func (c *Client) sendNotification(publicKey *ecdsa.PublicKey, installationIDs [] // For now we set the ChatID to our own identity key, this will work fine for blocked users // and muted 1-to-1 chats, but not for group chats. ChatId: common.Shake256([]byte(chatID)), + Author: common.Shake256([]byte(types.EncodeHex(crypto.FromECDSAPub(&c.config.Identity.PublicKey)))), AccessToken: i.AccessToken, PublicKey: common.HashPublicKey(publicKey), InstallationId: i.InstallationID, diff --git a/protocol/pushnotificationserver/server.go b/protocol/pushnotificationserver/server.go index a992b805a..718ccfe9a 100644 --- a/protocol/pushnotificationserver/server.go +++ b/protocol/pushnotificationserver/server.go @@ -21,6 +21,8 @@ import ( const encryptedPayloadKeyLength = 16 const defaultGorushURL = "https://gorush.status.im" +var errUnhandledPushNotificationType = errors.New("unhandled push notification type") + type Config struct { Enabled bool // Identity is our identity key @@ -56,7 +58,7 @@ func (s *Server) Start() error { s.config.Logger.Info("starting push notification server") if s.config.Identity == nil { - s.config.Logger.Info("Identity nil") + s.config.Logger.Debug("Identity nil") // Pull identity from database identity, err := s.persistence.GetIdentity() if err != nil { @@ -139,7 +141,7 @@ func (s *Server) HandlePushNotificationQuery(publicKey *ecdsa.PublicKey, message func (s *Server) HandlePushNotificationRequest(publicKey *ecdsa.PublicKey, messageID []byte, request protobuf.PushNotificationRequest) error { - s.config.Logger.Info("handling pn request", zap.Binary("message-id", messageID)) + s.config.Logger.Debug("handling pn request", zap.Binary("message-id", messageID)) // This is at-most-once semantic for now exists, err := s.persistence.PushNotificationExists(messageID) @@ -148,7 +150,7 @@ func (s *Server) HandlePushNotificationRequest(publicKey *ecdsa.PublicKey, } if exists { - s.config.Logger.Info("already handled") + s.config.Logger.Debug("already handled") return nil } @@ -304,7 +306,7 @@ func (s *Server) validateRegistration(publicKey *ecdsa.PublicKey, payload []byte // buildPushNotificationQueryResponse check if we have the client information and send them back func (s *Server) buildPushNotificationQueryResponse(query *protobuf.PushNotificationQuery) *protobuf.PushNotificationQueryResponse { - s.config.Logger.Info("handling push notification query") + s.config.Logger.Debug("handling push notification query") response := &protobuf.PushNotificationQueryResponse{} if query == nil || len(query.PublicKeys) == 0 { return response @@ -349,6 +351,49 @@ func (s *Server) contains(list [][]byte, chatID []byte) bool { return false } +type reportResult struct { + sendNotification bool + report *protobuf.PushNotificationReport +} + +// buildPushNotificationReport checks the request against the registration and +// returns whether we should send the notification and what the response should be +func (s *Server) buildPushNotificationReport(pn *protobuf.PushNotification, registration *protobuf.PushNotificationRegistration) (*reportResult, error) { + response := &reportResult{} + report := &protobuf.PushNotificationReport{ + PublicKey: pn.PublicKey, + InstallationId: pn.InstallationId, + } + + if pn.Type == protobuf.PushNotification_UNKNOWN_PUSH_NOTIFICATION_TYPE { + s.config.Logger.Warn("unhandled type") + return nil, errUnhandledPushNotificationType + } + + if registration == nil { + s.config.Logger.Warn("empty registration") + report.Error = protobuf.PushNotificationReport_NOT_REGISTERED + } else if registration.AccessToken != pn.AccessToken { + s.config.Logger.Debug("invalid token") + report.Error = protobuf.PushNotificationReport_WRONG_TOKEN + } else if (s.isMessageNotification(pn) && !s.isValidMessageNotification(pn, registration)) || (s.isMentionNotification(pn) && !s.isValidMentionNotification(pn, registration)) { + s.config.Logger.Debug("filtered notification") + // We report as successful but don't send the notification + // for privacy reasons, as otherwise we would disclose that + // the sending client has been blocked or that the registering + // client has not joined a given public chat + report.Success = true + } else { + response.sendNotification = true + s.config.Logger.Debug("sending push notification") + report.Success = true + } + + response.report = report + + return response, nil +} + // buildPushNotificationRequestResponse will build a response func (s *Server) buildPushNotificationRequestResponse(request *protobuf.PushNotificationRequest) (*protobuf.PushNotificationResponse, []*RequestAndRegistration) { response := &protobuf.PushNotificationResponse{} @@ -363,49 +408,36 @@ func (s *Server) buildPushNotificationRequestResponse(request *protobuf.PushNoti // collect successful requests & registrations var requestAndRegistrations []*RequestAndRegistration - // TODO: this logic needs to be extracted and tested for _, pn := range request.Requests { registration, err := s.persistence.GetPushNotificationRegistrationByPublicKeyAndInstallationID(pn.PublicKey, pn.InstallationId) - report := &protobuf.PushNotificationReport{ - PublicKey: pn.PublicKey, - InstallationId: pn.InstallationId, - } - s.config.Logger.Info("registration and request", zap.Any("registration", registration), zap.Any("request", pn)) - - if pn.Type == protobuf.PushNotification_UNKNOWN_PUSH_NOTIFICATION_TYPE { - s.config.Logger.Warn("unhandled type") - continue - } - + var report *protobuf.PushNotificationReport if err != nil { - s.config.Logger.Error("failed to retrieve registration", zap.Error(err)) - report.Error = protobuf.PushNotificationReport_UNKNOWN_ERROR_TYPE - } else if registration == nil { - s.config.Logger.Warn("empty registration") - report.Error = protobuf.PushNotificationReport_NOT_REGISTERED - } else if registration.AccessToken != pn.AccessToken { - s.config.Logger.Debug("invalid token") - report.Error = protobuf.PushNotificationReport_WRONG_TOKEN - } else if s.contains(registration.BlockedChatList, pn.ChatId) || (s.isMentionNotification(pn) && !s.isValidMentionNotification(pn, registration)) { - // We report as successful but don't send the notification - // for privacy reasons, as otherwise we would disclose that - // the sending client has been blocked or that the registering - // client has not joined a given public chat - report.Success = true - s.config.Logger.Debug("invalid token", zap.Bool("blocked", s.contains(registration.BlockedChatList, pn.ChatId)), zap.Bool("mention", (s.isMentionNotification(pn) && !s.isValidMentionNotification(pn, registration)))) + report = &protobuf.PushNotificationReport{ + PublicKey: pn.PublicKey, + Error: protobuf.PushNotificationReport_UNKNOWN_ERROR_TYPE, + InstallationId: pn.InstallationId, + } } else { - s.config.Logger.Debug("sending push notification") - // For now we just assume that the notification will be successful - requestAndRegistrations = append(requestAndRegistrations, &RequestAndRegistration{ - Request: pn, - Registration: registration, - }) - report.Success = true + response, err := s.buildPushNotificationReport(pn, registration) + if err != nil { + s.config.Logger.Warn("unhandled type") + continue + } + + if response.sendNotification { + requestAndRegistrations = append(requestAndRegistrations, &RequestAndRegistration{ + Request: pn, + Registration: registration, + }) + } + report = response.report + } + response.Reports = append(response.Reports, report) } - s.config.Logger.Info("built pn request") + s.config.Logger.Debug("built pn request") if len(requestAndRegistrations) == 0 { s.config.Logger.Warn("no request and registration") return response, nil @@ -434,7 +466,7 @@ func (s *Server) listenToPublicKeyQueryTopic(hashedPublicKey []byte) error { // buildPushNotificationRegistrationResponse will check the registration is valid, save it, and listen to the topic for the queries func (s *Server) buildPushNotificationRegistrationResponse(publicKey *ecdsa.PublicKey, payload []byte) *protobuf.PushNotificationRegistrationResponse { - s.config.Logger.Info("handling push notification registration") + s.config.Logger.Debug("handling push notification registration") response := &protobuf.PushNotificationRegistrationResponse{ RequestId: common.Shake256(payload), } @@ -452,7 +484,7 @@ func (s *Server) buildPushNotificationRegistrationResponse(publicKey *ecdsa.Publ } if registration.Unregister { - s.config.Logger.Info("unregistering client") + s.config.Logger.Debug("unregistering client") // We save an empty registration, only keeping version and installation-id if err := s.persistence.UnregisterPushNotificationRegistration(common.HashPublicKey(publicKey), registration.InstallationId, registration.Version); err != nil { response.Error = protobuf.PushNotificationRegistrationResponse_INTERNAL_ERROR @@ -474,7 +506,7 @@ func (s *Server) buildPushNotificationRegistrationResponse(publicKey *ecdsa.Publ } response.Success = true - s.config.Logger.Info("handled push notification registration successfully") + s.config.Logger.Debug("handled push notification registration successfully") return response } @@ -483,6 +515,23 @@ func (s *Server) isMentionNotification(pn *protobuf.PushNotification) bool { return pn.Type == protobuf.PushNotification_MENTION } +// isValidMentionNotification checks: +// this is a mention +// mentions are enabled +// the user joined the public chat +// the author is not blocked func (s *Server) isValidMentionNotification(pn *protobuf.PushNotification, registration *protobuf.PushNotificationRegistration) bool { - return s.isMentionNotification(pn) && !registration.BlockMentions && s.contains(registration.AllowedMentionsChatList, pn.ChatId) + return s.isMentionNotification(pn) && !registration.BlockMentions && s.contains(registration.AllowedMentionsChatList, pn.ChatId) && !s.contains(registration.BlockedChatList, pn.Author) +} + +func (s *Server) isMessageNotification(pn *protobuf.PushNotification) bool { + return pn.Type == protobuf.PushNotification_MESSAGE +} + +// isValidMentionNotification checks: +// this is a message +// the chat is not muted +// the author is not blocked +func (s *Server) isValidMessageNotification(pn *protobuf.PushNotification, registration *protobuf.PushNotificationRegistration) bool { + return s.isMessageNotification(pn) && !s.contains(registration.BlockedChatList, pn.ChatId) && !s.contains(registration.BlockedChatList, pn.Author) } diff --git a/protocol/pushnotificationserver/server_test.go b/protocol/pushnotificationserver/server_test.go index 68f15f686..c46977d29 100644 --- a/protocol/pushnotificationserver/server_test.go +++ b/protocol/pushnotificationserver/server_test.go @@ -670,3 +670,210 @@ func (s *ServerSuite) TestPushNotificationDisabledMentions() { s.Require().NotNil(pushNotificationResponse) s.Require().Nil(requestAndRegistrations) } + +func (s *ServerSuite) TestBuildPushNotificationReport() { + accessToken := "a" + chatID := []byte("chat-id") + author := []byte("author") + blockedAuthor := []byte("blocked-author") + blockedChatID := []byte("blocked-chat-id") + blockedChatList := [][]byte{blockedChatID, blockedAuthor} + nonJoinedChatID := []byte("non-joined-chat-id") + allowedMentionsChatList := [][]byte{chatID} + validMessagePN := &protobuf.PushNotification{ + Type: protobuf.PushNotification_MESSAGE, + ChatId: chatID, + Author: author, + AccessToken: accessToken, + } + validMentionPN := &protobuf.PushNotification{ + Type: protobuf.PushNotification_MENTION, + ChatId: chatID, + AccessToken: accessToken, + } + validRegistration := &protobuf.PushNotificationRegistration{ + AccessToken: accessToken, + BlockedChatList: blockedChatList, + AllowedMentionsChatList: allowedMentionsChatList, + } + blockedMentionsRegistration := &protobuf.PushNotificationRegistration{ + AccessToken: accessToken, + BlockMentions: true, + BlockedChatList: blockedChatList, + AllowedMentionsChatList: allowedMentionsChatList, + } + + testCases := []struct { + name string + pn *protobuf.PushNotification + registration *protobuf.PushNotificationRegistration + expectedError error + expectedResponse *reportResult + }{ + { + name: "valid message", + pn: validMessagePN, + registration: validRegistration, + expectedResponse: &reportResult{ + sendNotification: true, + report: &protobuf.PushNotificationReport{ + Success: true, + }, + }, + }, + { + name: "valid mention", + pn: validMentionPN, + registration: validRegistration, + expectedResponse: &reportResult{ + sendNotification: true, + report: &protobuf.PushNotificationReport{ + Success: true, + }, + }, + }, + { + name: "unknow push notification", + pn: &protobuf.PushNotification{ + ChatId: chatID, + AccessToken: accessToken, + }, + registration: validRegistration, + expectedError: errUnhandledPushNotificationType, + }, + { + name: "empty registration", + pn: validMessagePN, + registration: nil, + expectedResponse: &reportResult{ + sendNotification: false, + report: &protobuf.PushNotificationReport{ + Success: false, + Error: protobuf.PushNotificationReport_NOT_REGISTERED, + }, + }, + }, + { + name: "invalid access token message", + pn: &protobuf.PushNotification{ + Type: protobuf.PushNotification_MESSAGE, + Author: author, + ChatId: chatID, + AccessToken: "invalid", + }, + registration: validRegistration, + expectedResponse: &reportResult{ + sendNotification: false, + report: &protobuf.PushNotificationReport{ + Success: false, + Error: protobuf.PushNotificationReport_WRONG_TOKEN, + }, + }, + }, + { + name: "invalid access token mention", + pn: &protobuf.PushNotification{ + Type: protobuf.PushNotification_MENTION, + Author: author, + ChatId: chatID, + AccessToken: "invalid", + }, + registration: validRegistration, + expectedResponse: &reportResult{ + sendNotification: false, + report: &protobuf.PushNotificationReport{ + Success: false, + Error: protobuf.PushNotificationReport_WRONG_TOKEN, + }, + }, + }, + { + name: "blocked chat list message", + pn: &protobuf.PushNotification{ + Type: protobuf.PushNotification_MESSAGE, + ChatId: blockedChatID, + Author: author, + AccessToken: accessToken, + }, + registration: validRegistration, + expectedResponse: &reportResult{ + sendNotification: false, + report: &protobuf.PushNotificationReport{ + Success: true, + }, + }, + }, + { + name: "blocked group chat message", + pn: &protobuf.PushNotification{ + Type: protobuf.PushNotification_MESSAGE, + Author: blockedAuthor, + ChatId: chatID, + AccessToken: accessToken, + }, + registration: validRegistration, + expectedResponse: &reportResult{ + sendNotification: false, + report: &protobuf.PushNotificationReport{ + Success: true, + }, + }, + }, + { + name: "blocked chat list mention", + pn: &protobuf.PushNotification{ + Type: protobuf.PushNotification_MENTION, + Author: blockedAuthor, + ChatId: chatID, + AccessToken: accessToken, + }, + registration: validRegistration, + expectedResponse: &reportResult{ + sendNotification: false, + report: &protobuf.PushNotificationReport{ + Success: true, + }, + }, + }, + { + name: "blocked mentions", + pn: &protobuf.PushNotification{ + Type: protobuf.PushNotification_MENTION, + Author: author, + ChatId: chatID, + AccessToken: accessToken, + }, + registration: blockedMentionsRegistration, + expectedResponse: &reportResult{ + sendNotification: false, + report: &protobuf.PushNotificationReport{ + Success: true, + }, + }, + }, + { + name: "not in allowed mention chat list", + pn: &protobuf.PushNotification{ + Type: protobuf.PushNotification_MENTION, + Author: author, + ChatId: nonJoinedChatID, + AccessToken: accessToken, + }, + registration: validRegistration, + expectedResponse: &reportResult{ + sendNotification: false, + report: &protobuf.PushNotificationReport{ + Success: true, + }, + }, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + response, err := s.server.buildPushNotificationReport(tc.pn, tc.registration) + s.Require().Equal(tc.expectedError, err) + s.Require().Equal(tc.expectedResponse, response) + }) + } +}