WIP: Hybrid Groups Initial Sketch #545
No reviewers
Labels
No Label
applications
BLOCKED
bug
design
duplicate
enhancement
fixed?
funding-needed
help wanted
infrastructure
invalid
payments
qubes
question
ready-for-implementation
refactor
spam
tapir-server
testing
tor
wontfix
No Milestone
No Assignees
2 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: cwtch.im/cwtch#545
Loading…
Reference in New Issue
No description provided.
Delete Branch "hybridgroups"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Ok, this is part 1.
This implements the most basic version of hybrid groups where a group manager can proxy messages between peers with some very basic filtering.
What is done:
NewConversation
,InternalInsertMessage
andSignMessage
- these are needed because Extensions now need to manage inserting messages on behalf of a conversation.Things that are definitely missing:
However, even without all these things, I think now is the right time to review this PR and get a feel for this code. All those other things are nuanced and will require detailed review and I don't want them lost while reviewing all the stuff in this PR - which is mostly a structural sketch.
Ok I got through the first few files only, then the cat let me know it was bed time. Will pick up and continue soon!
@ -405,3 +408,3 @@
log.Debugf("restartFlow: Creating a New Protocol Engine...")
app.engines[profile.GetOnion()] = engine
eventBus.Publish(event.NewEventList(event.ProtocolEngineCreated))
eventBus.Publish(event.NewEventList(event.ProtocolEngineCreated, event.Handle, profile.GetOnion()))
Can you add/update the comment above event.ProtocolEngineCreated in common.go. We don't type arguments to events but I've been trying to at least leave comments there about how to use them
@ -515,6 +518,7 @@ func (app *application) eventHandler() {
log.Infof("peer appearing offline, not launching listen threads or connecting jobs")
app.ConfigureConnections(onion, false, false, false)
} else {
log.Infof("configuring online connections for peer")
add onion address else this line becomes noise when multiple peers activating (or remove log)
@ -54,6 +54,7 @@ func (q *infiniteQueue) resize() {
// Add puts an element on the end of the queue.
func (q *infiniteQueue) Add(elem Event) {
delete
@ -0,0 +56,4 @@
// This file contains code for the Hybrid Group / Managed Group types..
type HybridGroupMessage struct {
Author string // the authors cwtch address
MemberGroupID uint32
why not GroupID and MessageID?
ah is it not the ID of hte group but some member ID in the group? i see
and the MemeberMessageID?
@ -0,0 +67,4 @@
func AuthenticateMessage(message HybridGroupMessage) bool {
messageCopy := message
messageCopy.Signature = []byte{}
// Otherwise we derive the public key from the sender and check it against that.
otherwise?
@ -0,0 +72,4 @@
if err == nil {
data, err := json.Marshal(messageCopy)
if err == nil && len(decodedPub) >= 32 {
return ed25519.Verify(decodedPub[:32], data, message.Signature)
only the first 32 bytes of an decoded onion address are the public key? can we make a like onion utils file and functions somewhere so it's a little easier to read / write with out having to remember / google the structure of an onion address?
we have messages from an "admin" with ManageGroup true in the ACL but how does this get setup or changed? every new member is added with DefaultACL, we're missing messages about adjusting the ACL of members so we could create new admins, demote old ones, etc?
... reads top comment showing things still undo... ahh..
@ -0,0 +121,4 @@
// handleRotateKeyEvent rotates the encryption key for a given group
// assumes we are called after an event provided by an authorized peer (i.e. ManageGroup == true)
func (f *ManagedGroupFunctionality) handleRotateKeyEvent(profile peer.CwtchPeer, conversation model.Conversation, rke RotateKeyEvent) {
Do we need to store the old keys so we can reconstruct message history? or is it that if we have the invite, we'll have the first key, and subequently can read the rotate messages in order, etc, and reconstruct, but only if we have full history?
@ -0,0 +127,4 @@
profile.SetConversationAttribute(conversation.ID, keyScope, keyB64)
}
func (f *ManagedGroupFunctionality) handleNewMessageEvent(profile peer.CwtchPeer, conversation model.Conversation, nme NewMessageEvent) {
so a group manager can also send messages? relay them? what's the imagined use case here? group manager replacing servers?
@ -0,0 +141,4 @@
log.Errorf("unable to decrypt hybrid group message: %v", err)
return
}
//
ah we dont do anything with it yet?
@ -0,0 +145,4 @@
}
}
func (f *ManagedGroupFunctionality) handleNewClearMessageEvent(profile peer.CwtchPeer, conversation model.Conversation, nme NewClearMessageEvent) {
what is the difference between receiving a message and a clear message from a group manager?
@ -0,0 +129,4 @@
if err != nil {
return err
}
// enable channel 2 on this conversation (hybrid groups management channel)
what are channels?
@ -88,0 +96,4 @@
return true
}
if requestedChannel == 1 {
return false // channel 1 is mapped to channel 0 for backwards compatibility
? this hasn't launched? backwards compatibility with what? and why return false if it's "mapped to 0"? we have 0 so isnt this kinda true?
@ -19,1 +26,4 @@
const OverlayFileSharing = 200
// ManageGroupEvent is the canonical identifier for the manage group overlay
const OverlayManageGroupEvent = 0x302
shouldn't there also be a 0x300 for the admin channel 0 then?
I'm not sure I get why we're overloading channel into overlay here and not just another byte sized field in managed group messages? don't this mean adding binary logic somewhere to check an overlay contains 0x300 then?
@ -424,0 +443,4 @@
}
func (cp *cwtchPeer) resolveChannel(overlay int) int {
requestedChannel := overlay & 0xFF
right like this. we use big json blob structs for so much, why bit packing for this?
also, is there an envisioned use for the range between 0xFF and 0x300? that seems abandoned?
@ -439,0 +469,4 @@
var cm model.MessageWrapper
err = json.Unmarshal([]byte(message), &cm)
// we are now explictly rejecting invalidly encoded messages...
was this happening a lot?
seems like that's a failing of our API then. perhaps the exposed send message shouldn't take a pre encoded message wrapper but the arguments ti construct one?
@ -439,0 +476,4 @@
requestedChannel := cp.resolveChannel(cm.Overlay)
// if this channel has not been registered for a particular conversation
// then default to channel = 0;
if conversationInfo.HasChannel(requestedChannel) {
resolveChannel will turn all legacy overlays to have channel 0 and hasChannel auto trues 0.
for managed groups was it 0 or 2 that is the admin channel? do we need this manual setting? wont managed group messages have a channel explicitly set?
@ -1482,9 +1558,23 @@ func (cp *cwtchPeer) storeMessage(handle string, message string, sent time.Time)
}
}
var cm model.MessageWrapper
this check again? at least make it a private helper function like
validateMessageWrapper
@ -0,0 +79,4 @@
// ***** Cwtch Server management *****
app := app2.NewApp(acn, "./storage", app2.LoadAppSettings("./storage"))
managerApp := app2.NewApp(acn, "./managerstorage", app2.LoadAppSettings("./managerstorage"))
why a second app for the manager profile?
@ -0,0 +122,4 @@
t.Fatalf("could not create hybrid contact (bob): %v", err)
}
// Now we can allow alice, bob and carol to create a new hybrid group...
nit: there is no carol