128 lines
3.9 KiB
Go
128 lines
3.9 KiB
Go
|
package encryptedstorage
|
||
|
|
||
|
import (
|
||
|
"crypto/rand"
|
||
|
app2 "cwtch.im/cwtch/app"
|
||
|
"cwtch.im/cwtch/app/utils"
|
||
|
"cwtch.im/cwtch/model"
|
||
|
"cwtch.im/cwtch/model/constants"
|
||
|
"cwtch.im/cwtch/peer"
|
||
|
"encoding/base64"
|
||
|
"fmt"
|
||
|
"git.openprivacy.ca/openprivacy/connectivity/tor"
|
||
|
"git.openprivacy.ca/openprivacy/log"
|
||
|
mrand "math/rand"
|
||
|
"os"
|
||
|
"path"
|
||
|
"path/filepath"
|
||
|
"testing"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
func TestEncryptedStorage(t *testing.T) {
|
||
|
|
||
|
os.Mkdir("tordir", 0700)
|
||
|
dataDir := filepath.Join("tordir", "tor")
|
||
|
os.MkdirAll(dataDir, 0700)
|
||
|
|
||
|
// we don't need real randomness for the port, just to avoid a possible conflict...
|
||
|
mrand.Seed(int64(time.Now().Nanosecond()))
|
||
|
socksPort := mrand.Intn(1000) + 9051
|
||
|
controlPort := mrand.Intn(1000) + 9052
|
||
|
|
||
|
// generate a random password
|
||
|
key := make([]byte, 64)
|
||
|
_, err := rand.Read(key)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
tor.NewTorrc().WithSocksPort(socksPort).WithOnionTrafficOnly().WithHashedPassword(base64.StdEncoding.EncodeToString(key)).WithControlPort(controlPort).Build("tordir/tor/torrc")
|
||
|
acn, err := tor.NewTorACNWithAuth("./tordir", path.Join("..", "..", "tor"), controlPort, tor.HashedPasswordAuthenticator{Password: base64.StdEncoding.EncodeToString(key)})
|
||
|
if err != nil {
|
||
|
t.Fatalf("Could not start Tor: %v", err)
|
||
|
}
|
||
|
|
||
|
cwtchDir := path.Join(".", "encrypted_storage_profiles")
|
||
|
os.RemoveAll(cwtchDir)
|
||
|
os.Mkdir(cwtchDir, 0700)
|
||
|
|
||
|
fmt.Println("Creating Alice...")
|
||
|
|
||
|
log.SetLevel(log.LevelDebug)
|
||
|
defer acn.Close()
|
||
|
acn.WaitTillBootstrapped()
|
||
|
app := app2.NewApp(acn, cwtchDir)
|
||
|
app.CreateTaggedPeer("alice", "password", constants.ProfileTypeV1Password)
|
||
|
app.CreateTaggedPeer("bob", "password", constants.ProfileTypeV1Password)
|
||
|
|
||
|
alice := utils.WaitGetPeer(app, "alice")
|
||
|
bob := utils.WaitGetPeer(app, "bob")
|
||
|
|
||
|
alice.Listen()
|
||
|
bob.Listen()
|
||
|
|
||
|
// To keep this large test organized, we will break it down into sub tests...
|
||
|
subTestAliceAddAndDeleteBob(t, alice, bob)
|
||
|
|
||
|
alice.PeerWithOnion(bob.GetOnion())
|
||
|
|
||
|
time.Sleep(time.Second * 30)
|
||
|
|
||
|
alice.SendMessage(bob.GetOnion(), "Hello Bob")
|
||
|
time.Sleep(time.Second * 30)
|
||
|
|
||
|
ci,_ := bob.FetchConversationInfo(alice.GetOnion())
|
||
|
body, _, err := bob.GetChannelMessage(ci.ID, 0, 1)
|
||
|
if body != "Hello Bob" || err != nil {
|
||
|
t.Fatalf("unexpected message in conversation channel %v %v", body, err)
|
||
|
} else {
|
||
|
t.Logf("succesfully found message in conversation channel %v", body)
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// Sub Test testing that Alice can add Bob, delete the conversation associated with Bob, and then add Bob again
|
||
|
// Under a different conversation identifier.
|
||
|
func subTestAliceAddAndDeleteBob(t *testing.T, alice peer.CwtchPeer, bob peer.CwtchPeer) {
|
||
|
|
||
|
t.Logf("Starting Sub Test AliceAddAndDeleteBob")
|
||
|
|
||
|
alice.NewContactConversation(bob.GetOnion(), model.AccessControl{Read: true, Append: true, Blocked: false}, true)
|
||
|
|
||
|
// Test Basic Fetching
|
||
|
bobCI, err := alice.FetchConversationInfo(bob.GetOnion())
|
||
|
if bobCI == nil || err != nil {
|
||
|
t.Fatalf("alice should have been able to fetch bobs conversationf info ci:%v err:%v", bobCI, err)
|
||
|
} else {
|
||
|
t.Logf("Bobs Conversation Info fetched successfully: %v", bobCI)
|
||
|
}
|
||
|
|
||
|
oldID := bobCI.ID
|
||
|
|
||
|
alice.DeleteConversation(bob.GetOnion())
|
||
|
|
||
|
// Test Basic Fetching
|
||
|
bobCI, err = alice.FetchConversationInfo(bob.GetOnion())
|
||
|
if bobCI != nil {
|
||
|
t.Fatalf("alice should **not** have been able to fetch bobs conversationf info ci:%v err:%v", bobCI, err)
|
||
|
} else {
|
||
|
t.Logf("expected error fetching deleted conversation info: %v", err)
|
||
|
}
|
||
|
|
||
|
alice.NewContactConversation(bob.GetOnion(), model.AccessControl{Read: true, Append: true, Blocked: false}, true)
|
||
|
|
||
|
// Test Basic Fetching
|
||
|
bobCI, err = alice.FetchConversationInfo(bob.GetOnion())
|
||
|
if bobCI == nil || err != nil {
|
||
|
t.Fatalf("alice should have been able to fetch bobs conversationf info ci:%v err:%v", bobCI, err)
|
||
|
} else {
|
||
|
t.Logf("Bobs Conversation Info fetched successfully: %v", bobCI)
|
||
|
}
|
||
|
|
||
|
if oldID == bobCI.ID {
|
||
|
t.Fatalf("bob should have a different conversation ID. Instead it is the same as the old conversation id, meaning something has gone wrong in the storage engine.")
|
||
|
}
|
||
|
|
||
|
}
|