Handle mentions on server
This commit is contained in:
parent
8ee3c75510
commit
18877cae6f
|
@ -152,10 +152,16 @@ func (s *Server) HandlePushNotificationRequest(publicKey *ecdsa.PublicKey,
|
|||
return nil
|
||||
}
|
||||
|
||||
response := s.buildPushNotificationRequestResponseAndSendNotification(&request)
|
||||
response, requestsAndRegistrations := s.buildPushNotificationRequestResponse(&request)
|
||||
//AndSendNotification(&request)
|
||||
if response == nil {
|
||||
return nil
|
||||
}
|
||||
err = s.sendPushNotification(requestsAndRegistrations)
|
||||
if err != nil {
|
||||
s.config.Logger.Error("failed to send go rush notification", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
encodedMessage, err := proto.Marshal(response)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -334,23 +340,22 @@ func (s *Server) buildPushNotificationQueryResponse(query *protobuf.PushNotifica
|
|||
return response
|
||||
}
|
||||
|
||||
func (s *Server) blockedChatID(blockedChatIDs [][]byte, chatID []byte) bool {
|
||||
for _, blockedChatID := range blockedChatIDs {
|
||||
if bytes.Equal(blockedChatID, chatID) {
|
||||
func (s *Server) contains(list [][]byte, chatID []byte) bool {
|
||||
for _, list := range list {
|
||||
if bytes.Equal(list, chatID) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// buildPushNotificationRequestResponseAndSendNotification will build a response
|
||||
// and fire-and-forget send a query to the gorush instance
|
||||
func (s *Server) buildPushNotificationRequestResponseAndSendNotification(request *protobuf.PushNotificationRequest) *protobuf.PushNotificationResponse {
|
||||
// buildPushNotificationRequestResponse will build a response
|
||||
func (s *Server) buildPushNotificationRequestResponse(request *protobuf.PushNotificationRequest) (*protobuf.PushNotificationResponse, []*RequestAndRegistration) {
|
||||
response := &protobuf.PushNotificationResponse{}
|
||||
// We don't even send a response in this case
|
||||
if request == nil || len(request.MessageId) == 0 {
|
||||
s.config.Logger.Warn("empty message id")
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
response.MessageId = request.MessageId
|
||||
|
@ -378,10 +383,10 @@ func (s *Server) buildPushNotificationRequestResponseAndSendNotification(request
|
|||
report.Error = protobuf.PushNotificationReport_NOT_REGISTERED
|
||||
} else if registration.AccessToken != pn.AccessToken {
|
||||
report.Error = protobuf.PushNotificationReport_WRONG_TOKEN
|
||||
} else if s.blockedChatID(registration.BlockedChatList, pn.ChatId) {
|
||||
} else if s.contains(registration.BlockedChatList, pn.ChatId) {
|
||||
// We report as successful but don't send the notification
|
||||
report.Success = true
|
||||
} else {
|
||||
} else if s.isMessageNotification(pn) || s.isValidMentionNotification(pn, registration) {
|
||||
// For now we just assume that the notification will be successful
|
||||
requestAndRegistrations = append(requestAndRegistrations, &RequestAndRegistration{
|
||||
Request: pn,
|
||||
|
@ -389,27 +394,24 @@ func (s *Server) buildPushNotificationRequestResponseAndSendNotification(request
|
|||
})
|
||||
report.Success = true
|
||||
}
|
||||
|
||||
response.Reports = append(response.Reports, report)
|
||||
}
|
||||
|
||||
s.config.Logger.Info("built pn request")
|
||||
if len(requestAndRegistrations) == 0 {
|
||||
s.config.Logger.Warn("no request and registration")
|
||||
return response
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// This can be done asynchronously
|
||||
return response, requestAndRegistrations
|
||||
}
|
||||
|
||||
func (s *Server) sendPushNotification(requestAndRegistrations []*RequestAndRegistration) error {
|
||||
if len(requestAndRegistrations) == 0 {
|
||||
return nil
|
||||
}
|
||||
goRushRequest := PushNotificationRegistrationToGoRushRequest(requestAndRegistrations)
|
||||
err := sendGoRushNotification(goRushRequest, s.config.GorushURL, s.config.Logger)
|
||||
if err != nil {
|
||||
s.config.Logger.Error("failed to send go rush notification", zap.Error(err))
|
||||
// TODO: handle this error?
|
||||
// GoRush will not let us know that the sending of the push notification has failed,
|
||||
// so this likely mean that the actual HTTP request has failed, or there was some unexpected error
|
||||
}
|
||||
|
||||
return response
|
||||
return sendGoRushNotification(goRushRequest, s.config.GorushURL, s.config.Logger)
|
||||
}
|
||||
|
||||
// listenToPublicKeyQueryTopic listen to a topic derived from the hashed public key
|
||||
|
@ -468,3 +470,11 @@ func (s *Server) buildPushNotificationRegistrationResponse(publicKey *ecdsa.Publ
|
|||
|
||||
return response
|
||||
}
|
||||
|
||||
func (s *Server) isMessageNotification(pn *protobuf.PushNotification) bool {
|
||||
return pn.Type == protobuf.PushNotification_MESSAGE
|
||||
}
|
||||
|
||||
func (s *Server) isValidMentionNotification(pn *protobuf.PushNotification, registration *protobuf.PushNotificationRegistration) bool {
|
||||
return !registration.BlockMentions && pn.Type == protobuf.PushNotification_MENTION && s.contains(registration.AllowedMentionsChatList, pn.ChatId)
|
||||
}
|
||||
|
|
|
@ -582,3 +582,91 @@ func (s *ServerSuite) TestbuildPushNotificationQueryResponseWithFiltering() {
|
|||
s.Require().Equal(s.installationID, queryResponse.Info[0].InstallationId)
|
||||
s.Require().Equal(allowedKeyList, queryResponse.Info[0].AllowedKeyList)
|
||||
}
|
||||
|
||||
func (s *ServerSuite) TestPushNotificationMentions() {
|
||||
existingChatID := []byte("existing-chat-id")
|
||||
nonExistingChatID := []byte("non-existing-chat-id")
|
||||
registration := &protobuf.PushNotificationRegistration{
|
||||
DeviceToken: "abc",
|
||||
AccessToken: s.accessToken,
|
||||
Grant: s.grant,
|
||||
TokenType: protobuf.PushNotificationRegistration_APN_TOKEN,
|
||||
InstallationId: s.installationID,
|
||||
AllowedMentionsChatList: [][]byte{existingChatID},
|
||||
Version: 1,
|
||||
}
|
||||
payload, err := proto.Marshal(registration)
|
||||
s.Require().NoError(err)
|
||||
|
||||
cyphertext, err := common.Encrypt(payload, s.sharedKey, rand.Reader)
|
||||
s.Require().NoError(err)
|
||||
response := s.server.buildPushNotificationRegistrationResponse(&s.key.PublicKey, cyphertext)
|
||||
s.Require().NotNil(response)
|
||||
s.Require().True(response.Success)
|
||||
|
||||
pushNotificationRequest := &protobuf.PushNotificationRequest{
|
||||
MessageId: []byte("message-id"),
|
||||
Requests: []*protobuf.PushNotification{
|
||||
{
|
||||
AccessToken: s.accessToken,
|
||||
PublicKey: common.HashPublicKey(&s.key.PublicKey),
|
||||
ChatId: existingChatID,
|
||||
InstallationId: s.installationID,
|
||||
Type: protobuf.PushNotification_MENTION,
|
||||
},
|
||||
{
|
||||
AccessToken: s.accessToken,
|
||||
PublicKey: common.HashPublicKey(&s.key.PublicKey),
|
||||
ChatId: nonExistingChatID,
|
||||
InstallationId: s.installationID,
|
||||
Type: protobuf.PushNotification_MENTION,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
pushNotificationResponse, requestAndRegistrations := s.server.buildPushNotificationRequestResponse(pushNotificationRequest)
|
||||
s.Require().NotNil(pushNotificationResponse)
|
||||
s.Require().NotNil(requestAndRegistrations)
|
||||
|
||||
// only one should succeed
|
||||
s.Require().Len(requestAndRegistrations, 1)
|
||||
}
|
||||
|
||||
func (s *ServerSuite) TestPushNotificationDisabledMentions() {
|
||||
existingChatID := []byte("existing-chat-id")
|
||||
registration := &protobuf.PushNotificationRegistration{
|
||||
DeviceToken: "abc",
|
||||
AccessToken: s.accessToken,
|
||||
Grant: s.grant,
|
||||
TokenType: protobuf.PushNotificationRegistration_APN_TOKEN,
|
||||
BlockMentions: true,
|
||||
InstallationId: s.installationID,
|
||||
AllowedMentionsChatList: [][]byte{existingChatID},
|
||||
Version: 1,
|
||||
}
|
||||
payload, err := proto.Marshal(registration)
|
||||
s.Require().NoError(err)
|
||||
|
||||
cyphertext, err := common.Encrypt(payload, s.sharedKey, rand.Reader)
|
||||
s.Require().NoError(err)
|
||||
response := s.server.buildPushNotificationRegistrationResponse(&s.key.PublicKey, cyphertext)
|
||||
s.Require().NotNil(response)
|
||||
s.Require().True(response.Success)
|
||||
|
||||
pushNotificationRequest := &protobuf.PushNotificationRequest{
|
||||
MessageId: []byte("message-id"),
|
||||
Requests: []*protobuf.PushNotification{
|
||||
{
|
||||
AccessToken: s.accessToken,
|
||||
PublicKey: common.HashPublicKey(&s.key.PublicKey),
|
||||
ChatId: existingChatID,
|
||||
InstallationId: s.installationID,
|
||||
Type: protobuf.PushNotification_MENTION,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
pushNotificationResponse, requestAndRegistrations := s.server.buildPushNotificationRequestResponse(pushNotificationRequest)
|
||||
s.Require().NotNil(pushNotificationResponse)
|
||||
s.Require().Nil(requestAndRegistrations)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue