Merge branch 'master' of git.openprivacy.ca:cwtch.im/ui into ebf201902131852

This commit is contained in:
erinn 2019-02-13 18:53:52 -08:00
commit 21a905eb3b
7 changed files with 95 additions and 32 deletions

View File

@ -1,12 +1,26 @@
# Setup # Cwtch - UI
## Android This codebase provides a graphical user interface for Desktop and Android for [Cwtch: Privacy Preserving Infrastructure for Asynchronous, Decentralized and Metadata Resistant Applications](https://git.openprivacy.ca/cwtch.im/cwtch)
A arm-pie version of tor like [tor-0.3.4.8.arm-pie](https://git.openprivacy.ca/openprivacy/buildfiles/raw/master/tor/tor-0.3.4.8.arm-pie) is required to be placed in `android/libs/armeabi-v7a` with the name `libtor.so` # Security
# Deployment **Cwtch is an experimental concept and prototype. We do not recommend you use Cwtch today if you require secure communication.** At least, not yet.
If you discover a security issue, please log an issue above, or email team@cwtch.im.
# Compiling & Running
This code relies on [therecipe/qt](https://github.com/therecipe/qt) before getting started consult the [Installation](https://github.com/therecipe/qt/wiki/Installation) and [Getting Started](https://github.com/therecipe/qt/wiki/Getting-Started) documentation to get that up and running. It will make building this much easier.
## Desktop
qtdeploy build desktop
./deploy/linux/ui.sh -local -debug 2>&1 | grep -v 'Detected anchors on an item that is managed by a layout.'
The -local and -debug flags are helpful when developing.
## Android ## Android
A arm-pie version of tor like [tor-0.3.5.7-armeabi-v7a](https://git.openprivacy.ca/openprivacy/buildfiles/src/master/tor/tor-0.3.5.7-armeabi-v7a.so) is required to be placed in `android/libs/armeabi-v7a` with the name `libtor.so`
qtdeploy -docker build android qtdeploy -docker build android
adb install deploy/android/build-debug.apk adb install deploy/android/build-debug.apk

View File

@ -41,9 +41,9 @@ type GrandCentralDispatcher struct {
_ func(name, onion, image string) `signal:"UpdateMyProfile"` _ func(name, onion, image string) `signal:"UpdateMyProfile"`
_ func(status int, str string) `signal:"TorStatus"` _ func(status int, str string) `signal:"TorStatus"`
// other stuff i can't ontologize atm // settings helpers
_ func(str string) `signal:"InvokePopup"` _ func(str string) `signal:"InvokePopup"`
_ func(groupID, name, server, invitation string, addrbooknames, addrbookaddrs []string) `signal:"SupplyGroupSettings"` _ func(groupID, name, server, invitation string, accepted bool, addrbooknames, addrbookaddrs []string) `signal:"SupplyGroupSettings"`
_ func(onion, nick string) `signal:"SupplyPeerSettings"` _ func(onion, nick string) `signal:"SupplyPeerSettings"`
// signals emitted from the ui (written in go, below) // signals emitted from the ui (written in go, below)
@ -55,7 +55,8 @@ type GrandCentralDispatcher struct {
_ func(nick string) `signal:"updateNick,auto"` _ func(nick string) `signal:"updateNick,auto"`
_ func(server, groupName string) `signal:"createGroup,auto"` _ func(server, groupName string) `signal:"createGroup,auto"`
_ func(groupID string) `signal:"leaveGroup,auto"` _ func(groupID string) `signal:"leaveGroup,auto"`
_ func() `signal:"requestGroupSettings,auto"` _ func(groupID string) `signal:"acceptGroup,auto"`
_ func(groupID string) `signal:"requestGroupSettings,auto"`
_ func(groupID, nick string) `signal:"saveGroupSettings,auto"` _ func(groupID, nick string) `signal:"saveGroupSettings,auto"`
_ func() `signal:"requestPeerSettings,auto"` _ func() `signal:"requestPeerSettings,auto"`
_ func(onion, nick string) `signal:"savePeerSettings,auto"` _ func(onion, nick string) `signal:"savePeerSettings,auto"`
@ -251,16 +252,16 @@ func (this *GrandCentralDispatcher) savePeerSettings(onion, nick string) {
this.UIState.UpdateContact(onion) this.UIState.UpdateContact(onion)
} }
func (this *GrandCentralDispatcher) requestGroupSettings() { func (this *GrandCentralDispatcher) requestGroupSettings(groupID string) {
group := the.Peer.GetGroup(this.CurrentOpenConversation()) group := the.Peer.GetGroup(groupID)
if group == nil { if group == nil {
log.Errorf("couldn't find group %v", this.CurrentOpenConversation()) log.Errorf("couldn't find group %v", groupID)
return return
} }
nick, _ := group.GetAttribute("nick") nick, _ := group.GetAttribute("nick")
invite, _ := the.Peer.ExportGroup(this.CurrentOpenConversation()) invite, _ := the.Peer.ExportGroup(groupID)
contactaddrs := the.Peer.GetContacts() contactaddrs := the.Peer.GetContacts()
contactnames := make([]string, len(contactaddrs)) contactnames := make([]string, len(contactaddrs))
@ -273,7 +274,7 @@ func (this *GrandCentralDispatcher) requestGroupSettings() {
} }
} }
this.SupplyGroupSettings(group.GroupID, nick, group.GroupServer, invite, contactnames, contactaddrs) this.SupplyGroupSettings(group.GroupID, nick, group.GroupServer, invite, group.Accepted, contactnames, contactaddrs)
} }
func (this *GrandCentralDispatcher) saveGroupSettings(groupID, nick string) { func (this *GrandCentralDispatcher) saveGroupSettings(groupID, nick string) {
@ -431,6 +432,14 @@ func (this *GrandCentralDispatcher) leaveGroup(groupID string) {
this.UIState.UpdateContactAttribute(groupID, "deleted", "deleted") this.UIState.UpdateContactAttribute(groupID, "deleted", "deleted")
} }
func (this *GrandCentralDispatcher) acceptGroup(groupID string) {
if the.Peer.GetGroup(groupID) != nil {
the.Peer.AcceptInvite(groupID)
the.Peer.JoinServer(the.Peer.GetGroup(groupID).GroupServer)
this.UIState.UpdateContact(groupID)
}
}
func (this *GrandCentralDispatcher) setAttribute(onion, key, value string) { func (this *GrandCentralDispatcher) setAttribute(onion, key, value string) {
pp,_ := the.Peer.GetProfile().GetContact(onion) pp,_ := the.Peer.GetProfile().GetContact(onion)
if pp != nil { if pp != nil {

View File

@ -55,10 +55,10 @@ func (this *InterfaceState) GetContact(handle string) *gobjects.Contact {
handle, handle,
handle, handle,
cwutil.RandomGroupImage(handle), cwutil.RandomGroupImage(handle),
"", group.GroupServer,
0, 0,
0, 0,
false, group.Accepted,
}) })
go the.Peer.JoinServer(group.GroupServer) go the.Peer.JoinServer(group.GroupServer)
@ -78,7 +78,7 @@ func (this *InterfaceState) GetContact(handle string) *gobjects.Contact {
false, false,
}) })
} else if contact == nil { } else if contact == nil {
log.Errorf("Attempting to add non existent contact to ui %v", handle) //log.Errorf("Attempting to add non existent contact to ui %v", handle)
} }
} }
} }

