forked from cwtch.im/cwtch
CLI now supports cwtch peering and invites
This commit is contained in:
parent
c28af5f7ae
commit
8d8eb89507
|
@ -3,3 +3,5 @@
|
|||
*private_key*
|
||||
*.messages
|
||||
*.test
|
||||
*test_*
|
||||
*_test*
|
||||
|
|
30
app/app.go
30
app/app.go
|
@ -3,24 +3,38 @@ package app
|
|||
import (
|
||||
"git.mascherari.press/cwtch/model"
|
||||
"git.mascherari.press/cwtch/peer"
|
||||
"log"
|
||||
)
|
||||
|
||||
type Application struct {
|
||||
Peer *peer.CwtchPeer
|
||||
Peer *peer.CwtchPeer
|
||||
}
|
||||
|
||||
func (app *Application) NewProfile(name string, filename string) error {
|
||||
profile := peer.NewCwtchPeer(name)
|
||||
app.Peer = profile
|
||||
return profile.Save(filename)
|
||||
err := profile.Save(filename)
|
||||
if err == nil {
|
||||
go func() {
|
||||
err := app.Peer.Listen()
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
func (app *Application) SetProfile(filename string) error {
|
||||
profile,err := peer.LoadCwtchPeer(filename)
|
||||
profile, err := peer.LoadCwtchPeer(filename)
|
||||
app.Peer = profile
|
||||
if err == nil {
|
||||
app.Peer.Listen()
|
||||
go func() {
|
||||
err := app.Peer.Listen()
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -33,12 +47,6 @@ func (app *Application) SendMessageToPeer(onion string) {
|
|||
|
||||
}
|
||||
|
||||
func (app *Application) GetPeers() []model.PublicProfile {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (app *Application) GetNewMessages() []model.Message {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"bufio"
|
||||
"fmt"
|
||||
app2 "git.mascherari.press/cwtch/app"
|
||||
"os"
|
||||
"strings"
|
||||
app2 "git.mascherari.press/cwtch/app"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
quit := false
|
||||
app := app2.Application{}
|
||||
profilefile := ""
|
||||
for !quit {
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
|
@ -40,6 +41,7 @@ func main() {
|
|||
case "loadprofile":
|
||||
if len(commands) == 2 {
|
||||
err := app.SetProfile(commands[1])
|
||||
profilefile = commands[1]
|
||||
if err == nil {
|
||||
fmt.Printf("Loaded profile for %v\n", commands[1])
|
||||
} else {
|
||||
|
@ -55,7 +57,25 @@ func main() {
|
|||
} else {
|
||||
fmt.Printf("Profile needs to be set")
|
||||
}
|
||||
case "invite":
|
||||
if len(commands) == 2 {
|
||||
fmt.Printf("Inviting cwtch:%v\n", commands[1])
|
||||
app.PeerRequest(commands[1])
|
||||
} else {
|
||||
fmt.Printf("Error inviting peer, usage: invite [onion]\n")
|
||||
}
|
||||
case "peers":
|
||||
peers := app.Peer.GetPeers()
|
||||
for p, s := range peers {
|
||||
fmt.Printf("Name: %v Status: %v\n", p, s)
|
||||
}
|
||||
case "contacts":
|
||||
for _, c := range app.Peer.Profile.Contacts {
|
||||
fmt.Printf("Name: %v, Onion: %v, Trusted: %v\n", c.Name, c.Onion, c.Trusted)
|
||||
}
|
||||
case "save":
|
||||
app.Peer.Save(profilefile)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ type PublicProfile struct {
|
|||
Ed25519PublicKey ed25519.PublicKey
|
||||
Trusted bool
|
||||
Blocked bool
|
||||
Onion string
|
||||
}
|
||||
|
||||
// Profile encapsulates all the attributes necessary to be a Cwtch Peer.
|
||||
|
@ -29,7 +30,6 @@ type Profile struct {
|
|||
Contacts map[string]PublicProfile
|
||||
Ed25519PrivateKey ed25519.PrivateKey
|
||||
OnionPrivateKey *rsa.PrivateKey
|
||||
Onion string
|
||||
Groups map[string]*Group
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ func (p *Profile) GetCwtchIdentityPacket() (message []byte) {
|
|||
// AddCwtchIdentity takes a wire message and if it is a CwtchIdentity message adds the identity as a contact
|
||||
// otherwise returns an error
|
||||
func (p *Profile) AddCwtchIdentity(onion string, ci *protocol.CwtchIdentity) {
|
||||
p.AddContact(onion, PublicProfile{Name: ci.GetName(), Ed25519PublicKey: ci.GetEd25519PublicKey()})
|
||||
p.AddContact(onion, PublicProfile{Name: ci.GetName(), Ed25519PublicKey: ci.GetEd25519PublicKey(), Onion: onion})
|
||||
}
|
||||
|
||||
// AddContact allows direct manipulation of cwtch contacts
|
||||
|
|
|
@ -38,6 +38,16 @@ func (m *Manager) ManageServerConnection(host string, handler func(string, *prot
|
|||
m.lock.Unlock()
|
||||
}
|
||||
|
||||
func (m *Manager) GetPeers() map[string]ConnectionState {
|
||||
rm := make(map[string]ConnectionState)
|
||||
m.lock.Lock()
|
||||
for onion, ppc := range m.peerConnections {
|
||||
rm[onion] = ppc.GetState()
|
||||
}
|
||||
m.lock.Unlock()
|
||||
return rm
|
||||
}
|
||||
|
||||
func (m *Manager) GetPeerPeerConnectionForOnion(host string) (ppc *PeerPeerConnection) {
|
||||
m.lock.Lock()
|
||||
ppc = m.peerConnections[host]
|
||||
|
|
|
@ -41,6 +41,10 @@ func (ppc *PeerPeerConnection) HandleGroupInvite(gci *protocol.GroupChatInvite)
|
|||
ppc.profile.ProcessInvite(gci, ppc.PeerHostname)
|
||||
}
|
||||
|
||||
func (ppc *PeerPeerConnection) GetClientIdentityPacket() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ppc *PeerPeerConnection) SendGroupInvite(invite []byte) {
|
||||
ppc.connection.Do(func() error {
|
||||
channel := ppc.connection.Channel("im.cwtch.peer", channels.Outbound)
|
||||
|
@ -56,9 +60,10 @@ func (ppc *PeerPeerConnection) SendGroupInvite(invite []byte) {
|
|||
|
||||
// Run manages the setup and teardown of a peer->peer connection
|
||||
func (ppc *PeerPeerConnection) Run() error {
|
||||
ppc.state = CONNECTING
|
||||
rc, err := goricochet.Open(ppc.PeerHostname)
|
||||
if err == nil {
|
||||
rc.TraceLog(true)
|
||||
rc.TraceLog(false)
|
||||
ppc.connection = *rc
|
||||
ppc.state = CONNECTED
|
||||
_, err := connection.HandleOutboundConnection(&ppc.connection).ProcessAuthAsClient(identity.Initialize(ppc.profile.Name, ppc.profile.OnionPrivateKey))
|
||||
|
|
|
@ -74,6 +74,10 @@ func (tp *TestPeer) HandleGroupInvite(gci *protocol.GroupChatInvite) {
|
|||
tp.ReceivedGroupInvite = true
|
||||
}
|
||||
|
||||
func (tp *TestPeer) GetClientIdentityPacket() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestPeerPeerConnection(t *testing.T) {
|
||||
profile := model.GenerateNewProfile("sarah")
|
||||
ppc := NewPeerPeerConnection("127.0.0.1:5452|kwke2hntvyfqm7dr", profile)
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/s-rah/go-ricochet/channels"
|
||||
"github.com/s-rah/go-ricochet/connection"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"sync"
|
||||
)
|
||||
|
||||
|
@ -30,14 +31,26 @@ type CwtchPeer struct {
|
|||
mutex sync.Mutex
|
||||
Log chan string `json:"-"`
|
||||
connectionsManager *connections.Manager
|
||||
profilefile string
|
||||
}
|
||||
|
||||
func (cp *CwtchPeer) setup() {
|
||||
cp.Log = make(chan string)
|
||||
cp.connectionsManager = connections.NewConnectionsManager()
|
||||
cp.Init()
|
||||
|
||||
go cp.connectionsManager.AttemptReconnections()
|
||||
|
||||
for onion := range cp.Profile.Contacts {
|
||||
cp.PeerWithOnion(onion)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func NewCwtchPeer(name string) *CwtchPeer {
|
||||
cp := new(CwtchPeer)
|
||||
cp.Profile = model.GenerateNewProfile(name)
|
||||
cp.Log = make(chan string)
|
||||
cp.connectionsManager = connections.NewConnectionsManager()
|
||||
cp.Init()
|
||||
cp.setup()
|
||||
return cp
|
||||
}
|
||||
|
||||
|
@ -45,6 +58,7 @@ func (cp *CwtchPeer) Save(profilefile string) error {
|
|||
cp.mutex.Lock()
|
||||
bytes, _ := json.Marshal(cp)
|
||||
err := ioutil.WriteFile(profilefile, bytes, 0600)
|
||||
cp.profilefile = profilefile
|
||||
cp.mutex.Unlock()
|
||||
return err
|
||||
}
|
||||
|
@ -53,6 +67,8 @@ func LoadCwtchPeer(profilefile string) (*CwtchPeer, error) {
|
|||
bytes, _ := ioutil.ReadFile(profilefile)
|
||||
cp := new(CwtchPeer)
|
||||
err := json.Unmarshal(bytes, &cp)
|
||||
cp.setup()
|
||||
cp.profilefile = profilefile
|
||||
return cp, err
|
||||
}
|
||||
|
||||
|
@ -90,6 +106,10 @@ func (cp *CwtchPeer) SendMessageToGroup(groupid string, message string) {
|
|||
psc.SendGroupMessage(gm)
|
||||
}
|
||||
|
||||
func (cp *CwtchPeer) GetPeers() map[string]connections.ConnectionState {
|
||||
return cp.connectionsManager.GetPeers()
|
||||
}
|
||||
|
||||
func (cp *CwtchPeer) Listen() error {
|
||||
cwtchpeer := new(application.RicochetApplication)
|
||||
l, err := application.SetupOnion("127.0.0.1:9051", "tcp4", "", cp.Profile.OnionPrivateKey, 9878)
|
||||
|
@ -111,7 +131,7 @@ func (cp *CwtchPeer) Listen() error {
|
|||
})
|
||||
|
||||
cwtchpeer.Init(cp.Profile.OnionPrivateKey, af, new(application.AcceptAllContactManager))
|
||||
cp.Log <- "Running cwtch peer on " + l.Addr().String()
|
||||
log.Printf("Running cwtch peer on %v", l.Addr().String())
|
||||
cwtchpeer.Run(l)
|
||||
return nil
|
||||
}
|
||||
|
@ -132,8 +152,9 @@ type CwtchPeerHandler struct {
|
|||
}
|
||||
|
||||
func (cph *CwtchPeerHandler) ClientIdentity(ci *protocol.CwtchIdentity) {
|
||||
cph.Peer.Log <- "Received Client Identity from " + cph.Onion + " " + ci.String()
|
||||
log.Printf("Received Client Identity from %v %v\n", cph.Onion, ci.String())
|
||||
cph.Peer.Profile.AddCwtchIdentity(cph.Onion, ci)
|
||||
cph.Peer.Save(cph.Peer.profilefile)
|
||||
}
|
||||
|
||||
func (cph *CwtchPeerHandler) HandleGroupInvite(gci *protocol.GroupChatInvite) {
|
||||
|
@ -142,3 +163,7 @@ func (cph *CwtchPeerHandler) HandleGroupInvite(gci *protocol.GroupChatInvite) {
|
|||
|
||||
func (cph *CwtchPeerHandler) HandleGroupMessage(gm *protocol.GroupMessage) {
|
||||
}
|
||||
|
||||
func (cph *CwtchPeerHandler) GetClientIdentityPacket() []byte {
|
||||
return cph.Peer.Profile.GetCwtchIdentityPacket()
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ type CwtchPeerChannel struct {
|
|||
type CwtchPeerChannelHandler interface {
|
||||
ClientIdentity(*protocol.CwtchIdentity)
|
||||
HandleGroupInvite(*protocol.GroupChatInvite)
|
||||
GetClientIdentityPacket() []byte
|
||||
}
|
||||
|
||||
// SendMessage sends a raw message on this channel
|
||||
|
@ -99,6 +100,10 @@ func (cpc *CwtchPeerChannel) Packet(data []byte) {
|
|||
if err == nil {
|
||||
if cpp.GetCwtchIdentify() != nil {
|
||||
cpc.Handler.ClientIdentity(cpp.GetCwtchIdentify())
|
||||
pkt := cpc.Handler.GetClientIdentityPacket()
|
||||
if pkt != nil {
|
||||
cpc.SendMessage(pkt)
|
||||
}
|
||||
} else if cpp.GetGroupChatInvite() != nil {
|
||||
cpc.Handler.HandleGroupInvite(cpp.GetGroupChatInvite())
|
||||
}
|
||||
|
|
|
@ -48,6 +48,10 @@ func (th *TestHandler) HandleGroupInvite(ci *protocol.GroupChatInvite) {
|
|||
//}
|
||||
}
|
||||
|
||||
func (th *TestHandler) GetClientIdentityPacket() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestPeerChannel(t *testing.T) {
|
||||
th := new(TestHandler)
|
||||
cpc := new(CwtchPeerChannel)
|
||||
|
|
Loading…
Reference in New Issue