From 927f7625890c04a08a389e9d848a6c917a5f9553 Mon Sep 17 00:00:00 2001 From: Andrea Maria Piana Date: Fri, 3 Jul 2020 10:02:28 +0200 Subject: [PATCH] Send gorush notifications --- protocol/protobuf/push_notifications.pb.go | 289 +++++++++++++----- protocol/protobuf/push_notifications.proto | 26 +- protocol/push_notification_server/common.go | 58 ++++ protocol/push_notification_server/gorush.go | 79 +++++ .../push_notification_server/gorush_test.go | 107 +++++++ .../push_notification_server.go | 109 +++---- .../push_notification_server_persistence.go | 24 +- ...sh_notification_server_persistence_test.go | 4 +- .../push_notification_server_test.go | 12 +- 9 files changed, 545 insertions(+), 163 deletions(-) create mode 100644 protocol/push_notification_server/common.go create mode 100644 protocol/push_notification_server/gorush.go create mode 100644 protocol/push_notification_server/gorush_test.go diff --git a/protocol/protobuf/push_notifications.pb.go b/protocol/protobuf/push_notifications.pb.go index 603e10b94..f853da320 100644 --- a/protocol/protobuf/push_notifications.pb.go +++ b/protocol/protobuf/push_notifications.pb.go @@ -82,6 +82,37 @@ func (PushNotificationRegistrationResponse_ErrorType) EnumDescriptor() ([]byte, return fileDescriptor_200acd86044eaa5d, []int{1, 0} } +type PushNotificationReport_ErrorType int32 + +const ( + PushNotificationReport_UNKNOWN_ERROR_TYPE PushNotificationReport_ErrorType = 0 + PushNotificationReport_WRONG_TOKEN PushNotificationReport_ErrorType = 1 + PushNotificationReport_INTERNAL_ERROR PushNotificationReport_ErrorType = 2 + PushNotificationReport_NOT_REGISTERED PushNotificationReport_ErrorType = 3 +) + +var PushNotificationReport_ErrorType_name = map[int32]string{ + 0: "UNKNOWN_ERROR_TYPE", + 1: "WRONG_TOKEN", + 2: "INTERNAL_ERROR", + 3: "NOT_REGISTERED", +} + +var PushNotificationReport_ErrorType_value = map[string]int32{ + "UNKNOWN_ERROR_TYPE": 0, + "WRONG_TOKEN": 1, + "INTERNAL_ERROR": 2, + "NOT_REGISTERED": 3, +} + +func (x PushNotificationReport_ErrorType) String() string { + return proto.EnumName(PushNotificationReport_ErrorType_name, int32(x)) +} + +func (PushNotificationReport_ErrorType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_200acd86044eaa5d, []int{9, 0} +} + type PushNotificationRegistration struct { TokenType PushNotificationRegistration_TokenType `protobuf:"varint,1,opt,name=token_type,json=tokenType,proto3,enum=protobuf.PushNotificationRegistration_TokenType" json:"token_type,omitempty"` Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` @@ -486,6 +517,9 @@ func (m *PushNotificationQueryResponse) GetSuccess() bool { type PushNotification struct { AccessToken string `protobuf:"bytes,1,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"` ChatId string `protobuf:"bytes,2,opt,name=chat_id,json=chatId,proto3" json:"chat_id,omitempty"` + PublicKey []byte `protobuf:"bytes,3,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + 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"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -530,11 +564,31 @@ func (m *PushNotification) GetChatId() string { return "" } +func (m *PushNotification) GetPublicKey() []byte { + if m != nil { + return m.PublicKey + } + return nil +} + +func (m *PushNotification) GetInstallationId() string { + if m != nil { + return m.InstallationId + } + return "" +} + +func (m *PushNotification) GetMessage() []byte { + if m != nil { + return m.Message + } + return nil +} + type PushNotificationRequest struct { Requests []*PushNotification `protobuf:"bytes,1,rep,name=requests,proto3" json:"requests,omitempty"` - Message []byte `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` - MessageId string `protobuf:"bytes,3,opt,name=message_id,json=messageId,proto3" json:"message_id,omitempty"` - AckRequired string `protobuf:"bytes,4,opt,name=ack_required,json=ackRequired,proto3" json:"ack_required,omitempty"` + MessageId string `protobuf:"bytes,2,opt,name=message_id,json=messageId,proto3" json:"message_id,omitempty"` + AckRequired string `protobuf:"bytes,3,opt,name=ack_required,json=ackRequired,proto3" json:"ack_required,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -572,13 +626,6 @@ func (m *PushNotificationRequest) GetRequests() []*PushNotification { return nil } -func (m *PushNotificationRequest) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - func (m *PushNotificationRequest) GetMessageId() string { if m != nil { return m.MessageId @@ -593,48 +640,120 @@ func (m *PushNotificationRequest) GetAckRequired() string { return "" } -type PushNotificationAcknowledgement struct { - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` +type PushNotificationReport struct { + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + Error PushNotificationReport_ErrorType `protobuf:"varint,2,opt,name=error,proto3,enum=protobuf.PushNotificationReport_ErrorType" json:"error,omitempty"` + PublicKey []byte `protobuf:"bytes,3,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + InstallationId string `protobuf:"bytes,4,opt,name=installation_id,json=installationId,proto3" json:"installation_id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } -func (m *PushNotificationAcknowledgement) Reset() { *m = PushNotificationAcknowledgement{} } -func (m *PushNotificationAcknowledgement) String() string { return proto.CompactTextString(m) } -func (*PushNotificationAcknowledgement) ProtoMessage() {} -func (*PushNotificationAcknowledgement) Descriptor() ([]byte, []int) { +func (m *PushNotificationReport) Reset() { *m = PushNotificationReport{} } +func (m *PushNotificationReport) String() string { return proto.CompactTextString(m) } +func (*PushNotificationReport) ProtoMessage() {} +func (*PushNotificationReport) Descriptor() ([]byte, []int) { return fileDescriptor_200acd86044eaa5d, []int{9} } -func (m *PushNotificationAcknowledgement) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PushNotificationAcknowledgement.Unmarshal(m, b) +func (m *PushNotificationReport) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PushNotificationReport.Unmarshal(m, b) } -func (m *PushNotificationAcknowledgement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PushNotificationAcknowledgement.Marshal(b, m, deterministic) +func (m *PushNotificationReport) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PushNotificationReport.Marshal(b, m, deterministic) } -func (m *PushNotificationAcknowledgement) XXX_Merge(src proto.Message) { - xxx_messageInfo_PushNotificationAcknowledgement.Merge(m, src) +func (m *PushNotificationReport) XXX_Merge(src proto.Message) { + xxx_messageInfo_PushNotificationReport.Merge(m, src) } -func (m *PushNotificationAcknowledgement) XXX_Size() int { - return xxx_messageInfo_PushNotificationAcknowledgement.Size(m) +func (m *PushNotificationReport) XXX_Size() int { + return xxx_messageInfo_PushNotificationReport.Size(m) } -func (m *PushNotificationAcknowledgement) XXX_DiscardUnknown() { - xxx_messageInfo_PushNotificationAcknowledgement.DiscardUnknown(m) +func (m *PushNotificationReport) XXX_DiscardUnknown() { + xxx_messageInfo_PushNotificationReport.DiscardUnknown(m) } -var xxx_messageInfo_PushNotificationAcknowledgement proto.InternalMessageInfo +var xxx_messageInfo_PushNotificationReport proto.InternalMessageInfo -func (m *PushNotificationAcknowledgement) GetId() string { +func (m *PushNotificationReport) GetSuccess() bool { if m != nil { - return m.Id + return m.Success + } + return false +} + +func (m *PushNotificationReport) GetError() PushNotificationReport_ErrorType { + if m != nil { + return m.Error + } + return PushNotificationReport_UNKNOWN_ERROR_TYPE +} + +func (m *PushNotificationReport) GetPublicKey() []byte { + if m != nil { + return m.PublicKey + } + return nil +} + +func (m *PushNotificationReport) GetInstallationId() string { + if m != nil { + return m.InstallationId } return "" } +type PushNotificationResponse struct { + MessageId string `protobuf:"bytes,1,opt,name=message_id,json=messageId,proto3" json:"message_id,omitempty"` + Reports []*PushNotificationReport `protobuf:"bytes,2,rep,name=reports,proto3" json:"reports,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PushNotificationResponse) Reset() { *m = PushNotificationResponse{} } +func (m *PushNotificationResponse) String() string { return proto.CompactTextString(m) } +func (*PushNotificationResponse) ProtoMessage() {} +func (*PushNotificationResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_200acd86044eaa5d, []int{10} +} + +func (m *PushNotificationResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PushNotificationResponse.Unmarshal(m, b) +} +func (m *PushNotificationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PushNotificationResponse.Marshal(b, m, deterministic) +} +func (m *PushNotificationResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PushNotificationResponse.Merge(m, src) +} +func (m *PushNotificationResponse) XXX_Size() int { + return xxx_messageInfo_PushNotificationResponse.Size(m) +} +func (m *PushNotificationResponse) XXX_DiscardUnknown() { + xxx_messageInfo_PushNotificationResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_PushNotificationResponse proto.InternalMessageInfo + +func (m *PushNotificationResponse) GetMessageId() string { + if m != nil { + return m.MessageId + } + return "" +} + +func (m *PushNotificationResponse) GetReports() []*PushNotificationReport { + if m != nil { + return m.Reports + } + return nil +} + func init() { proto.RegisterEnum("protobuf.PushNotificationRegistration_TokenType", PushNotificationRegistration_TokenType_name, PushNotificationRegistration_TokenType_value) proto.RegisterEnum("protobuf.PushNotificationRegistrationResponse_ErrorType", PushNotificationRegistrationResponse_ErrorType_name, PushNotificationRegistrationResponse_ErrorType_value) + proto.RegisterEnum("protobuf.PushNotificationReport_ErrorType", PushNotificationReport_ErrorType_name, PushNotificationReport_ErrorType_value) proto.RegisterType((*PushNotificationRegistration)(nil), "protobuf.PushNotificationRegistration") proto.RegisterType((*PushNotificationRegistrationResponse)(nil), "protobuf.PushNotificationRegistrationResponse") proto.RegisterType((*PushNotificationAdvertisementInfo)(nil), "protobuf.PushNotificationAdvertisementInfo") @@ -644,59 +763,65 @@ func init() { proto.RegisterType((*PushNotificationQueryResponse)(nil), "protobuf.PushNotificationQueryResponse") proto.RegisterType((*PushNotification)(nil), "protobuf.PushNotification") proto.RegisterType((*PushNotificationRequest)(nil), "protobuf.PushNotificationRequest") - proto.RegisterType((*PushNotificationAcknowledgement)(nil), "protobuf.PushNotificationAcknowledgement") + proto.RegisterType((*PushNotificationReport)(nil), "protobuf.PushNotificationReport") + proto.RegisterType((*PushNotificationResponse)(nil), "protobuf.PushNotificationResponse") } func init() { proto.RegisterFile("push_notifications.proto", fileDescriptor_200acd86044eaa5d) } var fileDescriptor_200acd86044eaa5d = []byte{ - // 766 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0xdd, 0x6e, 0xda, 0x48, - 0x14, 0x5e, 0x1b, 0x92, 0xe0, 0x13, 0x96, 0x90, 0x51, 0x7e, 0xbc, 0xd1, 0x66, 0x43, 0xbc, 0x95, - 0x8a, 0x5a, 0x09, 0xb5, 0xa9, 0xd4, 0xe6, 0x96, 0x12, 0xa7, 0xb5, 0x12, 0x0c, 0x1d, 0xa0, 0x55, - 0xaf, 0x2c, 0x63, 0x0f, 0xc1, 0xc2, 0xb1, 0xe9, 0xcc, 0x38, 0x11, 0x17, 0x95, 0xfa, 0x04, 0x7d, - 0x93, 0xde, 0xe4, 0x1d, 0xfa, 0x5e, 0x95, 0xc7, 0x36, 0x21, 0x40, 0x22, 0xae, 0xec, 0xf3, 0xcd, - 0xf9, 0x66, 0xe6, 0x7c, 0xe7, 0x7c, 0x03, 0xea, 0x38, 0x62, 0x43, 0x2b, 0x08, 0xb9, 0x37, 0xf0, - 0x1c, 0x9b, 0x7b, 0x61, 0xc0, 0x6a, 0x63, 0x1a, 0xf2, 0x10, 0x15, 0xc4, 0xa7, 0x1f, 0x0d, 0xb4, - 0xdf, 0x39, 0xf8, 0xb7, 0x1d, 0xb1, 0xa1, 0x39, 0x93, 0x85, 0xc9, 0x95, 0xc7, 0x38, 0x15, 0xff, - 0xa8, 0x05, 0xc0, 0xc3, 0x11, 0x09, 0x2c, 0x3e, 0x19, 0x13, 0x55, 0xaa, 0x48, 0xd5, 0xd2, 0xc9, - 0xab, 0x5a, 0xc6, 0xaf, 0x3d, 0xc5, 0xad, 0x75, 0x63, 0x62, 0x77, 0x32, 0x26, 0x58, 0xe1, 0xd9, - 0x2f, 0xda, 0x81, 0x35, 0x11, 0xa8, 0x72, 0x45, 0xaa, 0x2a, 0x38, 0x09, 0xd0, 0x73, 0xd8, 0xf2, - 0x02, 0xc6, 0x6d, 0xdf, 0x17, 0x54, 0xcb, 0x73, 0xd5, 0x9c, 0x58, 0x2f, 0xcd, 0xc2, 0x86, 0x8b, - 0x8e, 0xa1, 0x68, 0x3b, 0x0e, 0x61, 0xcc, 0x4a, 0x76, 0xc9, 0x8b, 0xac, 0xcd, 0x04, 0x13, 0x07, - 0x22, 0x15, 0x36, 0x48, 0x60, 0xf7, 0x7d, 0xe2, 0xaa, 0x6b, 0x15, 0xa9, 0x5a, 0xc0, 0x59, 0x18, - 0xaf, 0xdc, 0x10, 0xca, 0xbc, 0x30, 0x50, 0xd7, 0x2b, 0x52, 0x35, 0x8f, 0xb3, 0x10, 0xbd, 0x80, - 0x6d, 0xdb, 0xf7, 0xc3, 0x5b, 0xe2, 0x5a, 0x11, 0x23, 0xd4, 0xf2, 0x3d, 0xc6, 0xd5, 0x8d, 0x4a, - 0xae, 0x5a, 0xc4, 0x5b, 0xe9, 0x42, 0x8f, 0x11, 0x7a, 0xe9, 0x31, 0x1e, 0xe7, 0xf6, 0xfd, 0xd0, - 0x19, 0x11, 0xd7, 0x72, 0x86, 0x36, 0x4f, 0x72, 0x0b, 0x49, 0x6e, 0xba, 0xd0, 0x18, 0xda, 0x5c, - 0xe4, 0xfe, 0x07, 0x10, 0x05, 0x54, 0x88, 0x42, 0xa8, 0xaa, 0x88, 0xeb, 0xcc, 0x20, 0xda, 0x39, - 0x28, 0x53, 0x95, 0xd0, 0x1e, 0xa0, 0x9e, 0x79, 0x61, 0xb6, 0xbe, 0x98, 0x56, 0xb7, 0x75, 0xa1, - 0x9b, 0x56, 0xf7, 0x6b, 0x5b, 0x2f, 0xff, 0x85, 0xfe, 0x06, 0xa5, 0xde, 0x4e, 0xb1, 0xb2, 0x84, - 0x10, 0x94, 0xce, 0x0d, 0xac, 0xbf, 0xaf, 0x77, 0xf4, 0x14, 0x93, 0xb5, 0x3b, 0x19, 0x9e, 0x3d, - 0xd5, 0x0b, 0x4c, 0xd8, 0x38, 0x0c, 0x18, 0x89, 0x25, 0x60, 0x91, 0x10, 0x4b, 0x34, 0xb3, 0x80, - 0xb3, 0x10, 0x99, 0xb0, 0x46, 0x28, 0x0d, 0xa9, 0x68, 0x4c, 0xe9, 0xe4, 0x74, 0xb5, 0x26, 0x67, - 0x1b, 0xd7, 0xf4, 0x98, 0x2b, 0x9a, 0x9d, 0x6c, 0x83, 0x0e, 0x01, 0x28, 0xf9, 0x16, 0x11, 0xc6, - 0xb3, 0x6e, 0x16, 0xb1, 0x92, 0x22, 0x86, 0xab, 0xfd, 0x90, 0x40, 0x99, 0x72, 0x66, 0x4b, 0xd7, - 0x31, 0x6e, 0xe1, 0xac, 0xf4, 0x5d, 0xd8, 0x6e, 0xd6, 0x2f, 0xcf, 0x5b, 0xb8, 0xa9, 0x9f, 0x59, - 0x4d, 0xbd, 0xd3, 0xa9, 0x7f, 0xd0, 0xcb, 0x12, 0xda, 0x81, 0xf2, 0x67, 0x1d, 0x77, 0x8c, 0x96, - 0x69, 0x35, 0x8d, 0x4e, 0xb3, 0xde, 0x6d, 0x7c, 0x2c, 0xcb, 0xe8, 0x00, 0xf6, 0x7a, 0x66, 0xa7, - 0xd7, 0x6e, 0xb7, 0x70, 0x57, 0x3f, 0x9b, 0xd5, 0x30, 0x17, 0x8b, 0x66, 0x98, 0x5d, 0x1d, 0x9b, - 0xf5, 0xcb, 0xe4, 0x84, 0x72, 0x5e, 0xfb, 0x29, 0xc1, 0xf1, 0x7c, 0x6d, 0x75, 0xf7, 0x86, 0x50, - 0xee, 0x31, 0x72, 0x4d, 0x02, 0x6e, 0x04, 0x83, 0x30, 0xae, 0x63, 0x1c, 0xf5, 0x7d, 0xcf, 0xb1, - 0x46, 0x64, 0x22, 0x44, 0x2b, 0x62, 0x25, 0x41, 0x2e, 0xc8, 0x64, 0x61, 0x20, 0xe5, 0xc5, 0x81, - 0x5c, 0x75, 0xb8, 0xb5, 0xef, 0xa0, 0x36, 0xc2, 0x80, 0xdb, 0x0e, 0x6f, 0x84, 0x2e, 0x79, 0x70, - 0x15, 0x64, 0xc3, 0xde, 0x82, 0x9f, 0x2d, 0x2f, 0x18, 0x84, 0xaa, 0x54, 0xc9, 0x55, 0x37, 0x4f, - 0x5e, 0x3e, 0xde, 0xaf, 0x85, 0x9a, 0xf0, 0xce, 0x78, 0x2e, 0x25, 0x46, 0xb5, 0x53, 0xd8, 0x9d, - 0xa7, 0x7e, 0x8a, 0x08, 0x9d, 0xa0, 0x23, 0xd8, 0xbc, 0x97, 0x80, 0x89, 0x03, 0x8b, 0x18, 0xa6, - 0x1a, 0x30, 0xed, 0x4e, 0x82, 0x7f, 0x96, 0x52, 0x85, 0x82, 0xf3, 0x12, 0x49, 0x2b, 0x49, 0x24, - 0x2f, 0xf5, 0xff, 0xc3, 0x6e, 0xe4, 0xe6, 0xbb, 0xb1, 0xd4, 0xc7, 0xf9, 0xa5, 0x3e, 0xd6, 0x28, - 0x1c, 0x2e, 0xbd, 0xf3, 0xd4, 0x2b, 0xef, 0x20, 0x3f, 0x23, 0xf0, 0xff, 0x8f, 0x0b, 0x3c, 0x2d, - 0x15, 0x0b, 0xc2, 0xac, 0xc9, 0xe4, 0x07, 0x26, 0xd3, 0x4c, 0x28, 0xcf, 0x93, 0x57, 0x91, 0x67, - 0x1f, 0x36, 0xc4, 0x53, 0x33, 0x95, 0x65, 0x3d, 0x0e, 0x0d, 0x57, 0xfb, 0x25, 0xc1, 0xfe, 0xa2, - 0x3d, 0x85, 0xc7, 0xd0, 0x5b, 0x28, 0xa4, 0x76, 0x63, 0x69, 0x09, 0x07, 0x4f, 0x78, 0x7a, 0x9a, - 0x1b, 0xdf, 0xfe, 0x9a, 0x30, 0x66, 0x5f, 0x11, 0x71, 0x58, 0x11, 0x67, 0x61, 0x2c, 0x7e, 0xfa, - 0x7b, 0x3f, 0xc3, 0x4a, 0x8a, 0x64, 0x6f, 0xf3, 0xc8, 0x8a, 0x37, 0xf2, 0x28, 0x71, 0xef, 0xdf, - 0xe6, 0x11, 0x4e, 0x21, 0xed, 0x35, 0x1c, 0x2d, 0x4c, 0xa7, 0x33, 0x0a, 0xc2, 0x5b, 0x9f, 0xb8, - 0x57, 0xc9, 0xa0, 0x97, 0x40, 0xf6, 0xdc, 0x54, 0x04, 0xd9, 0x73, 0xfb, 0xeb, 0xe2, 0xce, 0x6f, - 0xfe, 0x04, 0x00, 0x00, 0xff, 0xff, 0x16, 0x49, 0x40, 0xfd, 0xcf, 0x06, 0x00, 0x00, + // 847 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x94, 0x51, 0x8f, 0xdb, 0x44, + 0x10, 0xc7, 0xb1, 0x93, 0xbb, 0xc4, 0x93, 0x70, 0x97, 0xae, 0xae, 0x57, 0x53, 0x51, 0x48, 0x0d, + 0x12, 0x51, 0x91, 0x22, 0x74, 0x48, 0x50, 0xf1, 0x44, 0xb8, 0xf3, 0x1d, 0xd1, 0x5d, 0xec, 0xb0, + 0xf1, 0x51, 0x21, 0x21, 0x59, 0x8e, 0xbd, 0xd7, 0x58, 0x71, 0x6d, 0xb3, 0xbb, 0x2e, 0xca, 0x03, + 0x12, 0x9f, 0x80, 0x17, 0xde, 0xf8, 0x14, 0xa8, 0xdf, 0x81, 0xef, 0x85, 0xbc, 0xb6, 0x53, 0xc7, + 0x71, 0x73, 0x79, 0xe8, 0x93, 0x3d, 0xb3, 0x33, 0xbb, 0x3b, 0xbf, 0xd9, 0xf9, 0x83, 0x1a, 0x27, + 0x6c, 0x61, 0x87, 0x11, 0xf7, 0xef, 0x7c, 0xd7, 0xe1, 0x7e, 0x14, 0xb2, 0x61, 0x4c, 0x23, 0x1e, + 0xa1, 0xb6, 0xf8, 0xcc, 0x93, 0x3b, 0xed, 0xbf, 0x06, 0x7c, 0x3c, 0x4d, 0xd8, 0xc2, 0x28, 0x45, + 0x61, 0xf2, 0xd2, 0x67, 0x9c, 0x8a, 0x7f, 0x64, 0x02, 0xf0, 0x68, 0x49, 0x42, 0x9b, 0xaf, 0x62, + 0xa2, 0x4a, 0x7d, 0x69, 0x70, 0x74, 0xf6, 0xd5, 0xb0, 0xc8, 0x1f, 0xee, 0xca, 0x1d, 0x5a, 0x69, + 0xa2, 0xb5, 0x8a, 0x09, 0x56, 0x78, 0xf1, 0x8b, 0x4e, 0xe0, 0x40, 0x18, 0xaa, 0xdc, 0x97, 0x06, + 0x0a, 0xce, 0x0c, 0xf4, 0x05, 0x1c, 0xfb, 0x21, 0xe3, 0x4e, 0x10, 0x88, 0x54, 0xdb, 0xf7, 0xd4, + 0x86, 0x58, 0x3f, 0x2a, 0xbb, 0xc7, 0x1e, 0x7a, 0x0a, 0x5d, 0xc7, 0x75, 0x09, 0x63, 0x76, 0xb6, + 0x4b, 0x53, 0x44, 0x75, 0x32, 0x9f, 0x38, 0x10, 0xa9, 0xd0, 0x22, 0xa1, 0x33, 0x0f, 0x88, 0xa7, + 0x1e, 0xf4, 0xa5, 0x41, 0x1b, 0x17, 0x66, 0xba, 0xf2, 0x9a, 0x50, 0xe6, 0x47, 0xa1, 0x7a, 0xd8, + 0x97, 0x06, 0x4d, 0x5c, 0x98, 0xe8, 0x19, 0x3c, 0x70, 0x82, 0x20, 0xfa, 0x9d, 0x78, 0x76, 0xc2, + 0x08, 0xb5, 0x03, 0x9f, 0x71, 0xb5, 0xd5, 0x6f, 0x0c, 0xba, 0xf8, 0x38, 0x5f, 0xb8, 0x65, 0x84, + 0xde, 0xf8, 0x8c, 0xa7, 0xb1, 0xf3, 0x20, 0x72, 0x97, 0xc4, 0xb3, 0xdd, 0x85, 0xc3, 0xb3, 0xd8, + 0x76, 0x16, 0x9b, 0x2f, 0x9c, 0x2f, 0x1c, 0x2e, 0x62, 0x3f, 0x01, 0x48, 0x42, 0x2a, 0xa0, 0x10, + 0xaa, 0x2a, 0xe2, 0x3a, 0x25, 0x8f, 0x76, 0x09, 0xca, 0x9a, 0x12, 0x3a, 0x05, 0x74, 0x6b, 0x5c, + 0x1b, 0xe6, 0x0b, 0xc3, 0xb6, 0xcc, 0x6b, 0xdd, 0xb0, 0xad, 0x5f, 0xa6, 0x7a, 0xef, 0x03, 0xf4, + 0x21, 0x28, 0xa3, 0x69, 0xee, 0xeb, 0x49, 0x08, 0xc1, 0xd1, 0xe5, 0x18, 0xeb, 0x3f, 0x8c, 0x66, + 0x7a, 0xee, 0x93, 0xb5, 0x37, 0x32, 0x7c, 0xbe, 0xab, 0x17, 0x98, 0xb0, 0x38, 0x0a, 0x19, 0x49, + 0x11, 0xb0, 0x44, 0xc0, 0x12, 0xcd, 0x6c, 0xe3, 0xc2, 0x44, 0x06, 0x1c, 0x10, 0x4a, 0x23, 0x2a, + 0x1a, 0x73, 0x74, 0xf6, 0x7c, 0xbf, 0x26, 0x17, 0x1b, 0x0f, 0xf5, 0x34, 0x57, 0x34, 0x3b, 0xdb, + 0x06, 0x3d, 0x01, 0xa0, 0xe4, 0xb7, 0x84, 0x30, 0x5e, 0x74, 0xb3, 0x8b, 0x95, 0xdc, 0x33, 0xf6, + 0xb4, 0x3f, 0x25, 0x50, 0xd6, 0x39, 0xe5, 0xd2, 0x75, 0x8c, 0x4d, 0x5c, 0x94, 0xfe, 0x10, 0x1e, + 0x4c, 0x46, 0x37, 0x97, 0x26, 0x9e, 0xe8, 0x17, 0xf6, 0x44, 0x9f, 0xcd, 0x46, 0x57, 0x7a, 0x4f, + 0x42, 0x27, 0xd0, 0xfb, 0x59, 0xc7, 0xb3, 0xb1, 0x69, 0xd8, 0x93, 0xf1, 0x6c, 0x32, 0xb2, 0xce, + 0x7f, 0xec, 0xc9, 0xe8, 0x31, 0x9c, 0xde, 0x1a, 0xb3, 0xdb, 0xe9, 0xd4, 0xc4, 0x96, 0x7e, 0x51, + 0x66, 0xd8, 0x48, 0xa1, 0x8d, 0x0d, 0x4b, 0xc7, 0xc6, 0xe8, 0x26, 0x3b, 0xa1, 0xd7, 0xd4, 0xfe, + 0x92, 0xe0, 0x69, 0xb5, 0xb6, 0x91, 0xf7, 0x9a, 0x50, 0xee, 0x33, 0xf2, 0x8a, 0x84, 0x7c, 0x1c, + 0xde, 0x45, 0x69, 0x1d, 0x71, 0x32, 0x0f, 0x7c, 0xd7, 0x5e, 0x92, 0x95, 0x80, 0xd6, 0xc5, 0x4a, + 0xe6, 0xb9, 0x26, 0xab, 0xad, 0x07, 0x29, 0x6f, 0x3f, 0xc8, 0x7d, 0x1f, 0xb7, 0xf6, 0x07, 0xa8, + 0xe7, 0x51, 0xc8, 0x1d, 0x97, 0x9f, 0x47, 0x1e, 0xd9, 0xb8, 0x0a, 0x72, 0xe0, 0x74, 0x6b, 0x9e, + 0x6d, 0x3f, 0xbc, 0x8b, 0x54, 0xa9, 0xdf, 0x18, 0x74, 0xce, 0xbe, 0x7c, 0x77, 0xbf, 0xb6, 0x6a, + 0xc2, 0x27, 0x71, 0x25, 0x24, 0xf5, 0x6a, 0xcf, 0xe1, 0x61, 0x35, 0xf5, 0xa7, 0x84, 0xd0, 0x15, + 0xfa, 0x14, 0x3a, 0x6f, 0x11, 0x30, 0x71, 0x60, 0x17, 0xc3, 0x9a, 0x01, 0xd3, 0xde, 0x48, 0xf0, + 0x51, 0x6d, 0xaa, 0x20, 0x58, 0x45, 0x24, 0xed, 0x85, 0x48, 0xae, 0x9d, 0xff, 0xcd, 0x6e, 0x34, + 0xaa, 0xdd, 0xa8, 0x9d, 0xe3, 0x66, 0xed, 0x1c, 0x6b, 0x14, 0x9e, 0xd4, 0xde, 0x79, 0x3d, 0x2b, + 0xdf, 0x42, 0xb3, 0x04, 0xf8, 0xb3, 0x77, 0x03, 0x5e, 0x97, 0x8a, 0x45, 0x42, 0x79, 0xc8, 0xe4, + 0x8d, 0x21, 0xd3, 0xfe, 0x95, 0xa0, 0x57, 0xcd, 0xde, 0x87, 0xcf, 0x23, 0x68, 0x09, 0xad, 0x59, + 0x73, 0x39, 0x4c, 0xcd, 0xfb, 0x79, 0xd4, 0x70, 0x6d, 0xd6, 0x72, 0x55, 0xa1, 0xf5, 0x8a, 0x30, + 0xe6, 0xbc, 0x24, 0x42, 0x34, 0xbb, 0xb8, 0x30, 0xb5, 0xbf, 0x25, 0x78, 0xb4, 0xad, 0x00, 0x62, + 0x8c, 0xd1, 0x37, 0xd0, 0xce, 0x27, 0x9a, 0xe5, 0x94, 0x1e, 0xef, 0x90, 0x8d, 0x75, 0x6c, 0x7a, + 0xeb, 0x7c, 0xfb, 0xb7, 0x15, 0x29, 0xb9, 0xa7, 0x10, 0xf9, 0xa5, 0x9d, 0x86, 0xfb, 0x94, 0x14, + 0xd3, 0xd2, 0x71, 0xdc, 0x25, 0xce, 0x5d, 0xda, 0x3f, 0x32, 0x9c, 0x6e, 0xdf, 0x2a, 0x8e, 0x28, + 0xdf, 0x21, 0x71, 0xdf, 0x6f, 0x4a, 0xdc, 0xb3, 0x5d, 0x12, 0x97, 0x6e, 0x55, 0x2b, 0x6a, 0xef, + 0x03, 0xb7, 0xf6, 0xeb, 0x3e, 0xe2, 0x77, 0x0c, 0x9d, 0x17, 0xd8, 0x34, 0xae, 0xca, 0xca, 0x5f, + 0x11, 0x31, 0x39, 0xf5, 0x19, 0xa6, 0x65, 0x63, 0xfd, 0x6a, 0x3c, 0xb3, 0x74, 0xac, 0x5f, 0xf4, + 0x1a, 0x5a, 0x02, 0xea, 0x76, 0x41, 0xf9, 0xa3, 0xde, 0x44, 0x2f, 0x55, 0xd1, 0x7f, 0x07, 0x2d, + 0x2a, 0x6a, 0x4f, 0x9f, 0x6e, 0xda, 0xd0, 0xfe, 0x7d, 0x90, 0x70, 0x91, 0x30, 0x3f, 0x14, 0x91, + 0x5f, 0xff, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xb5, 0x18, 0xec, 0xa3, 0x79, 0x08, 0x00, 0x00, } diff --git a/protocol/protobuf/push_notifications.proto b/protocol/protobuf/push_notifications.proto index f3b5bc9a2..e88dcfd6f 100644 --- a/protocol/protobuf/push_notifications.proto +++ b/protocol/protobuf/push_notifications.proto @@ -62,15 +62,31 @@ message PushNotificationQueryResponse { message PushNotification { string access_token = 1; string chat_id = 2; + bytes public_key = 3; + string installation_id = 4; + bytes message = 5; } message PushNotificationRequest { repeated PushNotification requests = 1; - bytes message = 2; - string message_id = 3; - string ack_required = 4; + string message_id = 2; + string ack_required = 3; } -message PushNotificationAcknowledgement { - string id = 1; +message PushNotificationReport { + bool success = 1; + ErrorType error = 2; + enum ErrorType { + UNKNOWN_ERROR_TYPE = 0; + WRONG_TOKEN = 1; + INTERNAL_ERROR = 2; + NOT_REGISTERED = 3; + } + bytes public_key = 3; + string installation_id = 4; +} + +message PushNotificationResponse { + string message_id = 1; + repeated PushNotificationReport reports = 2; } diff --git a/protocol/push_notification_server/common.go b/protocol/push_notification_server/common.go new file mode 100644 index 000000000..589a6301b --- /dev/null +++ b/protocol/push_notification_server/common.go @@ -0,0 +1,58 @@ +package push_notification_server + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/ecdsa" + "github.com/status-im/status-go/eth-node/crypto" + "golang.org/x/crypto/sha3" + "io" +) + +func hashPublicKey(pk *ecdsa.PublicKey) []byte { + return shake256(crypto.CompressPubkey(pk)) +} + +func decrypt(cyphertext []byte, key []byte) ([]byte, error) { + if len(cyphertext) < nonceLength { + return nil, ErrInvalidCiphertextLength + } + + c, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + gcm, err := cipher.NewGCM(c) + if err != nil { + return nil, err + } + + nonce := cyphertext[:nonceLength] + return gcm.Open(nil, nonce, cyphertext[nonceLength:], nil) +} + +func encrypt(plaintext []byte, key []byte, reader io.Reader) ([]byte, error) { + c, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + gcm, err := cipher.NewGCM(c) + if err != nil { + return nil, err + } + + nonce := make([]byte, gcm.NonceSize()) + if _, err = io.ReadFull(reader, nonce); err != nil { + return nil, err + } + + return gcm.Seal(nonce, nonce, plaintext, nil), nil +} + +func shake256(buf []byte) []byte { + h := make([]byte, 64) + sha3.ShakeSum256(h, buf) + return h +} diff --git a/protocol/push_notification_server/gorush.go b/protocol/push_notification_server/gorush.go new file mode 100644 index 000000000..90a515b89 --- /dev/null +++ b/protocol/push_notification_server/gorush.go @@ -0,0 +1,79 @@ +package push_notification_server + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "net/http" + + "github.com/status-im/status-go/protocol/protobuf" +) + +const defaultNotificationMessage = "You have a new message" + +type GoRushRequestData struct { + EncryptedMessage string `json:"encryptedMessage"` + ChatID string `json:"chatId"` + PublicKey string `json:"publicKey"` +} + +type GoRushRequestNotification struct { + Tokens []string `json:"tokens"` + Platform uint `json:"platform"` + Message string `json:"message"` + Data *GoRushRequestData `json:"data"` +} + +type GoRushRequest struct { + Notifications []*GoRushRequestNotification `json:"notifications"` +} + +type RequestAndRegistration struct { + Request *protobuf.PushNotification + Registration *protobuf.PushNotificationRegistration +} + +func tokenTypeToGoRushPlatform(tokenType protobuf.PushNotificationRegistration_TokenType) uint { + switch tokenType { + case protobuf.PushNotificationRegistration_APN_TOKEN: + return 1 + case protobuf.PushNotificationRegistration_FIREBASE_TOKEN: + return 2 + } + return 0 +} + +func PushNotificationRegistrationToGoRushRequest(requestAndRegistrations []*RequestAndRegistration) *GoRushRequest { + goRushRequests := &GoRushRequest{} + for _, requestAndRegistration := range requestAndRegistrations { + + request := requestAndRegistration.Request + registration := requestAndRegistration.Registration + goRushRequests.Notifications = append(goRushRequests.Notifications, + &GoRushRequestNotification{ + Tokens: []string{registration.Token}, + Platform: tokenTypeToGoRushPlatform(registration.TokenType), + Message: defaultNotificationMessage, + Data: &GoRushRequestData{ + EncryptedMessage: hex.EncodeToString(request.Message), + ChatID: request.ChatId, + PublicKey: hex.EncodeToString(request.PublicKey), + }, + }) + } + return goRushRequests +} + +func sendGoRushNotification(request *GoRushRequest, url string) error { + payload, err := json.Marshal(request) + if err != nil { + return err + } + + _, err = http.Post(url+"/api/push", "application/json", bytes.NewReader(payload)) + if err != nil { + return err + } + return nil + +} diff --git a/protocol/push_notification_server/gorush_test.go b/protocol/push_notification_server/gorush_test.go new file mode 100644 index 000000000..fda1de8a5 --- /dev/null +++ b/protocol/push_notification_server/gorush_test.go @@ -0,0 +1,107 @@ +package push_notification_server + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/status-im/status-go/protocol/protobuf" +) + +func TestPushNotificationRegistrationToGoRushRequest(t *testing.T) { + message1 := []byte("message-1") + message2 := []byte("message-2") + message3 := []byte("message-3") + hexMessage1 := hex.EncodeToString(message1) + hexMessage2 := hex.EncodeToString(message2) + hexMessage3 := hex.EncodeToString(message3) + chatID := "chat-id" + publicKey1 := []byte("public-key-1") + publicKey2 := []byte("public-key-2") + installationID1 := "installation-id-1" + installationID2 := "installation-id-2" + installationID3 := "installation-id-3" + var platform1 uint = 1 + var platform2 uint = 2 + var platform3 uint = 2 + token1 := "token-1" + token2 := "token-2" + token3 := "token-3" + + requestAndRegistrations := []*RequestAndRegistration{ + { + Request: &protobuf.PushNotification{ + ChatId: chatID, + PublicKey: publicKey1, + InstallationId: installationID1, + Message: message1, + }, + Registration: &protobuf.PushNotificationRegistration{ + Token: token1, + TokenType: protobuf.PushNotificationRegistration_APN_TOKEN, + }, + }, + { + Request: &protobuf.PushNotification{ + ChatId: chatID, + PublicKey: publicKey1, + InstallationId: installationID2, + Message: message2, + }, + Registration: &protobuf.PushNotificationRegistration{ + Token: token2, + TokenType: protobuf.PushNotificationRegistration_FIREBASE_TOKEN, + }, + }, + { + Request: &protobuf.PushNotification{ + ChatId: chatID, + PublicKey: publicKey2, + InstallationId: installationID3, + Message: message3, + }, + Registration: &protobuf.PushNotificationRegistration{ + Token: token3, + TokenType: protobuf.PushNotificationRegistration_FIREBASE_TOKEN, + }, + }, + } + + expectedRequests := &GoRushRequest{ + Notifications: []*GoRushRequestNotification{ + { + Tokens: []string{token1}, + Platform: platform1, + Message: defaultNotificationMessage, + Data: &GoRushRequestData{ + EncryptedMessage: hexMessage1, + ChatID: chatID, + PublicKey: hex.EncodeToString(publicKey1), + }, + }, + { + Tokens: []string{token2}, + Platform: platform2, + Message: defaultNotificationMessage, + Data: &GoRushRequestData{ + EncryptedMessage: hexMessage2, + ChatID: chatID, + PublicKey: hex.EncodeToString(publicKey1), + }, + }, + { + Tokens: []string{token3}, + Platform: platform3, + Message: defaultNotificationMessage, + Data: &GoRushRequestData{ + EncryptedMessage: hexMessage3, + ChatID: chatID, + PublicKey: hex.EncodeToString(publicKey2), + }, + }, + }, + } + actualRequests := PushNotificationRegistrationToGoRushRequest(requestAndRegistrations) + require.Equal(t, expectedRequests, actualRequests) +} diff --git a/protocol/push_notification_server/push_notification_server.go b/protocol/push_notification_server/push_notification_server.go index 2d386d1a6..d9d761744 100644 --- a/protocol/push_notification_server/push_notification_server.go +++ b/protocol/push_notification_server/push_notification_server.go @@ -1,13 +1,8 @@ package push_notification_server import ( - "errors" - "io" - - "crypto/aes" - "crypto/cipher" "crypto/ecdsa" - "golang.org/x/crypto/sha3" + "errors" "github.com/golang/protobuf/proto" "github.com/google/uuid" @@ -90,7 +85,7 @@ func (p *Server) ValidateRegistration(publicKey *ecdsa.PublicKey, payload []byte return nil, ErrMalformedPushNotificationRegistrationInstallationID } - previousRegistration, err := p.persistence.GetPushNotificationRegistrationByPublicKeyAndInstallationID(publicKey, registration.InstallationId) + previousRegistration, err := p.persistence.GetPushNotificationRegistrationByPublicKeyAndInstallationID(hashPublicKey(publicKey), registration.InstallationId) if err != nil { return nil, err } @@ -151,6 +146,58 @@ func (p *Server) HandlePushNotificationQuery(query *protobuf.PushNotificationQue return response } +func (p *Server) HandlePushNotificationRequest(request *protobuf.PushNotificationRequest) *protobuf.PushNotificationResponse { + response := &protobuf.PushNotificationResponse{} + // We don't even send a response in this case + if request == nil || len(request.MessageId) == 0 { + return nil + } + + response.MessageId = request.MessageId + + // Collect successful requests & registrations + var requestAndRegistrations []*RequestAndRegistration + + for _, pn := range request.Requests { + registration, err := p.persistence.GetPushNotificationRegistrationByPublicKeyAndInstallationID(pn.PublicKey, pn.InstallationId) + report := &protobuf.PushNotificationReport{ + PublicKey: pn.PublicKey, + InstallationId: pn.InstallationId, + } + + if err != nil { + // TODO: log error + report.Error = protobuf.PushNotificationReport_UNKNOWN_ERROR_TYPE + } else if registration == nil { + report.Error = protobuf.PushNotificationReport_NOT_REGISTERED + } else if registration.AccessToken != pn.AccessToken { + report.Error = protobuf.PushNotificationReport_WRONG_TOKEN + } else { + // For now we just assume that the notification will be successful + requestAndRegistrations = append(requestAndRegistrations, &RequestAndRegistration{ + Request: pn, + Registration: registration, + }) + report.Success = true + } + + response.Reports = append(response.Reports, report) + } + + if len(requestAndRegistrations) == 0 { + return response + } + + // This can be done asynchronously + goRushRequest := PushNotificationRegistrationToGoRushRequest(requestAndRegistrations) + err := sendGoRushNotification(goRushRequest, p.config.GorushURL) + if err != nil { + // TODO: handle this error? + } + + return response +} + func (p *Server) HandlePushNotificationRegistration(publicKey *ecdsa.PublicKey, payload []byte) *protobuf.PushNotificationRegistrationResponse { response := &protobuf.PushNotificationRegistrationResponse{ RequestId: shake256(payload), @@ -175,12 +222,12 @@ func (p *Server) HandlePushNotificationRegistration(publicKey *ecdsa.PublicKey, Version: registration.Version, InstallationId: registration.InstallationId, } - if err := p.persistence.SavePushNotificationRegistration(publicKey, emptyRegistration); err != nil { + if err := p.persistence.SavePushNotificationRegistration(hashPublicKey(publicKey), emptyRegistration); err != nil { response.Error = protobuf.PushNotificationRegistrationResponse_INTERNAL_ERROR return response } - } else if err := p.persistence.SavePushNotificationRegistration(publicKey, registration); err != nil { + } else if err := p.persistence.SavePushNotificationRegistration(hashPublicKey(publicKey), registration); err != nil { response.Error = protobuf.PushNotificationRegistrationResponse_INTERNAL_ERROR return response } @@ -189,47 +236,3 @@ func (p *Server) HandlePushNotificationRegistration(publicKey *ecdsa.PublicKey, return response } - -func decrypt(cyphertext []byte, key []byte) ([]byte, error) { - if len(cyphertext) < nonceLength { - return nil, ErrInvalidCiphertextLength - } - - c, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - gcm, err := cipher.NewGCM(c) - if err != nil { - return nil, err - } - - nonce := cyphertext[:nonceLength] - return gcm.Open(nil, nonce, cyphertext[nonceLength:], nil) -} - -func encrypt(plaintext []byte, key []byte, reader io.Reader) ([]byte, error) { - c, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - gcm, err := cipher.NewGCM(c) - if err != nil { - return nil, err - } - - nonce := make([]byte, gcm.NonceSize()) - if _, err = io.ReadFull(reader, nonce); err != nil { - return nil, err - } - - return gcm.Seal(nonce, nonce, plaintext, nil), nil -} - -func shake256(buf []byte) []byte { - h := make([]byte, 64) - sha3.ShakeSum256(h, buf) - return h -} diff --git a/protocol/push_notification_server/push_notification_server_persistence.go b/protocol/push_notification_server/push_notification_server_persistence.go index 6213b70ff..f7f73cb67 100644 --- a/protocol/push_notification_server/push_notification_server_persistence.go +++ b/protocol/push_notification_server/push_notification_server_persistence.go @@ -1,26 +1,24 @@ package push_notification_server import ( - "crypto/ecdsa" "database/sql" "strings" "github.com/golang/protobuf/proto" - "github.com/status-im/status-go/eth-node/crypto" "github.com/status-im/status-go/protocol/protobuf" ) type Persistence interface { // GetPushNotificationRegistrationByPublicKeyAndInstallationID retrieve a push notification registration from storage given a public key and installation id - GetPushNotificationRegistrationByPublicKeyAndInstallationID(publicKey *ecdsa.PublicKey, installationID string) (*protobuf.PushNotificationRegistration, error) + GetPushNotificationRegistrationByPublicKeyAndInstallationID(publicKey []byte, installationID string) (*protobuf.PushNotificationRegistration, error) // GetPushNotificationRegistrationByPublicKey retrieve all the push notification registrations from storage given a public key GetPushNotificationRegistrationByPublicKeys(publicKeys [][]byte) ([]*PushNotificationIDAndRegistration, error) // DeletePushNotificationRegistration deletes a push notification registration from storage given a public key and installation id - DeletePushNotificationRegistration(publicKey *ecdsa.PublicKey, installationID string) error + DeletePushNotificationRegistration(publicKey []byte, installationID string) error // SavePushNotificationRegistration saves a push notification option to the db - SavePushNotificationRegistration(publicKey *ecdsa.PublicKey, registration *protobuf.PushNotificationRegistration) error + SavePushNotificationRegistration(publicKey []byte, registration *protobuf.PushNotificationRegistration) error } type SQLitePersistence struct { @@ -31,9 +29,9 @@ func NewSQLitePersistence(db *sql.DB) Persistence { return &SQLitePersistence{db: db} } -func (p *SQLitePersistence) GetPushNotificationRegistrationByPublicKeyAndInstallationID(publicKey *ecdsa.PublicKey, installationID string) (*protobuf.PushNotificationRegistration, error) { +func (p *SQLitePersistence) GetPushNotificationRegistrationByPublicKeyAndInstallationID(publicKey []byte, installationID string) (*protobuf.PushNotificationRegistration, error) { var marshaledRegistration []byte - err := p.db.QueryRow(`SELECT registration FROM push_notification_server_registrations WHERE public_key = ? AND installation_id = ?`, hashPublicKey(publicKey), installationID).Scan(&marshaledRegistration) + err := p.db.QueryRow(`SELECT registration FROM push_notification_server_registrations WHERE public_key = ? AND installation_id = ?`, publicKey, installationID).Scan(&marshaledRegistration) if err == sql.ErrNoRows { return nil, nil @@ -90,21 +88,17 @@ func (p *SQLitePersistence) GetPushNotificationRegistrationByPublicKeys(publicKe return registrations, nil } -func (p *SQLitePersistence) SavePushNotificationRegistration(publicKey *ecdsa.PublicKey, registration *protobuf.PushNotificationRegistration) error { +func (p *SQLitePersistence) SavePushNotificationRegistration(publicKey []byte, registration *protobuf.PushNotificationRegistration) error { marshaledRegistration, err := proto.Marshal(registration) if err != nil { return err } - _, err = p.db.Exec(`INSERT INTO push_notification_server_registrations (public_key, installation_id, version, registration) VALUES (?, ?, ?, ?)`, hashPublicKey(publicKey), registration.InstallationId, registration.Version, marshaledRegistration) + _, err = p.db.Exec(`INSERT INTO push_notification_server_registrations (public_key, installation_id, version, registration) VALUES (?, ?, ?, ?)`, publicKey, registration.InstallationId, registration.Version, marshaledRegistration) return err } -func (p *SQLitePersistence) DeletePushNotificationRegistration(publicKey *ecdsa.PublicKey, installationID string) error { - _, err := p.db.Exec(`DELETE FROM push_notification_server_registrations WHERE public_key = ? AND installation_id = ?`, hashPublicKey(publicKey), installationID) +func (p *SQLitePersistence) DeletePushNotificationRegistration(publicKey []byte, installationID string) error { + _, err := p.db.Exec(`DELETE FROM push_notification_server_registrations WHERE public_key = ? AND installation_id = ?`, publicKey, installationID) return err } - -func hashPublicKey(pk *ecdsa.PublicKey) []byte { - return shake256(crypto.CompressPubkey(pk)) -} diff --git a/protocol/push_notification_server/push_notification_server_persistence_test.go b/protocol/push_notification_server/push_notification_server_persistence_test.go index bc0ec7052..258a0c224 100644 --- a/protocol/push_notification_server/push_notification_server_persistence_test.go +++ b/protocol/push_notification_server/push_notification_server_persistence_test.go @@ -49,9 +49,9 @@ func (s *SQLitePersistenceSuite) TestSaveAndRetrieve() { Version: 5, } - s.Require().NoError(s.persistence.SavePushNotificationRegistration(&key.PublicKey, registration)) + s.Require().NoError(s.persistence.SavePushNotificationRegistration(hashPublicKey(&key.PublicKey), registration)) - retrievedRegistration, err := s.persistence.GetPushNotificationRegistrationByPublicKeyAndInstallationID(&key.PublicKey, installationID) + retrievedRegistration, err := s.persistence.GetPushNotificationRegistrationByPublicKeyAndInstallationID(hashPublicKey(&key.PublicKey), installationID) s.Require().NoError(err) s.Require().True(proto.Equal(registration, retrievedRegistration)) diff --git a/protocol/push_notification_server/push_notification_server_test.go b/protocol/push_notification_server/push_notification_server_test.go index 8f5d6e8b7..19c5999da 100644 --- a/protocol/push_notification_server/push_notification_server_test.go +++ b/protocol/push_notification_server/push_notification_server_test.go @@ -149,7 +149,7 @@ func (s *ServerSuite) TestPushNotificationServerValidateRegistration() { s.Require().NoError(err) // Setup persistence - s.Require().NoError(s.persistence.SavePushNotificationRegistration(&s.key.PublicKey, &protobuf.PushNotificationRegistration{ + s.Require().NoError(s.persistence.SavePushNotificationRegistration(hashPublicKey(&s.key.PublicKey), &protobuf.PushNotificationRegistration{ AccessToken: s.accessToken, TokenType: protobuf.PushNotificationRegistration_APN_TOKEN, InstallationId: s.installationID, @@ -159,7 +159,7 @@ func (s *ServerSuite) TestPushNotificationServerValidateRegistration() { s.Require().Equal(ErrInvalidPushNotificationRegistrationVersion, err) // Cleanup persistence - s.Require().NoError(s.persistence.DeletePushNotificationRegistration(&s.key.PublicKey, s.installationID)) + s.Require().NoError(s.persistence.DeletePushNotificationRegistration(hashPublicKey(&s.key.PublicKey), s.installationID)) // Unregistering message payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{ @@ -346,7 +346,7 @@ func (s *ServerSuite) TestPushNotificationHandleRegistration() { s.Require().NoError(err) // Setup persistence - s.Require().NoError(s.persistence.SavePushNotificationRegistration(&s.key.PublicKey, &protobuf.PushNotificationRegistration{ + s.Require().NoError(s.persistence.SavePushNotificationRegistration(hashPublicKey(&s.key.PublicKey), &protobuf.PushNotificationRegistration{ AccessToken: s.accessToken, InstallationId: s.installationID, Version: 2})) @@ -357,7 +357,7 @@ func (s *ServerSuite) TestPushNotificationHandleRegistration() { s.Require().Equal(response.Error, protobuf.PushNotificationRegistrationResponse_VERSION_MISMATCH) // Cleanup persistence - s.Require().NoError(s.persistence.DeletePushNotificationRegistration(&s.key.PublicKey, s.installationID)) + s.Require().NoError(s.persistence.DeletePushNotificationRegistration(hashPublicKey(&s.key.PublicKey), s.installationID)) // Missing access token payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{ @@ -421,7 +421,7 @@ func (s *ServerSuite) TestPushNotificationHandleRegistration() { s.Require().True(response.Success) // Pull from the db - retrievedRegistration, err := s.persistence.GetPushNotificationRegistrationByPublicKeyAndInstallationID(&s.key.PublicKey, s.installationID) + retrievedRegistration, err := s.persistence.GetPushNotificationRegistrationByPublicKeyAndInstallationID(hashPublicKey(&s.key.PublicKey), s.installationID) s.Require().NoError(err) s.Require().NotNil(retrievedRegistration) s.Require().True(proto.Equal(retrievedRegistration, registration)) @@ -442,7 +442,7 @@ func (s *ServerSuite) TestPushNotificationHandleRegistration() { s.Require().True(response.Success) // Check is gone from the db - retrievedRegistration, err = s.persistence.GetPushNotificationRegistrationByPublicKeyAndInstallationID(&s.key.PublicKey, s.installationID) + retrievedRegistration, err = s.persistence.GetPushNotificationRegistrationByPublicKeyAndInstallationID(hashPublicKey(&s.key.PublicKey), s.installationID) s.Require().NoError(err) s.Require().NotNil(retrievedRegistration) s.Require().Empty(retrievedRegistration.AccessToken)