19
main.go
View File

@ -27,7 +27,13 @@ func init() {
} }
func main() { func main() {
log.SetLevel(log.LevelInfo)
if len(os.Args) >= 3 && os.Args[2] == "-debug" {
log.SetLevel(log.LevelDebug)
} else {
log.SetLevel(log.LevelInfo)
}
// our globals // our globals
gcd := gothings.NewGrandCentralDispatcher(nil) gcd := gothings.NewGrandCentralDispatcher(nil)
@ -40,7 +46,7 @@ func main() {
// this is to load local qml files quickly when developing // this is to load local qml files quickly when developing
var qmlSource *core.QUrl var qmlSource *core.QUrl
if len(os.Args) == 2 && os.Args[1] == "-local" { if len(os.Args) >= 2 && os.Args[1] == "-local" {
qmlSource = core.QUrl_FromLocalFile("./qml/main.qml") qmlSource = core.QUrl_FromLocalFile("./qml/main.qml")
} else { } else {
qmlSource = core.NewQUrl3("qrc:/qml/main.qml", 0) qmlSource = core.NewQUrl3("qrc:/qml/main.qml", 0)
@ -171,8 +177,9 @@ func loadCwtchData(gcd *gothings.GrandCentralDispatcher, acn connectivity.ACN) {
nick = group.GroupID[:12] nick = group.GroupID[:12]
} }
deleted,_ := group.GetAttribute("deleted") deleted,_ := group.GetAttribute("deleted")
if deleted != "deleted" { // Only join servers for active and explicitly accepted groups.
the.Peer.JoinServer(group.GroupServer) if deleted != "deleted"{
gcd.UIState.AddContact(&gobjects.Contact{ gcd.UIState.AddContact(&gobjects.Contact{
Handle: group.GroupID, Handle: group.GroupID,
DisplayName: nick, DisplayName: nick,
@ -181,5 +188,9 @@ func loadCwtchData(gcd *gothings.GrandCentralDispatcher, acn connectivity.ACN) {
Trusted: group.Accepted, Trusted: group.Accepted,
}) })
} }
if group.Accepted {
the.Peer.JoinServer(group.GroupServer)
}
} }
} }

View File

@ -120,7 +120,7 @@ ColumnLayout { // groupSettingsPane
Connections { Connections {
target: gcd target: gcd
onSupplyGroupSettings: function(gid, name, server, invite, addrbooknames, addrbookaddrs) { onSupplyGroupSettings: function(gid, name, server, invite, accepted, addrbooknames, addrbookaddrs) {
console.log("Supplied " + gid + " " + name) console.log("Supplied " + gid + " " + name)
gsp.groupID = gid gsp.groupID = gid
toolbar.text = name toolbar.text = name

View File

@ -10,7 +10,9 @@ import "../overlays"
ColumnLayout { ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
property alias title: toolbar.text property alias title: toolbar.text
id: overlay
property string name
property bool accepted
StackToolbar { StackToolbar {
id: toolbar id: toolbar
@ -19,7 +21,7 @@ ColumnLayout {
aux.onClicked: { aux.onClicked: {
if (gcd.currentOpenConversation.length == 32) { if (gcd.currentOpenConversation.length == 32) {
theStack.pane = theStack.groupProfilePane theStack.pane = theStack.groupProfilePane
gcd.requestGroupSettings() gcd.requestGroupSettings(gcd.currentOpenConversation)
} else { } else {
theStack.pane = theStack.userProfilePane theStack.pane = theStack.userProfilePane
gcd.requestPeerSettings() gcd.requestPeerSettings()
@ -28,6 +30,29 @@ ColumnLayout {
back.visible: false back.visible: false
} }
RowLayout {
visible:!overlay.accepted
Text {
text: "Do you want to accept the invitation to " + overlay.name + "?"
}
SimpleButton {
text: "Accept"
icon: "regular/heart"
onClicked: {
gcd.acceptGroup(gcd.currentOpenConversation)
gcd.requestGroupSettings(gcd.currentOpenConversation)
}
}
SimpleButton {
text: "Reject"
icon: "regular/trash-alt"
onClicked: {
gcd.leaveGroup(gcd.currentOpenConversation)
theStack.pane = theStack.emptyPane
}
}
}
RowLayout { RowLayout {
id: switcher id: switcher
@ -54,18 +79,12 @@ ColumnLayout {
} }
SimpleButton { SimpleButton {
text: "Game 1" text: "Puzzle Game"
onClicked: overlayStack.overlay = overlayStack.game1Overlay onClicked: overlayStack.overlay = overlayStack.game1Overlay
} }
SimpleButton {
text: "Game 2"
onClicked: overlayStack.overlay = overlayStack.game2Overlay
}
} }
StackLayout { StackLayout {
@ -81,7 +100,6 @@ ColumnLayout {
readonly property int listOverlay: 1 readonly property int listOverlay: 1
readonly property int bulletinOverlay: 2 readonly property int bulletinOverlay: 2
readonly property int game1Overlay: 3 readonly property int game1Overlay: 3
readonly property int game2Overlay: 4
ChatOverlay {} //0 ChatOverlay {} //0
@ -91,7 +109,15 @@ ColumnLayout {
BulletinOverlay{} //2 BulletinOverlay{} //2
Game1Overlay{} //3 Game1Overlay{} //3
Game2Overlay{} //4
} }
Connections {
target: gcd
onSupplyGroupSettings: function(gid, name, server, invite, accepted, addrbooknames, addrbookaddrs) {
console.log("Supplied " + gid + " " + name + "Accepted " + accepted)
overlay.name = name
overlay.accepted = accepted
}
}
} }

View File

@ -88,6 +88,9 @@ RowLayout { // LOTS OF NESTING TO DEAL WITH QT WEIRDNESS, SORRY
isActive = true isActive = true
theStack.pane = theStack.messagePane theStack.pane = theStack.messagePane
gcd.loadMessagesPane(handle) gcd.loadMessagesPane(handle)
if (handle.length == 32) {
gcd.requestGroupSettings(handle)
}
} }
onEntered: { onEntered: {