Implement correct getter and setter functionality for Communities
This commit is contained in:
parent
243135d744
commit
03e28eea0d
|
@ -40,7 +40,7 @@ type Config struct {
|
||||||
RequestsToJoin []*RequestToJoin
|
RequestsToJoin []*RequestToJoin
|
||||||
MemberIdentity *ecdsa.PublicKey
|
MemberIdentity *ecdsa.PublicKey
|
||||||
SyncedAt uint64
|
SyncedAt uint64
|
||||||
RekeyedAt *time.Time
|
RekeyedAt time.Time
|
||||||
EventsData *EventsData
|
EventsData *EventsData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ var ErrOldRequestToLeave = errors.New("old request to leave")
|
||||||
|
|
||||||
const OR = " OR "
|
const OR = " OR "
|
||||||
const communitiesBaseQuery = `
|
const communitiesBaseQuery = `
|
||||||
SELECT c.id, c.private_key, c.description, c.joined, c.spectated, c.verified, c.muted, c.muted_till, c.rekeyed, r.clock, ae.raw_events, ae.raw_description
|
SELECT c.id, c.private_key, c.description, c.joined, c.spectated, c.verified, c.muted, c.muted_till, c.rekeyed_at, r.clock, ae.raw_events, ae.raw_description
|
||||||
FROM communities_communities c
|
FROM communities_communities c
|
||||||
LEFT JOIN communities_requests_to_join r ON c.id = r.community_id AND r.public_key = ?
|
LEFT JOIN communities_requests_to_join r ON c.id = r.community_id AND r.public_key = ?
|
||||||
LEFT JOIN communities_events ae ON c.id = ae.id`
|
LEFT JOIN communities_events ae ON c.id = ae.id`
|
||||||
|
@ -143,12 +143,12 @@ func (p *Persistence) queryCommunities(memberIdentity *ecdsa.PublicKey, query st
|
||||||
|
|
||||||
// Community events specific fields
|
// Community events specific fields
|
||||||
var eventsBytes, eventsDescriptionBytes []byte
|
var eventsBytes, eventsDescriptionBytes []byte
|
||||||
err := rows.Scan(&publicKeyBytes, &privateKeyBytes, &descriptionBytes, &joined, &spectated, &verified, &muted, &muteTill, &requestedToJoinAt, &rekeyedAt, &eventsBytes, &eventsDescriptionBytes)
|
err := rows.Scan(&publicKeyBytes, &privateKeyBytes, &descriptionBytes, &joined, &spectated, &verified, &muted, &muteTill, &rekeyedAt, &requestedToJoinAt, &eventsBytes, &eventsDescriptionBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
org, err := unmarshalCommunityFromDB(memberIdentity, publicKeyBytes, privateKeyBytes, descriptionBytes, joined, spectated, verified, muted, muteTill.Time, &rekeyedAt.Time, uint64(requestedToJoinAt.Int64), eventsBytes, eventsDescriptionBytes, p.logger)
|
org, err := unmarshalCommunityFromDB(memberIdentity, publicKeyBytes, privateKeyBytes, descriptionBytes, joined, spectated, verified, muted, muteTill.Time, rekeyedAt.Time, uint64(requestedToJoinAt.Int64), eventsBytes, eventsDescriptionBytes, p.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -190,8 +190,7 @@ func (p *Persistence) rowsToCommunities(memberIdentity *ecdsa.PublicKey, rows *s
|
||||||
// Community specific fields
|
// Community specific fields
|
||||||
var publicKeyBytes, privateKeyBytes, descriptionBytes []byte
|
var publicKeyBytes, privateKeyBytes, descriptionBytes []byte
|
||||||
var joined, spectated, verified, muted bool
|
var joined, spectated, verified, muted bool
|
||||||
var muteTill sql.NullTime
|
var muteTill, rekeyedAt sql.NullTime
|
||||||
var rekeyedAt sql.NullTime
|
|
||||||
|
|
||||||
// Request to join specific fields
|
// Request to join specific fields
|
||||||
var rtjID, rtjCommunityID []byte
|
var rtjID, rtjCommunityID []byte
|
||||||
|
@ -202,13 +201,13 @@ func (p *Persistence) rowsToCommunities(memberIdentity *ecdsa.PublicKey, rows *s
|
||||||
var eventsBytes, eventsDescriptionBytes []byte
|
var eventsBytes, eventsDescriptionBytes []byte
|
||||||
|
|
||||||
err = rows.Scan(
|
err = rows.Scan(
|
||||||
&publicKeyBytes, &privateKeyBytes, &descriptionBytes, &joined, &spectated, &verified, &muted, &muteTill,
|
&publicKeyBytes, &privateKeyBytes, &descriptionBytes, &joined, &spectated, &verified, &muted, &muteTill, &rekeyedAt,
|
||||||
&rtjID, &rtjPublicKey, &rtjClock, &rtjENSName, &rtjChatID, &rtjCommunityID, &rtjState, &eventsBytes, &eventsDescriptionBytes)
|
&rtjID, &rtjPublicKey, &rtjClock, &rtjENSName, &rtjChatID, &rtjCommunityID, &rtjState, &eventsBytes, &eventsDescriptionBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
comm, err = unmarshalCommunityFromDB(memberIdentity, publicKeyBytes, privateKeyBytes, descriptionBytes, joined, spectated, verified, muted, muteTill.Time, &rekeyedAt.Time, uint64(rtjClock.Int64), eventsBytes, eventsDescriptionBytes, p.logger)
|
comm, err = unmarshalCommunityFromDB(memberIdentity, publicKeyBytes, privateKeyBytes, descriptionBytes, joined, spectated, verified, muted, muteTill.Time, rekeyedAt.Time, uint64(rtjClock.Int64), eventsBytes, eventsDescriptionBytes, p.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -225,7 +224,7 @@ func (p *Persistence) rowsToCommunities(memberIdentity *ecdsa.PublicKey, rows *s
|
||||||
|
|
||||||
func (p *Persistence) JoinedAndPendingCommunitiesWithRequests(memberIdentity *ecdsa.PublicKey) (comms []*Community, err error) {
|
func (p *Persistence) JoinedAndPendingCommunitiesWithRequests(memberIdentity *ecdsa.PublicKey) (comms []*Community, err error) {
|
||||||
query := `SELECT
|
query := `SELECT
|
||||||
c.id, c.private_key, c.description, c.joined, c.spectated, c.verified, c.muted, c.muted_till,
|
c.id, c.private_key, c.description, c.joined, c.spectated, c.verified, c.muted, c.muted_till, c.rekeyed_at,
|
||||||
r.id, r.public_key, r.clock, r.ens_name, r.chat_id, r.community_id, r.state, ae.raw_events, ae.raw_description
|
r.id, r.public_key, r.clock, r.ens_name, r.chat_id, r.community_id, r.state, ae.raw_events, ae.raw_description
|
||||||
FROM communities_communities c
|
FROM communities_communities c
|
||||||
LEFT JOIN communities_requests_to_join r ON c.id = r.community_id AND r.public_key = ?
|
LEFT JOIN communities_requests_to_join r ON c.id = r.community_id AND r.public_key = ?
|
||||||
|
@ -242,7 +241,7 @@ WHERE c.Joined OR r.state = ?`
|
||||||
|
|
||||||
func (p *Persistence) DeletedCommunities(memberIdentity *ecdsa.PublicKey) (comms []*Community, err error) {
|
func (p *Persistence) DeletedCommunities(memberIdentity *ecdsa.PublicKey) (comms []*Community, err error) {
|
||||||
query := `SELECT
|
query := `SELECT
|
||||||
c.id, c.private_key, c.description, c.joined, c.spectated, c.verified, c.muted, c.muted_till,
|
c.id, c.private_key, c.description, c.joined, c.spectated, c.verified, c.muted, c.muted_till, c.rekeyed_at,
|
||||||
r.id, r.public_key, r.clock, r.ens_name, r.chat_id, r.community_id, r.state, ae.raw_events, ae.raw_description
|
r.id, r.public_key, r.clock, r.ens_name, r.chat_id, r.community_id, r.state, ae.raw_events, ae.raw_description
|
||||||
FROM communities_communities c
|
FROM communities_communities c
|
||||||
LEFT JOIN communities_requests_to_join r ON c.id = r.community_id AND r.public_key = ?
|
LEFT JOIN communities_requests_to_join r ON c.id = r.community_id AND r.public_key = ?
|
||||||
|
@ -271,23 +270,23 @@ func (p *Persistence) GetByID(memberIdentity *ecdsa.PublicKey, id []byte) (*Comm
|
||||||
var muteTill sql.NullTime
|
var muteTill sql.NullTime
|
||||||
var rekeyed sql.NullTime
|
var rekeyed sql.NullTime
|
||||||
var requestedToJoinAt sql.NullInt64
|
var requestedToJoinAt sql.NullInt64
|
||||||
|
var rekeyedAt sql.NullTime
|
||||||
|
|
||||||
// Community events specific fields
|
// Community events specific fields
|
||||||
var eventsBytes, eventsDescriptionBytes []byte
|
var eventsBytes, eventsDescriptionBytes []byte
|
||||||
|
|
||||||
err := p.db.QueryRow(communitiesBaseQuery+` WHERE c.id = ?`, common.PubkeyToHex(memberIdentity), id).Scan(&publicKeyBytes, &privateKeyBytes, &descriptionBytes, &joined, &spectated, &verified, &muted, &muteTill, &rekeyed, &requestedToJoinAt, &eventsBytes, &eventsDescriptionBytes)
|
err := p.db.QueryRow(communitiesBaseQuery+` WHERE c.id = ?`, common.PubkeyToHex(memberIdentity), id).Scan(&publicKeyBytes, &privateKeyBytes, &descriptionBytes, &joined, &spectated, &verified, &muted, &muteTill, &rekeyedAt, &requestedToJoinAt, &eventsBytes, &eventsDescriptionBytes)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return unmarshalCommunityFromDB(memberIdentity, publicKeyBytes, privateKeyBytes, descriptionBytes, joined, spectated, verified, muted, muteTill.Time, &rekeyed.Time, uint64(requestedToJoinAt.Int64), eventsBytes, eventsDescriptionBytes, p.logger)
|
return unmarshalCommunityFromDB(memberIdentity, publicKeyBytes, privateKeyBytes, descriptionBytes, joined, spectated, verified, muted, muteTill.Time, rekeyed.Time, uint64(requestedToJoinAt.Int64), eventsBytes, eventsDescriptionBytes, p.logger)
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarshalCommunityFromDB(memberIdentity *ecdsa.PublicKey, publicKeyBytes, privateKeyBytes, descriptionBytes []byte, joined,
|
func unmarshalCommunityFromDB(memberIdentity *ecdsa.PublicKey, publicKeyBytes, privateKeyBytes, descriptionBytes []byte, joined,
|
||||||
spectated, verified, muted bool, muteTill time.Time, rekeyedAt *time.Time, requestedToJoinAt uint64, eventsBytes []byte,
|
spectated, verified, muted bool, muteTill time.Time, rekeyedAt time.Time, requestedToJoinAt uint64, eventsBytes []byte,
|
||||||
eventsDescriptionBytes []byte, logger *zap.Logger) (*Community, error) {
|
eventsDescriptionBytes []byte, logger *zap.Logger) (*Community, error) {
|
||||||
|
|
||||||
var privateKey *ecdsa.PrivateKey
|
var privateKey *ecdsa.PrivateKey
|
||||||
|
@ -1273,11 +1272,17 @@ func decodeEventsData(eventsBytes []byte, eventsDescriptionBytes []byte) (*Event
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Persistence) GetRekeyedAtClock(id []byte, time *time.Time) error {
|
// GetRekeyedAtClock returns the rekeyed_at time of a given community
|
||||||
_, err := p.db.Exec(`UPDATE communities_communities SET rekeyed_at = ? WHERE id = ? AND rekeyed_at < ?`, time, id, time)
|
func (p *Persistence) GetRekeyedAtClock(id []byte) (*time.Time, error) {
|
||||||
return err
|
rekeyedAt := time.Time{}
|
||||||
|
err := p.db.QueryRow(`SELECT rekeyed_at FROM communities_communities WHERE id = ?`, id).Scan(&rekeyedAt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &rekeyedAt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetRekeyedAtClock sets the rekeyed_at time value of a given community
|
||||||
func (p *Persistence) SetRekeyedAtClock(id []byte, time *time.Time) error {
|
func (p *Persistence) SetRekeyedAtClock(id []byte, time *time.Time) error {
|
||||||
_, err := p.db.Exec(`UPDATE communities_communities SET rekeyed_at = ? WHERE id = ? AND rekeyed_at < ?`, time, id, time)
|
_, err := p.db.Exec(`UPDATE communities_communities SET rekeyed_at = ? WHERE id = ? AND rekeyed_at < ?`, time, id, time)
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -471,3 +471,42 @@ func (s *PersistenceSuite) TestSaveCheckChannelPermissionResponse() {
|
||||||
s.Require().Equal(responses[chatID].ViewAndPostPermissions.Permissions["one"].Criteria, []bool{true, true, true, true})
|
s.Require().Equal(responses[chatID].ViewAndPostPermissions.Permissions["one"].Criteria, []bool{true, true, true, true})
|
||||||
s.Require().Equal(responses[chatID].ViewAndPostPermissions.Permissions["two"].Criteria, []bool{false})
|
s.Require().Equal(responses[chatID].ViewAndPostPermissions.Permissions["two"].Criteria, []bool{false})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *PersistenceSuite) TestGetRekeyedAtClock() {
|
||||||
|
key, err := crypto.GenerateKey()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// there is one community inserted by default
|
||||||
|
communities, err := s.db.AllCommunities(&key.PublicKey)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(communities, 1)
|
||||||
|
|
||||||
|
community := Community{
|
||||||
|
config: &Config{
|
||||||
|
PrivateKey: key,
|
||||||
|
ID: &key.PublicKey,
|
||||||
|
Joined: true,
|
||||||
|
Spectated: true,
|
||||||
|
Verified: true,
|
||||||
|
CommunityDescription: &protobuf.CommunityDescription{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
s.Require().NoError(s.db.SaveCommunity(&community))
|
||||||
|
|
||||||
|
communities, err = s.db.AllCommunities(&key.PublicKey)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Len(communities, 2)
|
||||||
|
s.Equal(types.HexBytes(crypto.CompressPubkey(&key.PublicKey)), communities[1].ID())
|
||||||
|
s.True(communities[1].Joined())
|
||||||
|
s.True(communities[1].Spectated())
|
||||||
|
s.True(communities[1].Verified())
|
||||||
|
s.Zero(communities[1].config.RekeyedAt.Unix())
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
err = s.db.SetRekeyedAtClock(communities[1].ID(), &now)
|
||||||
|
s.NoError(err)
|
||||||
|
|
||||||
|
then, err := s.db.GetRekeyedAtClock(communities[0].ID())
|
||||||
|
s.NoError(err)
|
||||||
|
now.Equal(*then)
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package communities
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/status-im/status-go/protocol/protobuf"
|
"github.com/status-im/status-go/protocol/protobuf"
|
||||||
)
|
)
|
||||||
|
@ -15,9 +16,11 @@ type RawCommunityRow struct {
|
||||||
Verified bool
|
Verified bool
|
||||||
SyncedAt uint64
|
SyncedAt uint64
|
||||||
Muted bool
|
Muted bool
|
||||||
|
RekeyedAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func fromSyncCommunityProtobuf(syncCommProto *protobuf.SyncCommunity) RawCommunityRow {
|
func fromSyncCommunityProtobuf(syncCommProto *protobuf.SyncCommunity) RawCommunityRow {
|
||||||
|
// TODO handle rekeyedAt value
|
||||||
return RawCommunityRow{
|
return RawCommunityRow{
|
||||||
ID: syncCommProto.Id,
|
ID: syncCommProto.Id,
|
||||||
Description: syncCommProto.Description,
|
Description: syncCommProto.Description,
|
||||||
|
@ -31,9 +34,7 @@ func fromSyncCommunityProtobuf(syncCommProto *protobuf.SyncCommunity) RawCommuni
|
||||||
|
|
||||||
func (p *Persistence) scanRowToStruct(rowScan func(dest ...interface{}) error) (*RawCommunityRow, error) {
|
func (p *Persistence) scanRowToStruct(rowScan func(dest ...interface{}) error) (*RawCommunityRow, error) {
|
||||||
rcr := new(RawCommunityRow)
|
rcr := new(RawCommunityRow)
|
||||||
|
var syncedAt, muteTill, rekeyedAt sql.NullTime
|
||||||
syncedAt := sql.NullTime{}
|
|
||||||
muteTill := sql.NullTime{}
|
|
||||||
|
|
||||||
err := rowScan(
|
err := rowScan(
|
||||||
&rcr.ID,
|
&rcr.ID,
|
||||||
|
@ -44,11 +45,15 @@ func (p *Persistence) scanRowToStruct(rowScan func(dest ...interface{}) error) (
|
||||||
&rcr.Spectated,
|
&rcr.Spectated,
|
||||||
&rcr.Muted,
|
&rcr.Muted,
|
||||||
&muteTill,
|
&muteTill,
|
||||||
|
&rekeyedAt,
|
||||||
&syncedAt,
|
&syncedAt,
|
||||||
)
|
)
|
||||||
if syncedAt.Valid {
|
if syncedAt.Valid {
|
||||||
rcr.SyncedAt = uint64(syncedAt.Time.Unix())
|
rcr.SyncedAt = uint64(syncedAt.Time.Unix())
|
||||||
}
|
}
|
||||||
|
if rekeyedAt.Valid {
|
||||||
|
rcr.RekeyedAt = rekeyedAt.Time
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE communities_communities ADD COLUMN rekeyed_at TIMESTAMP DEFAULT 0 NOT NULL;
|
Loading…
Reference in New Issue