diff --git a/Makefile b/Makefile index 51c19c5..9e49925 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ DEFAULT_GOAL: linux all: linux android windows +<<<<<<< HEAD ARCH := $(shell uname -m) ARM_X_CC := aarch64-linux-gnu-gcc @@ -18,14 +19,18 @@ endif linux: EXPERIMENTS ?= serverExperiment linux: libCwtch.so $(LINUX_X_ARM) +======= +linux: EXPERIMENTS ?= groupsExperiment serverExperiment +linux: libCwtch.so +>>>>>>> 8e046b2 (Expose Search and new ServerList Functions) -macos: EXPERIMENTS ?= serverExperiment +macos: EXPERIMENTS ?= groupsExperiment serverExperiment macos: libCwtch.x64.dylib libCwtch.arm64.dylib -android: EXPERIMENTS ?= +android: EXPERIMENTS ?= groupsExperiment android: cwtch.aar -windows: EXPERIMENTS ?= serverExperiment +windows: EXPERIMENTS ?= groupsExperiment serverExperiment windows: libCwtch.dll diff --git a/constants/attributes.go b/constants/attributes.go index 1b8cb95..5ddb9d5 100644 --- a/constants/attributes.go +++ b/constants/attributes.go @@ -13,8 +13,5 @@ const PeerOnline = "peer-online" const PeerAutostart = "autostart" -// Description is used on server contacts, -const Description = "description" - // ConversationNotificationPolicy is the attribute label for conversations. When App NotificationPolicy is OptIn a true value here opts in const ConversationNotificationPolicy = "notification-policy" diff --git a/experiments/servers/servers_functionality.go b/experiments/server_hosting/servers_functionality.go similarity index 99% rename from experiments/servers/servers_functionality.go rename to experiments/server_hosting/servers_functionality.go index 1fde761..4d3a7e4 100644 --- a/experiments/servers/servers_functionality.go +++ b/experiments/server_hosting/servers_functionality.go @@ -1,4 +1,4 @@ -package servers +package server_hosting import ( "cwtch.im/cwtch/app" diff --git a/features/groups/group_functionality.go b/features/groups/group_functionality.go deleted file mode 100644 index 99f3496..0000000 --- a/features/groups/group_functionality.go +++ /dev/null @@ -1,66 +0,0 @@ -package groups - -import ( - "cwtch.im/cwtch/event" - "cwtch.im/cwtch/model" - "cwtch.im/cwtch/model/attr" - constants2 "cwtch.im/cwtch/model/constants" - "cwtch.im/cwtch/peer" - "cwtch.im/cwtch/protocol/connections" - "fmt" - "git.openprivacy.ca/cwtch.im/cwtch-autobindings/constants" -) - -const groupExperiment = "tapir-groups-experiment" - -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") -) - -// GroupFunctionality provides experiment gated server functionality -type GroupFunctionality struct { -} - -// ExperimentGate returns GroupFunctionality if the experiment is enabled, and an error otherwise. -func ExperimentGate(experimentMap map[string]bool) (*GroupFunctionality, error) { - if experimentMap[groupExperiment] { - return new(GroupFunctionality), nil - } - return nil, fmt.Errorf("gated by %v", groupExperiment) -} - -// GetServerInfoList compiles all the information the UI might need regarding all servers.. -func (gf *GroupFunctionality) GetServerInfoList(profile peer.CwtchPeer) []Server { - var servers []Server - for _, server := range profile.GetServers() { - servers = append(servers, gf.GetServerInfo(server, profile)) - } - return servers -} - -// GetServerInfo compiles all the information the UI might need regarding a particular server including any verified -// cryptographic keys -func (gf *GroupFunctionality) GetServerInfo(serverOnion string, profile peer.CwtchPeer) 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(constants2.SyncPreLastMessageTime)).ToString()] - recentTimeStr := serverInfo.Attributes[attr.LocalScope.ConstructScopedZonedPath(attr.LegacyGroupZone.ConstructZonedPath(constants2.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} -} diff --git a/features/groups/group_functionality_test.go b/features/groups/group_functionality_test.go deleted file mode 100644 index 84fa070..0000000 --- a/features/groups/group_functionality_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package groups - -import "testing" - -func TestGroupFunctionality_IsEnabled(t *testing.T) { - - _, err := ExperimentGate(map[string]bool{}) - - if err == nil { - t.Fatalf("group functionality should be disabled") - } - - _, err = ExperimentGate(map[string]bool{groupExperiment: true}) - - if err != nil { - t.Fatalf("group functionality should be enabled") - } - - _, err = ExperimentGate(map[string]bool{groupExperiment: false}) - if err == nil { - t.Fatalf("group functionality should be disabled") - } -} diff --git a/features/groups/server.go b/features/groups/server.go deleted file mode 100644 index f48592c..0000000 --- a/features/groups/server.go +++ /dev/null @@ -1,20 +0,0 @@ -package groups - -type ServerKey struct { - Type string `json:"type"` - Key string `json:"key"` -} - -type SyncStatus struct { - StartTime string `json:"startTime"` - LastMessageTime string `json:"lastMessageTime"` -} - -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"` -} diff --git a/go.mod b/go.mod index 179d5b3..384e39f 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.openprivacy.ca/cwtch.im/cwtch-autobindings go 1.19 require ( - cwtch.im/cwtch v0.21.0 + cwtch.im/cwtch v0.22.0 git.openprivacy.ca/cwtch.im/server v1.4.5 git.openprivacy.ca/openprivacy/connectivity v1.10.0 git.openprivacy.ca/openprivacy/log v1.0.3 diff --git a/go.sum b/go.sum index a9b0911..a13b48b 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,6 @@ cwtch.im/cwtch v0.18.0/go.mod h1:StheazFFY7PKqBbEyDVLhzWW6WOat41zV0ckC240c5Y= -cwtch.im/cwtch v0.21.0 h1:mZotCp9OOnP+FOX0OnrmdXDqZs0cufT2shLgUyZEW7c= -cwtch.im/cwtch v0.21.0/go.mod h1:h8S7EgEM+8pE1k+XLB5jAFdIPlOzwoXEY0GH5mQye5A= +cwtch.im/cwtch v0.22.0 h1:yTrjbdVnSE/7Oz0aLi0QH6Cxj3Tmncc9WQOXmvHt1z4= +cwtch.im/cwtch v0.22.0/go.mod h1:h8S7EgEM+8pE1k+XLB5jAFdIPlOzwoXEY0GH5mQye5A= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= diff --git a/spec b/spec index cdad13c..4c4b4be 100644 --- a/spec +++ b/spec @@ -21,6 +21,9 @@ profile UnblockConversation conversation profile DeleteConversation conversation profile PeerWithOnion string:handle +# Search +(json)profile SearchConversations string:pattern + # Message Management (json)profile EnhancedSendMessage conversation string:msg (json)profile EnhancedGetMessageById conversation message @@ -32,6 +35,12 @@ profile UpdateMessageAttribute conversation channel message string:attributeKey # Group Management profile StartGroup string:name string:server +## Server List Management... +import "cwtch.im/cwtch/functionality/servers" +!groupsExperiment global groupsExperimentServers *servers.Functionality servers +@profile-experiment GetServerInfoList servers +@profile-experiment GetServerInfo servers string:serverOnion + # Filesharing Management import "cwtch.im/cwtch/functionality/filesharing" @profile-experiment DownloadFileDefaultLimit filesharing conversation string:filepath string:manifest string:filekey @@ -44,8 +53,8 @@ import "cwtch.im/cwtch/functionality/filesharing" # Server Hosting Experiment -!serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers" -!serverExperiment global serverExperiment *servers.ServersFunctionality servers +!serverExperiment import "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/server_hosting" +!serverExperiment global serverExperiment *server_hosting.ServersFunctionality server_hosting !serverExperiment exp CreateServer application password string:description bool:autostart !serverExperiment exp SetServerAttribute application string:handle string:key string:val !serverExperiment exp LoadServers application acn password diff --git a/utils/eventHandler.go b/utils/eventHandler.go index 9ddc343..d2c74f2 100644 --- a/utils/eventHandler.go +++ b/utils/eventHandler.go @@ -1,23 +1,22 @@ package utils import ( - "cwtch.im/cwtch/settings" - "encoding/json" - "fmt" - "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/servers" - "os" - "strconv" - "cwtch.im/cwtch/app" "cwtch.im/cwtch/app/plugins" + "cwtch.im/cwtch/functionality/servers" "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" + "fmt" constants2 "git.openprivacy.ca/cwtch.im/cwtch-autobindings/constants" - "git.openprivacy.ca/cwtch.im/cwtch-autobindings/features/groups" + "git.openprivacy.ca/cwtch.im/cwtch-autobindings/experiments/server_hosting" "git.openprivacy.ca/openprivacy/log" + "os" + "strconv" "time" @@ -66,10 +65,11 @@ func (eh *EventHandler) HandleApp(application app.Application) { application.GetPrimaryBus().Subscribe(event.ACNVersion, eh.appBusQueue) application.GetPrimaryBus().Subscribe(settings.UpdateGlobalSettings, eh.appBusQueue) application.GetPrimaryBus().Subscribe(settings.CwtchStarted, eh.appBusQueue) - application.GetPrimaryBus().Subscribe(servers.NewServer, eh.appBusQueue) - application.GetPrimaryBus().Subscribe(servers.ServerIntentUpdate, eh.appBusQueue) - application.GetPrimaryBus().Subscribe(servers.ServerDeleted, eh.appBusQueue) - application.GetPrimaryBus().Subscribe(servers.ServerStatsUpdate, eh.appBusQueue) + application.GetPrimaryBus().Subscribe(servers.UpdateServerInfo, eh.appBusQueue) + application.GetPrimaryBus().Subscribe(server_hosting.NewServer, eh.appBusQueue) + application.GetPrimaryBus().Subscribe(server_hosting.ServerIntentUpdate, eh.appBusQueue) + application.GetPrimaryBus().Subscribe(server_hosting.ServerDeleted, eh.appBusQueue) + application.GetPrimaryBus().Subscribe(server_hosting.ServerStatsUpdate, eh.appBusQueue) application.GetPrimaryBus().Subscribe(event.StartingStorageMiragtion, eh.appBusQueue) application.GetPrimaryBus().Subscribe(event.DoneStorageMigration, eh.appBusQueue) } @@ -174,7 +174,7 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { } // Construct our conversations and our srever lists var contacts []Contact - var servers []groups.Server + var knownServers []servers.Server conversations, err := profile.FetchConversations() @@ -186,9 +186,9 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { // has been disabled and then is later re-enabled. As such we need to ensure that this list is // re-fetched when the group experiment is enabled via a dedicated ListServerInfo event... if conversationInfo.IsServer() { - groupHandler, err := groups.ExperimentGate(eh.app.ReadSettings().Experiments) + groupHandler := servers.FunctionalityGate() if err == nil { - servers = append(servers, groupHandler.GetServerInfo(conversationInfo.Handle, profile)) + knownServers = append(knownServers, groupHandler.GetServerInfo(profile, conversationInfo.Handle)) } continue } @@ -309,8 +309,8 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { e.Data["ContactsJson"] = string(bytes) // Marshal the server list into the new peer event... - serversListBytes, _ := json.Marshal(servers) - e.Data[groups.ServerList] = string(serversListBytes) + serversListBytes, _ := json.Marshal(knownServers) + e.Data[servers.ServerList] = string(serversListBytes) log.Debugf("contactsJson %v", e.Data["ContactsJson"]) } @@ -572,6 +572,8 @@ func (eh *EventHandler) startHandlingPeer(onion string) { eventBus.Subscribe(event.FileDownloaded, q) eventBus.Subscribe(event.TokenManagerInfo, q) eventBus.Subscribe(event.ProtocolEngineCreated, q) + eventBus.Subscribe(event.SearchResult, q) + eventBus.Subscribe(event.SearchCancelled, q) go eh.forwardProfileMessages(onion, q) }