Merge pull request 'Small Fixups' (#409) from p2p-interim-new-storage into master
Reviewed-on: #409
This commit is contained in:
commit
18280adf14
|
@ -113,9 +113,13 @@ func (ap *appletPlugins) AddPlugin(peerid string, id plugins.PluginID, bus event
|
|||
pluginsinf, _ := ap.plugins.Load(peerid)
|
||||
peerPlugins := pluginsinf.([]plugins.Plugin)
|
||||
|
||||
newp := plugins.Get(id, bus, acn, peerid)
|
||||
newp.Start()
|
||||
peerPlugins = append(peerPlugins, newp)
|
||||
log.Debugf("storing plugin for %v %v", peerid, peerPlugins)
|
||||
ap.plugins.Store(peerid, peerPlugins)
|
||||
newp, err := plugins.Get(id, bus, acn, peerid)
|
||||
if err == nil {
|
||||
newp.Start()
|
||||
peerPlugins = append(peerPlugins, newp)
|
||||
log.Debugf("storing plugin for %v %v", peerid, peerPlugins)
|
||||
ap.plugins.Store(peerid, peerPlugins)
|
||||
} else {
|
||||
log.Errorf("error adding plugin: %v", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package plugins
|
|||
|
||||
import (
|
||||
"cwtch.im/cwtch/event"
|
||||
"fmt"
|
||||
"git.openprivacy.ca/openprivacy/connectivity"
|
||||
)
|
||||
|
||||
|
@ -21,13 +22,13 @@ type Plugin interface {
|
|||
}
|
||||
|
||||
// Get is a plugin factory for the requested plugin
|
||||
func Get(id PluginID, bus event.Manager, acn connectivity.ACN, onion string) Plugin {
|
||||
func Get(id PluginID, bus event.Manager, acn connectivity.ACN, onion string) (Plugin, error) {
|
||||
switch id {
|
||||
case CONNECTIONRETRY:
|
||||
return NewConnectionRetry(bus, onion)
|
||||
return NewConnectionRetry(bus, onion), nil
|
||||
case NETWORKCHECK:
|
||||
return NewNetworkCheck(bus, acn)
|
||||
return NewNetworkCheck(bus, acn), nil
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil, fmt.Errorf("plugin not defined %v", id)
|
||||
}
|
||||
|
|
|
@ -78,21 +78,3 @@ func (scope Scope) IsPublic() bool {
|
|||
func (scope Scope) IsConversation() bool {
|
||||
return scope == ConversationScope
|
||||
}
|
||||
|
||||
// GetLocalScope takes a path and attaches the local scope to it
|
||||
// Deprecated: Use ConstructScopedZonedPath
|
||||
func GetLocalScope(path string) string {
|
||||
return string(LocalScope) + Separator + path
|
||||
}
|
||||
|
||||
// GetPublicScope takes a path and attaches the local scope to it
|
||||
// Deprecated: Use ConstructScopedZonedPath
|
||||
func GetPublicScope(path string) string {
|
||||
return string(PublicScope) + Separator + path
|
||||
}
|
||||
|
||||
// GetPeerScope takes a path and attaches the peer scope to it
|
||||
// Deprecated: Use ConstructScopedZonedPath
|
||||
func GetPeerScope(path string) string {
|
||||
return string(PeerScope) + Separator + path
|
||||
}
|
||||
|
|
|
@ -421,7 +421,6 @@ func (cp *cwtchPeer) AutoHandleEvents(events []event.Type) {
|
|||
}
|
||||
|
||||
// ImportGroup initializes a group from an imported source rather than a peer invite
|
||||
// Status: TODO
|
||||
func (cp *cwtchPeer) ImportGroup(exportedInvite string) (int, error) {
|
||||
gci, err := model.ValidateInvite(exportedInvite)
|
||||
if err != nil {
|
||||
|
@ -640,7 +639,7 @@ func (cp *cwtchPeer) AddServer(serverSpecification string) (string, error) {
|
|||
val, exists := conversationInfo.Attributes[k]
|
||||
if exists {
|
||||
if val != v {
|
||||
// this is inconsistent!
|
||||
// the keybundle is inconsistent!
|
||||
return "", model.InconsistentKeyBundleError
|
||||
}
|
||||
}
|
||||
|
@ -761,7 +760,7 @@ func (cp *cwtchPeer) SendInviteToConversation(conversationID int, inviteConversa
|
|||
return errors.New("server bundle not found")
|
||||
}
|
||||
|
||||
invite = model.MessageWrapper{Overlay: model.OverlayInviteContact, Data: fmt.Sprintf("tofubundle:server:%s||%s", base64.StdEncoding.EncodeToString([]byte(bundle)), groupInvite)}
|
||||
invite = model.MessageWrapper{Overlay: model.OverlayInviteGroup, Data: fmt.Sprintf("tofubundle:server:%s||%s", base64.StdEncoding.EncodeToString([]byte(bundle)), groupInvite)}
|
||||
}
|
||||
|
||||
inviteBytes, err := json.Marshal(invite)
|
||||
|
@ -961,7 +960,7 @@ func (cp *cwtchPeer) eventHandler() {
|
|||
// it learns nothing else about each connection).
|
||||
// store the base64 encoded signature for later use
|
||||
|
||||
// TODO Server Connections should sent Connection ID
|
||||
// TODO Server Connections should send Connection ID
|
||||
ci, err := cp.FetchConversationInfo(ev.Data[event.GroupServer])
|
||||
if ci == nil || err != nil {
|
||||
log.Errorf("no server connection count")
|
||||
|
|
|
@ -28,7 +28,7 @@ func TestManifest(t *testing.T) {
|
|||
|
||||
t.Logf("%v", manifest)
|
||||
|
||||
// Try to tread the chunk
|
||||
// Try to read the chunk
|
||||
_, err = manifest.GetChunkBytes(1)
|
||||
if err == nil {
|
||||
t.Fatalf("chunk fetch should have thrown an error")
|
||||
|
@ -43,6 +43,11 @@ func TestManifest(t *testing.T) {
|
|||
t.Fatalf("chunk fetch error: %v", err)
|
||||
}
|
||||
|
||||
_, err = manifest.GetChunkBytes(0)
|
||||
if err != nil {
|
||||
t.Fatalf("chunk fetch error: %v", err)
|
||||
}
|
||||
|
||||
json, _ := json.Marshal(manifest)
|
||||
t.Logf("%s", json)
|
||||
|
||||
|
@ -112,7 +117,20 @@ func TestManifestLarge(t *testing.T) {
|
|||
t.Fatalf("could not store chunk %v %v", i, err)
|
||||
}
|
||||
|
||||
// Attempt to store the chunk in an invalid position...
|
||||
_, err = cwtchPngOutManifest.StoreChunk(uint64(i+1), contents)
|
||||
if err == nil {
|
||||
t.Fatalf("incorrect chunk store")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Attempt to store an invalid chunk...should trigger an error
|
||||
_, err = cwtchPngOutManifest.StoreChunk(uint64(len(cwtchPngManifest.Chunks)), []byte{0xff})
|
||||
if err == nil {
|
||||
t.Fatalf("incorrect chunk store")
|
||||
}
|
||||
|
||||
err = cwtchPngOutManifest.VerifyFile()
|
||||
if err != nil {
|
||||
t.Fatalf("could not verify file %v", err)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package storage
|
||||
|
||||
import (
|
||||
"cwtch.im/cwtch/event"
|
||||
"cwtch.im/cwtch/model"
|
||||
"cwtch.im/cwtch/storage/v1"
|
||||
)
|
||||
|
@ -9,14 +8,6 @@ import (
|
|||
// ProfileStore is an interface to managing the storage of Cwtch Profiles
|
||||
type ProfileStore interface {
|
||||
GetProfileCopy(timeline bool) *model.Profile
|
||||
GetNewPeerMessage() *event.Event
|
||||
CheckPassword(string) bool
|
||||
}
|
||||
|
||||
// CreateProfileWriterStore creates a profile store backed by a filestore listening for events and saving them
|
||||
// directory should be $appDir/profiles/$rand
|
||||
func CreateProfileWriterStore(eventManager event.Manager, directory, password string, profile *model.Profile) ProfileStore {
|
||||
return v1.CreateProfileWriterStore(eventManager, directory, password, profile)
|
||||
}
|
||||
|
||||
// LoadProfileWriterStore loads a profile store from filestore listening for events and saving them
|
||||
|
@ -24,12 +15,3 @@ func CreateProfileWriterStore(eventManager event.Manager, directory, password st
|
|||
func LoadProfileWriterStore(directory, password string) (ProfileStore, error) {
|
||||
return v1.LoadProfileWriterStore(directory, password)
|
||||
}
|
||||
|
||||
// ReadProfile reads a profile from storage and returns the profile
|
||||
// Should only be called for cache refresh of the profile after a ProfileWriterStore has opened
|
||||
// (and upgraded) the store, and thus supplied the key/salt
|
||||
func ReadProfile(directory string, key [32]byte, salt [128]byte) (*model.Profile, error) {
|
||||
return v1.ReadProfile(directory, key, salt)
|
||||
}
|
||||
|
||||
// ********* Versioning and upgrade **********
|
||||
|
|
|
@ -63,11 +63,7 @@ func DecryptFile(ciphertext []byte, key [32]byte) ([]byte, error) {
|
|||
func ReadEncryptedFile(directory, filename string, key [32]byte) ([]byte, error) {
|
||||
encryptedbytes, err := ioutil.ReadFile(path.Join(directory, filename))
|
||||
if err == nil {
|
||||
data, err := DecryptFile(encryptedbytes, key)
|
||||
if err == nil {
|
||||
return data, nil
|
||||
}
|
||||
return nil, err
|
||||
return DecryptFile(encryptedbytes, key)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -6,13 +6,10 @@ import (
|
|||
"encoding/json"
|
||||
"git.openprivacy.ca/openprivacy/log"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
const profileFilename = "profile"
|
||||
const version = "1"
|
||||
const versionFile = "VERSION"
|
||||
const saltFile = "SALT"
|
||||
|
||||
//ProfileStoreV1 storage for profiles and message streams that uses in memory key and fs stored salt instead of in memory password
|
||||
|
@ -24,48 +21,6 @@ type ProfileStoreV1 struct {
|
|||
salt [128]byte
|
||||
}
|
||||
|
||||
// CheckPassword returns true if the given password produces the same key as the current stored key, otherwise false.
|
||||
func (ps *ProfileStoreV1) CheckPassword(checkpass string) bool {
|
||||
oldkey := CreateKey(checkpass, ps.salt[:])
|
||||
return oldkey == ps.key
|
||||
}
|
||||
|
||||
// InitV1Directory generates a key and salt from a password, writes a SALT and VERSION file and returns the key and salt
|
||||
func InitV1Directory(directory, password string) ([32]byte, [128]byte, error) {
|
||||
os.Mkdir(directory, 0700)
|
||||
|
||||
key, salt, err := CreateKeySalt(password)
|
||||
if err != nil {
|
||||
log.Errorf("Could not create key for profile store from password: %v\n", err)
|
||||
return [32]byte{}, [128]byte{}, err
|
||||
}
|
||||
|
||||
if err = ioutil.WriteFile(path.Join(directory, versionFile), []byte(version), 0600); err != nil {
|
||||
log.Errorf("Could not write version file: %v", err)
|
||||
return [32]byte{}, [128]byte{}, err
|
||||
}
|
||||
|
||||
if err = ioutil.WriteFile(path.Join(directory, saltFile), salt[:], 0600); err != nil {
|
||||
log.Errorf("Could not write salt file: %v", err)
|
||||
return [32]byte{}, [128]byte{}, err
|
||||
}
|
||||
|
||||
return key, salt, nil
|
||||
}
|
||||
|
||||
// CreateProfileWriterStore creates a profile store backed by a filestore listening for events and saving them
|
||||
// directory should be $appDir/profiles/$rand
|
||||
func CreateProfileWriterStore(eventManager event.Manager, directory, password string, profile *model.Profile) *ProfileStoreV1 {
|
||||
key, salt, err := InitV1Directory(directory, password)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
ps := &ProfileStoreV1{fs: NewFileStore(directory, profileFilename, key), key: key, salt: salt, directory: directory, profile: profile}
|
||||
|
||||
return ps
|
||||
}
|
||||
|
||||
// LoadProfileWriterStore loads a profile store from filestore listening for events and saving them
|
||||
// directory should be $appDir/profiles/$rand
|
||||
func LoadProfileWriterStore(directory, password string) (*ProfileStoreV1, error) {
|
||||
|
@ -87,28 +42,6 @@ func LoadProfileWriterStore(directory, password string) (*ProfileStoreV1, error)
|
|||
return ps, nil
|
||||
}
|
||||
|
||||
// ReadProfile reads a profile from storqage and returns the profile
|
||||
// directory should be $appDir/profiles/$rand
|
||||
func ReadProfile(directory string, key [32]byte, salt [128]byte) (*model.Profile, error) {
|
||||
os.Mkdir(directory, 0700)
|
||||
ps := &ProfileStoreV1{fs: NewFileStore(directory, profileFilename, key), key: key, salt: salt, directory: directory, profile: nil}
|
||||
|
||||
err := ps.load()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
profile := ps.GetProfileCopy(true)
|
||||
|
||||
return profile, nil
|
||||
}
|
||||
|
||||
// GetNewPeerMessage is for AppService to call on Reload events, to reseed the AppClient with the loaded peers
|
||||
func (ps *ProfileStoreV1) GetNewPeerMessage() *event.Event {
|
||||
message := event.NewEventList(event.NewPeer, event.Identity, ps.profile.LocalID, event.Key, string(ps.key[:]), event.Salt, string(ps.salt[:]))
|
||||
return &message
|
||||
}
|
||||
|
||||
// load instantiates a cwtchPeer from the file store
|
||||
func (ps *ProfileStoreV1) load() error {
|
||||
decrypted, err := ps.fs.Read()
|
||||
|
|
|
@ -33,7 +33,6 @@ import (
|
|||
func waitForPeerPeerConnection(t *testing.T, peera peer.CwtchPeer, peerb peer.CwtchPeer) {
|
||||
for {
|
||||
state := peera.GetPeerState(peerb.GetOnion())
|
||||
//log.Infof("Waiting for Peer %v to peer with peer: %v - state: %v\n", peera.GetProfile().Name, peerb.GetProfile().Name, state)
|
||||
if state == connections.FAILED {
|
||||
t.Fatalf("%v could not connect to %v", peera.GetOnion(), peerb.GetOnion())
|
||||
}
|
||||
|
@ -42,8 +41,8 @@ func waitForPeerPeerConnection(t *testing.T, peera peer.CwtchPeer, peerb peer.Cw
|
|||
time.Sleep(time.Second * 5)
|
||||
continue
|
||||
} else {
|
||||
peerAName, _ := peera.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.Name)
|
||||
peerBName, _ := peerb.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.Name)
|
||||
peerAName, _ := peera.GetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name)
|
||||
peerBName, _ := peerb.GetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name)
|
||||
fmt.Printf("%v CONNECTED and AUTHED to %v\n", peerAName, peerBName)
|
||||
break
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue