Create server identity on start if necessary
This commit is contained in:
parent
3f4575b802
commit
7e8d1353d0
|
@ -1,7 +1,7 @@
|
||||||
// Code generated by go-bindata. DO NOT EDIT.
|
// Code generated by go-bindata. DO NOT EDIT.
|
||||||
// sources:
|
// sources:
|
||||||
// 1593601728_initial_schema.down.sql (200B)
|
// 1593601728_initial_schema.down.sql (200B)
|
||||||
// 1593601728_initial_schema.up.sql (517B)
|
// 1593601728_initial_schema.up.sql (675B)
|
||||||
// doc.go (382B)
|
// doc.go (382B)
|
||||||
|
|
||||||
package migrations
|
package migrations
|
||||||
|
@ -91,7 +91,7 @@ func _1593601728_initial_schemaDownSql() (*asset, error) {
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var __1593601728_initial_schemaUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x90\xc1\x4a\x03\x31\x14\x45\xf7\xf9\x8a\xbb\xec\x40\xff\x60\x56\x99\x98\x62\x20\xbc\xe8\x34\x23\xdd\x85\xda\x46\x7d\x38\xcc\x94\x24\x2d\xfa\xf7\xe2\x28\x38\xad\x9b\x22\x6e\x2f\x8f\x7b\xde\x3d\xaa\xd5\xd2\x6b\x78\xd9\x58\x0d\xb3\x02\x39\x0f\xbd\x31\x6b\xbf\xc6\xe1\x98\x5f\xc2\x30\x16\x7e\xe2\xdd\xb6\xf0\x38\x84\x1c\xd3\x29\xa6\x90\xe2\x33\xe7\x92\xa6\x2c\x63\x21\x80\xc3\xf1\xb1\xe7\x5d\x78\x8d\xef\x68\xac\x6b\xa6\x16\xea\xac\x5d\x0a\x80\x87\x5c\xb6\x7d\xff\xd5\xc0\x7b\x3c\xc8\x56\xdd\xca\xf6\xec\xe6\x14\x53\xe6\x71\x80\x21\x7f\x96\xcf\x49\x53\xf3\x67\xd8\x91\xb9\xef\xf4\xe2\x87\xb9\xbc\x64\x54\x70\x04\xe5\x68\x65\x8d\xf2\x68\xf5\x9d\x95\x4a\x8b\xaa\x16\xe2\x7b\xae\xa1\x1b\xbd\x01\xef\xdf\xc2\x75\x23\xc3\x6c\xa0\xa3\x2b\xcd\xcc\x3e\xac\xea\x7f\x20\x87\x4b\x93\x7f\xf9\xe4\xb7\xab\x5a\x88\x8f\x00\x00\x00\xff\xff\x5c\xf8\x30\xd8\x05\x02\x00\x00")
|
var __1593601728_initial_schemaUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x91\x31\x6b\xc3\x30\x14\x84\x77\xfd\x8a\x37\xc6\x90\xa1\xbb\x27\xd9\x91\xa9\x40\x48\xad\x23\x97\x6c\xc2\xb5\xd5\xe6\x51\x23\x07\x49\x31\xf5\xbf\x2f\x71\x86\x2a\x69\x87\x10\xb2\x1e\x8f\xbb\xf7\xdd\x95\x35\xa3\x9a\x81\xa6\x85\x60\xc0\x2b\x90\x4a\x03\xdb\xf1\xad\xde\xc2\xe1\x18\xf6\xc6\x8d\x11\x3f\xb0\x6b\x23\x8e\xce\x04\xeb\x27\xeb\x8d\xb7\x9f\x18\xa2\x5f\xb4\x00\x2b\x02\x70\x38\xbe\x0f\xd8\x99\x2f\x3b\x43\x21\x54\xb1\xb8\xc8\x46\x88\x35\x01\x40\x17\x62\x3b\x0c\x67\x07\xec\xe1\x8d\xd6\xe5\x33\xad\x2f\x6e\x26\xeb\x03\x8e\x0e\xb8\xd4\x17\x7a\x9a\xb4\x38\x9f\xc4\x46\xf2\xd7\x86\xad\x7e\x33\xd7\xd7\x19\x19\x28\x09\xa5\x92\x95\xe0\xa5\x86\x9a\xbd\x08\x5a\x32\x92\xe5\x84\xdc\x83\x8b\xbd\x75\x11\xe3\x7c\x26\xf5\x38\xb5\xd1\xfe\x8f\x1a\x66\x17\xf7\x36\x62\x77\xe2\x4c\x59\x60\xc3\x2a\xda\x08\x0d\x4f\x09\x40\x7a\x9d\xa5\xdf\x71\xb9\x61\x3b\xc0\xfe\xdb\xdc\x36\x81\x49\xea\x57\xf2\xc6\xdd\x92\xfe\xb2\xfc\x01\xc9\xe6\x7a\xe7\x7b\x3e\xf9\xbb\x64\x4e\xc8\x4f\x00\x00\x00\xff\xff\xcc\xa0\x4d\x54\xa3\x02\x00\x00")
|
||||||
|
|
||||||
func _1593601728_initial_schemaUpSqlBytes() ([]byte, error) {
|
func _1593601728_initial_schemaUpSqlBytes() ([]byte, error) {
|
||||||
return bindataRead(
|
return bindataRead(
|
||||||
|
@ -106,8 +106,8 @@ func _1593601728_initial_schemaUpSql() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "1593601728_initial_schema.up.sql", size: 517, mode: os.FileMode(0644), modTime: time.Unix(1594393629, 0)}
|
info := bindataFileInfo{name: "1593601728_initial_schema.up.sql", size: 675, mode: os.FileMode(0644), modTime: time.Unix(1594636412, 0)}
|
||||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf1, 0x55, 0xab, 0xbf, 0xee, 0x66, 0xe9, 0x81, 0x9f, 0x89, 0xca, 0x6b, 0xf8, 0x1d, 0x12, 0x59, 0xf6, 0x1e, 0xac, 0x79, 0x93, 0x8f, 0x47, 0xbd, 0x76, 0x65, 0xbb, 0x10, 0x99, 0x8a, 0xda, 0x9e}}
|
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfd, 0x61, 0x90, 0x79, 0xd9, 0x14, 0x65, 0xe9, 0x96, 0x53, 0x17, 0x33, 0x54, 0xeb, 0x8b, 0x5d, 0x95, 0x99, 0x10, 0x36, 0x58, 0xdd, 0xb2, 0xbf, 0x45, 0xd9, 0xbb, 0xc4, 0x92, 0xe, 0xce, 0x2}}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,12 @@ CREATE TABLE IF NOT EXISTS push_notification_server_registrations (
|
||||||
UNIQUE(public_key, installation_id) ON CONFLICT REPLACE
|
UNIQUE(public_key, installation_id) ON CONFLICT REPLACE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS push_notification_server_identity (
|
||||||
|
private_key BLOB NOT NULL,
|
||||||
|
synthetic_id INT NOT NULL DEFAULT 0,
|
||||||
|
UNIQUE(synthetic_id)
|
||||||
|
);
|
||||||
|
|
||||||
CREATE INDEX idx_push_notification_server_registrations_public_key ON push_notification_server_registrations(public_key);
|
CREATE INDEX idx_push_notification_server_registrations_public_key ON push_notification_server_registrations(public_key);
|
||||||
CREATE INDEX idx_push_notification_server_registrations_public_key_installation_id ON push_notification_server_registrations(public_key, installation_id);
|
CREATE INDEX idx_push_notification_server_registrations_public_key_installation_id ON push_notification_server_registrations(public_key, installation_id);
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package push_notification_server
|
package push_notification_server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
|
|
||||||
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
"github.com/status-im/status-go/protocol/protobuf"
|
"github.com/status-im/status-go/protocol/protobuf"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,6 +23,10 @@ type Persistence interface {
|
||||||
DeletePushNotificationRegistration(publicKey []byte, installationID string) error
|
DeletePushNotificationRegistration(publicKey []byte, installationID string) error
|
||||||
// SavePushNotificationRegistration saves a push notification option to the db
|
// SavePushNotificationRegistration saves a push notification option to the db
|
||||||
SavePushNotificationRegistration(publicKey []byte, registration *protobuf.PushNotificationRegistration) error
|
SavePushNotificationRegistration(publicKey []byte, registration *protobuf.PushNotificationRegistration) error
|
||||||
|
// GetIdentity returns the server identity key
|
||||||
|
GetIdentity() (*ecdsa.PrivateKey, error)
|
||||||
|
// SaveIdentity saves the server identity key
|
||||||
|
SaveIdentity(*ecdsa.PrivateKey) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type SQLitePersistence struct {
|
type SQLitePersistence struct {
|
||||||
|
@ -124,3 +130,25 @@ func (p *SQLitePersistence) DeletePushNotificationRegistration(publicKey []byte,
|
||||||
_, err := p.db.Exec(`DELETE FROM push_notification_server_registrations WHERE public_key = ? AND installation_id = ?`, publicKey, installationID)
|
_, err := p.db.Exec(`DELETE FROM push_notification_server_registrations WHERE public_key = ? AND installation_id = ?`, publicKey, installationID)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *SQLitePersistence) SaveIdentity(privateKey *ecdsa.PrivateKey) error {
|
||||||
|
_, err := p.db.Exec(`INSERT INTO push_notification_server_identity (private_key) VALUES (?)`, crypto.FromECDSA(privateKey))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *SQLitePersistence) GetIdentity() (*ecdsa.PrivateKey, error) {
|
||||||
|
var pkBytes []byte
|
||||||
|
err := p.db.QueryRow(`SELECT private_key FROM push_notification_server_identity LIMIT 1`).Scan(&pkBytes)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pk, err := crypto.ToECDSA(pkBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return pk, nil
|
||||||
|
}
|
||||||
|
|
|
@ -57,3 +57,29 @@ func (s *SQLitePersistenceSuite) TestSaveAndRetrieve() {
|
||||||
|
|
||||||
s.Require().True(proto.Equal(registration, retrievedRegistration))
|
s.Require().True(proto.Equal(registration, retrievedRegistration))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SQLitePersistenceSuite) TestSaveAndRetrieveIdentity() {
|
||||||
|
retrievedKey, err := s.persistence.GetIdentity()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Nil(retrievedKey)
|
||||||
|
|
||||||
|
key, err := crypto.GenerateKey()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().NoError(s.persistence.SaveIdentity(key))
|
||||||
|
|
||||||
|
retrievedKey, err = s.persistence.GetIdentity()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
s.Require().Equal(key, retrievedKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SQLitePersistenceSuite) TestSaveDifferentIdenities() {
|
||||||
|
key1, err := crypto.GenerateKey()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
key2, err := crypto.GenerateKey()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// First one should be successul, second should fail
|
||||||
|
s.Require().NoError(s.persistence.SaveIdentity(key1))
|
||||||
|
s.Require().Error(s.persistence.SaveIdentity(key2))
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const encryptedPayloadKeyLength = 16
|
const encryptedPayloadKeyLength = 16
|
||||||
|
const defaultGorushURL = "https://gorush.status.im"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// Identity is our identity key
|
// Identity is our identity key
|
||||||
|
@ -34,6 +35,10 @@ type Server struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(config *Config, persistence Persistence, messageProcessor *common.MessageProcessor) *Server {
|
func New(config *Config, persistence Persistence, messageProcessor *common.MessageProcessor) *Server {
|
||||||
|
if len(config.GorushURL) == 0 {
|
||||||
|
config.GorushURL = defaultGorushURL
|
||||||
|
|
||||||
|
}
|
||||||
return &Server{persistence: persistence, config: config, messageProcessor: messageProcessor}
|
return &Server{persistence: persistence, config: config, messageProcessor: messageProcessor}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,6 +275,24 @@ func (s *Server) HandlePushNotificationRegistration(publicKey *ecdsa.PublicKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Start() error {
|
func (s *Server) Start() error {
|
||||||
|
if s.config.Identity == nil {
|
||||||
|
// Pull identity from database
|
||||||
|
identity, err := s.persistence.GetIdentity()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if identity == nil {
|
||||||
|
identity, err = crypto.GenerateKey()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := s.persistence.SaveIdentity(identity); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.config.Identity = identity
|
||||||
|
}
|
||||||
|
|
||||||
pks, err := s.persistence.GetPushNotificationRegistrationPublicKeys()
|
pks, err := s.persistence.GetPushNotificationRegistrationPublicKeys()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -459,12 +459,9 @@ func buildMessengerOptions(
|
||||||
options = append(options, protocol.WithDatasync())
|
options = append(options, protocol.WithDatasync())
|
||||||
}
|
}
|
||||||
|
|
||||||
// For now build with default/hardcoded options.
|
|
||||||
if config.PushNotificationServerEnabled {
|
if config.PushNotificationServerEnabled {
|
||||||
config := &push_notification_server.Config{
|
config := &push_notification_server.Config{
|
||||||
Identity: identity,
|
Logger: logger,
|
||||||
Logger: logger,
|
|
||||||
GorushURL: "https://gorush.status.im",
|
|
||||||
}
|
}
|
||||||
options = append(options, protocol.WithPushNotificationServerConfig(config))
|
options = append(options, protocol.WithPushNotificationServerConfig(config))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue