diff --git a/bindings/group.go b/bindings/group.go index 3aa396d9895fca423818c9de7bffd8ebf030e39e..91eb91c91b2160432e6c0f71270a691e1a4a145d 100644 --- a/bindings/group.go +++ b/bindings/group.go @@ -15,7 +15,6 @@ import ( "gitlab.com/elixxir/client/cmix/rounds" gc "gitlab.com/elixxir/client/groupChat" gs "gitlab.com/elixxir/client/groupChat/groupStore" - "gitlab.com/elixxir/crypto/group" "gitlab.com/elixxir/primitives/format" "gitlab.com/xx_network/primitives/id" "sync" @@ -42,7 +41,7 @@ type groupChatTracker struct { } // make create a GroupChat from a groupChat.Wrapper, assigns it a unique ID, and -// adds it to the udTracker. +// adds it to the groupChatTracker. func (ut *groupChatTracker) make(gcInt gc.GroupChat) *GroupChat { ut.mux.Lock() defer ut.mux.Unlock() @@ -66,7 +65,7 @@ func (ut *groupChatTracker) get(id int) (*GroupChat, error) { c, exist := ut.tracked[id] if !exist { return nil, errors.Errorf( - "Cannot get UserDiscovery for ID %d, does not exist", id) + "Cannot get GroupChat for ID %d, does not exist", id) } return c, nil @@ -98,44 +97,45 @@ type GroupRequest interface { Callback(payload []byte) } -// LoadOrNewManager creates a bindings-layer group chat manager. +// LoadOrNewGroupChat creates a bindings-layer group chat manager. // // Parameters: // - e2eID - e2e object ID in the tracker. -// - groupID - GroupChat object ID in the tracker, given from previous call to LoadOrNewManager. +// - groupID - GroupChat object ID in the tracker, given from previous call +// to LoadOrNewGroupChat. // - requestFunc - a callback to handle group chat requests. // - processor - the group chat message processor. -func LoadOrNewManager(e2eID, groupID int, requestFunc GroupRequest, +func LoadOrNewGroupChat(e2eID, groupID int, requestFunc GroupRequest, processor GroupChatProcessor) (*GroupChat, error) { // Retrieve from singleton groupChat, err := groupChatTrackerSingleton.get(groupID) - if err != nil { // If not present, create/load group chat manager - // Get user from singleton - user, err := e2eTrackerSingleton.get(e2eID) - if err != nil { - return nil, err - } - - // Construct a wrapper for the request callback - requestCb := func(g gs.Group) { - //fixme: review this to see if should be json marshaled. - // At the moment, groupStore.DhKeyList is an unsupported - // type, it would need a MarshalJson method - requestFunc.Callback(g.Serialize()) - } - - // Construct a group chat manager - gcInt, err := gc.NewManager(user.api, requestCb, - &groupChatProcessor{bindingsCb: processor}) - if err != nil { - return nil, err - } - - // Construct wrapper - return groupChatTrackerSingleton.make(gcInt), nil + if err == nil { // If present, return group chat manager from singleton + return groupChat, nil + } + + // Get user from singleton + user, err := e2eTrackerSingleton.get(e2eID) + if err != nil { + return nil, err + } + // Construct a wrapper for the request callback + requestCb := func(g gs.Group) { + //fixme: review this to see if should be json marshaled. + // At the moment, groupStore.DhKeyList is an unsupported + // type, it would need a MarshalJson method (see the docstring for JoinGroup) + requestFunc.Callback(g.Serialize()) + } + + // Construct a group chat manager + gcInt, err := gc.NewManager(user.api, requestCb, + &groupChatProcessor{bindingsCb: processor}) + if err != nil { + return nil, err } - return groupChat, nil + + // Construct wrapper + return groupChatTrackerSingleton.make(gcInt), nil } // GetID returns the groupChatTracker ID for the GroupChat object. @@ -147,7 +147,7 @@ func (g *GroupChat) GetID() int { // group. // // Parameters: -// - membership - members the user wants in the group. +// - membership - IDs of members the user wants in the group. // - message - the initial message sent to all members in the group. This is an // optional parameter and may be nil. // - tag - the name of the group decided by the creator. This is an optional parameter @@ -166,17 +166,15 @@ func (g *GroupChat) MakeGroup(membership IdList, message, name []byte) ( // Construct group grp, rounds, status, err := g.m.MakeGroup(members, name, message) - errStr := "" if err != nil { - errStr = err.Error() + return nil, err } // Construct the group report report := GroupReport{ Id: grp.ID.Bytes(), - Rounds: makeRoundsList(rounds), + Rounds: makeRoundsList(rounds).Rounds, Status: int(status), - Err: errStr, } // Marshal the report @@ -186,8 +184,8 @@ func (g *GroupChat) MakeGroup(membership IdList, message, name []byte) ( // ResendRequest resends a group request to all members in the group. // // Parameters: -// - groupId - a byte representation of a group. This can be found in the data -// returned by GroupChat.MakeGroup. +// - groupId - a byte representation of a group's ID. +// This can be found in the report returned by GroupChat.MakeGroup. // // Returns: // - []byte - a JSON-marshalled GroupReport. @@ -206,19 +204,17 @@ func (g *GroupChat) ResendRequest(groupId []byte) ([]byte, error) { return nil, errors.Errorf("Failed to find group %s", groupID) } - // Resent request + // Resend request rnds, status, err := g.m.ResendRequest(groupID) - errStr := "" if err != nil { - errStr = err.Error() + return nil, err } - // Construct the group report + // Construct the group report on resent request report := &GroupReport{ Id: grp.ID.Bytes(), - Rounds: makeRoundsList(rnds), + Rounds: makeRoundsList(rnds).Rounds, Status: int(status), - Err: errStr, } // Marshal the report @@ -228,8 +224,12 @@ func (g *GroupChat) ResendRequest(groupId []byte) ([]byte, error) { // JoinGroup allows a user to join a group when a request is received. // // Parameters: -// - group - a serialized Group. This is received by the GroupRequest.Callback. +// - group - a byte slice representing serialized Group. +// This is received by the GroupRequest.Callback. This is NOT a JSON marshalled +// version of a group and should not be treated as such. As of now, there is no +// functionality for JSON marshaling a Group. func (g *GroupChat) JoinGroup(group []byte) error { + // todo: see the todo comment in LoadOrNewGroupChat grp, err := gs.DeserializeGroup(group) if err != nil { return err @@ -268,25 +268,30 @@ func (g *GroupChat) Send(groupId, return nil, errors.Errorf("Failed to unmarshal group ID: %+v", err) } + // Send group message round, timestamp, msgID, err := g.m.Send(groupID, message, tag) - errStr := "" if err != nil { - errStr = err.Error() + return nil, err } + // Construct send report sendReport := &GroupSendReport{ - RoundID: round, - Timestamp: timestamp, - MessageID: msgID, - Err: errStr, + RoundID: uint64(round), + Timestamp: timestamp.UnixNano(), + MessageID: msgID.Bytes(), } return json.Marshal(sendReport) } // GetGroups returns an IdList containing a list of group IDs that the user is a member of. -func (g *GroupChat) GetGroups() IdList { - return makeIdList(g.m.GetGroups()) +// +// Returns: +// - []byte - a JSON marshalled IdList representing all group ID's. +func (g *GroupChat) GetGroups() ([]byte, error) { + groupIds := makeIdList(g.m.GetGroups()) + + return json.Marshal(groupIds) } // GetGroup returns the group with the group ID. If no group exists, then the @@ -421,16 +426,14 @@ func (gcp *groupChatProcessor) String() string { // status of the send operation. type GroupReport struct { Id []byte - Rounds RoundsList + Rounds []int Status int - Err string } // GroupSendReport is returned when sending a group message. It contains the // round ID sent on and the timestamp of the send operation. type GroupSendReport struct { - RoundID id.Round - Timestamp time.Time - MessageID group.MessageID - Err string + RoundID uint64 + Timestamp int64 + MessageID []byte }