feat: media server and colorhash related change (#3500)
This commit is contained in:
parent
c26f45ae3d
commit
6fed50ce53
|
@ -35,6 +35,8 @@ import (
|
||||||
"github.com/status-im/status-go/nodecfg"
|
"github.com/status-im/status-go/nodecfg"
|
||||||
"github.com/status-im/status-go/params"
|
"github.com/status-im/status-go/params"
|
||||||
"github.com/status-im/status-go/protocol"
|
"github.com/status-im/status-go/protocol"
|
||||||
|
identityUtils "github.com/status-im/status-go/protocol/identity"
|
||||||
|
"github.com/status-im/status-go/protocol/identity/colorhash"
|
||||||
"github.com/status-im/status-go/protocol/requests"
|
"github.com/status-im/status-go/protocol/requests"
|
||||||
"github.com/status-im/status-go/rpc"
|
"github.com/status-im/status-go/rpc"
|
||||||
"github.com/status-im/status-go/services/ext"
|
"github.com/status-im/status-go/services/ext"
|
||||||
|
@ -180,6 +182,13 @@ func (b *GethStatusBackend) OpenAccounts() error {
|
||||||
b.multiaccountsDB = db
|
b.multiaccountsDB = db
|
||||||
// Probably we should iron out a bit better how to create/dispose of the status-service
|
// Probably we should iron out a bit better how to create/dispose of the status-service
|
||||||
b.statusNode.SetMultiaccountsDB(db)
|
b.statusNode.SetMultiaccountsDB(db)
|
||||||
|
|
||||||
|
err = b.statusNode.StartMediaServerWithoutDB()
|
||||||
|
if err != nil {
|
||||||
|
b.log.Error("failed to start media server without app db", "err", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -968,12 +977,44 @@ func (b *GethStatusBackend) VerifyDatabasePassword(keyUID string, password strin
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *GethStatusBackend) SaveAccountAndStartNodeWithKey(acc multiaccounts.Account, password string, settings settings.Settings, nodecfg *params.NodeConfig, subaccs []*accounts.Account, keyHex string) error {
|
func enrichMultiaccountInfo(account *multiaccounts.Account, subaccs []*accounts.Account) error {
|
||||||
err := b.SaveAccount(acc)
|
if account.ColorHash != nil && account.ColorID != 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, acc := range subaccs {
|
||||||
|
subaccs[i].KeyUID = account.KeyUID
|
||||||
|
|
||||||
|
if acc.Chat {
|
||||||
|
colorHash, err := colorhash.GenerateFor(string(acc.PublicKey.Bytes()))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
account.ColorHash = colorHash
|
||||||
|
|
||||||
|
colorID, err := identityUtils.ToColorID(string(acc.PublicKey.Bytes()))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
account.ColorID = colorID
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *GethStatusBackend) SaveAccountAndStartNodeWithKey(account multiaccounts.Account, password string, settings settings.Settings, nodecfg *params.NodeConfig, subaccs []*accounts.Account, keyHex string) error {
|
||||||
|
err := enrichMultiaccountInfo(&account, subaccs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = b.ensureAppDBOpened(acc, password)
|
err = b.SaveAccount(account)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = b.ensureAppDBOpened(account, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -981,7 +1022,7 @@ func (b *GethStatusBackend) SaveAccountAndStartNodeWithKey(acc multiaccounts.Acc
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return b.StartNodeWithKey(acc, password, keyHex)
|
return b.StartNodeWithKey(account, password, keyHex)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartNodeWithAccountAndInitialConfig is used after account and config was generated.
|
// StartNodeWithAccountAndInitialConfig is used after account and config was generated.
|
||||||
|
@ -995,7 +1036,12 @@ func (b *GethStatusBackend) StartNodeWithAccountAndInitialConfig(
|
||||||
subaccs []*accounts.Account,
|
subaccs []*accounts.Account,
|
||||||
) error {
|
) error {
|
||||||
b.log.Info("node config", "config", nodecfg)
|
b.log.Info("node config", "config", nodecfg)
|
||||||
err := b.SaveAccount(account)
|
|
||||||
|
err := enrichMultiaccountInfo(&account, subaccs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = b.SaveAccount(account)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -335,26 +335,6 @@ func SaveAccountAndLogin(accountData, password, settingsJSON, configJSON, subacc
|
||||||
return makeJSONResponse(err)
|
return makeJSONResponse(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, acc := range subaccs {
|
|
||||||
subaccs[i].KeyUID = account.KeyUID
|
|
||||||
|
|
||||||
if acc.Chat {
|
|
||||||
colorHash, err := colorhash.GenerateFor(string(acc.PublicKey.Bytes()))
|
|
||||||
if err != nil {
|
|
||||||
return makeJSONResponse(err)
|
|
||||||
}
|
|
||||||
account.ColorHash = colorHash
|
|
||||||
|
|
||||||
colorID, err := identityUtils.ToColorID(string(acc.PublicKey.Bytes()))
|
|
||||||
if err != nil {
|
|
||||||
return makeJSONResponse(err)
|
|
||||||
}
|
|
||||||
account.ColorID = colorID
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
api.RunAsync(func() error {
|
api.RunAsync(func() error {
|
||||||
log.Debug("starting a node, and saving account with configuration", "key-uid", account.KeyUID)
|
log.Debug("starting a node, and saving account with configuration", "key-uid", account.KeyUID)
|
||||||
err := statusBackend.StartNodeWithAccountAndInitialConfig(account, password, settings, &conf, subaccs)
|
err := statusBackend.StartNodeWithAccountAndInitialConfig(account, password, settings, &conf, subaccs)
|
||||||
|
@ -417,26 +397,6 @@ func SaveAccountAndLoginWithKeycard(accountData, password, settingsJSON, configJ
|
||||||
return makeJSONResponse(err)
|
return makeJSONResponse(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, acc := range subaccs {
|
|
||||||
subaccs[i].KeyUID = account.KeyUID
|
|
||||||
|
|
||||||
if acc.Chat {
|
|
||||||
colorHash, err := colorhash.GenerateFor(string(acc.PublicKey.Bytes()))
|
|
||||||
if err != nil {
|
|
||||||
return makeJSONResponse(err)
|
|
||||||
}
|
|
||||||
account.ColorHash = colorHash
|
|
||||||
|
|
||||||
colorID, err := identityUtils.ToColorID(string(acc.PublicKey.Bytes()))
|
|
||||||
if err != nil {
|
|
||||||
return makeJSONResponse(err)
|
|
||||||
}
|
|
||||||
account.ColorID = colorID
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
api.RunAsync(func() error {
|
api.RunAsync(func() error {
|
||||||
log.Debug("starting a node, and saving account with configuration", "key-uid", account.KeyUID)
|
log.Debug("starting a node, and saving account with configuration", "key-uid", account.KeyUID)
|
||||||
err := statusBackend.SaveAccountAndStartNodeWithKey(account, password, settings, &conf, subaccs, keyHex)
|
err := statusBackend.SaveAccountAndStartNodeWithKey(account, password, settings, &conf, subaccs, keyHex)
|
||||||
|
|
|
@ -362,7 +362,6 @@ func (db *Database) DeleteAccount(keyUID string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Account images
|
// Account images
|
||||||
|
|
||||||
func (db *Database) GetIdentityImages(keyUID string) (iis []*images.IdentityImage, err error) {
|
func (db *Database) GetIdentityImages(keyUID string) (iis []*images.IdentityImage, err error) {
|
||||||
rows, err := db.db.Query(`SELECT key_uid, name, image_payload, width, height, file_size, resize_target, clock FROM identity_images WHERE key_uid = ?`, keyUID)
|
rows, err := db.db.Query(`SELECT key_uid, name, image_payload, width, height, file_size, resize_target, clock FROM identity_images WHERE key_uid = ?`, keyUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -188,6 +188,34 @@ type StartOptions struct {
|
||||||
AccountsManager *accounts.Manager
|
AccountsManager *accounts.Manager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StartMediaServerWithoutDB starts media server without starting the node
|
||||||
|
// The server can only handle requests that don't require appdb or IPFS downloader
|
||||||
|
func (n *StatusNode) StartMediaServerWithoutDB() error {
|
||||||
|
if n.isRunning() {
|
||||||
|
n.log.Debug("node is already running, no need to StartMediaServerWithoutDB")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if n.httpServer != nil {
|
||||||
|
if err := n.httpServer.Stop(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
httpServer, err := server.NewMediaServer(nil, nil, n.multiaccountsDB)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
n.httpServer = httpServer
|
||||||
|
|
||||||
|
if err := n.httpServer.Start(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// StartWithOptions starts current StatusNode, failing if it's already started.
|
// StartWithOptions starts current StatusNode, failing if it's already started.
|
||||||
// It takes some options that allows to further configure starting process.
|
// It takes some options that allows to further configure starting process.
|
||||||
func (n *StatusNode) StartWithOptions(config *params.NodeConfig, options StartOptions) error {
|
func (n *StatusNode) StartWithOptions(config *params.NodeConfig, options StartOptions) error {
|
||||||
|
@ -240,18 +268,24 @@ func (n *StatusNode) startWithDB(config *params.NodeConfig, accs *accounts.Manag
|
||||||
|
|
||||||
n.downloader = ipfs.NewDownloader(config.RootDataDir)
|
n.downloader = ipfs.NewDownloader(config.RootDataDir)
|
||||||
|
|
||||||
|
if n.httpServer != nil {
|
||||||
|
if err := n.httpServer.Stop(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
httpServer, err := server.NewMediaServer(n.appDB, n.downloader, n.multiaccountsDB)
|
httpServer, err := server.NewMediaServer(n.appDB, n.downloader, n.multiaccountsDB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := httpServer.Start(); err != nil {
|
n.httpServer = httpServer
|
||||||
|
|
||||||
|
if err := n.httpServer.Start(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
n.httpServer = httpServer
|
if err := n.initServices(config, n.httpServer); err != nil {
|
||||||
|
|
||||||
if err := n.initServices(config, httpServer); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return n.startGethNode()
|
return n.startGethNode()
|
||||||
|
|
|
@ -36,6 +36,18 @@ const (
|
||||||
|
|
||||||
type HandlerPatternMap map[string]http.HandlerFunc
|
type HandlerPatternMap map[string]http.HandlerFunc
|
||||||
|
|
||||||
|
func handleRequestDBMissing(logger *zap.Logger) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
logger.Error("can't handle media request without appdb")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleRequestDownloaderMissing(logger *zap.Logger) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
logger.Error("can't handle media request without ipfs downloader")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func handleAccountImages(multiaccountsDB *multiaccounts.Database, logger *zap.Logger) http.HandlerFunc {
|
func handleAccountImages(multiaccountsDB *multiaccounts.Database, logger *zap.Logger) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
params := r.URL.Query()
|
params := r.URL.Query()
|
||||||
|
@ -60,21 +72,33 @@ func handleAccountImages(multiaccountsDB *multiaccounts.Database, logger *zap.Lo
|
||||||
var payload = identityImage.Payload
|
var payload = identityImage.Payload
|
||||||
|
|
||||||
if ringEnabled(params) {
|
if ringEnabled(params) {
|
||||||
pks, ok := params["publicKey"]
|
account, err := multiaccountsDB.GetAccount(keyUids[0])
|
||||||
if !ok || len(pks) == 0 {
|
|
||||||
logger.Error("no publicKey")
|
if err != nil {
|
||||||
|
logger.Error("handleAccountImages: failed to GetAccount .", zap.String("keyUid", keyUids[0]), zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
colorHash, err := colorhash.GenerateFor(pks[0])
|
|
||||||
if err != nil {
|
accColorHash := account.ColorHash
|
||||||
logger.Error("could not generate color hash")
|
|
||||||
return
|
if accColorHash == nil {
|
||||||
|
pks, ok := params["publicKey"]
|
||||||
|
if !ok || len(pks) == 0 {
|
||||||
|
logger.Error("no publicKey")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
accColorHash, err = colorhash.GenerateFor(pks[0])
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("could not generate color hash")
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var theme = getTheme(params, logger)
|
var theme = getTheme(params, logger)
|
||||||
|
|
||||||
payload, err = ring.DrawRing(&ring.DrawRingParam{
|
payload, err = ring.DrawRing(&ring.DrawRingParam{
|
||||||
Theme: theme, ColorHash: colorHash, ImageBytes: identityImage.Payload, Height: identityImage.Height, Width: identityImage.Width,
|
Theme: theme, ColorHash: accColorHash, ImageBytes: identityImage.Payload, Height: identityImage.Height, Width: identityImage.Width,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -103,6 +127,10 @@ func handleAccountImages(multiaccountsDB *multiaccounts.Database, logger *zap.Lo
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleContactImages(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
func handleContactImages(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
||||||
|
if db == nil {
|
||||||
|
return handleRequestDBMissing(logger)
|
||||||
|
}
|
||||||
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
params := r.URL.Query()
|
params := r.URL.Query()
|
||||||
pks, ok := params["publicKey"]
|
pks, ok := params["publicKey"]
|
||||||
|
@ -226,6 +254,10 @@ func handleIdenticon(logger *zap.Logger) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleDiscordAuthorAvatar(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
func handleDiscordAuthorAvatar(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
||||||
|
if db == nil {
|
||||||
|
return handleRequestDBMissing(logger)
|
||||||
|
}
|
||||||
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
authorIDs, ok := r.URL.Query()["authorId"]
|
authorIDs, ok := r.URL.Query()["authorId"]
|
||||||
if !ok || len(authorIDs) == 0 {
|
if !ok || len(authorIDs) == 0 {
|
||||||
|
@ -260,6 +292,10 @@ func handleDiscordAuthorAvatar(db *sql.DB, logger *zap.Logger) http.HandlerFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleDiscordAttachment(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
func handleDiscordAttachment(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
||||||
|
if db == nil {
|
||||||
|
return handleRequestDBMissing(logger)
|
||||||
|
}
|
||||||
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
messageIDs, ok := r.URL.Query()["messageId"]
|
messageIDs, ok := r.URL.Query()["messageId"]
|
||||||
if !ok || len(messageIDs) == 0 {
|
if !ok || len(messageIDs) == 0 {
|
||||||
|
@ -299,6 +335,10 @@ func handleDiscordAttachment(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleImage(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
func handleImage(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
||||||
|
if db == nil {
|
||||||
|
return handleRequestDBMissing(logger)
|
||||||
|
}
|
||||||
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
messageIDs, ok := r.URL.Query()["messageId"]
|
messageIDs, ok := r.URL.Query()["messageId"]
|
||||||
if !ok || len(messageIDs) == 0 {
|
if !ok || len(messageIDs) == 0 {
|
||||||
|
@ -332,6 +372,10 @@ func handleImage(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleAudio(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
func handleAudio(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
||||||
|
if db == nil {
|
||||||
|
return handleRequestDBMissing(logger)
|
||||||
|
}
|
||||||
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
messageIDs, ok := r.URL.Query()["messageId"]
|
messageIDs, ok := r.URL.Query()["messageId"]
|
||||||
if !ok || len(messageIDs) == 0 {
|
if !ok || len(messageIDs) == 0 {
|
||||||
|
@ -361,6 +405,10 @@ func handleAudio(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleIPFS(downloader *ipfs.Downloader, logger *zap.Logger) http.HandlerFunc {
|
func handleIPFS(downloader *ipfs.Downloader, logger *zap.Logger) http.HandlerFunc {
|
||||||
|
if downloader == nil {
|
||||||
|
return handleRequestDownloaderMissing(logger)
|
||||||
|
}
|
||||||
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
hashes, ok := r.URL.Query()["hash"]
|
hashes, ok := r.URL.Query()["hash"]
|
||||||
if !ok || len(hashes) == 0 {
|
if !ok || len(hashes) == 0 {
|
||||||
|
|
|
@ -110,6 +110,9 @@ func (s *SyncDeviceSuite) prepareBackendWithAccount(tmpdir string) *api.GethStat
|
||||||
accounts := []*accounts.Account{walletAccount, chatAccount}
|
accounts := []*accounts.Account{walletAccount, chatAccount}
|
||||||
err = backend.StartNodeWithAccountAndInitialConfig(account, s.password, *settings, nodeConfig, accounts)
|
err = backend.StartNodeWithAccountAndInitialConfig(account, s.password, *settings, nodeConfig, accounts)
|
||||||
require.NoError(s.T(), err)
|
require.NoError(s.T(), err)
|
||||||
|
multiaccounts, err := backend.GetAccounts()
|
||||||
|
require.NoError(s.T(), err)
|
||||||
|
require.NotEmpty(s.T(), multiaccounts[0].ColorHash)
|
||||||
|
|
||||||
return backend
|
return backend
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue