package peer import ( "encoding/json" "errors" "git.mascherari.press/cwtch/model" "git.mascherari.press/cwtch/peer/connections" "git.mascherari.press/cwtch/peer/peer" "git.mascherari.press/cwtch/protocol" "github.com/s-rah/go-ricochet/application" "github.com/s-rah/go-ricochet/channels" "github.com/s-rah/go-ricochet/connection" "io/ioutil" "sync" ) /** PeerConnectionPool Background thread running Process() Pointer to connections Move CwtchPeerChannel under peer/ Write tests for Peer Channel */ type CwtchPeer struct { connection.AutoConnectionHandler Profile *model.Profile mutex sync.Mutex Log chan string `json:"-"` connectionsManager *connections.Manager } func NewCwtchPeer(name string) *CwtchPeer { cp := new(CwtchPeer) cp.Profile = model.GenerateNewProfile(name) cp.Log = make(chan string) cp.connectionsManager = connections.NewConnectionsManager() cp.Init() return cp } func (cp *CwtchPeer) Save(profilefile string) error { cp.mutex.Lock() bytes, _ := json.Marshal(cp) err := ioutil.WriteFile(profilefile, bytes, 0600) cp.mutex.Unlock() return err } func LoadCwtchPeer(profilefile string) (*CwtchPeer, error) { bytes, _ := ioutil.ReadFile(profilefile) cp := new(CwtchPeer) err := json.Unmarshal(bytes, &cp) return cp, err } // AddContactRequest is the entry point for CwtchPeer relationships func (cp *CwtchPeer) PeerWithOnion(onion string) { cp.connectionsManager.ManagePeerConnection(onion, cp.Profile) } // InviteOnionToGroup kicks off the invite process func (cp *CwtchPeer) InviteOnionToGroup(onion string, groupid string) error { group := cp.Profile.GetGroupByGroupId(groupid) if group == nil { invite := group.Invite() ppc := cp.connectionsManager.GetPeerPeerConnectionForOnion(onion) ppc.SendGroupInvite(invite) } return errors.New("group id could not be found") } func (cp *CwtchPeer) ReceiveGroupMessage(server string, gm *protocol.GroupMessage) { cp.Profile.AttemptDecryption(gm.Ciphertext) } func (cp *CwtchPeer) JoinServer(onion string) { cp.connectionsManager.ManageServerConnection(onion, cp.ReceiveGroupMessage) } func (cp *CwtchPeer) SendMessageToGroup(groupid string, message string) { group := cp.Profile.GetGroupByGroupId(groupid) psc := cp.connectionsManager.GetPeerServerConnectionForOnion(group.GroupServer) ct, _ := cp.Profile.EncryptMessageToGroup(message, groupid) gm := &protocol.GroupMessage{ Ciphertext: ct, } psc.SendGroupMessage(gm) } func (cp *CwtchPeer) Listen() error { cwtchpeer := new(application.RicochetApplication) l, err := application.SetupOnion("127.0.0.1:9051", "tcp4", "", cp.Profile.OnionPrivateKey, 9878) if err != nil { return err } af := application.ApplicationInstanceFactory{} af.Init() af.AddHandler("im.cwtch.peer", func(rai *application.ApplicationInstance) func() channels.Handler { cpi := new(CwtchPeerInstance) cpi.Init(rai, cwtchpeer) return func() channels.Handler { cpc := new(peer.CwtchPeerChannel) cpc.Handler = &CwtchPeerHandler{Onion: rai.RemoteHostname, Peer: cp} return cpc } }) cwtchpeer.Init(cp.Profile.OnionPrivateKey, af, new(application.AcceptAllContactManager)) cp.Log <- "Running cwtch peer on " + l.Addr().String() cwtchpeer.Run(l) return nil } type CwtchPeerInstance struct { rai *application.ApplicationInstance ra *application.RicochetApplication } func (cpi *CwtchPeerInstance) Init(rai *application.ApplicationInstance, ra *application.RicochetApplication) { cpi.rai = rai cpi.ra = ra } type CwtchPeerHandler struct { Onion string Peer *CwtchPeer } func (cph *CwtchPeerHandler) ClientIdentity(ci *protocol.CwtchIdentity) { cph.Peer.Log <- "Received Client Identity from " + cph.Onion + " " + ci.String() cph.Peer.Profile.AddCwtchIdentity(cph.Onion, ci) } func (cph *CwtchPeerHandler) HandleGroupInvite(gci *protocol.GroupChatInvite) { cph.Peer.Profile.ProcessInvite(gci, cph.Onion) } func (cph *CwtchPeerHandler) HandleGroupMessage(gm *protocol.GroupMessage) { }