140 lines
3.7 KiB
Go
140 lines
3.7 KiB
Go
package communities
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"database/sql"
|
|
|
|
"github.com/golang/protobuf/proto"
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/status-im/status-go/eth-node/crypto"
|
|
"github.com/status-im/status-go/protocol/protobuf"
|
|
)
|
|
|
|
type Persistence struct {
|
|
db *sql.DB
|
|
logger *zap.Logger
|
|
}
|
|
|
|
func (p *Persistence) SaveCommunity(community *Community) error {
|
|
id := community.ID()
|
|
privateKey := community.PrivateKey()
|
|
description, err := community.ToBytes()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = p.db.Exec(`INSERT INTO communities_communities (id, private_key, description, joined, verified) VALUES (?, ?, ?,?,?)`, id, crypto.FromECDSA(privateKey), description, community.config.Joined, community.config.Verified)
|
|
return err
|
|
}
|
|
|
|
func (p *Persistence) queryCommunities(query string) (response []*Community, err error) {
|
|
|
|
rows, err := p.db.Query(query)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defer func() {
|
|
if err != nil {
|
|
// Don't shadow original error
|
|
_ = rows.Close()
|
|
return
|
|
|
|
}
|
|
err = rows.Close()
|
|
}()
|
|
|
|
for rows.Next() {
|
|
var publicKeyBytes, privateKeyBytes, descriptionBytes []byte
|
|
var joined bool
|
|
var verified bool
|
|
err := rows.Scan(&publicKeyBytes, &privateKeyBytes, &descriptionBytes, &joined, &verified)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
org, err := unmarshalCommunityFromDB(publicKeyBytes, privateKeyBytes, descriptionBytes, joined, verified, p.logger)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
response = append(response, org)
|
|
}
|
|
|
|
return response, nil
|
|
|
|
}
|
|
|
|
func (p *Persistence) AllCommunities() ([]*Community, error) {
|
|
query := `SELECT id, private_key, description,joined,verified FROM communities_communities`
|
|
return p.queryCommunities(query)
|
|
}
|
|
|
|
func (p *Persistence) JoinedCommunities() ([]*Community, error) {
|
|
query := `SELECT id, private_key, description,joined,verified FROM communities_communities WHERE joined`
|
|
return p.queryCommunities(query)
|
|
}
|
|
|
|
func (p *Persistence) CreatedCommunities() ([]*Community, error) {
|
|
query := `SELECT id, private_key, description,joined,verified FROM communities_communities WHERE private_key IS NOT NULL`
|
|
return p.queryCommunities(query)
|
|
}
|
|
|
|
func (p *Persistence) GetByID(id []byte) (*Community, error) {
|
|
var publicKeyBytes, privateKeyBytes, descriptionBytes []byte
|
|
var joined bool
|
|
var verified bool
|
|
|
|
err := p.db.QueryRow(`SELECT id, private_key, description, joined,verified FROM communities_communities WHERE id = ?`, id).Scan(&publicKeyBytes, &privateKeyBytes, &descriptionBytes, &joined, &verified)
|
|
|
|
if err == sql.ErrNoRows {
|
|
return nil, nil
|
|
} else if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return unmarshalCommunityFromDB(publicKeyBytes, privateKeyBytes, descriptionBytes, joined, verified, p.logger)
|
|
}
|
|
|
|
func unmarshalCommunityFromDB(publicKeyBytes, privateKeyBytes, descriptionBytes []byte, joined, verified bool, logger *zap.Logger) (*Community, error) {
|
|
|
|
var privateKey *ecdsa.PrivateKey
|
|
var err error
|
|
|
|
if privateKeyBytes != nil {
|
|
privateKey, err = crypto.ToECDSA(privateKeyBytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
metadata := &protobuf.ApplicationMetadataMessage{}
|
|
|
|
err = proto.Unmarshal(descriptionBytes, metadata)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
description := &protobuf.CommunityDescription{}
|
|
|
|
err = proto.Unmarshal(metadata.Payload, description)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
id, err := crypto.DecompressPubkey(publicKeyBytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
config := Config{
|
|
PrivateKey: privateKey,
|
|
CommunityDescription: description,
|
|
MarshaledCommunityDescription: descriptionBytes,
|
|
Logger: logger,
|
|
ID: id,
|
|
Verified: verified,
|
|
Joined: joined,
|
|
}
|
|
return New(config)
|
|
}
|