Compare commits
42 Commits
Author | SHA1 | Date |
---|---|---|
Dan Ballard | 7a65efaa78 | |
Sarah Jamie Lewis | 83c84b2049 | |
Sarah Jamie Lewis | 6618410cc9 | |
Sarah Jamie Lewis | 89f19928c2 | |
Sarah Jamie Lewis | 243727a131 | |
Sarah Jamie Lewis | dd0f1cd868 | |
Sarah Jamie Lewis | 5bf954f3d0 | |
Sarah Jamie Lewis | 425c3e6030 | |
Sarah Jamie Lewis | 32ea146ec0 | |
Sarah Jamie Lewis | 6321f09aad | |
Dan Ballard | 9e3fc6123b | |
Sarah Jamie Lewis | cbe687ce2e | |
Sarah Jamie Lewis | 6c0b2e2a4f | |
Sarah Jamie Lewis | 7c042334d3 | |
Sarah Jamie Lewis | c7c2259c2d | |
Sarah Jamie Lewis | c2c3c2894d | |
Sarah Jamie Lewis | 7ddf09caec | |
Sarah Jamie Lewis | 41a554a198 | |
Dan Ballard | b80db89284 | |
Sarah Jamie Lewis | 20dc170a78 | |
Sarah Jamie Lewis | 267e79368e | |
Sarah Jamie Lewis | f93616615a | |
Sarah Jamie Lewis | 3e9c9c3b70 | |
Sarah Jamie Lewis | f60fbfc3d5 | |
Sarah Jamie Lewis | f32ad741e0 | |
Sarah Jamie Lewis | a453ca9dc8 | |
Sarah Jamie Lewis | 3d2124126b | |
Sarah Jamie Lewis | 0f40f0d12d | |
Sarah Jamie Lewis | 6e0623170f | |
Sarah Jamie Lewis | 6fdcf5bac7 | |
Sarah Jamie Lewis | ae18550f71 | |
Sarah Jamie Lewis | 988ec07ebc | |
Sarah Jamie Lewis | 44241e2352 | |
Sarah Jamie Lewis | 403398b7a1 | |
Sarah Jamie Lewis | 5916333723 | |
Dan Ballard | 24b534d436 | |
Dan Ballard | c8692cc1b2 | |
Dan Ballard | dcec0f9274 | |
Sarah Jamie Lewis | 2e7a9be6c1 | |
Sarah Jamie Lewis | 7ebbfe91c9 | |
Sarah Jamie Lewis | 3029ed65ff | |
Sarah Jamie Lewis | e91db69e6e |
23
.drone.yml
23
.drone.yml
|
@ -5,15 +5,20 @@ name: linux-android-windows-test
|
|||
|
||||
steps:
|
||||
- name: fetch
|
||||
image: golang:1.19.1
|
||||
image: openpriv/go-cross-compile:2024.02
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /go
|
||||
commands:
|
||||
- go install honnef.co/go/tools/cmd/staticcheck@latest
|
||||
- wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/master/tor/tor
|
||||
- wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/master/tor/torrc
|
||||
- chmod a+x tor
|
||||
- go install go.uber.org/nilaway/cmd/nilaway@latest
|
||||
- wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/branch/master/tor/tor-0.4.8.9-linux-x86_64.tar.gz -O tor.tar.gz
|
||||
- tar -xzf tor.tar.gz
|
||||
- chmod a+x Tor/tor
|
||||
- export PATH=$PWD/Tor/:$PATH
|
||||
- export LD_LIBRARY_PATH=$PWD/Tor/
|
||||
- tor --version
|
||||
- export GO111MODULE=on
|
||||
- git fetch --tags
|
||||
- go mod download
|
||||
- echo `git describe --tags` > VERSION
|
||||
|
@ -21,7 +26,7 @@ steps:
|
|||
- export GOSUMDB="off"
|
||||
|
||||
- name: build-linux
|
||||
image: golang:1.19.1
|
||||
image: openpriv/go-cross-compile:2024.02
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /go
|
||||
|
@ -31,7 +36,7 @@ steps:
|
|||
- make linux
|
||||
|
||||
- name: build-android
|
||||
image: openpriv/android-go-mobile:2023.02
|
||||
image: openpriv/go-cross-compile:2024.02
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /go
|
||||
|
@ -44,7 +49,7 @@ steps:
|
|||
- make android
|
||||
|
||||
- name: build-windows
|
||||
image: openpriv/mingw-go:2023.01
|
||||
image: openpriv/go-cross-compile:2024.02
|
||||
environment:
|
||||
GOPATH: /go
|
||||
volumes:
|
||||
|
@ -55,7 +60,7 @@ steps:
|
|||
- make windows
|
||||
|
||||
- name: deploy-buildfiles
|
||||
image: kroniak/ssh-client
|
||||
image: openpriv/go-cross-compile:2024.02
|
||||
pull: if-not-exists
|
||||
environment:
|
||||
BUILDFILES_KEY:
|
||||
|
@ -146,7 +151,7 @@ steps:
|
|||
status: [ success ]
|
||||
commands:
|
||||
- echo $BUILDFILES_KEY > ~/id_rsab64
|
||||
- base64 -d ~/id_rsab64 > ~/id_rsa
|
||||
- base64 -d -i ~/id_rsab64 -o ~/id_rsa
|
||||
- chmod 400 ~/id_rsa
|
||||
- export DIR=libCwtch-autobindings-`cat COMMIT_DATE`-`cat VERSION`
|
||||
- mkdir -p $DIR
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
MIT License
|
||||
Copyright (c) 2023 Open Privacy Research Society
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
43
Makefile
43
Makefile
|
@ -7,20 +7,28 @@ DEFAULT_GOAL: linux
|
|||
|
||||
all: linux android windows
|
||||
|
||||
linux: EXPERIMENTS ?= serverExperiment
|
||||
linux: libCwtch.so
|
||||
ARCH := $(shell uname -m)
|
||||
ARM_X_CC := aarch64-linux-gnu-gcc
|
||||
|
||||
macos: EXPERIMENTS ?= serverExperiment
|
||||
# determine if the x64 cross arm64 compiler is available so we can add that target
|
||||
LINUX_X_ARM=
|
||||
ifneq (,$(shell which $(ARM_X_CC)))
|
||||
LINUX_X_ARM = libCwtch.x.so
|
||||
endif
|
||||
|
||||
linux: EXPERIMENTS ?= "serverExperiment"
|
||||
linux: libCwtch.so $(LINUX_X_ARM)
|
||||
|
||||
macos: EXPERIMENTS ?= "serverExperiment"
|
||||
macos: libCwtch.x64.dylib libCwtch.arm64.dylib
|
||||
|
||||
android: EXPERIMENTS ?=
|
||||
android: EXPERIMENTS ?= ""
|
||||
android: cwtch.aar
|
||||
|
||||
windows: EXPERIMENTS ?= serverExperiment
|
||||
windows: EXPERIMENTS ?= "serverExperiment"
|
||||
windows: libCwtch.dll
|
||||
|
||||
|
||||
|
||||
lib.go: generate/generate_bindings.go spec
|
||||
go run generate/generate_bindings.go --experiments "$(EXPERIMENTS)"
|
||||
|
||||
|
@ -29,18 +37,31 @@ libCwtch.so: lib.go
|
|||
./switch-ffi.sh
|
||||
go build -trimpath -ldflags "-buildid=autobindings-$(shell git describe --tags) -X main.buildVer=autobindings-$(shell git describe --tags) -X main.buildDate=$(shell git log -1 --format=%cd --date=format:%G-%m-%d-%H-%M)" -buildmode c-shared -o libCwtch.so
|
||||
mkdir -p build/linux
|
||||
mv libCwtch.so build/linux/
|
||||
mv libCwtch.h build/linux/
|
||||
ifeq ($(ARCH),x86_64)
|
||||
mv libCwtch.so build/linux/libCwtch.x64.so
|
||||
else ifeq ($(ARCH),aarch64)
|
||||
mv libCwtch.so build/linux/libCwtch.arm64.so
|
||||
endif
|
||||
mv libCwtch.h build/linux/libCwtch.h
|
||||
|
||||
libCwtch.x.so: lib.go
|
||||
./switch-ffi.sh
|
||||
mkdir -p build/linux
|
||||
ifeq ($(ARCH),x86_64)
|
||||
env CGO_ENABLED=1 CC=$(ARM_X_CC) GOARCH=arm64 go build -trimpath -ldflags "-buildid=autobindings-$(shell git describe --tags) -X main.buildVer=autobindings-$(shell git describe --tags) -X main.buildDate=$(shell git log -1 --format=%cd --date=format:%G-%m-%d-%H-%M)" -buildmode c-shared -o libCwtch.x.so
|
||||
mv libCwtch.x.so build/linux/libCwtch.arm64.so
|
||||
mv libCwtch.x.h build/linux/libCwtch.h
|
||||
endif
|
||||
|
||||
libCwtch.x64.dylib: lib.go
|
||||
./switch-ffi.sh
|
||||
go build -trimpath -ldflags "-buildid=autobindings-$(shell git describe --tags) -X main.buildVer=autobindings-$(shell git describe --tags) -X main.buildDate=$(shell git log -1 --format=%cd --date=format:%G-%m-%d-%H-%M)" -buildmode c-shared -o libCwtch.x64.dylib
|
||||
env CGO_CFLAGS="-mmacosx-version-min=10.12" CGO_LDFLAGS="-mmacosx-version-min=10.12" GOARCH=amd64 GOOS=darwin CGO_ENABLED=1 go build -trimpath -ldflags "-buildid=autobindings-$(shell git describe --tags) -X main.buildVer=autobindings-$(shell git describe --tags) -X main.buildDate=$(shell git log -1 --format=%cd --date=format:%G-%m-%d-%H-%M)" -buildmode c-shared -o libCwtch.x64.dylib
|
||||
mkdir -p build/macos
|
||||
mv libCwtch.x64.dylib build/macos/
|
||||
|
||||
libCwtch.arm64.dylib: lib.go
|
||||
./switch-ffi.sh
|
||||
env GOARCH=arm64 GOOS=darwin CGO_ENABLED=1 go build -trimpath -ldflags "-buildid=$(shell git describe --tags) -X main.buildVer=$(shell git describe --tags) -X main.buildDate=$(shell git log -1 --format=%cd --date=format:%G-%m-%d-%H-%M)" -buildmode c-shared -o libCwtch.arm64.dylib
|
||||
env CGO_CFLAGS="-mmacosx-version-min=10.12" CGO_LDFLAGS="-mmacosx-version-min=10.12" GOARCH=arm64 GOOS=darwin CGO_ENABLED=1 go build -trimpath -ldflags "-buildid=$(shell git describe --tags) -X main.buildVer=$(shell git describe --tags) -X main.buildDate=$(shell git log -1 --format=%cd --date=format:%G-%m-%d-%H-%M)" -buildmode c-shared -o libCwtch.arm64.dylib
|
||||
mkdir -p build/macos
|
||||
mv libCwtch.arm64.dylib build/macos/
|
||||
|
||||
|
@ -66,7 +87,7 @@ clean-autobindings:
|
|||
rm -f lib.go
|
||||
|
||||
clean:
|
||||
rm -fr lib.go cwtch.aar cwtch_go.apk libCwtch.h libCwtch.so cwtch-sources.jar libCwtch.dll libCwtch.*.dylib build
|
||||
rm -fr lib.go cwtch.aar cwtch_go.apk libCwtch.*.h libCwtch.*.so cwtch-sources.jar libCwtch.dll libCwtch.*.dylib build
|
||||
|
||||
# iOS - for testing purposes only for now, not officially supported
|
||||
|
||||
|
|
|
@ -10,8 +10,6 @@ Note for the Flutter-based Cwtch UI Application see: https://git.openprivacy.ca/
|
|||
go run generate/generate_bindings.go
|
||||
make linux // alternatively windows, android, macos
|
||||
|
||||
**NOTE:** Autobindings currently depends on an unreleased version of Cwtch (`cwtch.im/cwtch v0.18.10-0.20230221235514-49e0d849fa3e`).
|
||||
|
||||
### Experiments
|
||||
|
||||
Autobindings allow for comile time selection of experiments. Default selections for each target platform are supplied in Makefile but can be overridden with:
|
||||
|
@ -61,6 +59,10 @@ Other directives:
|
|||
- `LD_LIBRARY_PATH` set to point to `libCwtch.so`
|
||||
- or drop a symlink into `/usr/lib`
|
||||
|
||||
### Cross compile arm 64
|
||||
|
||||
Needs `sudo apt install gcc-aarch64-linux-gnu`
|
||||
|
||||
## Android
|
||||
|
||||
- copy `cwtch.aar` into `flutter_app/android/cwtch`
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package servers
|
||||
package server_hosting
|
||||
|
||||
import (
|
||||
"cwtch.im/cwtch/app"
|
|
@ -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}
|
||||
}
|
|
@ -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")
|
||||
}
|
||||
}
|
|
@ -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"`
|
||||
}
|
|
@ -96,7 +96,9 @@ func main() {
|
|||
case "profile":
|
||||
generatedBindings = generateProfileFunction(generatedBindings, fName, args)
|
||||
case "(json)profile":
|
||||
generatedBindings = generateJsonProfileFunction(generatedBindings, fName, args)
|
||||
generatedBindings = generateJsonProfileFunction(generatedBindings, fName, args, false)
|
||||
case "(json-err)profile":
|
||||
generatedBindings = generateJsonProfileFunction(generatedBindings, fName, args, true)
|
||||
case "@profile-experiment":
|
||||
experiment := args[0]
|
||||
generatedBindings = generateExperimentalProfileFunction(generatedBindings, experiment, fName, args[1:])
|
||||
|
@ -146,6 +148,10 @@ func intArgPrototype(varName string) (string, string, string, string) {
|
|||
return fmt.Sprintf(`%s C.int`, ToSnakeCase(varName)), fmt.Sprintf(`int(%v)`, ToSnakeCase(varName)), fmt.Sprintf(`%v int`, varName), varName
|
||||
}
|
||||
|
||||
func uintArgPrototype(varName string) (string, string, string, string) {
|
||||
return fmt.Sprintf(`%s C.uint`, ToSnakeCase(varName)), fmt.Sprintf(`int(%v)`, ToSnakeCase(varName)), fmt.Sprintf(`%v int`, varName), varName
|
||||
}
|
||||
|
||||
func conversationArgPrototype(varName string) (string, string, string, string) {
|
||||
return intArgPrototype(varName)
|
||||
}
|
||||
|
@ -235,7 +241,7 @@ func mapArgs(argsTypes []string) (string, string, string, string) {
|
|||
gUse = append(gUse, c4)
|
||||
case "int":
|
||||
if len(argTypeParts) != 2 {
|
||||
fmt.Printf("generic bool arg must have have e.g. bool:<name>\n")
|
||||
fmt.Printf("generic int arg must have have e.g. int:<name>\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
c1, c2, c3, c4 := intArgPrototype(argTypeParts[1])
|
||||
|
@ -243,6 +249,20 @@ func mapArgs(argsTypes []string) (string, string, string, string) {
|
|||
c2GoArgs = append(c2GoArgs, c2)
|
||||
goSpec = append(goSpec, c3)
|
||||
gUse = append(gUse, c4)
|
||||
case "uint":
|
||||
if len(argTypeParts) != 2 {
|
||||
fmt.Printf("generic uint arg must have have e.g. uint:<name>\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
c1, c2, c3, c4 := uintArgPrototype(argTypeParts[1])
|
||||
cArgs = append(cArgs, c1)
|
||||
c2GoArgs = append(c2GoArgs, c2)
|
||||
goSpec = append(goSpec, c3)
|
||||
// because of java/kotlin/android/gomobile inability to recognize unsigned integers
|
||||
// we need to pretent this is a signed interface...so do the final cast here...
|
||||
// this will cause bad behavior if a negative number is passed through the java
|
||||
// interface...so...don't do that...
|
||||
gUse = append(gUse, fmt.Sprintf("uint(%s)", c4))
|
||||
case "string":
|
||||
if len(argTypeParts) != 2 {
|
||||
fmt.Printf("generic string arg must have have e.g. string:<name>\n")
|
||||
|
@ -364,7 +384,7 @@ func {{FNAME}}({{GO_ARGS_SPEC}}) {
|
|||
return bindings
|
||||
}
|
||||
|
||||
func generateJsonProfileFunction(bindings string, name string, argsTypes []string) string {
|
||||
func generateJsonProfileFunction(bindings string, name string, argsTypes []string, handleErr bool) string {
|
||||
appPrototype := `
|
||||
//export c_{{FNAME}}
|
||||
func c_{{FNAME}}({{C_ARGS}}) *C.char {
|
||||
|
@ -374,14 +394,26 @@ func c_{{FNAME}}({{C_ARGS}}) *C.char {
|
|||
func {{FNAME}}({{GO_ARGS_SPEC}}) string {
|
||||
cwtchProfile := application.GetPeer(profile)
|
||||
if cwtchProfile != nil {
|
||||
return cwtchProfile.{{LIBNAME}}({{GO_ARG}})
|
||||
{{HANDLE_FUNC}}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
`
|
||||
|
||||
noErrorPrototype := `return cwtchProfile.{{LIBNAME}}({{GO_ARG}})`
|
||||
withErrorPrototype := `res,err := cwtchProfile.{{LIBNAME}}({{GO_ARG}})
|
||||
if err != nil {
|
||||
log.Errorf("could not {{FNAME}} %v", err)
|
||||
}
|
||||
return res`
|
||||
functionPrototype := noErrorPrototype
|
||||
if handleErr {
|
||||
functionPrototype = withErrorPrototype
|
||||
}
|
||||
|
||||
cArgs, c2GoArgs, goSpec, gUse := mapArgs(argsTypes)
|
||||
|
||||
appPrototype = strings.ReplaceAll(appPrototype, "{{HANDLE_FUNC}}", functionPrototype)
|
||||
appPrototype = strings.ReplaceAll(appPrototype, "{{FNAME}}", strings.TrimPrefix(name, "Enhanced"))
|
||||
appPrototype = strings.ReplaceAll(appPrototype, "{{LIBNAME}}", name)
|
||||
// We need to prepend a set of profile handle arguments...
|
||||
|
@ -407,7 +439,10 @@ func {{FNAME}}({{GO_ARGS_SPEC}}) {
|
|||
if cwtchProfile != nil {
|
||||
functionality := {{EXPERIMENT}}.FunctionalityGate()
|
||||
if functionality != nil {
|
||||
functionality.{{LIBNAME}}(cwtchProfile, {{GO_ARG}})
|
||||
err := functionality.{{LIBNAME}}(cwtchProfile, {{GO_ARG}})
|
||||
if err != nil {
|
||||
log.Errorf("error calling experimental feature {{FNAME}}: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
7
go.mod
7
go.mod
|
@ -1,11 +1,11 @@
|
|||
module git.openprivacy.ca/cwtch.im/cwtch-autobindings
|
||||
|
||||
go 1.19
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
cwtch.im/cwtch v0.20.8
|
||||
cwtch.im/cwtch v0.27.0
|
||||
git.openprivacy.ca/cwtch.im/server v1.4.5
|
||||
git.openprivacy.ca/openprivacy/connectivity v1.10.0
|
||||
git.openprivacy.ca/openprivacy/connectivity v1.11.0
|
||||
git.openprivacy.ca/openprivacy/log v1.0.3
|
||||
github.com/mutecomm/go-sqlcipher/v4 v4.4.2
|
||||
)
|
||||
|
@ -24,5 +24,4 @@ require (
|
|||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b // indirect
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
|
||||
)
|
||||
|
|
8
go.sum
8
go.sum
|
@ -1,6 +1,6 @@
|
|||
cwtch.im/cwtch v0.18.0/go.mod h1:StheazFFY7PKqBbEyDVLhzWW6WOat41zV0ckC240c5Y=
|
||||
cwtch.im/cwtch v0.20.8 h1:5N95p6uYquu9Vj2E9jK41FJpa679h1oYfiv/2jm5gbA=
|
||||
cwtch.im/cwtch v0.20.8/go.mod h1:h8S7EgEM+8pE1k+XLB5jAFdIPlOzwoXEY0GH5mQye5A=
|
||||
cwtch.im/cwtch v0.27.0 h1:MkNIZ+pT5ZwiGlKHk20GMUTlzBsmCWJEibbj6hr+WHw=
|
||||
cwtch.im/cwtch v0.27.0/go.mod h1:A3i92aFuhyHI2DYO2Qnvl5iqEw0Cox22pdiypHnMOy4=
|
||||
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=
|
||||
|
@ -13,8 +13,8 @@ git.openprivacy.ca/openprivacy/bine v0.0.4/go.mod h1:13ZqhKyqakDsN/ZkQkIGNULsmLy
|
|||
git.openprivacy.ca/openprivacy/bine v0.0.5 h1:DJs5gqw3SkvLSgRDvroqJxZ7F+YsbxbBRg5t0rU5gYE=
|
||||
git.openprivacy.ca/openprivacy/bine v0.0.5/go.mod h1:fwdeq6RO08WDkV0k7HfArsjRvurVULoUQmT//iaABZM=
|
||||
git.openprivacy.ca/openprivacy/connectivity v1.8.6/go.mod h1:Hn1gpOx/bRZp5wvCtPQVJPXrfeUH0EGiG/Aoa0vjGLg=
|
||||
git.openprivacy.ca/openprivacy/connectivity v1.10.0 h1:7P5xdFL4mGg9bwlIY+sdaNGUMazlMB82/v/6kXlvqxY=
|
||||
git.openprivacy.ca/openprivacy/connectivity v1.10.0/go.mod h1:OQO1+7OIz/jLxDrorEMzvZA6SEbpbDyLGpjoFqT3z1Y=
|
||||
git.openprivacy.ca/openprivacy/connectivity v1.11.0 h1:roASjaFtQLu+HdH5fa2wx6F00NL3YsUTlmXBJh8aLZk=
|
||||
git.openprivacy.ca/openprivacy/connectivity v1.11.0/go.mod h1:OQO1+7OIz/jLxDrorEMzvZA6SEbpbDyLGpjoFqT3z1Y=
|
||||
git.openprivacy.ca/openprivacy/log v1.0.3 h1:E/PMm4LY+Q9s3aDpfySfEDq/vYQontlvNj/scrPaga0=
|
||||
git.openprivacy.ca/openprivacy/log v1.0.3/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
|
|
27
quality.sh
27
quality.sh
|
@ -3,22 +3,29 @@
|
|||
echo "Checking code quality (you want to see no output here)"
|
||||
echo ""
|
||||
|
||||
echo "Vetting:"
|
||||
go vet generate/*
|
||||
|
||||
echo ""
|
||||
echo "Linting:"
|
||||
echo "Running staticcheck..."
|
||||
|
||||
staticcheck ./generate
|
||||
staticcheck lib.go
|
||||
staticcheck ./utils/*
|
||||
|
||||
# In the future we should remove include-pkgs. However, there are a few false positives in the overall go stdlib that make this
|
||||
# too noisy right now, specifically assigning nil to initialize slices (safe), and using go internal context channels assigned
|
||||
# nil (also safe).
|
||||
# We also have one file infinite_channel.go written in a way that static analysis cannot reason about easily. So it is explictly
|
||||
# ignored.
|
||||
echo "Running nilaway..."
|
||||
nilaway -include-pkgs="git.openprivacy.ca/cwtch.im/cwtch-autobindings,cwtch.im/cwtch,cwtch.im/tapir,git.openprivacy.ca/openprivacy/connectivity" -exclude-errors-in-files="./templates/lib_template.go" -exclude-file-docstrings="nolint:nilaway" lib.go
|
||||
nilaway -include-pkgs="git.openprivacy.ca/cwtch.im/cwtch-autobindings,cwtch.im/cwtch,cwtch.im/tapir,git.openprivacy.ca/openprivacy/connectivity" -exclude-errors-in-files="./templates/lib_template.go" -exclude-file-docstrings="nolint:nilaway" ./utils/
|
||||
|
||||
echo "Time to format"
|
||||
gofmt -l -s -w .
|
||||
gofmt -l -s -w ./utils/*
|
||||
gofmt -l -s -w ./generate/*
|
||||
|
||||
# ineffassign (https://github.com/gordonklaus/ineffassign)
|
||||
echo "Checking for ineffectual assignment of errors (unchecked errors...)"
|
||||
ineffassign .
|
||||
# echo "Checking for ineffectual assignment of errors (unchecked errors...)"
|
||||
# ineffassign .
|
||||
|
||||
# misspell (https://github.com/client9/misspell/cmd/misspell)
|
||||
echo "Checking for misspelled words..."
|
||||
misspell . | grep -v "testing/" | grep -v "vendor/" | grep -v "go.sum" | grep -v ".idea"
|
||||
# echo "Checking for misspelled words..."
|
||||
# misspell . | grep -v "testing/" | grep -v "vendor/" | grep -v "go.sum" | grep -v ".idea"
|
||||
|
|
21
spec
21
spec
|
@ -3,6 +3,7 @@
|
|||
# Peer Engine
|
||||
app ActivatePeerEngine profile
|
||||
app DeactivatePeerEngine profile
|
||||
app ConfigureConnections profile bool:listen bool:peers bool:servers
|
||||
|
||||
# Profile Management
|
||||
app CreateProfile name password bool:autostart
|
||||
|
@ -20,17 +21,31 @@ profile BlockConversation conversation
|
|||
profile UnblockConversation conversation
|
||||
profile DeleteConversation conversation
|
||||
profile PeerWithOnion string:handle
|
||||
profile DisconnectFromPeer string:handle
|
||||
(json-err)profile EnhancedGetConversationAccessControlList conversation
|
||||
profile EnhancedUpdateConversationAccessControlList conversation string:json
|
||||
|
||||
# Search
|
||||
(json)profile SearchConversations string:pattern
|
||||
|
||||
# Message Management
|
||||
(json)profile EnhancedSendMessage conversation string:msg
|
||||
(json)profile EnhancedGetMessageById conversation message
|
||||
(json)profile EnhancedGetMessageByContentHash conversation string:contentHash
|
||||
(json)profile EnhancedGetMessages conversation int:index int:count
|
||||
(json)profile EnhancedGetMessages conversation int:index uint:count
|
||||
(json)profile EnhancedSendInviteMessage conversation conversation:target
|
||||
profile UpdateMessageAttribute conversation channel message string:attributeKey string:attributeValue
|
||||
|
||||
# Group Management
|
||||
profile StartGroup string:name string:server
|
||||
profile QueueJoinServer string:handle
|
||||
profile DisconnectFromServer string:handle
|
||||
|
||||
## Server List Management...
|
||||
import "cwtch.im/cwtch/functionality/servers"
|
||||
@profile-experiment PublishServerUpdate servers
|
||||
@profile-experiment GetServerInfoList servers
|
||||
@profile-experiment DeleteServerInfo servers string:serverOnion
|
||||
|
||||
# Filesharing Management
|
||||
import "cwtch.im/cwtch/functionality/filesharing"
|
||||
|
@ -44,8 +59,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
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"runtime"
|
||||
"runtime/pprof"
|
||||
"strings"
|
||||
"strconv"
|
||||
"time"
|
||||
mrand "math/rand"
|
||||
"crypto/rand"
|
||||
|
@ -189,7 +190,6 @@ func _startCwtch(appDir string, torPath string) {
|
|||
log.Infof("libcwtch-go application launched")
|
||||
application.GetPrimaryBus().Publish(event.NewEvent(settings.CwtchStarted, map[event.Field]string{}))
|
||||
application.QueryACNVersion()
|
||||
application.LoadProfiles(app.DefactoPasswordForUnencryptedProfiles)
|
||||
|
||||
{{EXPERIMENT_REGISTER}}
|
||||
|
||||
|
@ -247,7 +247,7 @@ func ReconnectCwtchForeground() {
|
|||
|
||||
settingsJson, _ := json.Marshal(application.ReadSettings())
|
||||
application.GetPrimaryBus().Publish(event.NewEvent(settings.UpdateGlobalSettings, map[event.Field]string{event.Data: string(settingsJson)}))
|
||||
application.GetPrimaryBus().Publish(event.NewEvent(settings.CwtchStarted, map[event.Field]string{}))
|
||||
application.GetPrimaryBus().Publish(event.NewEvent(settings.CwtchStarted, map[event.Field]string{utils.ReloadEvent: event.True}))
|
||||
application.QueryACNStatus()
|
||||
application.QueryACNVersion()
|
||||
}
|
||||
|
@ -314,6 +314,8 @@ func SetProfileAttribute(profileOnion string, key string, value string) {
|
|||
profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.ProfileStatus, value)
|
||||
} else if zone == attr.ProfileZone && key == constants.PeerAutostart {
|
||||
profile.SetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.PeerAutostart, value)
|
||||
} else if zone == attr.ProfileZone && key == constants.PeerAppearOffline {
|
||||
profile.SetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.PeerAppearOffline, value)
|
||||
} else {
|
||||
log.Errorf("attempted to set an attribute with an unknown zone: %v", key)
|
||||
}
|
||||
|
@ -440,7 +442,6 @@ const (
|
|||
|
||||
func buildACN(globalSettings settings.GlobalSettings, torPath string, appDir string) (connectivity.ACN, settings.GlobalSettings, error) {
|
||||
|
||||
mrand.Seed(int64(time.Now().Nanosecond()))
|
||||
socksPort := mrand.Intn(1000) + 9600
|
||||
controlPort := socksPort + 1
|
||||
|
||||
|
@ -469,7 +470,30 @@ func buildACN(globalSettings settings.GlobalSettings, torPath string, appDir str
|
|||
// Override Ports if on Tails...
|
||||
if cwtchTails := os.Getenv("CWTCH_TAILS"); strings.ToLower(cwtchTails) == "true" {
|
||||
log.Infof("CWTCH_TAILS environment variable set... overriding tor config...")
|
||||
|
||||
controlPort = 9051
|
||||
|
||||
// In tails 5.13 the control port was changed to 951
|
||||
// so read the Tails Version File and if it exists...
|
||||
b, err := os.ReadFile("/etc/amnesia/version")
|
||||
if err == nil {
|
||||
// the file should start with the version followed
|
||||
// by a space...
|
||||
versionEnd := strings.Index(string(b), " ")
|
||||
versionStr := string(b)[:versionEnd]
|
||||
version, err := strconv.ParseFloat(versionStr, 64)
|
||||
if err == nil {
|
||||
log.Infof("Confirming Tails Version: %v", version)
|
||||
// assert the control port if we are at the dedicated version...
|
||||
// we know this change happened sometime after 5.11
|
||||
if version >= 5.13 {
|
||||
controlPort = 951
|
||||
}
|
||||
} else {
|
||||
log.Errorf("Unable to confirm Tails version. CWTCH_TAILS options may not function correctly.")
|
||||
}
|
||||
}
|
||||
|
||||
socksPort = 9050
|
||||
globalSettings.CustomControlPort = controlPort
|
||||
globalSettings.CustomSocksPort = socksPort
|
||||
|
|
|
@ -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,10 @@ 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(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)
|
||||
}
|
||||
|
@ -146,9 +145,15 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string {
|
|||
|
||||
// Start up the Profile
|
||||
if acnStatus == 100 {
|
||||
autostart, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants2.PeerAutostart)
|
||||
autostart, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.PeerAutostart)
|
||||
appearOffline, appearOfflineExists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.PeerAppearOffline)
|
||||
if !exists || autostart == "true" {
|
||||
eh.app.ActivatePeerEngine(onion)
|
||||
if appearOfflineExists && appearOffline == "true" {
|
||||
// don't configure any connections...
|
||||
} else {
|
||||
eh.app.ConfigureConnections(onion, true, true, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,6 +167,13 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string {
|
|||
}
|
||||
e.Data["autostart"] = autostart
|
||||
|
||||
appearOffline, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.PeerAppearOffline)
|
||||
// legacy profiles should not appearOffline by default
|
||||
if !exists {
|
||||
appearOffline = "false"
|
||||
}
|
||||
e.Data["appearOffline"] = appearOffline
|
||||
|
||||
// Name always exists
|
||||
e.Data[constants.Name], _ = profile.GetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name)
|
||||
e.Data[constants2.DefaultProfilePicture] = RandomProfileImage(onion)
|
||||
|
@ -174,7 +186,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 +198,10 @@ 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))
|
||||
serverInfo, _ := groupHandler.GetServerInfo(profile, conversationInfo.Handle)
|
||||
knownServers = append(knownServers, serverInfo)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
@ -211,7 +224,7 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string {
|
|||
cpicPath = RandomGroupImage(conversationInfo.Handle)
|
||||
defaultPath = RandomGroupImage(conversationInfo.Handle)
|
||||
} else {
|
||||
cpicPath = GetProfileImage(profile, conversationInfo, settings.DownloadPath)
|
||||
cpicPath = eh.GetProfileImage(profile, conversationInfo, settings.DownloadPath)
|
||||
defaultPath = RandomProfileImage(conversationInfo.Handle)
|
||||
}
|
||||
|
||||
|
@ -309,8 +322,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"])
|
||||
}
|
||||
|
@ -320,15 +333,17 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string {
|
|||
return string(json)
|
||||
}
|
||||
|
||||
func GetProfileImage(profile peer.CwtchPeer, conversationInfo *model.Conversation, basepath string) string {
|
||||
fileKey, err := profile.GetConversationAttribute(conversationInfo.ID, attr.PublicScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(constants.CustomProfileImageKey)))
|
||||
if err == nil {
|
||||
if value, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.complete", fileKey)); exists && value == event.True {
|
||||
fp, _ := filesharing.GenerateDownloadPath(basepath, fileKey, true)
|
||||
// check if the file exists...if it does then set the path...
|
||||
if _, err := os.Stat(fp); err == nil {
|
||||
image, _ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.path", fileKey))
|
||||
return image
|
||||
func (eh *EventHandler) GetProfileImage(profile peer.CwtchPeer, conversationInfo *model.Conversation, basepath string) string {
|
||||
if eh.app.IsFeatureEnabled(constants.ImagePreviewsExperiment) {
|
||||
fileKey, err := profile.GetConversationAttribute(conversationInfo.ID, attr.PublicScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(constants.CustomProfileImageKey)))
|
||||
if err == nil {
|
||||
if value, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.complete", fileKey)); exists && value == event.True {
|
||||
fp, _ := filesharing.GenerateDownloadPath(basepath, fileKey, true)
|
||||
// check if the file exists...if it does then set the path...
|
||||
if _, err := os.Stat(fp); err == nil {
|
||||
image, _ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.path", fileKey))
|
||||
return image
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -344,6 +359,10 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
log.Errorf("eh.app == nil in handleProfileEvent... this shouldnt happen?")
|
||||
} else {
|
||||
profile := eh.app.GetPeer(ev.Profile)
|
||||
if profile == nil {
|
||||
log.Errorf("something has gone very wrong. profile is nil in handleProfileEvent")
|
||||
return ""
|
||||
}
|
||||
log.Debugf("New Profile Event to Handle: %v", ev)
|
||||
switch ev.Event.EventType {
|
||||
case event.NewMessageFromPeer: //event.TimestampReceived, event.RemotePeer, event.Data
|
||||
|
@ -353,7 +372,7 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
if ci != nil && err == nil {
|
||||
ev.Event.Data[event.ConversationID] = strconv.Itoa(ci.ID)
|
||||
profile.SetConversationAttribute(ci.ID, attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(constants2.Archived)), event.False)
|
||||
ev.Event.Data[constants2.Picture] = GetProfileImage(profile, ci, eh.app.ReadSettings().DownloadPath)
|
||||
ev.Event.Data[constants2.Picture] = eh.GetProfileImage(profile, ci, eh.app.ReadSettings().DownloadPath)
|
||||
} else {
|
||||
// TODO This Conversation May Not Exist Yet...But we are not in charge of creating it...
|
||||
log.Errorf("todo wait for contact to be added before processing this event...")
|
||||
|
@ -382,13 +401,17 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
ev.Event.Data["Nick"] = ev.Event.Data["RemotePeer"]
|
||||
}
|
||||
}
|
||||
ev.Event.Data[constants2.Picture] = GetProfileImage(profile, ci, eh.app.ReadSettings().DownloadPath)
|
||||
ev.Event.Data[constants2.Picture] = eh.GetProfileImage(profile, ci, eh.app.ReadSettings().DownloadPath)
|
||||
}
|
||||
|
||||
conversationID, _ := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
profile.SetConversationAttribute(conversationID, attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(constants2.Archived)), event.False)
|
||||
|
||||
gci, _ := profile.GetConversationInfo(conversationID)
|
||||
gci, err := profile.GetConversationInfo(conversationID)
|
||||
if err != nil {
|
||||
log.Errorf("new message from non-existant group: %v", err)
|
||||
break
|
||||
}
|
||||
groupServer := gci.Attributes[attr.LocalScope.ConstructScopedZonedPath(attr.LegacyGroupZone.ConstructZonedPath(constants.GroupServer)).ToString()]
|
||||
state := profile.GetPeerState(groupServer)
|
||||
// if syncing, don't flood with notifications
|
||||
|
@ -407,11 +430,13 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
count, err := profile.GetChannelMessageCount(conversationID, 0)
|
||||
if err != nil {
|
||||
log.Errorf("error fetching channel message count %v %v", conversationID, err)
|
||||
break
|
||||
}
|
||||
|
||||
conversationInfo, err := profile.GetConversationInfo(conversationID)
|
||||
if err != nil {
|
||||
log.Errorf("error fetching conversation info for %v %v", conversationID, err)
|
||||
break
|
||||
}
|
||||
|
||||
blocked := constants.False
|
||||
|
@ -424,7 +449,11 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
accepted = constants.True
|
||||
}
|
||||
|
||||
acl, _ := json.Marshal(conversationInfo.ACL)
|
||||
acl, err := json.Marshal(conversationInfo.ACL)
|
||||
if err != nil {
|
||||
log.Errorf("received invalid ACL in conversation: %v", err)
|
||||
break
|
||||
}
|
||||
|
||||
lastMessage, _ := profile.GetMostRecentMessages(conversationID, 0, 0, 1)
|
||||
ev.Event.Data["unread"] = strconv.Itoa(count) // if this is a new contact with messages attached then by-definition these are unread...
|
||||
|
@ -444,8 +473,16 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
groupPic := RandomGroupImage(ev.Event.Data[event.GroupID])
|
||||
ev.Event.Data[constants2.Picture] = groupPic
|
||||
|
||||
conversationID, _ := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
conversationInfo, _ := profile.GetConversationInfo(conversationID)
|
||||
conversationID, err := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
if err != nil {
|
||||
log.Errorf("invalid conversation id recieved %v", err)
|
||||
break
|
||||
}
|
||||
conversationInfo, err := profile.GetConversationInfo(conversationID)
|
||||
if err != nil {
|
||||
log.Errorf("error fetching conversation info for %v %v", conversationID, err)
|
||||
break
|
||||
}
|
||||
acl, _ := json.Marshal(conversationInfo.ACL)
|
||||
ev.Event.Data["accessControlList"] = string(acl)
|
||||
case event.NewGroup:
|
||||
|
@ -456,51 +493,34 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
groupPic := RandomGroupImage(invite.GroupID)
|
||||
ev.Event.Data[constants2.Picture] = groupPic
|
||||
|
||||
conversationID, _ := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
conversationInfo, _ := profile.GetConversationInfo(conversationID)
|
||||
acl, _ := json.Marshal(conversationInfo.ACL)
|
||||
conversationID, err := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
if err != nil {
|
||||
log.Errorf("invalid conversation id recieved %v", err)
|
||||
break
|
||||
}
|
||||
conversationInfo, err := profile.GetConversationInfo(conversationID)
|
||||
if err != nil {
|
||||
log.Errorf("error fetching conversation info for %v %v", conversationID, err)
|
||||
break
|
||||
}
|
||||
acl, err := json.Marshal(conversationInfo.ACL)
|
||||
ev.Event.Data["accessControlList"] = string(acl)
|
||||
if err != nil {
|
||||
log.Errorf("received invalid ACL in conversation: %v", err)
|
||||
break
|
||||
}
|
||||
} else {
|
||||
log.Errorf("received a new group event which contained an invalid invite %v. this should never happen and likely means there is a bug in cwtch. Please file a ticket @ https://git.openprivacy.ca/cwtch.im/cwtch", err)
|
||||
return ""
|
||||
}
|
||||
case event.PeerStateChange:
|
||||
cxnState := connections.ConnectionStateToType()[ev.Event.Data[event.ConnectionState]]
|
||||
|
||||
// skip events the UI doesn't act on
|
||||
if cxnState == connections.CONNECTING || cxnState == connections.CONNECTED {
|
||||
return ""
|
||||
}
|
||||
|
||||
contact, err := profile.FetchConversationInfo(ev.Event.Data[event.RemotePeer])
|
||||
|
||||
if ev.Event.Data[event.RemotePeer] == profile.GetOnion() {
|
||||
return "" // suppress events from our own profile...
|
||||
}
|
||||
|
||||
// We do not know who this is...don't send any event until we see a message from them
|
||||
// (at that point the conversation will have been created...)
|
||||
if contact == nil || err != nil || contact.ID == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// if we already know this state, suppress
|
||||
if knownState, exists := contactStateCache[ev.Event.Data[event.RemotePeer]]; exists && cxnState == knownState {
|
||||
return ""
|
||||
}
|
||||
contactStateCache[ev.Event.Data[event.RemotePeer]] = cxnState
|
||||
case event.ServerStateChange:
|
||||
cxnState := connections.ConnectionStateToType()[ev.Event.Data[event.ConnectionState]]
|
||||
|
||||
// skip events the UI doesn't act on
|
||||
if cxnState == connections.CONNECTING || cxnState == connections.CONNECTED {
|
||||
return ""
|
||||
}
|
||||
|
||||
// if we already know this state, suppress
|
||||
if knownState, exists := contactStateCache[ev.Event.Data[event.RemotePeer]]; exists && cxnState == knownState {
|
||||
return ""
|
||||
}
|
||||
contactStateCache[ev.Event.Data[event.RemotePeer]] = cxnState
|
||||
case event.TokenManagerInfo:
|
||||
conversations, err := profile.FetchConversations()
|
||||
|
@ -546,6 +566,10 @@ func unwrap(original *EventProfileEnvelope) *event.Event {
|
|||
|
||||
func (eh *EventHandler) startHandlingPeer(onion string) {
|
||||
eventBus := eh.app.GetEventBus(onion)
|
||||
if eventBus == nil {
|
||||
log.Errorf("could not start handling peer events .. event bus is nil")
|
||||
return
|
||||
}
|
||||
q := event.NewQueue()
|
||||
|
||||
eventBus.Subscribe(event.NetworkStatus, q)
|
||||
|
@ -572,6 +596,9 @@ 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)
|
||||
eventBus.Subscribe(servers.UpdateServerInfo, q)
|
||||
go eh.forwardProfileMessages(onion, q)
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue