Extract Register On New Group Message Functions
continuous-integration/drone/push Build was killed Details
continuous-integration/drone/pr Build is pending Details

This commit is contained in:
Sarah Jamie Lewis 2022-05-12 15:15:54 -07:00
parent 0aa0c94af7
commit 74698a0e00
3 changed files with 49 additions and 39 deletions

View File

@ -5,6 +5,7 @@ import (
"cwtch.im/cwtch/model/attr"
"cwtch.im/cwtch/model/constants"
"cwtch.im/cwtch/peer"
"cwtch.im/cwtch/protocol/groups"
"encoding/json"
"errors"
"fmt"
@ -23,6 +24,29 @@ func FunctionalityGate(experimentMap map[string]bool) (*Functionality, error) {
return nil, errors.New("groupmanagement is not enabled")
}
func (f *Functionality) Init(cp peer.CwtchPeer) {
cp.RegisterOnNewGroupMessage(func(conversationID int, dgm groups.DecryptedGroupMessage, storage *peer.CwtchProfileStorage) {
/// Time to Handle any Meta-Actions
overlayMessage := new(model.MessageWrapper)
err := json.Unmarshal([]byte(dgm.Text), overlayMessage)
if err == nil {
if overlayMessage.Overlay == model.OverlayGroupManagement {
ci, _ := storage.GetConversation(conversationID)
// NOTE: this is safe because dm.Onion will only be valid if there is a valid signature
// from the onion on the message. As such we don't re-verify the signature here.
acl, exists := ci.ACL[dgm.Onion]
if exists && acl.ManageACL {
newACL := new(model.AccessControlList)
err := json.Unmarshal([]byte(overlayMessage.Data), newACL)
if err == nil {
storage.SetConversationACL(conversationID, *newACL)
}
}
}
}
})
}
// CreateManagedGroup is a convenience function for creating a new managed group
func (f *Functionality) CreateManagedGroup(cp peer.CwtchPeer, name string, server string) (int, error) {
return cp.StartGroup(name, server)

View File

@ -68,10 +68,25 @@ type cwtchPeer struct {
state map[string]connections.ConnectionState
onNewPeerMessageFunctions []func(conversationID int, message string, storage *CwtchProfileStorage)
onNewGroupMessageFunctions []func(conversationID int, dgm groups.DecryptedGroupMessage, storage *CwtchProfileStorage)
queue event.Queue
eventBus event.Manager
}
func (cp *cwtchPeer) RegisterOnNewPeerMessage(f func(conversationID int, message string, storage *CwtchProfileStorage)) {
cp.mutex.Lock()
defer cp.mutex.Unlock()
cp.onNewPeerMessageFunctions = append(cp.onNewPeerMessageFunctions, f)
}
func (cp *cwtchPeer) RegisterOnNewGroupMessage(f func(conversationID int, dgm groups.DecryptedGroupMessage, storage *CwtchProfileStorage)) {
cp.mutex.Lock()
defer cp.mutex.Unlock()
cp.onNewGroupMessageFunctions = append(cp.onNewGroupMessageFunctions, f)
}
func (cp *cwtchPeer) DoStorageTransaction(f func(storage *CwtchProfileStorage) error) error {
cp.mutex.Lock()
defer cp.mutex.Unlock()
@ -542,24 +557,6 @@ func (cp *cwtchPeer) BlockConversation(id int) error {
return cp.storage.SetConversationACL(id, ci.ACL)
}
func (cp *cwtchPeer) AddMember(id int, handle string, ac model.AccessControl) error {
cp.mutex.Lock()
defer cp.mutex.Unlock()
ci, err := cp.storage.GetConversation(id)
if err != nil {
return err
}
requesterHandle, _ := cp.storage.LoadProfileKeyValue(TypeAttribute, attr.PublicScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(constants.Onion)).ToString())
if ci.ACL[string(requesterHandle)].ManageACL {
aclCopy := ci.ACL
aclCopy[handle] = ac
cp.storage.SetConversationACL(id, ci.ACL)
}
return fmt.Errorf("unable to add a member to the conversation")
}
// UnblockConversation looks up a conversation by `handle` and sets the Blocked ACL field to `true`
// Further actions depend on the Accepted field
func (cp *cwtchPeer) UnblockConversation(id int) error {
@ -1356,23 +1353,8 @@ func (cp *cwtchPeer) attemptInsertOrAcknowledgeLegacyGroupConversation(conversat
id, err := cp.storage.InsertMessage(conversationID, 0, dm.Text, model.Attributes{constants.AttrAck: constants.True, "PreviousSignature": base64.StdEncoding.EncodeToString(dm.PreviousMessageSig), constants.AttrAuthor: dm.Onion, constants.AttrSentTimestamp: time.Unix(int64(dm.Timestamp), 0).Format(time.RFC3339Nano)}, signature, contenthash)
if err == nil {
/// Time to Handle any Meta-Actions
overlayMessage := new(model.MessageWrapper)
err := json.Unmarshal([]byte(dm.Text), overlayMessage)
if err == nil {
if overlayMessage.Overlay == model.OverlayGroupManagement {
ci, _ := cp.storage.GetConversation(conversationID)
// NOTE: this is safe because dm.Onion will only be valid if there is a valid signature
// from the onion on the message. As such we don't re-verify the signature here.
acl, exists := ci.ACL[dm.Onion]
if exists && acl.ManageACL {
newACL := new(model.AccessControlList)
err := json.Unmarshal([]byte(overlayMessage.Data), newACL)
if err == nil {
cp.storage.SetConversationACL(conversationID, *newACL)
}
}
}
for _, f := range cp.onNewGroupMessageFunctions {
f(id, *dm, cp.storage)
}
cp.eventBus.Publish(event.NewEvent(event.NewMessageFromGroup, map[event.Field]string{event.ConversationID: strconv.Itoa(conversationID), event.TimestampSent: time.Unix(int64(dm.Timestamp), 0).Format(time.RFC3339Nano), event.RemotePeer: dm.Onion, event.Index: strconv.Itoa(id), event.Data: dm.Text, event.ContentHash: contenthash}))

View File

@ -5,6 +5,7 @@ import (
"cwtch.im/cwtch/model"
"cwtch.im/cwtch/model/attr"
"cwtch.im/cwtch/protocol/connections"
"cwtch.im/cwtch/protocol/groups"
"git.openprivacy.ca/openprivacy/connectivity"
)
@ -106,10 +107,6 @@ type CwtchPeer interface {
GetConversationAttribute(conversation int, path attr.ScopedZonedPath) (string, error)
DeleteConversation(conversation int) error
AddMember(conversation int, handle string, ac model.AccessControl) error
DoStorageTransaction(func(storage *CwtchProfileStorage) error) error
// New Unified Conversation Channel Interfaces
GetChannelMessage(conversation int, channel int, id int) (string, model.Attributes, error)
GetChannelMessageCount(conversation int, channel int) (int, error)
@ -122,4 +119,11 @@ type CwtchPeer interface {
ChangePassword(oldpassword string, newpassword string, newpasswordAgain string) error
Export(file string) error
Delete()
// DoStorageTransaction is a low level API for building new functionality on top of Cwtch Peer
// in general you do not want to use this.
DoStorageTransaction(func(storage *CwtchProfileStorage) error) error
RegisterOnNewPeerMessage(func(conversationID int, message string, storage *CwtchProfileStorage))
RegisterOnNewGroupMessage(func(conversationID int, dgm groups.DecryptedGroupMessage, storage *CwtchProfileStorage))
}