Add skeleton for server and separate namespace for client

This commit is contained in:
Andrea Maria Piana 2020-06-30 10:30:58 +02:00
parent 92b699b59d
commit 4ded7bf74c
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
8 changed files with 129 additions and 70 deletions

View File

@ -25,6 +25,7 @@ import (
"github.com/status-im/status-go/protocol/identity/identicon" "github.com/status-im/status-go/protocol/identity/identicon"
"github.com/status-im/status-go/protocol/images" "github.com/status-im/status-go/protocol/images"
"github.com/status-im/status-go/protocol/protobuf" "github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/push_notification_client"
"github.com/status-im/status-go/protocol/sqlite" "github.com/status-im/status-go/protocol/sqlite"
"github.com/status-im/status-go/protocol/transport" "github.com/status-im/status-go/protocol/transport"
wakutransp "github.com/status-im/status-go/protocol/transport/waku" wakutransp "github.com/status-im/status-go/protocol/transport/waku"
@ -57,7 +58,7 @@ type Messenger struct {
encryptor *encryption.Protocol encryptor *encryption.Protocol
processor *messageProcessor processor *messageProcessor
handler *MessageHandler handler *MessageHandler
pushNotificationService *PushNotificationService pushNotificationClient *push_notification_client.Client
logger *zap.Logger logger *zap.Logger
verifyTransactionClient EthClient verifyTransactionClient EthClient
featureFlags featureFlags featureFlags featureFlags
@ -329,8 +330,8 @@ func NewMessenger(
logger, logger,
) )
pushNotificationPersistence := NewPushNotificationPersistence(database) pushNotificationClientPersistence := push_notification_client.NewPersistence(database)
pushNotificationService := NewPushNotificationService(pushNotificationPersistence) pushNotificationClient := push_notification_client.New(pushNotificationClientPersistence)
processor, err := newMessageProcessor( processor, err := newMessageProcessor(
identity, identity,
@ -339,7 +340,7 @@ func NewMessenger(
transp, transp,
logger, logger,
c.featureFlags, c.featureFlags,
pushNotificationService.HandleMessageSent, pushNotificationClient.HandleMessageSent,
) )
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed to create messageProcessor") return nil, errors.Wrap(err, "failed to create messageProcessor")
@ -355,7 +356,7 @@ func NewMessenger(
encryptor: encryptionProtocol, encryptor: encryptionProtocol,
processor: processor, processor: processor,
handler: handler, handler: handler,
pushNotificationService: pushNotificationService, pushNotificationClient: pushNotificationClient,
featureFlags: c.featureFlags, featureFlags: c.featureFlags,
systemMessagesTranslations: c.systemMessagesTranslations, systemMessagesTranslations: c.systemMessagesTranslations,
allChats: make(map[string]*Chat), allChats: make(map[string]*Chat),
@ -1473,8 +1474,8 @@ func (m *Messenger) SendChatMessage(ctx context.Context, message *Message) (*Mes
} }
// If the chat is not public, we instruct the pushNotificationService to send a notification // If the chat is not public, we instruct the pushNotificationService to send a notification
if !chat.Public() && m.pushNotificationService != nil { if !chat.Public() && m.pushNotificationClient != nil {
if err := m.pushNotificationService.NotifyOnMessageID(id); err != nil { if err := m.pushNotificationClient.NotifyOnMessageID(id); err != nil {
return nil, err return nil, err
} }

View File

@ -1,4 +1,4 @@
package protocol package push_notification_client
import ( import (
"crypto/aes" "crypto/aes"
@ -26,7 +26,7 @@ type PushNotificationServer struct {
registered bool registered bool
} }
type PushNotificationConfig struct { type Config struct {
// Identity is our identity key // Identity is our identity key
Identity *ecdsa.PrivateKey Identity *ecdsa.PrivateKey
// SendEnabled indicates whether we should be sending push notifications // SendEnabled indicates whether we should be sending push notifications
@ -47,9 +47,9 @@ type PushNotificationConfig struct {
InstallationID string InstallationID string
} }
type PushNotificationService struct { type Client struct {
persistence *PushNotificationPersistence persistence *Persistence
config *PushNotificationConfig config *Config
// lastPushNotificationRegister is the latest known push notification register message // lastPushNotificationRegister is the latest known push notification register message
lastPushNotificationRegister *protobuf.PushNotificationRegister lastPushNotificationRegister *protobuf.PushNotificationRegister
@ -63,8 +63,8 @@ type PushNotificationService struct {
reader io.Reader reader io.Reader
} }
func NewPushNotificationService(persistence *PushNotificationPersistence) *PushNotificationService { func New(persistence *Persistence) *Client {
return &PushNotificationService{persistence: persistence, reader: rand.Reader} return &Client{persistence: persistence, reader: rand.Reader}
} }
// This likely will return a channel as it's an asynchrous operation // This likely will return a channel as it's an asynchrous operation
@ -81,15 +81,15 @@ func sendPushNotificationTo(publicKey *ecdsa.PublicKey, chatID string) error {
// 1) Check we have reasonably fresh push notifications info // 1) Check we have reasonably fresh push notifications info
// 2) Otherwise it should fetch them // 2) Otherwise it should fetch them
// 3) Send a push notification to the devices in question // 3) Send a push notification to the devices in question
func (p *PushNotificationService) HandleMessageSent(publicKey *ecdsa.PublicKey, spec *encryption.ProtocolMessageSpec, messageIDs [][]byte) error { func (p *Client) HandleMessageSent(publicKey *ecdsa.PublicKey, spec *encryption.ProtocolMessageSpec, messageIDs [][]byte) error {
return nil return nil
} }
func (p *PushNotificationService) NotifyOnMessageID(messageID []byte) error { func (p *Client) NotifyOnMessageID(messageID []byte) error {
return nil return nil
} }
func (p *PushNotificationService) mutedChatIDsHashes() [][]byte { func (p *Client) mutedChatIDsHashes() [][]byte {
var mutedChatListHashes [][]byte var mutedChatListHashes [][]byte
for _, chatID := range p.config.MutedChatIDs { for _, chatID := range p.config.MutedChatIDs {
@ -99,7 +99,7 @@ func (p *PushNotificationService) mutedChatIDsHashes() [][]byte {
return mutedChatListHashes return mutedChatListHashes
} }
func (p *PushNotificationService) reEncryptTokenPair(token []byte, pair *protobuf.PushNotificationTokenPair) (*protobuf.PushNotificationTokenPair, error) { func (p *Client) reEncryptTokenPair(token []byte, pair *protobuf.PushNotificationTokenPair) (*protobuf.PushNotificationTokenPair, error) {
publicKey, err := crypto.DecompressPubkey(pair.PublicKey) publicKey, err := crypto.DecompressPubkey(pair.PublicKey)
if err != nil { if err != nil {
return nil, err return nil, err
@ -107,7 +107,7 @@ func (p *PushNotificationService) reEncryptTokenPair(token []byte, pair *protobu
return p.encryptTokenPair(publicKey, token) return p.encryptTokenPair(publicKey, token)
} }
func (p *PushNotificationService) encryptTokenPair(publicKey *ecdsa.PublicKey, token []byte) (*protobuf.PushNotificationTokenPair, error) { func (p *Client) encryptTokenPair(publicKey *ecdsa.PublicKey, token []byte) (*protobuf.PushNotificationTokenPair, error) {
sharedKey, err := ecies.ImportECDSA(p.config.Identity).GenerateShared( sharedKey, err := ecies.ImportECDSA(p.config.Identity).GenerateShared(
ecies.ImportECDSAPublic(publicKey), ecies.ImportECDSAPublic(publicKey),
accessTokenKeyLength, accessTokenKeyLength,
@ -127,7 +127,7 @@ func (p *PushNotificationService) encryptTokenPair(publicKey *ecdsa.PublicKey, t
}, nil }, nil
} }
func (p *PushNotificationService) allowedUserList(token []byte) ([]*protobuf.PushNotificationTokenPair, error) { func (p *Client) allowedUserList(token []byte) ([]*protobuf.PushNotificationTokenPair, error) {
var tokenPairs []*protobuf.PushNotificationTokenPair var tokenPairs []*protobuf.PushNotificationTokenPair
for _, publicKey := range p.config.ContactIDs { for _, publicKey := range p.config.ContactIDs {
tokenPair, err := p.encryptTokenPair(publicKey, token) tokenPair, err := p.encryptTokenPair(publicKey, token)
@ -141,7 +141,7 @@ func (p *PushNotificationService) allowedUserList(token []byte) ([]*protobuf.Pus
return tokenPairs, nil return tokenPairs, nil
} }
func (p *PushNotificationService) reEncryptAllowedUserList(token []byte, oldTokenPairs []*protobuf.PushNotificationTokenPair) ([]*protobuf.PushNotificationTokenPair, error) { func (p *Client) reEncryptAllowedUserList(token []byte, oldTokenPairs []*protobuf.PushNotificationTokenPair) ([]*protobuf.PushNotificationTokenPair, error) {
var tokenPairs []*protobuf.PushNotificationTokenPair var tokenPairs []*protobuf.PushNotificationTokenPair
for _, tokenPair := range oldTokenPairs { for _, tokenPair := range oldTokenPairs {
tokenPair, err := p.reEncryptTokenPair(token, tokenPair) tokenPair, err := p.reEncryptTokenPair(token, tokenPair)
@ -155,7 +155,7 @@ func (p *PushNotificationService) reEncryptAllowedUserList(token []byte, oldToke
return tokenPairs, nil return tokenPairs, nil
} }
func (p *PushNotificationService) buildPushNotificationOptionsMessage(token string) (*protobuf.PushNotificationOptions, error) { func (p *Client) buildPushNotificationOptionsMessage(token string) (*protobuf.PushNotificationOptions, error) {
allowedUserList, err := p.allowedUserList([]byte(token)) allowedUserList, err := p.allowedUserList([]byte(token))
if err != nil { if err != nil {
return nil, err return nil, err
@ -171,7 +171,7 @@ func (p *PushNotificationService) buildPushNotificationOptionsMessage(token stri
return options, nil return options, nil
} }
func (p *PushNotificationService) buildPushNotificationRegisterMessage() (*protobuf.PushNotificationRegister, error) { func (p *Client) buildPushNotificationRegisterMessage() (*protobuf.PushNotificationRegister, error) {
pushNotificationPreferences := &protobuf.PushNotificationPreferences{} pushNotificationPreferences := &protobuf.PushNotificationPreferences{}
if p.lastPushNotificationRegister != nil { if p.lastPushNotificationRegister != nil {
@ -219,37 +219,37 @@ func (p *PushNotificationService) buildPushNotificationRegisterMessage() (*proto
return message, nil return message, nil
} }
func (p *PushNotificationService) Register(deviceToken string) error { func (p *Client) Register(deviceToken string) error {
return nil return nil
} }
// HandlePushNotificationRegistrationResponse should check whether the response was successful or not, retry if necessary otherwise store the result in the database // HandlePushNotificationRegistrationResponse should check whether the response was successful or not, retry if necessary otherwise store the result in the database
func (p *PushNotificationService) HandlePushNotificationRegistrationResponse(response *protobuf.PushNotificationRegistrationResponse) error { func (p *Client) HandlePushNotificationRegistrationResponse(response *protobuf.PushNotificationRegistrationResponse) error {
return nil return nil
} }
// HandlePushNotificationAdvertisement should store any info related to push notifications // HandlePushNotificationAdvertisement should store any info related to push notifications
func (p *PushNotificationService) HandlePushNotificationAdvertisement(info *protobuf.PushNotificationAdvertisementInfo) error { func (p *Client) HandlePushNotificationAdvertisement(info *protobuf.PushNotificationAdvertisementInfo) error {
return nil return nil
} }
// HandlePushNotificationQueryResponse should update the data in the database for a given user // HandlePushNotificationQueryResponse should update the data in the database for a given user
func (p *PushNotificationService) HandlePushNotificationQueryResponse(response *protobuf.PushNotificationQueryResponse) error { func (p *Client) HandlePushNotificationQueryResponse(response *protobuf.PushNotificationQueryResponse) error {
return nil return nil
} }
// HandlePushNotificationAcknowledgement should set the request as processed // HandlePushNotificationAcknowledgement should set the request as processed
func (p *PushNotificationService) HandlePushNotificationAcknowledgement(ack *protobuf.PushNotificationAcknowledgement) error { func (p *Client) HandlePushNotificationAcknowledgement(ack *protobuf.PushNotificationAcknowledgement) error {
return nil return nil
} }
func (p *PushNotificationService) SetContactIDs(contactIDs []*ecdsa.PublicKey) error { func (p *Client) SetContactIDs(contactIDs []*ecdsa.PublicKey) error {
p.config.ContactIDs = contactIDs p.config.ContactIDs = contactIDs
// Update or schedule update // Update or schedule update
return nil return nil
} }
func (p *PushNotificationService) SetMutedChatIDs(chatIDs []string) error { func (p *Client) SetMutedChatIDs(chatIDs []string) error {
p.config.MutedChatIDs = chatIDs p.config.MutedChatIDs = chatIDs
// Update or schedule update // Update or schedule update
return nil return nil

View File

@ -0,0 +1,26 @@
package push_notification_client
import (
"crypto/ecdsa"
"database/sql"
)
type Persistence struct {
db *sql.DB
}
func NewPersistence(db *sql.DB) *Persistence {
return &Persistence{db: db}
}
func (p *Persistence) TrackPushNotification(messageID []byte) error {
return nil
}
func (p *Persistence) ShouldSentNotificationFor(publicKey *ecdsa.PublicKey, messageID []byte) (bool, error) {
return false, nil
}
func (p *Persistence) SentFor(publicKey *ecdsa.PublicKey, messageID []byte) error {
return nil
}

View File

@ -1,4 +1,4 @@
package protocol package push_notification_client
import ( import (
"bytes" "bytes"
@ -59,7 +59,7 @@ func TestBuildPushNotificationRegisterMessage(t *testing.T) {
// Reset random generator // Reset random generator
uuid.SetRand(rand.New(rand.NewSource(seed))) uuid.SetRand(rand.New(rand.NewSource(seed)))
config := &PushNotificationConfig{ config := &Config{
Identity: identity, Identity: identity,
RemoteNotificationsEnabled: true, RemoteNotificationsEnabled: true,
MutedChatIDs: mutedChatList, MutedChatIDs: mutedChatList,
@ -67,11 +67,11 @@ func TestBuildPushNotificationRegisterMessage(t *testing.T) {
InstallationID: myInstallationID, InstallationID: myInstallationID,
} }
service := &PushNotificationService{} client := &Client{}
service.config = config client.config = config
service.DeviceToken = myDeviceToken client.DeviceToken = myDeviceToken
// Set reader // Set reader
service.reader = bytes.NewReader([]byte(expectedUUID)) client.reader = bytes.NewReader([]byte(expectedUUID))
options := &protobuf.PushNotificationOptions{ options := &protobuf.PushNotificationOptions{
Token: myDeviceToken, Token: myDeviceToken,
@ -92,7 +92,7 @@ func TestBuildPushNotificationRegisterMessage(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
expectedMessage := &protobuf.PushNotificationRegister{Payload: marshaledPreferences} expectedMessage := &protobuf.PushNotificationRegister{Payload: marshaledPreferences}
actualMessage, err := service.buildPushNotificationRegisterMessage() actualMessage, err := client.buildPushNotificationRegisterMessage()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, expectedMessage, actualMessage) require.Equal(t, expectedMessage, actualMessage)
@ -177,7 +177,7 @@ func TestBuildPushNotificationRegisterMessageWithPrevious(t *testing.T) {
// Reset random generator // Reset random generator
uuid.SetRand(rand.New(rand.NewSource(seed))) uuid.SetRand(rand.New(rand.NewSource(seed)))
config := &PushNotificationConfig{ config := &Config{
Identity: identity, Identity: identity,
RemoteNotificationsEnabled: true, RemoteNotificationsEnabled: true,
MutedChatIDs: mutedChatList, MutedChatIDs: mutedChatList,
@ -185,12 +185,12 @@ func TestBuildPushNotificationRegisterMessageWithPrevious(t *testing.T) {
InstallationID: installationID1, InstallationID: installationID1,
} }
service := &PushNotificationService{} client := &Client{}
service.config = config client.config = config
service.DeviceToken = deviceToken1 client.DeviceToken = deviceToken1
service.lastPushNotificationRegister = lastPushNotificationRegister client.lastPushNotificationRegister = lastPushNotificationRegister
// Set reader // Set reader
service.reader = bytes.NewReader([]byte(expectedUUID)) client.reader = bytes.NewReader([]byte(expectedUUID))
options1 := &protobuf.PushNotificationOptions{ options1 := &protobuf.PushNotificationOptions{
Token: deviceToken1, Token: deviceToken1,
@ -212,7 +212,7 @@ func TestBuildPushNotificationRegisterMessageWithPrevious(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
expectedMessage := &protobuf.PushNotificationRegister{Payload: marshaledPreferences} expectedMessage := &protobuf.PushNotificationRegister{Payload: marshaledPreferences}
actualMessage, err := service.buildPushNotificationRegisterMessage() actualMessage, err := client.buildPushNotificationRegisterMessage()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, expectedMessage, actualMessage) require.Equal(t, expectedMessage, actualMessage)

View File

@ -1,26 +0,0 @@
package protocol
import (
"crypto/ecdsa"
"database/sql"
)
type PushNotificationPersistence struct {
db *sql.DB
}
func NewPushNotificationPersistence(db *sql.DB) *PushNotificationPersistence {
return &PushNotificationPersistence{db: db}
}
func (p *PushNotificationPersistence) TrackPushNotification(messageID []byte) error {
return nil
}
func (p *PushNotificationPersistence) ShouldSentNotificationFor(publicKey *ecdsa.PublicKey, messageID []byte) (bool, error) {
return false, nil
}
func (p *PushNotificationPersistence) PushNotificationSentFor(publicKey *ecdsa.PublicKey, messageID []byte) error {
return nil
}

View File

@ -0,0 +1,32 @@
package protocol
import (
"crypto/ecdsa"
"errors"
"github.com/status-im/status-go/protocol/protobuf"
)
var ErrEmptyPushNotificationRegisterMessage = errors.New("empty PushNotificationRegisterMessage")
type Config struct {
// Identity is our identity key
Identity *ecdsa.PrivateKey
// GorushUrl is the url for the gorush service
GorushURL string
}
type Server struct {
persistence *Persistence
config *Config
}
func New(persistence *Persistence) *Server {
return &Server{persistence: persistence}
}
func (p *Server) ValidateRegistration(previousRegistration *protobuf.PushNotificationRegister, newRegistration *protobuf.PushNotificationRegister) error {
if newRegistration == nil {
return ErrEmptyPushNotificationRegisterMessage
}
return nil
}

View File

@ -0,0 +1,13 @@
package protocol
import (
"database/sql"
)
type Persistence struct {
db *sql.DB
}
func NewPersistence(db *sql.DB) *Persistence {
return &Persistence{db: db}
}

View File

@ -0,0 +1,13 @@
package protocol
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestPushNotificationServerValidateRegistration(t *testing.T) {
server := Server{}
require.Equal(t, ErrEmptyPushNotificationRegisterMessage, server.ValidateRegistration(nil, nil))
}