cwtch/app/app.go

96 lines
2.4 KiB
Go

package app
import (
"cwtch.im/cwtch/connectivity/tor"
"cwtch.im/cwtch/peer"
"errors"
"fmt"
"log"
"os"
"path"
)
// Application is a facade over a cwtchPeer that provides some wrapping logic.
type Application struct {
Peer peer.CwtchPeerInterface
TorManager *tor.Manager
directory string
}
// NewApp creates a new app with some environment awareness and initializes a Tor Manager
func NewApp(appDirectory string, torPath string) (*Application, error) {
log.Printf("NewApp(%v, %v)\n", appDirectory, torPath)
app := &Application{Peer: nil, directory: appDirectory}
os.MkdirAll(path.Join(appDirectory, "tor"), 0700)
err := app.startTor(torPath)
if err != nil {
return nil, err
}
return app, nil
}
// NewProfile creates a new cwtchPeer with a given name.
func (app *Application) NewProfile(name string, password string) error {
log.Printf("NewProfile(%v, %v)\n", name, password)
if app.Peer != nil {
return errors.New("Profile already created")
}
app.Peer = peer.NewCwtchPeer(name, password, path.Join(app.directory, name+".json"))
err := app.Peer.Save()
if err == nil {
err = app.startPeer()
}
return err
}
// startTor will create a local torrc if needed
func (app *Application) startTor(torPath string) error {
// Creating a local cwtch tor server config for the user
// creating $app.directory/torrc file
// SOCKSPort socksPort
// ControlPort controlPort
torrc := path.Join(app.directory, "tor", "torrc")
if _, err := os.Stat(torrc); os.IsNotExist(err) {
log.Printf("writing torrc to: %v\n", torrc)
file, err := os.Create(torrc)
if err != nil {
return err
}
fmt.Fprintf(file, "SOCKSPort %d\nControlPort %d\nCookieAuthentication 0\nSafeSocks 1\n", 9050, 9051)
file.Close()
}
tm, err := tor.NewTorManager(9050, 9051, torPath, torrc)
if err != nil {
return err
}
app.TorManager = tm
return nil
}
// SetProfile loads an existing profile from the given filename.
func (app *Application) SetProfile(filename string, password string) error {
profile, err := peer.LoadCwtchPeer(filename, password)
if err != nil {
return err
}
app.Peer = profile
return app.startPeer()
}
func (app *Application) startPeer() error {
go func() {
e := app.Peer.Listen()
if e != nil {
log.Panic(e)
}
}()
return nil
}
// PeerRequest attempts to setup peer relationship with the given onion address.`
func (app *Application) PeerRequest(onion string) {
app.Peer.PeerWithOnion(onion)
}