Handle query from client

This commit is contained in:
Andrea Maria Piana 2020-07-02 15:57:50 +02:00
parent 2eee956dc6
commit 52da9de0c6
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
6 changed files with 326 additions and 177 deletions

View File

@ -377,7 +377,7 @@ type PushNotificationQueryInfo struct {
AccessToken string `protobuf:"bytes,1,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"`
InstallationId string `protobuf:"bytes,2,opt,name=installation_id,json=installationId,proto3" json:"installation_id,omitempty"`
PublicKey []byte `protobuf:"bytes,3,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
AllowedUserList []byte `protobuf:"bytes,4,opt,name=allowed_user_list,json=allowedUserList,proto3" json:"allowed_user_list,omitempty"`
AllowedUserList [][]byte `protobuf:"bytes,4,rep,name=allowed_user_list,json=allowedUserList,proto3" json:"allowed_user_list,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -429,7 +429,7 @@ func (m *PushNotificationQueryInfo) GetPublicKey() []byte {
return nil
}
func (m *PushNotificationQueryInfo) GetAllowedUserList() []byte {
func (m *PushNotificationQueryInfo) GetAllowedUserList() [][]byte {
if m != nil {
return m.AllowedUserList
}
@ -438,6 +438,7 @@ func (m *PushNotificationQueryInfo) GetAllowedUserList() []byte {
type PushNotificationQueryResponse struct {
Info []*PushNotificationQueryInfo `protobuf:"bytes,1,rep,name=info,proto3" json:"info,omitempty"`
Success bool `protobuf:"varint,2,opt,name=success,proto3" json:"success,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -475,6 +476,13 @@ func (m *PushNotificationQueryResponse) GetInfo() []*PushNotificationQueryInfo {
return nil
}
func (m *PushNotificationQueryResponse) GetSuccess() bool {
if m != nil {
return m.Success
}
return false
}
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"`
@ -642,53 +650,53 @@ func init() {
func init() { proto.RegisterFile("push_notifications.proto", fileDescriptor_200acd86044eaa5d) }
var fileDescriptor_200acd86044eaa5d = []byte{
// 763 bytes of a gzipped FileDescriptorProto
// 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, 0x2b,
0x2d, 0x6a, 0x25, 0xd4, 0xa6, 0x52, 0x9b, 0x5b, 0x4a, 0x9c, 0xd6, 0x4a, 0x30, 0x74, 0x80, 0xfe,
0x5c, 0x59, 0xc6, 0x1e, 0x82, 0x85, 0xe3, 0xa1, 0x9e, 0x71, 0x22, 0x2e, 0x2a, 0xf5, 0x09, 0xfa,
0x26, 0xbd, 0xc9, 0x3b, 0xf4, 0xbd, 0x2a, 0x8f, 0x6d, 0x42, 0x80, 0x44, 0x5c, 0xd9, 0xe7, 0x9b,
0xef, 0xcc, 0xcc, 0xf9, 0xce, 0xf9, 0x06, 0xd4, 0x71, 0xc4, 0x86, 0x56, 0x40, 0xb9, 0x37, 0xf0,
0x1c, 0x9b, 0x7b, 0x34, 0x60, 0xb5, 0x71, 0x48, 0x39, 0x45, 0x05, 0xf1, 0xe9, 0x47, 0x03, 0xed,
0x57, 0x0e, 0xfe, 0x6e, 0x47, 0x6c, 0x68, 0xce, 0xb0, 0x30, 0xb9, 0xf2, 0x18, 0x0f, 0xc5, 0x3f,
0x6a, 0x01, 0x70, 0x3a, 0x22, 0x81, 0xc5, 0x27, 0x63, 0xa2, 0x4a, 0x15, 0xa9, 0x5a, 0x3a, 0x79,
0x51, 0xcb, 0xf2, 0x6b, 0x4f, 0xe5, 0xd6, 0xba, 0x71, 0x62, 0x77, 0x32, 0x26, 0x58, 0xe1, 0xd9,
0x2f, 0xda, 0x81, 0x35, 0x11, 0xa8, 0x72, 0x45, 0xaa, 0x2a, 0x38, 0x09, 0xd0, 0xff, 0xb0, 0xe5,
0x05, 0x8c, 0xdb, 0xbe, 0x2f, 0x52, 0x2d, 0xcf, 0x55, 0x73, 0x62, 0xbd, 0x34, 0x0b, 0x1b, 0x2e,
0x3a, 0x86, 0xa2, 0xed, 0x38, 0x84, 0x31, 0x2b, 0xd9, 0x25, 0x2f, 0x58, 0x9b, 0x09, 0x26, 0x0e,
0x44, 0x2a, 0x6c, 0x90, 0xc0, 0xee, 0xfb, 0xc4, 0x55, 0xd7, 0x2a, 0x52, 0xb5, 0x80, 0xb3, 0x30,
0x5e, 0xb9, 0x21, 0x21, 0xf3, 0x68, 0xa0, 0xae, 0x57, 0xa4, 0x6a, 0x1e, 0x67, 0x21, 0x7a, 0x06,
0xdb, 0xb6, 0xef, 0xd3, 0x5b, 0xe2, 0x5a, 0x11, 0x23, 0xa1, 0xe5, 0x7b, 0x8c, 0xab, 0x1b, 0x95,
0x5c, 0xb5, 0x88, 0xb7, 0xd2, 0x85, 0x1e, 0x23, 0xe1, 0xa5, 0xc7, 0x78, 0xcc, 0xed, 0xfb, 0xd4,
0x19, 0x11, 0xd7, 0x72, 0x86, 0x36, 0x4f, 0xb8, 0x85, 0x84, 0x9b, 0x2e, 0x34, 0x86, 0x36, 0x17,
0xdc, 0x7f, 0x00, 0xa2, 0x20, 0x14, 0xa2, 0x90, 0x50, 0x55, 0xc4, 0x75, 0x66, 0x10, 0xed, 0x1c,
0x94, 0xa9, 0x4a, 0x68, 0x0f, 0x50, 0xcf, 0xbc, 0x30, 0x5b, 0x9f, 0x4c, 0xab, 0xdb, 0xba, 0xd0,
0x4d, 0xab, 0xfb, 0xa5, 0xad, 0x97, 0xff, 0x40, 0x7f, 0x82, 0x52, 0x6f, 0xa7, 0x58, 0x59, 0x42,
0x08, 0x4a, 0xe7, 0x06, 0xd6, 0xdf, 0xd6, 0x3b, 0x7a, 0x8a, 0xc9, 0xda, 0x9d, 0x0c, 0xff, 0x3d,
0xd5, 0x0b, 0x4c, 0xd8, 0x98, 0x06, 0x8c, 0xc4, 0x12, 0xb0, 0x48, 0x88, 0x25, 0x9a, 0x59, 0xc0,
0x59, 0x88, 0x4c, 0x58, 0x23, 0x61, 0x48, 0x43, 0xd1, 0x98, 0xd2, 0xc9, 0xe9, 0x6a, 0x4d, 0xce,
0x36, 0xae, 0xe9, 0x71, 0xae, 0x68, 0x76, 0xb2, 0x0d, 0x3a, 0x04, 0x08, 0xc9, 0xd7, 0x88, 0x30,
0x9e, 0x75, 0xb3, 0x88, 0x95, 0x14, 0x31, 0x5c, 0xed, 0xbb, 0x04, 0xca, 0x34, 0x67, 0xb6, 0x74,
0x1d, 0xe3, 0x16, 0xce, 0x4a, 0xdf, 0x85, 0xed, 0x66, 0xfd, 0xf2, 0xbc, 0x85, 0x9b, 0xfa, 0x99,
0xd5, 0xd4, 0x3b, 0x9d, 0xfa, 0x3b, 0xbd, 0x2c, 0xa1, 0x1d, 0x28, 0x7f, 0xd4, 0x71, 0xc7, 0x68,
0x99, 0x56, 0xd3, 0xe8, 0x34, 0xeb, 0xdd, 0xc6, 0xfb, 0xb2, 0x8c, 0x0e, 0x60, 0xaf, 0x67, 0x76,
0x7a, 0xed, 0x76, 0x0b, 0x77, 0xf5, 0xb3, 0x59, 0x0d, 0x73, 0xb1, 0x68, 0x86, 0xd9, 0xd5, 0xb1,
0x59, 0xbf, 0x4c, 0x4e, 0x28, 0xe7, 0xb5, 0x1f, 0x12, 0x1c, 0xcf, 0xd7, 0x56, 0x77, 0x6f, 0x48,
0xc8, 0x3d, 0x46, 0xae, 0x49, 0xc0, 0x8d, 0x60, 0x40, 0xe3, 0x3a, 0xc6, 0x51, 0xdf, 0xf7, 0x1c,
0x6b, 0x44, 0x26, 0x42, 0xb4, 0x22, 0x56, 0x12, 0xe4, 0x82, 0x4c, 0x16, 0x06, 0x52, 0x5e, 0x1c,
0xc8, 0x55, 0x87, 0x5b, 0xfb, 0x06, 0x6a, 0x83, 0x06, 0xdc, 0x76, 0x78, 0x83, 0xba, 0xe4, 0xc1,
0x55, 0x90, 0x0d, 0x7b, 0x0b, 0x7e, 0xb6, 0xbc, 0x60, 0x40, 0x55, 0xa9, 0x92, 0xab, 0x6e, 0x9e,
0x3c, 0x7f, 0xbc, 0x5f, 0x0b, 0x35, 0xe1, 0x9d, 0xf1, 0x1c, 0x25, 0x46, 0xb5, 0x53, 0xd8, 0x9d,
0x4f, 0xfd, 0x10, 0x91, 0x70, 0x82, 0x8e, 0x60, 0xf3, 0x5e, 0x02, 0x26, 0x0e, 0x2c, 0x62, 0x98,
0x6a, 0xc0, 0xb4, 0x3b, 0x09, 0xfe, 0x5a, 0x9a, 0x2a, 0x14, 0x9c, 0x97, 0x48, 0x5a, 0x49, 0x22,
0x79, 0xa9, 0xff, 0x1f, 0x76, 0x23, 0x37, 0xdf, 0x8d, 0xa5, 0x3e, 0xce, 0x0b, 0xd6, 0xbc, 0x8f,
0xb5, 0xcf, 0x70, 0xb8, 0xf4, 0xce, 0x53, 0xaf, 0xbc, 0x81, 0xfc, 0x8c, 0xc0, 0xff, 0x3e, 0x2e,
0xf0, 0xb4, 0x54, 0x2c, 0x12, 0x34, 0x13, 0xca, 0xf3, 0x94, 0x55, 0x44, 0xd8, 0x87, 0x0d, 0xf1,
0xa0, 0x4c, 0x8b, 0x5f, 0x8f, 0x43, 0xc3, 0xd5, 0x7e, 0x4a, 0xb0, 0xbf, 0x68, 0x42, 0xe1, 0x24,
0xf4, 0x1a, 0x0a, 0xa9, 0xa9, 0x58, 0x7a, 0xd1, 0x83, 0x27, 0x9c, 0x3b, 0xe5, 0xc6, 0x0f, 0xc1,
0x35, 0x61, 0xcc, 0xbe, 0x22, 0xe2, 0xb0, 0x22, 0xce, 0xc2, 0x58, 0xe2, 0xf4, 0xf7, 0x7e, 0x52,
0x95, 0x14, 0xc9, 0x5e, 0xe0, 0x91, 0x15, 0x6f, 0xe4, 0x85, 0xc4, 0xbd, 0x7f, 0x81, 0x47, 0x38,
0x85, 0xb4, 0x97, 0x70, 0xb4, 0x30, 0x83, 0xce, 0x28, 0xa0, 0xb7, 0x3e, 0x71, 0xaf, 0x92, 0x71,
0x2e, 0x81, 0xec, 0xb9, 0xa9, 0x08, 0xb2, 0xe7, 0xf6, 0xd7, 0xc5, 0x9d, 0x5f, 0xfd, 0x0e, 0x00,
0x00, 0xff, 0xff, 0x6a, 0xc9, 0xcf, 0x6e, 0xb5, 0x06, 0x00, 0x00,
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,
}

View File

@ -51,11 +51,12 @@ message PushNotificationQueryInfo {
string access_token = 1;
string installation_id = 2;
bytes public_key = 3;
bytes allowed_user_list = 4;
repeated bytes allowed_user_list = 4;
}
message PushNotificationQueryResponse {
repeated PushNotificationQueryInfo info = 1;
bool success = 2;
}
message PushNotification {

View File

@ -90,7 +90,7 @@ func (p *Server) ValidateRegistration(publicKey *ecdsa.PublicKey, payload []byte
return nil, ErrMalformedPushNotificationRegistrationInstallationID
}
previousRegistration, err := p.persistence.GetPushNotificationRegistration(publicKey, registration.InstallationId)
previousRegistration, err := p.persistence.GetPushNotificationRegistrationByPublicKeyAndInstallationID(publicKey, registration.InstallationId)
if err != nil {
return nil, err
}
@ -115,6 +115,38 @@ func (p *Server) ValidateRegistration(publicKey *ecdsa.PublicKey, payload []byte
return registration, nil
}
func (p *Server) HandlePushNotificationQuery(query *protobuf.PushNotificationQuery) *protobuf.PushNotificationQueryResponse {
response := &protobuf.PushNotificationQueryResponse{}
if query == nil || len(query.PublicKeys) == 0 {
return response
}
registrations, err := p.persistence.GetPushNotificationRegistrationByPublicKeys(query.PublicKeys)
if err != nil {
// TODO: log errors
return response
}
for _, idAndResponse := range registrations {
registration := idAndResponse.Registration
info := &protobuf.PushNotificationQueryInfo{
PublicKey: idAndResponse.ID,
InstallationId: registration.InstallationId,
}
if len(registration.AllowedUserList) > 0 {
info.AllowedUserList = registration.AllowedUserList
} else {
info.AccessToken = registration.AccessToken
}
response.Info = append(response.Info, info)
}
response.Success = true
return response
}
func (p *Server) HandlePushNotificationRegistration(publicKey *ecdsa.PublicKey, payload []byte) *protobuf.PushNotificationRegistrationResponse {
response := &protobuf.PushNotificationRegistrationResponse{
RequestId: shake256(payload),

View File

@ -3,6 +3,7 @@ package push_notification_server
import (
"crypto/ecdsa"
"database/sql"
"strings"
"github.com/golang/protobuf/proto"
@ -11,8 +12,11 @@ import (
)
type Persistence interface {
// GetPushNotificationRegistration retrieve a push notification registration from storage given a public key and installation id
GetPushNotificationRegistration(publicKey *ecdsa.PublicKey, installationID string) (*protobuf.PushNotificationRegistration, error)
// GetPushNotificationRegistrationByPublicKeyAndInstallationID retrieve a push notification registration from storage given a public key and installation id
GetPushNotificationRegistrationByPublicKeyAndInstallationID(publicKey *ecdsa.PublicKey, 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
// SavePushNotificationRegistration saves a push notification option to the db
@ -27,9 +31,9 @@ func NewSQLitePersistence(db *sql.DB) Persistence {
return &SQLitePersistence{db: db}
}
func (p *SQLitePersistence) GetPushNotificationRegistration(publicKey *ecdsa.PublicKey, installationID string) (*protobuf.PushNotificationRegistration, error) {
func (p *SQLitePersistence) GetPushNotificationRegistrationByPublicKeyAndInstallationID(publicKey *ecdsa.PublicKey, 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 = ?`, p.hashPublicKey(publicKey), installationID).Scan(&marshaledRegistration)
err := p.db.QueryRow(`SELECT registration FROM push_notification_server_registrations WHERE public_key = ? AND installation_id = ?`, hashPublicKey(publicKey), installationID).Scan(&marshaledRegistration)
if err == sql.ErrNoRows {
return nil, nil
@ -45,21 +49,62 @@ func (p *SQLitePersistence) GetPushNotificationRegistration(publicKey *ecdsa.Pub
return registration, nil
}
type PushNotificationIDAndRegistration struct {
ID []byte
Registration *protobuf.PushNotificationRegistration
}
func (p *SQLitePersistence) GetPushNotificationRegistrationByPublicKeys(publicKeys [][]byte) ([]*PushNotificationIDAndRegistration, error) {
// TODO: check for a max number of keys
publicKeyArgs := make([]interface{}, 0, len(publicKeys))
for _, pk := range publicKeys {
publicKeyArgs = append(publicKeyArgs, pk)
}
inVector := strings.Repeat("?, ", len(publicKeys)-1) + "?"
rows, err := p.db.Query(`SELECT public_key,registration FROM push_notification_server_registrations WHERE public_key IN (`+inVector+`)`, publicKeyArgs...)
if err != nil {
return nil, err
}
defer rows.Close()
var registrations []*PushNotificationIDAndRegistration
for rows.Next() {
response := &PushNotificationIDAndRegistration{}
var marshaledRegistration []byte
err := rows.Scan(&response.ID, &marshaledRegistration)
if err != nil {
return nil, err
}
registration := &protobuf.PushNotificationRegistration{}
if err := proto.Unmarshal(marshaledRegistration, registration); err != nil {
return nil, err
}
response.Registration = registration
registrations = append(registrations, response)
}
return registrations, nil
}
func (p *SQLitePersistence) SavePushNotificationRegistration(publicKey *ecdsa.PublicKey, 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 (?, ?, ?, ?)`, p.hashPublicKey(publicKey), registration.InstallationId, registration.Version, marshaledRegistration)
_, err = p.db.Exec(`INSERT INTO push_notification_server_registrations (public_key, installation_id, version, registration) VALUES (?, ?, ?, ?)`, hashPublicKey(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 = ?`, p.hashPublicKey(publicKey), installationID)
_, err := p.db.Exec(`DELETE FROM push_notification_server_registrations WHERE public_key = ? AND installation_id = ?`, hashPublicKey(publicKey), installationID)
return err
}
func (p *SQLitePersistence) hashPublicKey(pk *ecdsa.PublicKey) []byte {
func hashPublicKey(pk *ecdsa.PublicKey) []byte {
return shake256(crypto.CompressPubkey(pk))
}

View File

@ -51,7 +51,7 @@ func (s *SQLitePersistenceSuite) TestSaveAndRetrieve() {
s.Require().NoError(s.persistence.SavePushNotificationRegistration(&key.PublicKey, registration))
retrievedRegistration, err := s.persistence.GetPushNotificationRegistration(&key.PublicKey, installationID)
retrievedRegistration, err := s.persistence.GetPushNotificationRegistrationByPublicKeyAndInstallationID(&key.PublicKey, installationID)
s.Require().NoError(err)
s.Require().True(proto.Equal(registration, retrievedRegistration))

View File

@ -1,6 +1,7 @@
package push_notification_server
import (
"crypto/ecdsa"
"crypto/rand"
"io/ioutil"
"os"
@ -15,13 +16,23 @@ import (
)
func TestServerSuite(t *testing.T) {
suite.Run(t, new(ServerSuite))
s := new(ServerSuite)
s.accessToken = "b6ae4fde-bb65-11ea-b3de-0242ac130004"
s.installationID = "c6ae4fde-bb65-11ea-b3de-0242ac130004"
suite.Run(t, s)
}
type ServerSuite struct {
suite.Suite
tmpFile *os.File
persistence Persistence
tmpFile *os.File
persistence Persistence
accessToken string
installationID string
identity *ecdsa.PrivateKey
key *ecdsa.PrivateKey
sharedKey []byte
server *Server
}
func (s *ServerSuite) SetupTest() {
@ -32,226 +43,212 @@ func (s *ServerSuite) SetupTest() {
database, err := sqlite.Open(s.tmpFile.Name(), "")
s.Require().NoError(err)
s.persistence = NewSQLitePersistence(database)
}
func (s *ServerSuite) TestPushNotificationServerValidateRegistration() {
accessToken := "b6ae4fde-bb65-11ea-b3de-0242ac130004"
installationID := "c6ae4fde-bb65-11ea-b3de-0242ac130004"
identity, err := crypto.GenerateKey()
s.Require().NoError(err)
s.identity = identity
key, err := crypto.GenerateKey()
s.Require().NoError(err)
s.key = key
config := &Config{
Identity: identity,
}
server := New(config, s.persistence)
s.server = New(config, s.persistence)
key, err := crypto.GenerateKey()
sharedKey, err := s.server.generateSharedKey(&s.key.PublicKey)
s.Require().NoError(err)
s.sharedKey = sharedKey
sharedKey, err := server.generateSharedKey(&key.PublicKey)
s.Require().NoError(err)
}
func (s *ServerSuite) TestPushNotificationServerValidateRegistration() {
// Empty payload
_, err = server.ValidateRegistration(&key.PublicKey, nil)
_, err := s.server.ValidateRegistration(&s.key.PublicKey, nil)
s.Require().Equal(ErrEmptyPushNotificationRegistrationPayload, err)
// Empty key
_, err = server.ValidateRegistration(nil, []byte("payload"))
_, err = s.server.ValidateRegistration(nil, []byte("payload"))
s.Require().Equal(ErrEmptyPushNotificationRegistrationPublicKey, err)
// Invalid cyphertext length
_, err = server.ValidateRegistration(&key.PublicKey, []byte("too short"))
_, err = s.server.ValidateRegistration(&s.key.PublicKey, []byte("too short"))
s.Require().Equal(ErrInvalidCiphertextLength, err)
// Invalid cyphertext length
_, err = server.ValidateRegistration(&key.PublicKey, []byte("too short"))
_, err = s.server.ValidateRegistration(&s.key.PublicKey, []byte("too short"))
s.Require().Equal(ErrInvalidCiphertextLength, err)
// Invalid ciphertext
_, err = server.ValidateRegistration(&key.PublicKey, []byte("not too short but invalid"))
_, err = s.server.ValidateRegistration(&s.key.PublicKey, []byte("not too short but invalid"))
s.Require().Error(ErrInvalidCiphertextLength, err)
// Different key ciphertext
cyphertext, err := encrypt([]byte("plaintext"), make([]byte, 32), rand.Reader)
s.Require().NoError(err)
_, err = server.ValidateRegistration(&key.PublicKey, cyphertext)
_, err = s.server.ValidateRegistration(&s.key.PublicKey, cyphertext)
s.Require().Error(err)
// Right cyphertext but non unmarshable payload
cyphertext, err = encrypt([]byte("plaintext"), sharedKey, rand.Reader)
cyphertext, err = encrypt([]byte("plaintext"), s.sharedKey, rand.Reader)
s.Require().NoError(err)
_, err = server.ValidateRegistration(&key.PublicKey, cyphertext)
_, err = s.server.ValidateRegistration(&s.key.PublicKey, cyphertext)
s.Require().Equal(ErrCouldNotUnmarshalPushNotificationRegistration, err)
// Missing installationID
payload, err := proto.Marshal(&protobuf.PushNotificationRegistration{
AccessToken: accessToken,
AccessToken: s.accessToken,
Version: 1,
})
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
_, err = server.ValidateRegistration(&key.PublicKey, cyphertext)
_, err = s.server.ValidateRegistration(&s.key.PublicKey, cyphertext)
s.Require().Equal(ErrMalformedPushNotificationRegistrationInstallationID, err)
// Malformed installationID
payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{
AccessToken: accessToken,
AccessToken: s.accessToken,
InstallationId: "abc",
Version: 1,
})
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
_, err = server.ValidateRegistration(&key.PublicKey, cyphertext)
_, err = s.server.ValidateRegistration(&s.key.PublicKey, cyphertext)
s.Require().Equal(ErrMalformedPushNotificationRegistrationInstallationID, err)
// Version set to 0
payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{
AccessToken: accessToken,
InstallationId: installationID,
AccessToken: s.accessToken,
InstallationId: s.installationID,
})
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
_, err = server.ValidateRegistration(&key.PublicKey, cyphertext)
_, err = s.server.ValidateRegistration(&s.key.PublicKey, cyphertext)
s.Require().Equal(ErrInvalidPushNotificationRegistrationVersion, err)
// Version lower than previous one
payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{
AccessToken: accessToken,
InstallationId: installationID,
AccessToken: s.accessToken,
InstallationId: s.installationID,
Version: 1,
})
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
// Setup persistence
s.Require().NoError(s.persistence.SavePushNotificationRegistration(&key.PublicKey, &protobuf.PushNotificationRegistration{
AccessToken: accessToken,
InstallationId: installationID,
s.Require().NoError(s.persistence.SavePushNotificationRegistration(&s.key.PublicKey, &protobuf.PushNotificationRegistration{
AccessToken: s.accessToken,
InstallationId: s.installationID,
Version: 2}))
_, err = server.ValidateRegistration(&key.PublicKey, cyphertext)
_, err = s.server.ValidateRegistration(&s.key.PublicKey, cyphertext)
s.Require().Equal(ErrInvalidPushNotificationRegistrationVersion, err)
// Cleanup persistence
s.Require().NoError(s.persistence.DeletePushNotificationRegistration(&key.PublicKey, installationID))
s.Require().NoError(s.persistence.DeletePushNotificationRegistration(&s.key.PublicKey, s.installationID))
// Unregistering message
payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{
InstallationId: installationID,
InstallationId: s.installationID,
Unregister: true,
Version: 1,
})
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
_, err = server.ValidateRegistration(&key.PublicKey, cyphertext)
_, err = s.server.ValidateRegistration(&s.key.PublicKey, cyphertext)
s.Require().Nil(err)
// Missing access token
payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{
InstallationId: installationID,
InstallationId: s.installationID,
Version: 1,
})
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
_, err = server.ValidateRegistration(&key.PublicKey, cyphertext)
_, err = s.server.ValidateRegistration(&s.key.PublicKey, cyphertext)
s.Require().Equal(ErrMalformedPushNotificationRegistrationAccessToken, err)
// Invalid access token
payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{
AccessToken: "bc",
InstallationId: installationID,
InstallationId: s.installationID,
Version: 1,
})
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
_, err = server.ValidateRegistration(&key.PublicKey, cyphertext)
_, err = s.server.ValidateRegistration(&s.key.PublicKey, cyphertext)
s.Require().Equal(ErrMalformedPushNotificationRegistrationAccessToken, err)
// Missing device token
payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{
AccessToken: accessToken,
InstallationId: installationID,
AccessToken: s.accessToken,
InstallationId: s.installationID,
Version: 1,
})
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
_, err = server.ValidateRegistration(&key.PublicKey, cyphertext)
_, err = s.server.ValidateRegistration(&s.key.PublicKey, cyphertext)
s.Require().Equal(ErrMalformedPushNotificationRegistrationDeviceToken, err)
// Successful
payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{
Token: "abc",
AccessToken: accessToken,
InstallationId: installationID,
AccessToken: s.accessToken,
InstallationId: s.installationID,
Version: 1,
})
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
_, err = server.ValidateRegistration(&key.PublicKey, cyphertext)
_, err = s.server.ValidateRegistration(&s.key.PublicKey, cyphertext)
s.Require().NoError(err)
}
func (s *ServerSuite) TestPushNotificationHandleRegistration() {
accessToken := "b6ae4fde-bb65-11ea-b3de-0242ac130004"
installationID := "c6ae4fde-bb65-11ea-b3de-0242ac130004"
identity, err := crypto.GenerateKey()
s.Require().NoError(err)
config := &Config{
Identity: identity,
}
server := New(config, s.persistence)
key, err := crypto.GenerateKey()
s.Require().NoError(err)
sharedKey, err := server.generateSharedKey(&key.PublicKey)
s.Require().NoError(err)
// Empty payload
response := server.HandlePushNotificationRegistration(&key.PublicKey, nil)
response := s.server.HandlePushNotificationRegistration(&s.key.PublicKey, nil)
s.Require().NotNil(response)
s.Require().False(response.Success)
s.Require().Equal(response.Error, protobuf.PushNotificationRegistrationResponse_MALFORMED_MESSAGE)
// Empty key
response = server.HandlePushNotificationRegistration(nil, []byte("payload"))
response = s.server.HandlePushNotificationRegistration(nil, []byte("payload"))
s.Require().NotNil(response)
s.Require().False(response.Success)
s.Require().Equal(response.Error, protobuf.PushNotificationRegistrationResponse_MALFORMED_MESSAGE)
// Invalid cyphertext length
response = server.HandlePushNotificationRegistration(&key.PublicKey, []byte("too short"))
response = s.server.HandlePushNotificationRegistration(&s.key.PublicKey, []byte("too short"))
s.Require().NotNil(response)
s.Require().False(response.Success)
s.Require().Equal(response.Error, protobuf.PushNotificationRegistrationResponse_MALFORMED_MESSAGE)
// Invalid cyphertext length
response = server.HandlePushNotificationRegistration(&key.PublicKey, []byte("too short"))
response = s.server.HandlePushNotificationRegistration(&s.key.PublicKey, []byte("too short"))
s.Require().NotNil(response)
s.Require().False(response.Success)
s.Require().Equal(response.Error, protobuf.PushNotificationRegistrationResponse_MALFORMED_MESSAGE)
// Invalid ciphertext
response = server.HandlePushNotificationRegistration(&key.PublicKey, []byte("not too short but invalid"))
response = s.server.HandlePushNotificationRegistration(&s.key.PublicKey, []byte("not too short but invalid"))
s.Require().NotNil(response)
s.Require().False(response.Success)
s.Require().Equal(response.Error, protobuf.PushNotificationRegistrationResponse_MALFORMED_MESSAGE)
@ -259,95 +256,95 @@ func (s *ServerSuite) TestPushNotificationHandleRegistration() {
// Different key ciphertext
cyphertext, err := encrypt([]byte("plaintext"), make([]byte, 32), rand.Reader)
s.Require().NoError(err)
response = server.HandlePushNotificationRegistration(&key.PublicKey, cyphertext)
response = s.server.HandlePushNotificationRegistration(&s.key.PublicKey, cyphertext)
s.Require().NotNil(response)
s.Require().False(response.Success)
s.Require().Equal(response.Error, protobuf.PushNotificationRegistrationResponse_MALFORMED_MESSAGE)
// Right cyphertext but non unmarshable payload
cyphertext, err = encrypt([]byte("plaintext"), sharedKey, rand.Reader)
cyphertext, err = encrypt([]byte("plaintext"), s.sharedKey, rand.Reader)
s.Require().NoError(err)
response = server.HandlePushNotificationRegistration(&key.PublicKey, cyphertext)
response = s.server.HandlePushNotificationRegistration(&s.key.PublicKey, cyphertext)
s.Require().NotNil(response)
s.Require().False(response.Success)
s.Require().Equal(response.Error, protobuf.PushNotificationRegistrationResponse_MALFORMED_MESSAGE)
// Missing installationID
payload, err := proto.Marshal(&protobuf.PushNotificationRegistration{
AccessToken: accessToken,
AccessToken: s.accessToken,
Version: 1,
})
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
response = server.HandlePushNotificationRegistration(&key.PublicKey, cyphertext)
response = s.server.HandlePushNotificationRegistration(&s.key.PublicKey, cyphertext)
s.Require().NotNil(response)
s.Require().False(response.Success)
s.Require().Equal(response.Error, protobuf.PushNotificationRegistrationResponse_MALFORMED_MESSAGE)
// Malformed installationID
payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{
AccessToken: accessToken,
AccessToken: s.accessToken,
InstallationId: "abc",
Version: 1,
})
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
response = server.HandlePushNotificationRegistration(&key.PublicKey, cyphertext)
response = s.server.HandlePushNotificationRegistration(&s.key.PublicKey, cyphertext)
s.Require().NotNil(response)
s.Require().False(response.Success)
s.Require().Equal(response.Error, protobuf.PushNotificationRegistrationResponse_MALFORMED_MESSAGE)
// Version set to 0
payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{
AccessToken: accessToken,
InstallationId: installationID,
AccessToken: s.accessToken,
InstallationId: s.installationID,
})
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
response = server.HandlePushNotificationRegistration(&key.PublicKey, cyphertext)
response = s.server.HandlePushNotificationRegistration(&s.key.PublicKey, cyphertext)
s.Require().NotNil(response)
s.Require().False(response.Success)
s.Require().Equal(response.Error, protobuf.PushNotificationRegistrationResponse_VERSION_MISMATCH)
// Version lower than previous one
payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{
AccessToken: accessToken,
InstallationId: installationID,
AccessToken: s.accessToken,
InstallationId: s.installationID,
Version: 1,
})
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
// Setup persistence
s.Require().NoError(s.persistence.SavePushNotificationRegistration(&key.PublicKey, &protobuf.PushNotificationRegistration{
AccessToken: accessToken,
InstallationId: installationID,
s.Require().NoError(s.persistence.SavePushNotificationRegistration(&s.key.PublicKey, &protobuf.PushNotificationRegistration{
AccessToken: s.accessToken,
InstallationId: s.installationID,
Version: 2}))
response = server.HandlePushNotificationRegistration(&key.PublicKey, cyphertext)
response = s.server.HandlePushNotificationRegistration(&s.key.PublicKey, cyphertext)
s.Require().NotNil(response)
s.Require().False(response.Success)
s.Require().Equal(response.Error, protobuf.PushNotificationRegistrationResponse_VERSION_MISMATCH)
// Cleanup persistence
s.Require().NoError(s.persistence.DeletePushNotificationRegistration(&key.PublicKey, installationID))
s.Require().NoError(s.persistence.DeletePushNotificationRegistration(&s.key.PublicKey, s.installationID))
// Missing access token
payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{
InstallationId: installationID,
InstallationId: s.installationID,
Version: 1,
})
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
response = server.HandlePushNotificationRegistration(&key.PublicKey, cyphertext)
response = s.server.HandlePushNotificationRegistration(&s.key.PublicKey, cyphertext)
s.Require().NotNil(response)
s.Require().False(response.Success)
s.Require().Equal(response.Error, protobuf.PushNotificationRegistrationResponse_MALFORMED_MESSAGE)
@ -355,29 +352,29 @@ func (s *ServerSuite) TestPushNotificationHandleRegistration() {
// Invalid access token
payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{
AccessToken: "bc",
InstallationId: installationID,
InstallationId: s.installationID,
Version: 1,
})
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
response = server.HandlePushNotificationRegistration(&key.PublicKey, cyphertext)
response = s.server.HandlePushNotificationRegistration(&s.key.PublicKey, cyphertext)
s.Require().NotNil(response)
s.Require().False(response.Success)
s.Require().Equal(response.Error, protobuf.PushNotificationRegistrationResponse_MALFORMED_MESSAGE)
// Missing device token
payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{
AccessToken: accessToken,
InstallationId: installationID,
AccessToken: s.accessToken,
InstallationId: s.installationID,
Version: 1,
})
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
response = server.HandlePushNotificationRegistration(&key.PublicKey, cyphertext)
response = s.server.HandlePushNotificationRegistration(&s.key.PublicKey, cyphertext)
s.Require().NotNil(response)
s.Require().False(response.Success)
s.Require().Equal(response.Error, protobuf.PushNotificationRegistrationResponse_MALFORMED_MESSAGE)
@ -385,21 +382,21 @@ func (s *ServerSuite) TestPushNotificationHandleRegistration() {
// Successful
registration := &protobuf.PushNotificationRegistration{
Token: "abc",
AccessToken: accessToken,
InstallationId: installationID,
AccessToken: s.accessToken,
InstallationId: s.installationID,
Version: 1,
}
payload, err = proto.Marshal(registration)
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
response = server.HandlePushNotificationRegistration(&key.PublicKey, cyphertext)
response = s.server.HandlePushNotificationRegistration(&s.key.PublicKey, cyphertext)
s.Require().NotNil(response)
s.Require().True(response.Success)
// Pull from the db
retrievedRegistration, err := s.persistence.GetPushNotificationRegistration(&key.PublicKey, installationID)
retrievedRegistration, err := s.persistence.GetPushNotificationRegistrationByPublicKeyAndInstallationID(&s.key.PublicKey, s.installationID)
s.Require().NoError(err)
s.Require().NotNil(retrievedRegistration)
s.Require().True(proto.Equal(retrievedRegistration, registration))
@ -407,25 +404,91 @@ func (s *ServerSuite) TestPushNotificationHandleRegistration() {
// Unregistering message
payload, err = proto.Marshal(&protobuf.PushNotificationRegistration{
Token: "token",
InstallationId: installationID,
InstallationId: s.installationID,
Unregister: true,
Version: 2,
})
s.Require().NoError(err)
cyphertext, err = encrypt(payload, sharedKey, rand.Reader)
cyphertext, err = encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
response = server.HandlePushNotificationRegistration(&key.PublicKey, cyphertext)
response = s.server.HandlePushNotificationRegistration(&s.key.PublicKey, cyphertext)
s.Require().NotNil(response)
s.Require().True(response.Success)
// Check is gone from the db
retrievedRegistration, err = s.persistence.GetPushNotificationRegistration(&key.PublicKey, installationID)
retrievedRegistration, err = s.persistence.GetPushNotificationRegistrationByPublicKeyAndInstallationID(&s.key.PublicKey, s.installationID)
s.Require().NoError(err)
s.Require().NotNil(retrievedRegistration)
s.Require().Empty(retrievedRegistration.AccessToken)
s.Require().Empty(retrievedRegistration.Token)
s.Require().Equal(uint64(2), retrievedRegistration.Version)
s.Require().Equal(installationID, retrievedRegistration.InstallationId)
s.Require().Equal(s.installationID, retrievedRegistration.InstallationId)
s.Require().Equal(shake256(cyphertext), response.RequestId)
}
func (s *ServerSuite) TestHandlePushNotificationQueryNoFiltering() {
hashedPublicKey := hashPublicKey(&s.key.PublicKey)
// Successful
registration := &protobuf.PushNotificationRegistration{
Token: "abc",
AccessToken: s.accessToken,
InstallationId: s.installationID,
Version: 1,
}
payload, err := proto.Marshal(registration)
s.Require().NoError(err)
cyphertext, err := encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
response := s.server.HandlePushNotificationRegistration(&s.key.PublicKey, cyphertext)
s.Require().NotNil(response)
s.Require().True(response.Success)
query := &protobuf.PushNotificationQuery{
PublicKeys: [][]byte{[]byte("non-existing"), hashedPublicKey},
}
queryResponse := s.server.HandlePushNotificationQuery(query)
s.Require().NotNil(queryResponse)
s.Require().True(queryResponse.Success)
s.Require().Len(queryResponse.Info, 1)
s.Require().Equal(s.accessToken, queryResponse.Info[0].AccessToken)
s.Require().Equal(hashedPublicKey, queryResponse.Info[0].PublicKey)
s.Require().Equal(s.installationID, queryResponse.Info[0].InstallationId)
s.Require().Nil(queryResponse.Info[0].AllowedUserList)
}
func (s *ServerSuite) TestHandlePushNotificationQueryWithFiltering() {
hashedPublicKey := hashPublicKey(&s.key.PublicKey)
allowedUserList := [][]byte{[]byte("a")}
// Successful
registration := &protobuf.PushNotificationRegistration{
Token: "abc",
AccessToken: s.accessToken,
InstallationId: s.installationID,
AllowedUserList: allowedUserList,
Version: 1,
}
payload, err := proto.Marshal(registration)
s.Require().NoError(err)
cyphertext, err := encrypt(payload, s.sharedKey, rand.Reader)
s.Require().NoError(err)
response := s.server.HandlePushNotificationRegistration(&s.key.PublicKey, cyphertext)
s.Require().NotNil(response)
s.Require().True(response.Success)
query := &protobuf.PushNotificationQuery{
PublicKeys: [][]byte{[]byte("non-existing"), hashedPublicKey},
}
queryResponse := s.server.HandlePushNotificationQuery(query)
s.Require().NotNil(queryResponse)
s.Require().True(queryResponse.Success)
s.Require().Len(queryResponse.Info, 1)
s.Require().Equal(hashedPublicKey, queryResponse.Info[0].PublicKey)
s.Require().Equal(s.installationID, queryResponse.Info[0].InstallationId)
s.Require().Equal(allowedUserList, queryResponse.Info[0].AllowedUserList)
}