Update Server Attribute. Fix Profile Attribute Updates. Add UNIQUE constraint to type/key in profile attributes
continuous-integration/drone/pr Build is pending Details
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Sarah Jamie Lewis 2021-11-25 14:34:47 -08:00
parent 1b9a9a0b72
commit e9f986cc2e
4 changed files with 20 additions and 8 deletions

View File

@ -252,6 +252,9 @@ const (
FileDownloadProgressUpdate = Type("FileDownloadProgressUpdate") FileDownloadProgressUpdate = Type("FileDownloadProgressUpdate")
FileDownloaded = Type("FileDownloaded") FileDownloaded = Type("FileDownloaded")
FileVerificationFailed = Type("FileVerificationFailed") FileVerificationFailed = Type("FileVerificationFailed")
// Profile Attribute Event
UpdatedProfileAttribute = Type("UpdatedProfileAttribute")
) )
// Field defines common event attributes // Field defines common event attributes

View File

@ -133,10 +133,8 @@ func (cp *cwtchPeer) GetScopedZonedAttribute(scope attr.Scope, zone attr.Zone, k
defer cp.mutex.Unlock() defer cp.mutex.Unlock()
scopedZonedKey := scope.ConstructScopedZonedPath(zone.ConstructZonedPath(key)) scopedZonedKey := scope.ConstructScopedZonedPath(zone.ConstructZonedPath(key))
log.Debugf("looking up attribute %v %v %v (%v)", scope, zone, key, scopedZonedKey)
value, err := cp.storage.LoadProfileKeyValue(TypeAttribute, scopedZonedKey.ToString()) value, err := cp.storage.LoadProfileKeyValue(TypeAttribute, scopedZonedKey.ToString())
log.Debugf("found [%v] %v", string(value), err)
if err != nil { if err != nil {
return "", false return "", false
} }
@ -151,12 +149,18 @@ func (cp *cwtchPeer) SetScopedZonedAttribute(scope attr.Scope, zone attr.Zone, k
defer cp.mutex.Unlock() defer cp.mutex.Unlock()
scopedZonedKey := scope.ConstructScopedZonedPath(zone.ConstructZonedPath(key)) scopedZonedKey := scope.ConstructScopedZonedPath(zone.ConstructZonedPath(key))
log.Debugf("storing attribute: %v = %v", scopedZonedKey, value)
err := cp.storage.StoreProfileKeyValue(TypeAttribute, scopedZonedKey.ToString(), []byte(value)) err := cp.storage.StoreProfileKeyValue(TypeAttribute, scopedZonedKey.ToString(), []byte(value))
if err != nil { if err != nil {
log.Errorf("error setting attribute %v") log.Errorf("error setting attribute %v")
return
} }
// We always want to publish profile level attributes to the ui
// This should be low traffic.
cp.eventBus.Publish(event.NewEvent(event.UpdatedProfileAttribute, map[event.Field]string{event.Key: scopedZonedKey.ToString(), event.Data: value}))
} }
// SendMessage is a higher level that merges sending messages to contacts and group handles // SendMessage is a higher level that merges sending messages to contacts and group handles
@ -275,7 +279,6 @@ func ImportLegacyProfile(profile *model.Profile, cps *CwtchProfileStorage) Cwtch
cp.queue = event.NewQueue() cp.queue = event.NewQueue()
cp.state = make(map[string]connections.ConnectionState) cp.state = make(map[string]connections.ConnectionState)
// Store all the Necessary Base Attributes In The Database // Store all the Necessary Base Attributes In The Database
cp.SetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.Name, profile.Name)
cp.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, profile.Name) cp.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, profile.Name)
cp.storage.StoreProfileKeyValue(TypeAttribute, attr.PublicScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(constants.Onion)).ToString(), []byte(tor.GetTorV3Hostname(profile.Ed25519PublicKey))) cp.storage.StoreProfileKeyValue(TypeAttribute, attr.PublicScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(constants.Onion)).ToString(), []byte(tor.GetTorV3Hostname(profile.Ed25519PublicKey)))
cp.storage.StoreProfileKeyValue(TypePrivateKey, "Ed25519PrivateKey", profile.Ed25519PrivateKey) cp.storage.StoreProfileKeyValue(TypePrivateKey, "Ed25519PrivateKey", profile.Ed25519PrivateKey)
@ -923,8 +926,14 @@ func (cp *cwtchPeer) eventHandler() {
// The security of cwtch groups are also not dependent on the servers inability to uniquely tag connections (as long as // The security of cwtch groups are also not dependent on the servers inability to uniquely tag connections (as long as
// it learns nothing else about each connection). // it learns nothing else about each connection).
// store the base64 encoded signature for later use // store the base64 encoded signature for later use
//cp.SetConversationAttribute(ev.Data[event.GroupServer], lastKnownSignature, ev.Data[event.Signature])
// TODO Server Connections should sent Connection ID
ci, err := cp.FetchConversationInfo(ev.Data[event.GroupServer])
if ci == nil || err != nil {
log.Errorf("no server connection count")
return
}
cp.SetConversationAttribute(ci.ID, attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(lastReceivedSignature)), ev.Data[event.Signature])
conversations, err := cp.FetchConversations() conversations, err := cp.FetchConversations()
if err == nil { if err == nil {
for _, conversationInfo := range conversations { for _, conversationInfo := range conversations {

View File

@ -63,7 +63,7 @@ type ChannelID struct {
Channel int Channel int
} }
const insertProfileKeySQLStmt = `insert into profile_kv(KeyType, KeyName, KeyValue) values(?,?,?);` const insertProfileKeySQLStmt = `insert or replace into profile_kv(KeyType, KeyName, KeyValue) values(?,?,?);`
const selectProfileKeySQLStmt = `select KeyValue from profile_kv where KeyType=(?) and KeyName=(?);` const selectProfileKeySQLStmt = `select KeyValue from profile_kv where KeyType=(?) and KeyName=(?);`
const insertConversationSQLStmt = `insert into conversations(Handle, Attributes, ACL, Accepted) values(?,?,?,?);` const insertConversationSQLStmt = `insert into conversations(Handle, Attributes, ACL, Accepted) values(?,?,?,?);`
@ -701,7 +701,7 @@ func (cps *CwtchProfileStorage) Close() {
if err == nil { if err == nil {
for _, conversation := range ci { for _, conversation := range ci {
if !conversation.IsGroup() && !conversation.IsServer() { if !conversation.IsGroup() && !conversation.IsServer() {
if conversation.Attributes[event.SaveHistoryKey] != event.SaveHistoryConfirmed { if conversation.Attributes[attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(event.SaveHistoryKey)).ToString()] != event.SaveHistoryConfirmed {
log.Infof("purging conversation...") log.Infof("purging conversation...")
// TODO: At some point in the future this needs to iterate over channels and make a decision for each on.. // TODO: At some point in the future this needs to iterate over channels and make a decision for each on..
cps.PurgeConversationChannel(conversation.ID, 0) cps.PurgeConversationChannel(conversation.ID, 0)

View File

@ -6,7 +6,7 @@ import (
) )
// SQLCreateTableProfileKeyValue creates the Profile Key Value Table // SQLCreateTableProfileKeyValue creates the Profile Key Value Table
const SQLCreateTableProfileKeyValue = `create table if not exists profile_kv (KeyType text, KeyName text, KeyValue blob);` const SQLCreateTableProfileKeyValue = `create table if not exists profile_kv (KeyType text, KeyName text, KeyValue blob, UNIQUE (KeyType,KeyName));`
// SQLCreateTableConversations creates the Profile Key Value Table // SQLCreateTableConversations creates the Profile Key Value Table
const SQLCreateTableConversations = `create table if not exists conversations (ID integer unique primary key autoincrement, Handle text, Attributes blob, ACL blob, Accepted bool);` const SQLCreateTableConversations = `create table if not exists conversations (ID integer unique primary key autoincrement, Handle text, Attributes blob, ACL blob, Accepted bool);`