Merge pull request 'Move server handling logic back into Cwtch (from libCwtch-go / autobindings)' (#525) from server-update into master
continuous-integration/drone/push Build is pending Details

Reviewed-on: #525
Reviewed-by: Dan Ballard <dan@openprivacy.ca>
This commit is contained in:
Sarah Jamie Lewis 2023-07-25 19:03:20 +00:00
commit 6b212beb00
5 changed files with 133 additions and 3 deletions

View File

@ -5,6 +5,7 @@ import (
"cwtch.im/cwtch/event"
"cwtch.im/cwtch/extensions"
"cwtch.im/cwtch/functionality/filesharing"
"cwtch.im/cwtch/functionality/servers"
"cwtch.im/cwtch/model"
"cwtch.im/cwtch/model/attr"
"cwtch.im/cwtch/model/constants"
@ -362,6 +363,7 @@ func (app *application) registerHooks(profile peer.CwtchPeer) {
profile.RegisterHook(extensions.ProfileValueExtension{})
profile.RegisterHook(new(filesharing.Functionality))
profile.RegisterHook(new(filesharing.ImagePreviewsFunctionality))
profile.RegisterHook(new(servers.Functionality))
// Ensure that Profiles have the Most Up to Date Settings...
profile.NotifySettingsUpdate(app.settings.ReadGlobalSettings())
}

View File

@ -0,0 +1,123 @@
package servers
import (
"cwtch.im/cwtch/event"
"cwtch.im/cwtch/model"
"cwtch.im/cwtch/model/attr"
"cwtch.im/cwtch/model/constants"
"cwtch.im/cwtch/peer"
"cwtch.im/cwtch/protocol/connections"
"cwtch.im/cwtch/settings"
"encoding/json"
)
const (
// ServerList is a json encoded list of servers
ServerList = event.Field("ServerList")
)
const (
// UpdateServerInfo is an event containing a ProfileOnion and a ServerList
UpdateServerInfo = event.Type("UpdateServerInfo")
)
// Functionality groups some common UI triggered functions for contacts...
type Functionality struct {
}
func (f *Functionality) NotifySettingsUpdate(settings settings.GlobalSettings) {
}
func (f *Functionality) EventsToRegister() []event.Type {
return []event.Type{event.ProtocolEngineCreated, event.ManifestReceived, event.FileDownloaded}
}
func (f *Functionality) ExperimentsToRegister() []string {
return []string{constants.GroupsExperiment}
}
// OnEvent handles File Sharing Hooks like Manifest Received and FileDownloaded
func (f *Functionality) OnEvent(ev event.Event, profile peer.CwtchPeer) {
if profile.IsFeatureEnabled(constants.GroupsExperiment) {
switch ev.EventType {
// keep the UI in sync with the current backend server updates...
// TODO: do we need a secondary heartbeat for less common updates?
case event.Heartbeat:
f.PublishServerUpdate(profile)
}
}
}
func (f *Functionality) OnContactRequestValue(profile peer.CwtchPeer, conversation model.Conversation, eventID string, path attr.ScopedZonedPath) {
// nop
}
func (f *Functionality) OnContactReceiveValue(profile peer.CwtchPeer, conversation model.Conversation, path attr.ScopedZonedPath, value string, exists bool) {
// nopt
}
// FunctionalityGate returns filesharing functionality - gates now happen on function calls.
func FunctionalityGate() *Functionality {
return new(Functionality)
}
// ServerKey packages up key information...
// TODO: Can this be merged with KeyBundle?
type ServerKey struct {
Type string `json:"type"`
Key string `json:"key"`
}
// SyncStatus packages up server sync information...
type SyncStatus struct {
StartTime string `json:"startTime"`
LastMessageTime string `json:"lastMessageTime"`
}
// Server encapsulates the information needed to represent a server...
type Server struct {
Onion string `json:"onion"`
Identifier int `json:"identifier"`
Status string `json:"status"`
Description string `json:"description"`
Keys []ServerKey `json:"keys"`
SyncProgress SyncStatus `json:"syncProgress"`
}
// PublishServerUpdate serializes the current list of group servers and publishes an event with this information
func (f *Functionality) PublishServerUpdate(profile peer.CwtchPeer) {
serverListForOnion := f.GetServerInfoList(profile)
serversListBytes, _ := json.Marshal(serverListForOnion)
profile.PublishEvent(event.NewEvent(UpdateServerInfo, map[event.Field]string{"ProfileOnion": profile.GetOnion(), ServerList: string(serversListBytes)}))
}
// GetServerInfoList compiles all the information the UI might need regarding all servers..
func (f *Functionality) GetServerInfoList(profile peer.CwtchPeer) []Server {
var servers []Server
for _, server := range profile.GetServers() {
servers = append(servers, f.GetServerInfo(profile, server))
}
return servers
}
// GetServerInfo compiles all the information the UI might need regarding a particular server including any verified
// cryptographic keys
func (f *Functionality) GetServerInfo(profile peer.CwtchPeer, serverOnion string) Server {
serverInfo, _ := profile.FetchConversationInfo(serverOnion)
keyTypes := []model.KeyType{model.KeyTypeServerOnion, model.KeyTypeTokenOnion, model.KeyTypePrivacyPass}
var serverKeys []ServerKey
for _, keyType := range keyTypes {
if key, has := serverInfo.GetAttribute(attr.PublicScope, attr.ServerKeyZone, string(keyType)); has {
serverKeys = append(serverKeys, ServerKey{Type: string(keyType), Key: key})
}
}
description, _ := serverInfo.GetAttribute(attr.LocalScope, attr.ServerZone, constants.Description)
startTimeStr := serverInfo.Attributes[attr.LocalScope.ConstructScopedZonedPath(attr.LegacyGroupZone.ConstructZonedPath(constants.SyncPreLastMessageTime)).ToString()]
recentTimeStr := serverInfo.Attributes[attr.LocalScope.ConstructScopedZonedPath(attr.LegacyGroupZone.ConstructZonedPath(constants.SyncMostRecentMessageTime)).ToString()]
syncStatus := SyncStatus{startTimeStr, recentTimeStr}
return Server{Onion: serverOnion, Identifier: serverInfo.ID, Status: connections.ConnectionStateName[profile.GetPeerState(serverInfo.Handle)], Keys: serverKeys, Description: description, SyncProgress: syncStatus}
}

View File

@ -63,3 +63,6 @@ const ProfileStatus = "profile-status"
const ProfileAttribute1 = "profile-attribute-1"
const ProfileAttribute2 = "profile-attribute-2"
const ProfileAttribute3 = "profile-attribute-3"
// Description is used on server contacts,
const Description = "description"

View File

@ -1,5 +1,7 @@
package constants
const GroupsExperiment = "tapir-groups-experiment"
// FileSharingExperiment Allows file sharing
const FileSharingExperiment = "filesharing"

View File

@ -857,9 +857,9 @@ func (cp *cwtchPeer) doSearch(ctx context.Context, searchID string, pattern stri
// in the table (e.g. deleted messages, expired messages, etc.)
func (cp *cwtchPeer) SearchConversations(pattern string) string {
// TODO: For now, we simply surround the pattern with the sqlite LIKE syntax for matching any prefix, and any suffix
// At some point we would like to extend this patternt to support e.g. searching a specific conversation, or
// searching for particular types of message.
// TODO: For now, we simply surround the pattern with the sqlite LIKE syntax for matching any prefix, and any suffix
// At some point we would like to extend this patternt to support e.g. searching a specific conversation, or
// searching for particular types of message.
pattern = fmt.Sprintf("%%%v%%", pattern)
// we need this lock here to prevent weirdness happening when reassigning cp.cancelSearchContext