Merge remote-tracking branch 'origin/master' into p2p-interim-new-storage
This commit is contained in:
commit
c1428762f8
|
@ -2,19 +2,21 @@ package filesharing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"cwtch.im/cwtch/model"
|
|
||||||
"cwtch.im/cwtch/model/attr"
|
|
||||||
"cwtch.im/cwtch/peer"
|
|
||||||
"cwtch.im/cwtch/protocol/files"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.openprivacy.ca/openprivacy/log"
|
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
path "path/filepath"
|
path "path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"cwtch.im/cwtch/model"
|
||||||
|
"cwtch.im/cwtch/model/attr"
|
||||||
|
"cwtch.im/cwtch/peer"
|
||||||
|
"cwtch.im/cwtch/protocol/files"
|
||||||
|
"git.openprivacy.ca/openprivacy/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Functionality groups some common UI triggered functions for contacts...
|
// Functionality groups some common UI triggered functions for contacts...
|
||||||
|
@ -45,8 +47,8 @@ func (f *Functionality) DownloadFile(profile peer.CwtchPeer, conversationID int,
|
||||||
// Store local.filesharing.filekey.manifest as the location of the manifest
|
// Store local.filesharing.filekey.manifest as the location of the manifest
|
||||||
profile.SetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.manifest", key), manifestFilePath)
|
profile.SetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.manifest", key), manifestFilePath)
|
||||||
|
|
||||||
// Store local.filesharing.filekey as the location of the download
|
// Store local.filesharing.filekey.path as the location of the download
|
||||||
profile.SetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, key, downloadFilePath)
|
profile.SetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.path", key), downloadFilePath)
|
||||||
|
|
||||||
// Get the value of conversation.filesharing.filekey.manifest.size from `handle`
|
// Get the value of conversation.filesharing.filekey.manifest.size from `handle`
|
||||||
profile.SendScopedZonedGetValToContact(conversationID, attr.ConversationScope, attr.FilesharingZone, fmt.Sprintf("%s.manifest.size", key))
|
profile.SendScopedZonedGetValToContact(conversationID, attr.ConversationScope, attr.FilesharingZone, fmt.Sprintf("%s.manifest.size", key))
|
||||||
|
@ -89,6 +91,9 @@ func (f *Functionality) ShareFile(filepath string, profile peer.CwtchPeer, conve
|
||||||
// manifest.FileName gets redacted in filesharing_subsystem (to remove the system-specific file hierarchy),
|
// manifest.FileName gets redacted in filesharing_subsystem (to remove the system-specific file hierarchy),
|
||||||
// but we need to *store* the full path because the sender also uses it to locate the file
|
// but we need to *store* the full path because the sender also uses it to locate the file
|
||||||
lenDiff := len(filepath) - len(path.Base(filepath))
|
lenDiff := len(filepath) - len(path.Base(filepath))
|
||||||
|
|
||||||
|
profile.SetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.ts", key), strconv.FormatInt(time.Now().Unix(), 10))
|
||||||
|
profile.SetScopedZonedAttribute(attr.ConversationScope, attr.FilesharingZone, fmt.Sprintf("%s.manifest", key), string(serializedManifest))
|
||||||
profile.SetScopedZonedAttribute(attr.ConversationScope, attr.FilesharingZone, fmt.Sprintf("%s.manifest.size", key), strconv.Itoa(int(math.Ceil(float64(len(serializedManifest)-lenDiff)/float64(files.DefaultChunkSize)))))
|
profile.SetScopedZonedAttribute(attr.ConversationScope, attr.FilesharingZone, fmt.Sprintf("%s.manifest.size", key), strconv.Itoa(int(math.Ceil(float64(len(serializedManifest)-lenDiff)/float64(files.DefaultChunkSize)))))
|
||||||
|
|
||||||
profile.ShareFile(key, string(serializedManifest))
|
profile.ShareFile(key, string(serializedManifest))
|
||||||
|
|
|
@ -18,6 +18,8 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"cwtch.im/cwtch/model/constants"
|
||||||
|
|
||||||
"cwtch.im/cwtch/event"
|
"cwtch.im/cwtch/event"
|
||||||
"cwtch.im/cwtch/model"
|
"cwtch.im/cwtch/model"
|
||||||
"cwtch.im/cwtch/model/attr"
|
"cwtch.im/cwtch/model/attr"
|
||||||
|
@ -33,7 +35,7 @@ var autoHandleableEvents = map[event.Type]bool{event.EncryptedGroupMessage: true
|
||||||
event.ServerStateChange: true, event.NewGroupInvite: true, event.NewMessageFromPeer: true,
|
event.ServerStateChange: true, event.NewGroupInvite: true, event.NewMessageFromPeer: true,
|
||||||
event.PeerAcknowledgement: true, event.PeerError: true, event.SendMessageToPeerError: true, event.SendMessageToGroupError: true,
|
event.PeerAcknowledgement: true, event.PeerError: true, event.SendMessageToPeerError: true, event.SendMessageToGroupError: true,
|
||||||
event.NewGetValMessageFromPeer: true, event.NewRetValMessageFromPeer: true, event.ProtocolEngineStopped: true, event.RetryServerRequest: true,
|
event.NewGetValMessageFromPeer: true, event.NewRetValMessageFromPeer: true, event.ProtocolEngineStopped: true, event.RetryServerRequest: true,
|
||||||
event.ManifestSizeReceived: true, event.ManifestReceived: true}
|
event.ManifestSizeReceived: true, event.ManifestReceived: true, event.FileDownloaded: true}
|
||||||
|
|
||||||
// DefaultEventsToHandle specifies which events will be subscribed to
|
// DefaultEventsToHandle specifies which events will be subscribed to
|
||||||
// when a peer has its Init() function called
|
// when a peer has its Init() function called
|
||||||
|
@ -594,13 +596,14 @@ func (cp *cwtchPeer) StartGroup(name string, server string) (int, error) {
|
||||||
|
|
||||||
// AddServer takes in a serialized server specification (a bundle of related keys) and adds a contact for the
|
// AddServer takes in a serialized server specification (a bundle of related keys) and adds a contact for the
|
||||||
// server assuming there are no errors and the contact doesn't already exist.
|
// server assuming there are no errors and the contact doesn't already exist.
|
||||||
|
// Returns the onion of the new server if added
|
||||||
// TODO in the future this function should also integrate with a trust provider to validate the key bundle.
|
// TODO in the future this function should also integrate with a trust provider to validate the key bundle.
|
||||||
// Status: Ready for 1.5
|
// Status: Ready for 1.5
|
||||||
func (cp *cwtchPeer) AddServer(serverSpecification string) error {
|
func (cp *cwtchPeer) AddServer(serverSpecification string) error {
|
||||||
// This confirms that the server did at least sign the bundle
|
// This confirms that the server did at least sign the bundle
|
||||||
keyBundle, err := model.DeserializeAndVerify([]byte(serverSpecification))
|
keyBundle, err := model.DeserializeAndVerify([]byte(serverSpecification))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
log.Debugf("Got new key bundle %v", keyBundle.Serialize())
|
log.Debugf("Got new key bundle %v", keyBundle.Serialize())
|
||||||
|
|
||||||
|
@ -608,7 +611,7 @@ func (cp *cwtchPeer) AddServer(serverSpecification string) error {
|
||||||
// keys or subsets of keys, but for now they must commit only to a complete set of keys required for Cwtch Groups
|
// keys or subsets of keys, but for now they must commit only to a complete set of keys required for Cwtch Groups
|
||||||
// (that way we can be assured that the keybundle we store is a valid one)
|
// (that way we can be assured that the keybundle we store is a valid one)
|
||||||
if !keyBundle.HasKeyType(model.KeyTypeTokenOnion) || !keyBundle.HasKeyType(model.KeyTypeServerOnion) || !keyBundle.HasKeyType(model.KeyTypePrivacyPass) {
|
if !keyBundle.HasKeyType(model.KeyTypeTokenOnion) || !keyBundle.HasKeyType(model.KeyTypeServerOnion) || !keyBundle.HasKeyType(model.KeyTypePrivacyPass) {
|
||||||
return errors.New("keybundle is incomplete")
|
return "", errors.New("keybundle is incomplete")
|
||||||
}
|
}
|
||||||
|
|
||||||
if keyBundle.HasKeyType(model.KeyTypeServerOnion) {
|
if keyBundle.HasKeyType(model.KeyTypeServerOnion) {
|
||||||
|
@ -930,6 +933,13 @@ func (cp *cwtchPeer) storeMessage(handle string, message string, sent time.Time)
|
||||||
// ShareFile begins hosting the given serialized manifest
|
// ShareFile begins hosting the given serialized manifest
|
||||||
// Status: Ready for 1.5
|
// Status: Ready for 1.5
|
||||||
func (cp *cwtchPeer) ShareFile(fileKey string, serializedManifest string) {
|
func (cp *cwtchPeer) ShareFile(fileKey string, serializedManifest string) {
|
||||||
|
tsStr, exists := cp.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.ts", fileKey))
|
||||||
|
if exists {
|
||||||
|
ts, err := strconv.ParseInt(tsStr, 10, 64)
|
||||||
|
if err != nil || ts < time.Now().Unix()-2592000 {
|
||||||
|
log.Errorf("ignoring request to download a file offered more than 30 days ago")
|
||||||
|
}
|
||||||
|
}
|
||||||
cp.eventBus.Publish(event.NewEvent(event.ShareManifest, map[event.Field]string{event.FileKey: fileKey, event.SerializedManifest: serializedManifest}))
|
cp.eventBus.Publish(event.NewEvent(event.ShareManifest, map[event.Field]string{event.FileKey: fileKey, event.SerializedManifest: serializedManifest}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1044,7 +1054,7 @@ func (cp *cwtchPeer) eventHandler() {
|
||||||
|
|
||||||
manifestFilePath, exists := cp.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%v.manifest", fileKey))
|
manifestFilePath, exists := cp.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%v.manifest", fileKey))
|
||||||
if exists {
|
if exists {
|
||||||
downloadFilePath, exists := cp.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fileKey)
|
downloadFilePath, exists := cp.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%v.path", fileKey))
|
||||||
if exists {
|
if exists {
|
||||||
log.Debugf("downloading manifest to %v, file to %v", manifestFilePath, downloadFilePath)
|
log.Debugf("downloading manifest to %v, file to %v", manifestFilePath, downloadFilePath)
|
||||||
var manifest files.Manifest
|
var manifest files.Manifest
|
||||||
|
@ -1079,7 +1089,9 @@ func (cp *cwtchPeer) eventHandler() {
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("no download path found for manifest: %v", fileKey)
|
log.Errorf("no download path found for manifest: %v", fileKey)
|
||||||
}
|
}
|
||||||
|
case event.FileDownloaded:
|
||||||
|
fileKey := ev.Data[event.FileKey]
|
||||||
|
cp.SetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.complete", fileKey), "true")
|
||||||
case event.NewRetValMessageFromPeer:
|
case event.NewRetValMessageFromPeer:
|
||||||
onion := ev.Data[event.RemotePeer]
|
onion := ev.Data[event.RemotePeer]
|
||||||
scope := ev.Data[event.Scope]
|
scope := ev.Data[event.Scope]
|
||||||
|
|
Loading…
Reference in New Issue