Group Functionality Experiments with Server Lists
continuous-integration/drone/pr Build is passing
Details
continuous-integration/drone/pr Build is passing
Details
This commit is contained in:
parent
154ba4610d
commit
f9b4e1179e
|
@ -1,6 +1,8 @@
|
||||||
package groups
|
package groups
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cwtch.im/cwtch/event"
|
||||||
|
"cwtch.im/cwtch/model"
|
||||||
"cwtch.im/cwtch/peer"
|
"cwtch.im/cwtch/peer"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -9,22 +11,40 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ServerPrefix = "server:"
|
const serverPrefix = "server:"
|
||||||
const TofuBundlePrefix = "tofubundle:"
|
const tofuBundlePrefix = "tofubundle:"
|
||||||
const GroupPrefix = "torv3"
|
const groupPrefix = "torv3"
|
||||||
const GroupExperiment = "tapir-groups-experiment"
|
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")
|
||||||
|
)
|
||||||
|
|
||||||
|
// ReadServerInfo is a meta-interface for reading information about servers..
|
||||||
|
type ReadServerInfo interface {
|
||||||
|
peer.ReadContacts
|
||||||
|
peer.ReadServers
|
||||||
|
}
|
||||||
|
|
||||||
|
// GroupFunctionality provides experiment gated server functionality
|
||||||
type GroupFunctionality struct {
|
type GroupFunctionality struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExperimentGate returns GroupFunctionality if the experiment is enabled, and an error otherwise.
|
// ExperimentGate returns GroupFunctionality if the experiment is enabled, and an error otherwise.
|
||||||
func ExperimentGate(experimentMap map[string]bool) (*GroupFunctionality, error) {
|
func ExperimentGate(experimentMap map[string]bool) (*GroupFunctionality, error) {
|
||||||
if experimentMap[GroupExperiment] {
|
if experimentMap[groupExperiment] {
|
||||||
return new(GroupFunctionality), nil
|
return new(GroupFunctionality), nil
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("gated by %v", GroupExperiment)
|
return nil, fmt.Errorf("gated by %v", groupExperiment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SendMessage is a deprecated api
|
||||||
func (gf *GroupFunctionality) SendMessage(peer peer.CwtchPeer, handle string, message string) error {
|
func (gf *GroupFunctionality) SendMessage(peer peer.CwtchPeer, handle string, message string) error {
|
||||||
// TODO this auto accepting behaviour needs some thinking through
|
// TODO this auto accepting behaviour needs some thinking through
|
||||||
if !peer.GetGroup(handle).Accepted {
|
if !peer.GetGroup(handle).Accepted {
|
||||||
|
@ -43,25 +63,49 @@ func (gf *GroupFunctionality) SendMessage(peer peer.CwtchPeer, handle string, me
|
||||||
// ValidPrefix returns true if an import string contains a prefix that indicates it contains information about a
|
// ValidPrefix returns true if an import string contains a prefix that indicates it contains information about a
|
||||||
// server or a group
|
// server or a group
|
||||||
func (gf *GroupFunctionality) ValidPrefix(importString string) bool {
|
func (gf *GroupFunctionality) ValidPrefix(importString string) bool {
|
||||||
return strings.HasPrefix(importString, TofuBundlePrefix) || strings.HasPrefix(importString, ServerPrefix) || strings.HasPrefix(importString, GroupPrefix)
|
return strings.HasPrefix(importString, tofuBundlePrefix) || strings.HasPrefix(importString, serverPrefix) || strings.HasPrefix(importString, groupPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetServerInfoList compiles all the information the UI might need regarding all servers..
|
||||||
|
func (gf *GroupFunctionality) GetServerInfoList(profile ReadServerInfo) []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.ReadContacts) Server {
|
||||||
|
serverInfo := profile.GetContact(serverOnion)
|
||||||
|
keyTypes := []model.KeyType{model.KeyTypeServerOnion, model.KeyTypeTokenOnion, model.KeyTypePrivacyPass}
|
||||||
|
var serverKeys []ServerKey
|
||||||
|
|
||||||
|
for _, keyType := range keyTypes {
|
||||||
|
if key, has := serverInfo.GetAttribute(string(keyType)); has {
|
||||||
|
serverKeys = append(serverKeys, ServerKey{Type: string(keyType), Key: key})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Server{Onion: serverOnion, Status: serverInfo.State, Keys: serverKeys}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleImportString handles import strings for groups and servers
|
// HandleImportString handles import strings for groups and servers
|
||||||
func (gf *GroupFunctionality) HandleImportString(peer peer.CwtchPeer, importString string) error {
|
func (gf *GroupFunctionality) HandleImportString(peer peer.CwtchPeer, importString string) error {
|
||||||
|
|
||||||
if strings.HasPrefix(importString, TofuBundlePrefix) {
|
if strings.HasPrefix(importString, tofuBundlePrefix) {
|
||||||
bundle := strings.Split(importString, "||")
|
bundle := strings.Split(importString, "||")
|
||||||
gf.HandleImportString(peer, bundle[0][11:])
|
gf.HandleImportString(peer, bundle[0][11:])
|
||||||
gf.HandleImportString(peer, bundle[1])
|
gf.HandleImportString(peer, bundle[1])
|
||||||
return nil
|
return nil
|
||||||
} else if strings.HasPrefix(importString, ServerPrefix) {
|
} else if strings.HasPrefix(importString, serverPrefix) {
|
||||||
// Server Key Bundles are prefixed with
|
// Server Key Bundles are prefixed with
|
||||||
bundle, err := base64.StdEncoding.DecodeString(importString[7:])
|
bundle, err := base64.StdEncoding.DecodeString(importString[7:])
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return peer.AddServer(string(bundle))
|
return peer.AddServer(string(bundle))
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
} else if strings.HasPrefix(importString, GroupPrefix) {
|
} else if strings.HasPrefix(importString, groupPrefix) {
|
||||||
//eg: torv3JFDWkXExBsZLkjvfkkuAxHsiLGZBk0bvoeJID9ItYnU=EsEBCiBhOWJhZDU1OTQ0NWI3YmM2N2YxYTM5YjkzMTNmNTczNRIgpHeNaG+6jy750eDhwLO39UX4f2xs0irK/M3P6mDSYQIaOTJjM2ttb29ibnlnaGoyenc2cHd2N2Q1N3l6bGQ3NTNhdW8zdWdhdWV6enB2ZmFrM2FoYzRiZHlkCiJAdVSSVgsksceIfHe41OJu9ZFHO8Kwv3G6F5OK3Hw4qZ6hn6SiZjtmJlJezoBH0voZlCahOU7jCOg+dsENndZxAA==
|
//eg: torv3JFDWkXExBsZLkjvfkkuAxHsiLGZBk0bvoeJID9ItYnU=EsEBCiBhOWJhZDU1OTQ0NWI3YmM2N2YxYTM5YjkzMTNmNTczNRIgpHeNaG+6jy750eDhwLO39UX4f2xs0irK/M3P6mDSYQIaOTJjM2ttb29ibnlnaGoyenc2cHd2N2Q1N3l6bGQ3NTNhdW8zdWdhdWV6enB2ZmFrM2FoYzRiZHlkCiJAdVSSVgsksceIfHe41OJu9ZFHO8Kwv3G6F5OK3Hw4qZ6hn6SiZjtmJlJezoBH0voZlCahOU7jCOg+dsENndZxAA==
|
||||||
return peer.ImportGroup(importString)
|
return peer.ImportGroup(importString)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package groups
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
func TestGroupFunctionality_ValidPrefix(t *testing.T) {
|
func TestGroupFunctionality_ValidPrefix(t *testing.T) {
|
||||||
gf, _ := ExperimentGate(map[string]bool{GroupExperiment: true})
|
gf, _ := ExperimentGate(map[string]bool{groupExperiment: true})
|
||||||
if gf.ValidPrefix("torv3blahblahblah") == false {
|
if gf.ValidPrefix("torv3blahblahblah") == false {
|
||||||
t.Fatalf("torv3 should be a valid prefix")
|
t.Fatalf("torv3 should be a valid prefix")
|
||||||
}
|
}
|
||||||
|
@ -26,13 +26,13 @@ func TestGroupFunctionality_IsEnabled(t *testing.T) {
|
||||||
t.Fatalf("group functionality should be disabled")
|
t.Fatalf("group functionality should be disabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = ExperimentGate(map[string]bool{GroupExperiment: true})
|
_, err = ExperimentGate(map[string]bool{groupExperiment: true})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("group functionality should be enabled")
|
t.Fatalf("group functionality should be enabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = ExperimentGate(map[string]bool{GroupExperiment: false})
|
_, err = ExperimentGate(map[string]bool{groupExperiment: false})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("group functionality should be disabled")
|
t.Fatalf("group functionality should be disabled")
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package groups
|
||||||
|
|
||||||
|
type ServerKey struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Server struct {
|
||||||
|
Onion string `json:"onion"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Keys []ServerKey `json:"keys"`
|
||||||
|
}
|
3
go.mod
3
go.mod
|
@ -6,4 +6,5 @@ require (
|
||||||
cwtch.im/cwtch v0.6.6
|
cwtch.im/cwtch v0.6.6
|
||||||
git.openprivacy.ca/openprivacy/connectivity v1.4.2
|
git.openprivacy.ca/openprivacy/connectivity v1.4.2
|
||||||
git.openprivacy.ca/openprivacy/log v1.0.2
|
git.openprivacy.ca/openprivacy/log v1.0.2
|
||||||
)
|
golang.org/x/mobile v0.0.0-20210220033013-bdb1ca9a1e08 // indirect
|
||||||
|
)
|
||||||
|
|
13
go.sum
13
go.sum
|
@ -37,6 +37,7 @@ git.openprivacy.ca/openprivacy/log v1.0.0/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQN
|
||||||
git.openprivacy.ca/openprivacy/log v1.0.1/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw=
|
git.openprivacy.ca/openprivacy/log v1.0.1/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw=
|
||||||
git.openprivacy.ca/openprivacy/log v1.0.2 h1:HLP4wsw4ljczFAelYnbObIs821z+jgMPCe8uODPnGQM=
|
git.openprivacy.ca/openprivacy/log v1.0.2 h1:HLP4wsw4ljczFAelYnbObIs821z+jgMPCe8uODPnGQM=
|
||||||
git.openprivacy.ca/openprivacy/log v1.0.2/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw=
|
git.openprivacy.ca/openprivacy/log v1.0.2/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw=
|
||||||
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw=
|
github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
@ -80,14 +81,23 @@ go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg=
|
||||||
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200206161412-a0c6ece9d31a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200206161412-a0c6ece9d31a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI=
|
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI=
|
||||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
|
||||||
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
|
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
|
golang.org/x/mobile v0.0.0-20210220033013-bdb1ca9a1e08 h1:h+GZ3ubjuWaQjGe8owMGcmMVCqs0xYJtRG5y2bpHaqU=
|
||||||
|
golang.org/x/mobile v0.0.0-20210220033013-bdb1ca9a1e08/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
|
||||||
|
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
|
golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
@ -119,8 +129,11 @@ golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69 h1:yBHHx+XZqXJBm6Exke3N7V9gnlsyXxoCPEb1yVenjfk=
|
||||||
|
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20200625195345-7480c7b4547d h1:V1BGE5ZHrUIYZYNEm0i7jrPwSo3ks0HSn1TrartSqME=
|
golang.org/x/tools v0.0.0-20200625195345-7480c7b4547d h1:V1BGE5ZHrUIYZYNEm0i7jrPwSo3ks0HSn1TrartSqME=
|
||||||
golang.org/x/tools v0.0.0-20200625195345-7480c7b4547d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200625195345-7480c7b4547d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
|
|
48
lib.go
48
lib.go
|
@ -11,6 +11,7 @@ import (
|
||||||
"cwtch.im/cwtch/model/attr"
|
"cwtch.im/cwtch/model/attr"
|
||||||
"cwtch.im/cwtch/peer"
|
"cwtch.im/cwtch/peer"
|
||||||
contact "git.openprivacy.ca/flutter/libcwtch-go/features/contacts"
|
contact "git.openprivacy.ca/flutter/libcwtch-go/features/contacts"
|
||||||
|
"git.openprivacy.ca/flutter/libcwtch-go/features/groups"
|
||||||
"git.openprivacy.ca/openprivacy/connectivity"
|
"git.openprivacy.ca/openprivacy/connectivity"
|
||||||
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -28,6 +29,10 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
profileOnion = event.Field("profileOnion")
|
||||||
|
)
|
||||||
|
|
||||||
var application app.Application
|
var application app.Application
|
||||||
var eventHandler *utils.EventHandler
|
var eventHandler *utils.EventHandler
|
||||||
var acnQueue event.Queue
|
var acnQueue event.Queue
|
||||||
|
@ -97,12 +102,9 @@ func StartCwtch(appDir string, torPath string) {
|
||||||
settings := utils.ReadGlobalSettings()
|
settings := utils.ReadGlobalSettings()
|
||||||
settingsJson, _ := json.Marshal(settings)
|
settingsJson, _ := json.Marshal(settings)
|
||||||
|
|
||||||
|
|
||||||
newApp.LoadProfiles("be gay do crime")
|
newApp.LoadProfiles("be gay do crime")
|
||||||
application = newApp
|
application = newApp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Send global settings to the UI...
|
// Send global settings to the UI...
|
||||||
application.GetPrimaryBus().Publish(event.NewEvent(utils.UpdateGlobalSettings, map[event.Field]string{event.Data: string(settingsJson)}))
|
application.GetPrimaryBus().Publish(event.NewEvent(utils.UpdateGlobalSettings, map[event.Field]string{event.Data: string(settingsJson)}))
|
||||||
log.Infof("libcwtch-go application launched")
|
log.Infof("libcwtch-go application launched")
|
||||||
|
@ -149,6 +151,16 @@ func SendAppEvent(eventJson string) {
|
||||||
log.Debugf("New Settings %v", globalSettings)
|
log.Debugf("New Settings %v", globalSettings)
|
||||||
utils.WriteGlobalSettings(globalSettings)
|
utils.WriteGlobalSettings(globalSettings)
|
||||||
|
|
||||||
|
// Group Experiment Refresh
|
||||||
|
groupHandler, err := groups.ExperimentGate(utils.ReadGlobalSettings().Experiments)
|
||||||
|
if err == nil {
|
||||||
|
for profileOnion := range application.ListPeers() {
|
||||||
|
serverListForOnion := groupHandler.GetServerInfoList(application.GetPeer(profileOnion))
|
||||||
|
serversListBytes, _ := json.Marshal(serverListForOnion)
|
||||||
|
eventHandler.Push(event.NewEvent(groups.UpdateServerInfo, map[event.Field]string{"ProfileOnion": profileOnion, groups.ServerList: string(serversListBytes)}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Explicitly toggle blocking/unblocking of unknown connections for profiles
|
// Explicitly toggle blocking/unblocking of unknown connections for profiles
|
||||||
// that have been loaded.
|
// that have been loaded.
|
||||||
if utils.ReadGlobalSettings().BlockUnknownConnections {
|
if utils.ReadGlobalSettings().BlockUnknownConnections {
|
||||||
|
@ -349,7 +361,7 @@ func AcceptContact(profile, handle string) {
|
||||||
err := application.GetPeer(profile).SetContactAuthorization(handle, model.AuthApproved)
|
err := application.GetPeer(profile).SetContactAuthorization(handle, model.AuthApproved)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
eventHandler.Push(event.NewEvent(event.PeerStateChange, map[event.Field]string{
|
eventHandler.Push(event.NewEvent(event.PeerStateChange, map[event.Field]string{
|
||||||
"ProfileOnion": profile,
|
profileOnion: profile,
|
||||||
event.RemotePeer: handle,
|
event.RemotePeer: handle,
|
||||||
"authorization": string(model.AuthApproved),
|
"authorization": string(model.AuthApproved),
|
||||||
}))
|
}))
|
||||||
|
@ -367,7 +379,7 @@ func BlockContact(profile, handle string) {
|
||||||
err := application.GetPeer(profile).SetContactAuthorization(handle, model.AuthBlocked)
|
err := application.GetPeer(profile).SetContactAuthorization(handle, model.AuthBlocked)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
eventHandler.Push(event.NewEvent(event.PeerStateChange, map[event.Field]string{
|
eventHandler.Push(event.NewEvent(event.PeerStateChange, map[event.Field]string{
|
||||||
"ProfileOnion": profile,
|
profileOnion: profile,
|
||||||
event.RemotePeer: handle,
|
event.RemotePeer: handle,
|
||||||
"authorization": string(model.AuthBlocked),
|
"authorization": string(model.AuthBlocked),
|
||||||
}))
|
}))
|
||||||
|
@ -385,9 +397,9 @@ func DebugResetContact(profile, handle string) {
|
||||||
err := application.GetPeer(profile).SetContactAuthorization(handle, model.AuthUnknown)
|
err := application.GetPeer(profile).SetContactAuthorization(handle, model.AuthUnknown)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
application.GetPrimaryBus().Publish(event.NewEvent(event.PeerStateChange, map[event.Field]string{
|
application.GetPrimaryBus().Publish(event.NewEvent(event.PeerStateChange, map[event.Field]string{
|
||||||
"ProfileOnion": profile,
|
profileOnion: profile,
|
||||||
event.RemotePeer: handle,
|
event.RemotePeer: handle,
|
||||||
"authorization": string(model.AuthUnknown),
|
"authorization": string(model.AuthUnknown),
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("error resetting contact: %s", err.Error())
|
log.Errorf("error resetting contact: %s", err.Error())
|
||||||
|
@ -454,5 +466,25 @@ func ResetTor() {
|
||||||
globalACN.Restart()
|
globalACN.Restart()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//export c_CreateGroup
|
||||||
|
func c_CreateGroup(profile_ptr *C.char, profile_len C.int, server_ptr *C.char, server_len C.int) {
|
||||||
|
profile := C.GoStringN(profile_ptr, profile_len)
|
||||||
|
server := C.GoStringN(server_ptr, server_len)
|
||||||
|
CreateGroup(profile, server)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateGroup(profile string, server string) {
|
||||||
|
peer := application.GetPeer(profile)
|
||||||
|
_, err := groups.ExperimentGate(utils.ReadGlobalSettings().Experiments)
|
||||||
|
if err == nil {
|
||||||
|
gid, _, err := peer.StartGroup(server)
|
||||||
|
if err == nil {
|
||||||
|
log.Debugf("created group %v on %v: $v", profile, server, gid)
|
||||||
|
} else {
|
||||||
|
log.Errorf("error creating group or %v on server %v: %v", profile, server, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Leave as is, needed by ffi
|
// Leave as is, needed by ffi
|
||||||
func main() {}
|
func main() {}
|
||||||
|
|
|
@ -118,9 +118,18 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string {
|
||||||
e.Data["Online"] = online
|
e.Data["Online"] = online
|
||||||
|
|
||||||
var contacts []Contact
|
var contacts []Contact
|
||||||
|
var servers []groups.Server
|
||||||
for _, contact := range profile.GetContacts() {
|
for _, contact := range profile.GetContacts() {
|
||||||
|
|
||||||
|
// Only compile the server info if we have enabled the experiment...
|
||||||
|
// Note that this means that this info can become stale if when first loaded the experiment
|
||||||
|
// 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 profile.GetContact(contact).IsServer() {
|
if profile.GetContact(contact).IsServer() {
|
||||||
continue
|
groupHandler, err := groups.ExperimentGate(ReadGlobalSettings().Experiments)
|
||||||
|
if err == nil {
|
||||||
|
servers = append(servers, groupHandler.GetServerInfo(contact, profile))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
contactInfo := profile.GetContact(contact)
|
contactInfo := profile.GetContact(contact)
|
||||||
|
@ -132,20 +141,25 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string {
|
||||||
saveHistory = event.DeleteHistoryDefault
|
saveHistory = event.DeleteHistoryDefault
|
||||||
}
|
}
|
||||||
contacts = append(contacts, Contact{
|
contacts = append(contacts, Contact{
|
||||||
Name: name,
|
Name: name,
|
||||||
Onion: contactInfo.Onion,
|
Onion: contactInfo.Onion,
|
||||||
Status: contactInfo.State,
|
Status: contactInfo.State,
|
||||||
Picture: cpicPath,
|
Picture: cpicPath,
|
||||||
Authorization: string(contactInfo.Authorization),
|
Authorization: string(contactInfo.Authorization),
|
||||||
SaveHistory: saveHistory,
|
SaveHistory: saveHistory,
|
||||||
Messages: contactInfo.Timeline.Len(),
|
Messages: contactInfo.Timeline.Len(),
|
||||||
Unread: 0,
|
Unread: 0,
|
||||||
LastMessage: strconv.Itoa(getLastMessageTime(&contactInfo.Timeline)),
|
LastMessage: strconv.Itoa(getLastMessageTime(&contactInfo.Timeline)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes, _ := json.Marshal(contacts)
|
bytes, _ := json.Marshal(contacts)
|
||||||
e.Data["ContactsJson"] = string(bytes)
|
e.Data["ContactsJson"] = string(bytes)
|
||||||
|
|
||||||
|
// Marshal the server list into the new peer event...
|
||||||
|
serversListBytes, _ := json.Marshal(servers)
|
||||||
|
e.Data[groups.ServerList] = string(serversListBytes)
|
||||||
|
|
||||||
log.Infof("contactsJson %v", e.Data["ContactsJson"])
|
log.Infof("contactsJson %v", e.Data["ContactsJson"])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,24 +21,24 @@ const GlobalSettingsFilename = "ui.globals"
|
||||||
const saltFile = "SALT"
|
const saltFile = "SALT"
|
||||||
|
|
||||||
type GlobalSettings struct {
|
type GlobalSettings struct {
|
||||||
Locale string
|
Locale string
|
||||||
Theme string
|
Theme string
|
||||||
PreviousPid int64
|
PreviousPid int64
|
||||||
ExperimentsEnabled bool
|
ExperimentsEnabled bool
|
||||||
Experiments map[string]bool
|
Experiments map[string]bool
|
||||||
BlockUnknownConnections bool
|
BlockUnknownConnections bool
|
||||||
StateRootPane int
|
StateRootPane int
|
||||||
FirstTime bool
|
FirstTime bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var DefaultGlobalSettings = GlobalSettings{
|
var DefaultGlobalSettings = GlobalSettings{
|
||||||
Locale: "en",
|
Locale: "en",
|
||||||
Theme: "light",
|
Theme: "light",
|
||||||
PreviousPid: -1,
|
PreviousPid: -1,
|
||||||
ExperimentsEnabled: false,
|
ExperimentsEnabled: false,
|
||||||
Experiments: make(map[string]bool),
|
Experiments: make(map[string]bool),
|
||||||
StateRootPane: 0,
|
StateRootPane: 0,
|
||||||
FirstTime: true,
|
FirstTime: true,
|
||||||
BlockUnknownConnections: false,
|
BlockUnknownConnections: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue