Large API Refactor in prep for autobindings #494

Merged
sarah merged 7 commits from autobindings into eventhooks 2023-02-28 18:09:40 +00:00
11 changed files with 297 additions and 48 deletions

View File

@ -35,14 +35,24 @@ type application struct {
settings *GlobalSettingsFile
}
func (app *application) IsFeatureEnabled(experiment string) bool {
settings := app.ReadSettings()
if settings.ExperimentsEnabled {
if status, exists := settings.Experiments[experiment]; exists {
return status
}
}
return false
}
// Application is a full cwtch peer application. It allows management, usage and storage of multiple peers
type Application interface {
LoadProfiles(password string)
CreatePeer(name string, password string, attributes map[attr.ZonedPath]string)
// Deprecated in 1.10
CreateTaggedPeer(name string, password string, tag string)
CreateProfile(name string, password string, autostart bool)
ImportProfile(exportedCwtchFile string, password string) (peer.CwtchPeer, error)
DeletePeer(onion string, currentPassword string)
EnhancedImportProfile(exportedCwtchFile string, password string) string
DeleteProfile(onion string, currentPassword string)
AddPeerPlugin(onion string, pluginID plugins.PluginID)
GetPrimaryBus() event.Manager
@ -51,11 +61,12 @@ type Application interface {
QueryACNVersion()
ActivateEngines(doListn, doPeers, doServers bool)
ActivatePeerEngine(onion string, doListen, doPeers, doServers bool)
ActivatePeerEngine(onion string)
DeactivatePeerEngine(onion string)
ReadSettings() GlobalSettings
UpdateSettings(settings GlobalSettings)
IsFeatureEnabled(experiment string) bool
ShutdownPeer(string)
Shutdown()
@ -67,8 +78,7 @@ type Application interface {
// LoadProfileFn is the function signature for a function in an app that loads a profile
type LoadProfileFn func(profile peer.CwtchPeer)
// NewApp creates a new app with some environment awareness and initializes a Tor Manager
func NewApp(acn connectivity.ACN, appDirectory string) Application {
func LoadAppSettings(appDirectory string) *GlobalSettingsFile {
log.Debugf("NewApp(%v)\n", appDirectory)
os.MkdirAll(path.Join(appDirectory, "profiles"), 0700)
@ -79,6 +89,11 @@ func NewApp(acn connectivity.ACN, appDirectory string) Application {
if err != nil {
log.Errorf("error initializing global settings file %. Global settings might not be loaded or saves", err)
}
return settings
}
// NewApp creates a new app with some environment awareness and initializes a Tor Manager
func NewApp(acn connectivity.ACN, appDirectory string, settings *GlobalSettingsFile) Application {
app := &application{engines: make(map[string]connections.Engine), eventBuses: make(map[string]event.Manager), directory: appDirectory, appBus: event.NewEventManager(), settings: settings}
app.peers = make(map[string]peer.CwtchPeer)
@ -110,6 +125,14 @@ func (app *application) UpdateSettings(settings GlobalSettings) {
defer app.peerLock.Unlock()
for _, profile := range app.peers {
profile.UpdateExperiments(settings.ExperimentsEnabled, settings.Experiments)
// Explicitly toggle blocking/unblocking of unknown connections for profiles
// that have been loaded.
if settings.BlockUnknownConnections {
profile.BlockUnknownConnections()
} else {
profile.AllowUnknownConnections()
}
}
}
@ -159,11 +182,45 @@ func (ap *application) AddPlugin(peerid string, id plugins.PluginID, bus event.M
}
}
func (app *application) CreateProfile(name string, password string, autostart bool) {
autostartVal := constants.True
if !autostart {
autostartVal = constants.False
}
tagVal := constants.ProfileTypeV1Password
if password == DefactoPasswordForUnencryptedProfiles {
tagVal = constants.ProfileTypeV1DefaultPassword
}
app.CreatePeer(name, password, map[attr.ZonedPath]string{
attr.ProfileZone.ConstructZonedPath(constants.Tag): tagVal,
attr.ProfileZone.ConstructZonedPath(constants.PeerAutostart): autostartVal,
})
}
// Deprecated in 1.10
func (app *application) CreateTaggedPeer(name string, password string, tag string) {
app.CreatePeer(name, password, map[attr.ZonedPath]string{attr.ProfileZone.ConstructZonedPath(constants.Tag): tag})
}
func (app *application) setupPeer(profile peer.CwtchPeer) {
eventBus := event.NewEventManager()
app.eventBuses[profile.GetOnion()] = eventBus
// Initialize the Peer with the Given Event Bus
app.peers[profile.GetOnion()] = profile
profile.Init(app.eventBuses[profile.GetOnion()])
// Update the Peer with the Most Recent Experiment State...
settings := app.settings.ReadGlobalSettings()
profile.UpdateExperiments(settings.ExperimentsEnabled, settings.Experiments)
app.registerHooks(profile)
// Register the Peer With Application Plugins..
app.AddPeerPlugin(profile.GetOnion(), plugins.CONNECTIONRETRY) // Now Mandatory
}
func (app *application) CreatePeer(name string, password string, attributes map[attr.ZonedPath]string) {
app.appmutex.Lock()
defer app.appmutex.Unlock()
@ -177,26 +234,26 @@ func (app *application) CreatePeer(name string, password string, attributes map[
return
}
eventBus := event.NewEventManager()
app.eventBuses[profile.GetOnion()] = eventBus
profile.Init(app.eventBuses[profile.GetOnion()])
app.registerHooks(profile)
app.peers[profile.GetOnion()] = profile
app.setupPeer(profile)
for zp, val := range attributes {
zone, key := attr.ParseZone(zp.ToString())
profile.SetScopedZonedAttribute(attr.LocalScope, zone, key, val)
}
app.AddPeerPlugin(profile.GetOnion(), plugins.CONNECTIONRETRY) // Now Mandatory
app.appBus.Publish(event.NewEvent(event.NewPeer, map[event.Field]string{event.Identity: profile.GetOnion(), event.Created: event.True}))
}
func (app *application) DeletePeer(onion string, password string) {
log.Debugf("DeletePeer called on %v\n", onion)
func (app *application) DeleteProfile(onion string, password string) {
log.Debugf("DeleteProfile called on %v\n", onion)
app.appmutex.Lock()
defer app.appmutex.Unlock()
// allow a blank password to delete "unencrypted" accounts...
if password == "" {
password = DefactoPasswordForUnencryptedProfiles
}
if app.peers[onion].CheckPassword(password) {
// soft-shutdown
app.peers[onion].Shutdown()
@ -226,6 +283,14 @@ func (app *application) ImportProfile(exportedCwtchFile string, password string)
return profile, err
}
func (app *application) EnhancedImportProfile(exportedCwtchFile string, password string) string {
_, err := app.ImportProfile(exportedCwtchFile, password)
if err == nil {
return ""
}
return err.Error()
}
// LoadProfiles takes a password and attempts to load any profiles it can from storage with it and create Peers for them
func (app *application) LoadProfiles(password string) {
count := 0
@ -291,14 +356,8 @@ func (app *application) installProfile(profile peer.CwtchPeer) bool {
// Only attempt to finalize the profile if we don't have one loaded...
if app.peers[profile.GetOnion()] == nil {
eventBus := event.NewEventManager()
app.eventBuses[profile.GetOnion()] = eventBus
profile.Init(app.eventBuses[profile.GetOnion()])
app.registerHooks(profile)
app.peers[profile.GetOnion()] = profile
app.AddPeerPlugin(profile.GetOnion(), plugins.CONNECTIONRETRY) // Now Mandatory
app.setupPeer(profile)
// Finalize the Creation of Peer / Notify any Interfaces..
app.appBus.Publish(event.NewEvent(event.NewPeer, map[event.Field]string{event.Identity: profile.GetOnion(), event.Created: event.False}))
return true
}
@ -333,7 +392,7 @@ func (app *application) ActivateEngines(doListen, doPeers, doServers bool) {
}
// ActivePeerEngine creates a peer engine for use with an ACN, should be called once the underlying ACN is online
func (app *application) ActivatePeerEngine(onion string, doListen, doPeers, doServers bool) {
func (app *application) ActivatePeerEngine(onion string) {
profile := app.GetPeer(onion)
if profile != nil {
if _, exists := app.engines[onion]; !exists {
@ -341,10 +400,10 @@ func (app *application) ActivatePeerEngine(onion string, doListen, doPeers, doSe
app.eventBuses[profile.GetOnion()].Publish(event.NewEventList(event.ProtocolEngineCreated))
app.QueryACNStatus()
if doListen {
if true {
profile.Listen()
}
profile.StartConnections(doPeers, doServers)
profile.StartConnections(true, true)
}
}
}

View File

@ -228,7 +228,8 @@ type Field string
const (
// A peers local onion address
Onion = Field("Onion")
Onion = Field("Onion")
ProfileOnion = Field("ProfileOnion")
RemotePeer = Field("RemotePeer")
LastSeen = Field("LastSeen")

View File

@ -178,6 +178,65 @@ func (om *OverlayMessage) ShouldAutoDL() bool {
return false
}
func (f *Functionality) VerifyOrResumeDownload(profile peer.CwtchPeer, conversation int, fileKey string) {
if manifestFilePath, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.manifest", fileKey)); exists {
if downloadfilepath, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.path", fileKey)); exists {
log.Debugf("resuming %s", fileKey)
f.DownloadFile(profile, conversation, downloadfilepath, manifestFilePath, fileKey, files.MaxManifestSize*files.DefaultChunkSize)
} else {
log.Errorf("found manifest path but not download path for %s", fileKey)
}
} else {
log.Errorf("no stored manifest path found for %s", fileKey)
}
}
func (f *Functionality) CheckDownloadStatus(profile peer.CwtchPeer, fileKey string) {
path, _ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.path", fileKey))
if value, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.complete", fileKey)); exists && value == event.True {
profile.PublishEvent(event.NewEvent(event.FileDownloaded, map[event.Field]string{
event.ProfileOnion: profile.GetOnion(),
event.FileKey: fileKey,
event.FilePath: path,
event.TempFile: "",
}))
} else {
log.Debugf("CheckDownloadStatus found .path but not .complete")
profile.PublishEvent(event.NewEvent(event.FileDownloadProgressUpdate, map[event.Field]string{
event.ProfileOnion: profile.GetOnion(),
event.FileKey: fileKey,
event.Progress: "-1",
event.FileSizeInChunks: "-1",
event.FilePath: path,
}))
}
}
func (f *Functionality) EnhancedShareFile(profile peer.CwtchPeer, conversationID int, sharefilepath string) string {
fileKey, overlay, err := f.ShareFile(sharefilepath, profile)
if err != nil {
log.Errorf("error sharing file: %v", err)
} else if conversationID == -1 {
// FIXME: At some point we might want to allow arbitrary public files, but for now this API will assume
// there is only one, and it is the custom profile image...
profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.CustomProfileImageKey, fileKey)
} else {
// Set a new attribute so we can associate this download with this conversation...
profile.SetConversationAttribute(conversationID, attr.ConversationScope.ConstructScopedZonedPath(attr.FilesharingZone.ConstructZonedPath(fileKey)), "")
id, err := profile.SendMessage(conversationID, overlay)
if err == nil {
return profile.EnhancedGetMessageById(conversationID, id)
}
}
return ""
}
// DownloadFileDefaultLimit given a profile, a conversation handle and a file sharing key, start off a download process
// to downloadFilePath with a default filesize limit
func (f *Functionality) DownloadFileDefaultLimit(profile peer.CwtchPeer, conversationID int, downloadFilePath string, manifestFilePath string, key string) error {
return f.DownloadFile(profile, conversationID, downloadFilePath, manifestFilePath, key, files.MaxManifestSize*files.DefaultChunkSize)
}
// DownloadFile given a profile, a conversation handle and a file sharing key, start off a download process
// to downloadFilePath
func (f *Functionality) DownloadFile(profile peer.CwtchPeer, conversationID int, downloadFilePath string, manifestFilePath string, key string, limit uint64) error {
@ -409,6 +468,14 @@ type SharedFile struct {
Expired bool
}
func (f *Functionality) EnhancedGetSharedFiles(profile peer.CwtchPeer, conversationID int) string {
data, err := json.Marshal(f.GetSharedFiles(profile, conversationID))
if err == nil {
return string(data)
}
return ""
}
// GetSharedFiles returns all file shares associated with a given conversation
func (f *Functionality) GetSharedFiles(profile peer.CwtchPeer, conversationID int) []SharedFile {
sharedFiles := []SharedFile{}

View File

@ -56,3 +56,5 @@ const SyncPreLastMessageTime = "SyncPreLastMessageTime"
const SyncMostRecentMessageTime = "SyncMostRecentMessageTime"
const AttrLastConnectionTime = "last-connection-time"
const PeerAutostart = "autostart"
const Archived = "archived"

View File

@ -1,10 +1,13 @@
package model
import "sync"
// Experiments are optional functionality that can be enabled/disabled by an application either completely or individually.
// examples of experiments include File Sharing, Profile Images and Groups.
type Experiments struct {
enabled bool
experiments map[string]bool
lock sync.Mutex
}
// InitExperiments encapsulates a set of experiments separate from their storage in GlobalSettings.
@ -24,6 +27,10 @@ func (e *Experiments) IsEnabled(experiment string) bool {
// todo handle default-enabled functionality
return false
}
// go will sometimes panic if we do not lock this read-only map...
e.lock.Lock()
defer e.lock.Unlock()
enabled, exists := e.experiments[experiment]
if !exists {
return false

View File

@ -75,6 +75,94 @@ type cwtchPeer struct {
experimentsLock sync.Mutex
}
func (cp *cwtchPeer) EnhancedImportBundle(importString string) string {
sarah marked this conversation as resolved
Review

what's this for? Seems a weird "enhancement" that doesnt return an error just the string of the error?

what's this for? Seems a weird "enhancement" that doesnt return an error just the string of the error?
return cp.ImportBundle(importString).Error()
}
func (cp *cwtchPeer) EnhancedGetMessages(conversation int, index int, count int) string {
var emessages []EnhancedMessage = make([]EnhancedMessage, count)
messages, err := cp.GetMostRecentMessages(conversation, 0, index, count)
if err == nil {
for i, message := range messages {
time, _ := time.Parse(time.RFC3339Nano, message.Attr[constants.AttrSentTimestamp])
emessages[i].Message = model.Message{
Message: message.Body,
Acknowledged: message.Attr[constants.AttrAck] == constants.True,
Error: message.Attr[constants.AttrErr],
PeerID: message.Attr[constants.AttrAuthor],
Timestamp: time,
}
emessages[i].ID = message.ID
emessages[i].Attributes = message.Attr
emessages[i].ContentHash = model.CalculateContentHash(message.Attr[constants.AttrAuthor], message.Body)
}
}
bytes, _ := json.Marshal(emessages)
return string(bytes)
}
func (cp *cwtchPeer) EnhancedGetMessageById(conversation int, messageID int) string {
var message EnhancedMessage
dbmessage, attr, err := cp.GetChannelMessage(conversation, 0, messageID)
if err == nil {
time, _ := time.Parse(time.RFC3339Nano, attr[constants.AttrSentTimestamp])
message.Message = model.Message{
Message: dbmessage,
Acknowledged: attr[constants.AttrAck] == constants.True,
Error: attr[constants.AttrErr],
PeerID: attr[constants.AttrAuthor],
Timestamp: time,
}
message.ID = messageID
message.Attributes = attr
message.ContentHash = model.CalculateContentHash(attr[constants.AttrAuthor], dbmessage)
}
bytes, _ := json.Marshal(message)
return string(bytes)
}
func (cp *cwtchPeer) EnhancedGetMessageByContentHash(conversation int, contentHash string) string {
var message EnhancedMessage
offset, err := cp.GetChannelMessageByContentHash(conversation, 0, contentHash)
if err == nil {
messages, err := cp.GetMostRecentMessages(conversation, 0, offset, 1)
if err == nil {
time, _ := time.Parse(time.RFC3339Nano, messages[0].Attr[constants.AttrSentTimestamp])
message.Message = model.Message{
Message: messages[0].Body,
Acknowledged: messages[0].Attr[constants.AttrAck] == constants.True,
Error: messages[0].Attr[constants.AttrErr],
PeerID: messages[0].Attr[constants.AttrAuthor],
Timestamp: time,
}
message.ID = messages[0].ID
message.Attributes = messages[0].Attr
message.LocalIndex = offset
message.ContentHash = contentHash
} else {
log.Errorf("error fetching local index {} ", err)
}
}
bytes, _ := json.Marshal(message)
return string(bytes)
}
func (cp *cwtchPeer) EnhancedSendMessage(conversation int, message string) string {
mid, err := cp.SendMessage(conversation, message)
if err == nil {
return cp.EnhancedGetMessageById(conversation, mid)
}
return ""
}
func (cp *cwtchPeer) ArchiveConversation(conversationID int) {
cp.SetConversationAttribute(conversationID, attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(constants.Archived)), constants.True)
}
// IsFeatureEnabled returns true if the functionality defined by featureName has been enabled by the application, false otherwise.
// this function is intended to be used by ProfileHooks to determine if they should execute experimental functionality.
func (cp *cwtchPeer) IsFeatureEnabled(featureName string) bool {
@ -119,7 +207,7 @@ func (cp *cwtchPeer) StoreCachedTokens(tokenServer string, tokens []*privacypass
}
}
func (cp *cwtchPeer) Export(file string) error {
func (cp *cwtchPeer) ExportProfile(file string) error {
cp.mutex.Lock()
defer cp.mutex.Unlock()
return cp.storage.Export(file)

View File

@ -48,6 +48,10 @@ type ModifyServers interface {
// SendMessages enables a caller to sender messages to a contact
type SendMessages interface {
SendMessage(conversation int, message string) (int, error)
// EnhancedSendMessage Attempts to Send a Message and Immediately Attempts to Lookup the Message in the Database
EnhancedSendMessage(conversation int, message string) string
SendInviteToConversation(conversationID int, inviteConversationID int) (int, error)
SendScopedZonedGetValToContact(conversationID int, scope attr.Scope, zone attr.Zone, key string)
}
@ -101,10 +105,12 @@ type CwtchPeer interface {
// Import Bundle
ImportBundle(string) error
EnhancedImportBundle(string) string
// New Unified Conversation Interfaces
NewContactConversation(handle string, acl model.AccessControl, accepted bool) (int, error)
FetchConversations() ([]*model.Conversation, error)
ArchiveConversation(conversation int)
GetConversationInfo(conversation int) (*model.Conversation, error)
FetchConversationInfo(handle string) (*model.Conversation, error)
AcceptConversation(conversation int) error
@ -121,6 +127,15 @@ type CwtchPeer interface {
GetMostRecentMessages(conversation int, channel int, offset int, limit int) ([]model.ConversationMessage, error)
UpdateMessageAttribute(conversation int, channel int, id int, key string, value string) error
// EnhancedGetMessageById returns a json-encoded enhanced message, suitable for rendering in a UI
EnhancedGetMessageById(conversation int, mid int) string
sarah marked this conversation as resolved
Review

ah by enhanced you mean with all the extra stuff lg was injecting? i slightly like the term "enriched" or possibly something else? but enhanced more or less conveys the same too, to preference or taste i guess :)

ah by enhanced you mean with all the extra stuff lg was injecting? i slightly like the term "enriched" or possibly something else? but enhanced more or less conveys the same too, to preference or taste i guess :)
// EnhancedGetMessageByContentHash returns a json-encoded enhanced message, suitable for rendering in a UI
EnhancedGetMessageByContentHash(conversation int, hash string) string
// EnhancedGetMessages returns a set of json-encoded enhanced messages, suitable for rendering in a UI
EnhancedGetMessages(conversation int, index int, count int) string
// Server Token APIS
// TODO move these to feature protected interfaces
StoreCachedTokens(tokenServer string, tokens []*privacypass.Token)
@ -128,10 +143,20 @@ type CwtchPeer interface {
// Profile Management
CheckPassword(password string) bool
ChangePassword(oldpassword string, newpassword string, newpasswordAgain string) error
Export(file string) error
ExportProfile(file string) error
Delete()
PublishEvent(resp event.Event)
RegisterHook(hook ProfileHooks)
UpdateExperiments(enabled bool, experiments map[string]bool)
IsFeatureEnabled(featureName string) bool
}
// EnhancedMessage wraps a Cwtch model.Message with some additional data to reduce calls from the UI.
type EnhancedMessage struct {
model.Message
ID int // the actual ID of the message in the database (not the row number)
LocalIndex int // local index in the DB (row #). Can be empty (most calls supply it) but lookup by hash will fill it
ContentHash string
ContactImage string
Attributes map[string]string
}

View File

@ -34,7 +34,7 @@ func (fsss *FileSharingSubSystem) ShareFile(fileKey string, serializedManifest s
log.Errorf("could not share file %v", err)
return
}
log.Debugf("sharing file: %v %v", fileKey, serializedManifest)
log.Infof("sharing file: %v %v", fileKey, serializedManifest)
sarah marked this conversation as resolved
Review

debug?

debug?
fsss.activeShares.Store(fileKey, &manifest)
}

View File

@ -139,7 +139,7 @@ func TestCwtchPeerIntegration(t *testing.T) {
const ServerAddr = "nfhxzvzxinripgdh4t2m4xcy3crf6p4cbhectgckuj3idsjsaotgowad"
serverKeyBundle, _ := base64.StdEncoding.DecodeString(ServerKeyBundleBase64)
app := app2.NewApp(acn, "./storage")
app := app2.NewApp(acn, "./storage", app2.InitApp("./storage"))
usr, _ := user.Current()
cwtchDir := path.Join(usr.HomeDir, ".cwtch")
@ -152,31 +152,31 @@ func TestCwtchPeerIntegration(t *testing.T) {
// ***** cwtchPeer setup *****
log.Infoln("Creating Alice...")
app.CreateTaggedPeer("Alice", "asdfasdf", "test")
app.CreateProfile("Alice", "asdfasdf", true)
log.Infoln("Creating Bob...")
app.CreateTaggedPeer("Bob", "asdfasdf", "test")
app.CreateProfile("Bob", "asdfasdf", true)
log.Infoln("Creating Carol...")
app.CreateTaggedPeer("Carol", "asdfasdf", "test")
app.CreateProfile("Carol", "asdfasdf", true)
alice := app2.WaitGetPeer(app, "Alice")
aliceBus := app.GetEventBus(alice.GetOnion())
app.ActivatePeerEngine(alice.GetOnion(), true, true, true)
app.ActivatePeerEngine(alice.GetOnion())
log.Infoln("Alice created:", alice.GetOnion())
alice.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, "Alice")
alice.AutoHandleEvents([]event.Type{event.PeerStateChange, event.ServerStateChange, event.NewGroupInvite, event.NewRetValMessageFromPeer})
bob := app2.WaitGetPeer(app, "Bob")
bobBus := app.GetEventBus(bob.GetOnion())
app.ActivatePeerEngine(bob.GetOnion(), true, true, true)
app.ActivatePeerEngine(bob.GetOnion())
log.Infoln("Bob created:", bob.GetOnion())
bob.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, "Bob")
bob.AutoHandleEvents([]event.Type{event.PeerStateChange, event.ServerStateChange, event.NewGroupInvite, event.NewRetValMessageFromPeer})
carol := app2.WaitGetPeer(app, "Carol")
carolBus := app.GetEventBus(carol.GetOnion())
app.ActivatePeerEngine(carol.GetOnion(), true, true, true)
app.ActivatePeerEngine(carol.GetOnion())
log.Infoln("Carol created:", carol.GetOnion())
carol.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, "Carol")
carol.AutoHandleEvents([]event.Type{event.PeerStateChange, event.ServerStateChange, event.NewGroupInvite, event.NewRetValMessageFromPeer})

View File

@ -59,9 +59,9 @@ func TestEncryptedStorage(t *testing.T) {
defer acn.Close()
acn.WaitTillBootstrapped()
app := app2.NewApp(acn, cwtchDir)
app.CreateTaggedPeer("alice", "password", constants.ProfileTypeV1Password)
app.CreateTaggedPeer("bob", "password", constants.ProfileTypeV1Password)
app := app2.NewApp(acn, cwtchDir, app2.InitApp(cwtchDir))
app.CreateProfile("alice", "password", true)
app.CreateProfile("bob", "password", true)
alice := app2.WaitGetPeer(app, "alice")
bob := app2.WaitGetPeer(app, "bob")
@ -130,7 +130,7 @@ func TestEncryptedStorage(t *testing.T) {
t.Fatalf("expeced GetMostRecentMessages to return 1, instead returned: %v %v", len(messages), messages)
}
err = alice.Export("alice.tar.gz")
err = alice.ExportProfile("alice.tar.gz")
if err != nil {
t.Fatalf("could not export profile: %v", err)
}
@ -140,7 +140,7 @@ func TestEncryptedStorage(t *testing.T) {
t.Fatal("profile is already imported...this should fail")
}
app.DeletePeer(alice.GetOnion(), "password")
app.DeleteProfile(alice.GetOnion(), "password")
alice, err = app.ImportProfile("alice.tar.gz", "password")
if err != nil {
t.Fatalf("profile should have successfully imported: %s", err)

View File

@ -97,7 +97,7 @@ func TestFileSharing(t *testing.T) {
acn.WaitTillBootstrapped()
defer acn.Close()
app := app2.NewApp(acn, "./storage")
app := app2.NewApp(acn, "./storage", app2.InitApp("./storage"))
usr, _ := user.Current()
cwtchDir := path.Join(usr.HomeDir, ".cwtch")
@ -106,16 +106,16 @@ func TestFileSharing(t *testing.T) {
os.Mkdir(path.Join(cwtchDir, "testing"), 0700)
t.Logf("Creating Alice...")
app.CreateTaggedPeer("alice", "asdfasdf", "testing")
app.CreateProfile("alice", "asdfasdf", true)
t.Logf("Creating Bob...")
app.CreateTaggedPeer("bob", "asdfasdf", "testing")
app.CreateProfile("bob", "asdfasdf", true)
t.Logf("** Waiting for Alice, Bob...")
alice := app2.WaitGetPeer(app, "alice")
app.ActivatePeerEngine(alice.GetOnion(), true, true, true)
app.ActivatePeerEngine(alice.GetOnion())
bob := app2.WaitGetPeer(app, "bob")
app.ActivatePeerEngine(bob.GetOnion(), true, true, true)
app.ActivatePeerEngine(bob.GetOnion())
alice.AutoHandleEvents([]event.Type{event.PeerStateChange, event.NewRetValMessageFromPeer})
bob.AutoHandleEvents([]event.Type{event.PeerStateChange, event.NewRetValMessageFromPeer})
@ -178,7 +178,7 @@ func TestFileSharing(t *testing.T) {
testBobDownloadFile(t, bob, filesharingFunctionality, queueOracle)
// test that we can delete bob...
app.DeletePeer(bob.GetOnion(), "asdfasdf")
app.DeleteProfile(bob.GetOnion(), "asdfasdf")
queueOracle.Shutdown()
app.Shutdown()