From c230746546e611f52df32558b9680e26e143af8b Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 16 Mar 2021 12:54:25 -0700 Subject: [PATCH 1/3] Experimental Settings --- features/groups/group_functionality.go | 74 +++++++++++++++++++++ features/groups/group_functionality_test.go | 39 +++++++++++ lib.go | 7 +- 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 features/groups/group_functionality.go create mode 100644 features/groups/group_functionality_test.go diff --git a/features/groups/group_functionality.go b/features/groups/group_functionality.go new file mode 100644 index 0000000..f5ba3a5 --- /dev/null +++ b/features/groups/group_functionality.go @@ -0,0 +1,74 @@ +package groups + +import ( + "cwtch.im/cwtch/peer" + "encoding/base64" + "errors" + "fmt" + "git.openprivacy.ca/openprivacy/log" + "strings" +) + +const ServerPrefix = "server:" +const TofuBundlePrefix = "tofubundle:" +const GroupPrefix = "torv3" +const GroupExperiment = "tapir-groups-experiment" + +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) +} + +func (gf *GroupFunctionality) SendMessage(peer peer.CwtchPeer, handle string, message string) error { + // TODO this auto accepting behaviour needs some thinking through + if peer.GetGroup(handle).Accepted { + err := peer.AcceptInvite(handle) + if err != nil { + log.Errorf("tried to mark a nonexistent group as existed. bad!") + return err + } + } + + _, err := peer.SendMessageToGroupTracked(handle, message) + + return err +} + +// ValidPrefix returns true if an import string contains a prefix that indicates it contains information about a +// server or a group +func (gf *GroupFunctionality) ValidPrefix(importString string) bool { + return strings.HasPrefix(importString, TofuBundlePrefix) || strings.HasPrefix(importString, ServerPrefix) || strings.HasPrefix(importString, GroupPrefix) +} + +// HandleImportString handles import strings for groups and servers +func (gf *GroupFunctionality) HandleImportString(peer peer.CwtchPeer, importString string) error { + + if strings.HasPrefix(importString, TofuBundlePrefix) { + bundle := strings.Split(importString, "||") + gf.HandleImportString(peer, bundle[0][11:]) + gf.HandleImportString(peer, bundle[1]) + return nil + } + + // Server Key Bundles are prefixed with + if strings.HasPrefix(importString, ServerPrefix) { + bundle, err := base64.StdEncoding.DecodeString(importString[7:]) + if err == nil { + return peer.AddServer(string(bundle)) + } + return err + } + + //eg: torv3JFDWkXExBsZLkjvfkkuAxHsiLGZBk0bvoeJID9ItYnU=EsEBCiBhOWJhZDU1OTQ0NWI3YmM2N2YxYTM5YjkzMTNmNTczNRIgpHeNaG+6jy750eDhwLO39UX4f2xs0irK/M3P6mDSYQIaOTJjM2ttb29ibnlnaGoyenc2cHd2N2Q1N3l6bGQ3NTNhdW8zdWdhdWV6enB2ZmFrM2FoYzRiZHlkCiJAdVSSVgsksceIfHe41OJu9ZFHO8Kwv3G6F5OK3Hw4qZ6hn6SiZjtmJlJezoBH0voZlCahOU7jCOg+dsENndZxAA== + if strings.HasPrefix(importString, GroupPrefix) { + return peer.ImportGroup(importString) + } + + return errors.New("invalid_group_invite_prefix") +} diff --git a/features/groups/group_functionality_test.go b/features/groups/group_functionality_test.go new file mode 100644 index 0000000..4a3331a --- /dev/null +++ b/features/groups/group_functionality_test.go @@ -0,0 +1,39 @@ +package groups + +import "testing" + +func TestGroupFunctionality_ValidPrefix(t *testing.T) { + gf, _ := ExperimentGate(map[string]bool{GroupExperiment: true}) + if gf.ValidPrefix("torv3blahblahblah") == false { + t.Fatalf("torv3 should be a valid prefix") + } + if gf.ValidPrefix("tofubundle:32432423||3242342") == false { + t.Fatalf("tofubundle should be a valid prefix") + } + if gf.ValidPrefix("server:23541233t") == false { + t.Fatalf("server should be a valid prefix") + } + if gf.ValidPrefix("alice!24234") == true { + t.Fatalf("alice should be an invalid predix") + } +} + +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/lib.go b/lib.go index 364cb0a..ea0ec31 100644 --- a/lib.go +++ b/lib.go @@ -7,7 +7,6 @@ import ( "cwtch.im/cwtch/app" "cwtch.im/cwtch/event" "cwtch.im/cwtch/model/attr" - "cwtch.im/cwtch/peer" "encoding/json" @@ -166,6 +165,12 @@ func SendProfileEvent(onion string, eventJson string) { switch new_event.EventType { case event.SetAttribute: peer.SetAttribute(new_event.Data[event.Key], new_event.Data[event.Data]) + case event.SendMessageToGroup: + // TODO Uncomment and integrate once contacts/messages are loaded. + //groupHandler,err := groups.ExperimentGate(utils.ReadGlobalSettings().Experiments) + //if err == nil { + // err = groupHandler.SendMessage(peer, new_event.Data[event.GroupID], new_event.Data[event.Data]) + //} default: // rebroadcast catch all log.Infof("Received Event %v for %v but no libCwtch handler found, relaying the event directly", new_event, onion) From 3960244756a2fa7b5be9aae788b6601365468818 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 16 Mar 2021 13:54:31 -0700 Subject: [PATCH 2/3] Fix condition on Accept --- features/groups/group_functionality.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/groups/group_functionality.go b/features/groups/group_functionality.go index f5ba3a5..2f17e2d 100644 --- a/features/groups/group_functionality.go +++ b/features/groups/group_functionality.go @@ -27,7 +27,7 @@ func ExperimentGate(experimentMap map[string]bool) (*GroupFunctionality, error) func (gf *GroupFunctionality) SendMessage(peer peer.CwtchPeer, handle string, message string) error { // TODO this auto accepting behaviour needs some thinking through - if peer.GetGroup(handle).Accepted { + if !peer.GetGroup(handle).Accepted { err := peer.AcceptInvite(handle) if err != nil { log.Errorf("tried to mark a nonexistent group as existed. bad!") From eb570745a52f3eae143797d4af59470bf334fb33 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 16 Mar 2021 13:55:50 -0700 Subject: [PATCH 3/3] Formatt + if/else --- features/groups/group_functionality.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/features/groups/group_functionality.go b/features/groups/group_functionality.go index 2f17e2d..8ce5f7a 100644 --- a/features/groups/group_functionality.go +++ b/features/groups/group_functionality.go @@ -54,19 +54,15 @@ func (gf *GroupFunctionality) HandleImportString(peer peer.CwtchPeer, importStri gf.HandleImportString(peer, bundle[0][11:]) gf.HandleImportString(peer, bundle[1]) return nil - } - - // Server Key Bundles are prefixed with - if strings.HasPrefix(importString, ServerPrefix) { + } else if strings.HasPrefix(importString, ServerPrefix) { + // Server Key Bundles are prefixed with bundle, err := base64.StdEncoding.DecodeString(importString[7:]) if err == nil { return peer.AddServer(string(bundle)) } return err - } - - //eg: torv3JFDWkXExBsZLkjvfkkuAxHsiLGZBk0bvoeJID9ItYnU=EsEBCiBhOWJhZDU1OTQ0NWI3YmM2N2YxYTM5YjkzMTNmNTczNRIgpHeNaG+6jy750eDhwLO39UX4f2xs0irK/M3P6mDSYQIaOTJjM2ttb29ibnlnaGoyenc2cHd2N2Q1N3l6bGQ3NTNhdW8zdWdhdWV6enB2ZmFrM2FoYzRiZHlkCiJAdVSSVgsksceIfHe41OJu9ZFHO8Kwv3G6F5OK3Hw4qZ6hn6SiZjtmJlJezoBH0voZlCahOU7jCOg+dsENndZxAA== - if strings.HasPrefix(importString, GroupPrefix) { + } else if strings.HasPrefix(importString, GroupPrefix) { + //eg: torv3JFDWkXExBsZLkjvfkkuAxHsiLGZBk0bvoeJID9ItYnU=EsEBCiBhOWJhZDU1OTQ0NWI3YmM2N2YxYTM5YjkzMTNmNTczNRIgpHeNaG+6jy750eDhwLO39UX4f2xs0irK/M3P6mDSYQIaOTJjM2ttb29ibnlnaGoyenc2cHd2N2Q1N3l6bGQ3NTNhdW8zdWdhdWV6enB2ZmFrM2FoYzRiZHlkCiJAdVSSVgsksceIfHe41OJu9ZFHO8Kwv3G6F5OK3Hw4qZ6hn6SiZjtmJlJezoBH0voZlCahOU7jCOg+dsENndZxAA== return peer.ImportGroup(importString) }