diff --git a/bindings/channels.go b/bindings/channels.go index 72c8ca7d9b52c0e1718176e517fa69a1b16ea8d0..2838fc10ec4109f6b813fd2b4f3a01dd62fdd455 100644 --- a/bindings/channels.go +++ b/bindings/channels.go @@ -745,98 +745,116 @@ func (cm *ChannelsManager) RegisterReceiveHandler(messageType int, //////////////////////////////////////////////////////////////////////////////// // EventModel is an interface which an external party which uses the channels -// system passed an object which adheres to in order to get events on the channel. +// system passed an object which adheres to in order to get events on the +// channel. type EventModel interface { // JoinChannel is called whenever a channel is joined locally. // // Parameters: - // - channel is the pretty print representation of a channel. + // - channel - Returns the pretty print representation of a channel. JoinChannel(channel string) // LeaveChannel is called whenever a channel is left locally. // // Parameters: - // - ChannelId is the marshalled chenn - // This will receive a marshalled channel ID. + // - ChannelId - The marshalled channel [id.ID]. LeaveChannel(channelID []byte) - // ReceiveMessage is called whenever a message is received on a given channel - // It may be called multiple times on the same message, it is incumbent on - // the user of the API to filter such called by message ID. + // ReceiveMessage is called whenever a message is received on a given + // channel. It may be called multiple times on the same message. It is + // incumbent on the user of the API to filter such called by message ID. // // Parameters: - // - ChannelID is the marshalled channel ID. - // - MessageID is the marshalled message ID of the received message. - // - senderUsername is the username of the sender of the message. - // - text is the content of the message. - // - Timestamp is time the message was received, represented as - // nanoseconds since unix epoch. - // - Lease is a number of nanoseconds that the message is valid for. - // - Status is the status of the message. - // Statuses will be enumerated as such: - // Sent | 0 - // Delivered | 1 - // Failed | 2 - ReceiveMessage(channelID, messageID []byte, - senderUsername, text string, + // - channelID - The marshalled channel [id.ID]. + // - messageID - The bytes of the [channel.MessageID] of the received + // message. + // - senderUsername - The username of the sender of the message. + // - text - The content of the message. + // - timestamp - Time the message was received; represented as nanoseconds + // since unix epoch. + // - lease - The number of nanoseconds that the message is valid for. + // - roundId - The ID of the round that the message was received on. + // - status - the [channels.SentStatus] of the message. + // + // Statuses will be enumerated as such: + // Sent = 0 + // Delivered = 1 + // Failed = 2 + ReceiveMessage(channelID, messageID []byte, senderUsername, text string, timestamp, lease, roundId, status int64) - // ReceiveReply is called whenever a message is received which is a reply - // on a given channel. It may be called multiple times on the same message, - // it is incumbent on the user of the API to filter such called by message ID - // Messages may arrive out of order, so a reply in theory can arrive before - // the initial message, as a result it may be important to buffer replies. + // ReceiveReply is called whenever a message is received that is a reply on + // a given channel. It may be called multiple times on the same message. It + // is incumbent on the user of the API to filter such called by message ID. + // + // Messages may arrive our of order, so a reply in theory can arrive before + // the initial message. As a result, it may be important to buffer replies. // // Parameters: - // - ChannelID is the marshalled channel ID. - // - MessageID is the marshalled message ID of the received message. - // - reactionTo is the message ID for the message that received a reply. - // - senderUsername is the username of the sender of the message. - // - text is the content of the message, in this case a reply. - // - Timestamp is time the message was received, represented as - // nanoseconds since unix epoch. - // - Lease is a number of nanoseconds that the message is valid for. - // - Status is the status of the message. - // Statuses will be enumerated as such: - // Sent | 0 - // Delivered | 1 - // Failed | 2 + // - channelID - The marshalled channel [id.ID]. + // - messageID - The bytes of the [channel.MessageID] of the received + // message. + // - reactionTo - The [channel.MessageID] for the message that received a + // reply. + // - senderUsername - The username of the sender of the message. + // - text - The content of the message. + // - timestamp - Time the message was received; represented as nanoseconds + // since unix epoch. + // - lease - The number of nanoseconds that the message is valid for. + // - roundId - The ID of the round that the message was received on. + // - status - the [channels.SentStatus] of the message. + // + // Statuses will be enumerated as such: + // Sent = 0 + // Delivered = 1 + // Failed = 2 ReceiveReply(channelID, messageID, reactionTo []byte, senderUsername, text string, timestamp, lease, roundId, status int64) // ReceiveReaction is called whenever a reaction to a message is received - // on a given channel. It may be called multiple times on the same reaction, - // it is incumbent on the user of the API to filter such called by message ID + // on a given channel. It may be called multiple times on the same reaction. + // It is incumbent on the user of the API to filter such called by message + // ID. + // // Messages may arrive our of order, so a reply in theory can arrive before - // the initial message, as a result it may be important to buffer reactions. + // the initial message. As a result, it may be important to buffer + // reactions. // // Parameters: - // - ChannelID is the marshalled channel ID. - // - MessageID is the marshalled message ID of the received message. - // - reactionTo is the message ID for the message that received a reaction. - // - senderUsername is the username of the sender of the message. - // - reaction is the content of the message, in this case a reaction. - // - Timestamp is time the message was received, represented as - // nanoseconds since unix epoch. - // - Lease is a number of nanoseconds that the message is valid for. - // - Status is the status of the message. - // Statuses will be enumerated as such: - // Sent | 0 - // Delivered | 1 - // Failed | 2 + // - channelID - The marshalled channel [id.ID]. + // - messageID - The bytes of the [channel.MessageID] of the received + // message. + // - reactionTo - The [channel.MessageID] for the message that received a + // reply. + // - senderUsername - The username of the sender of the message. + // - reaction - The contents of the reaction message. + // - timestamp - Time the message was received; represented as nanoseconds + // since unix epoch. + // - lease - The number of nanoseconds that the message is valid for. + // - roundId - The ID of the round that the message was received on. + // - status - the [channels.SentStatus] of the message. + // + // Statuses will be enumerated as such: + // Sent = 0 + // Delivered = 1 + // Failed = 2 ReceiveReaction(channelID, messageID, reactionTo []byte, senderUsername, reaction string, timestamp, lease, roundId, status int64) - // UpdateSentStatus is called whenever the sent status of a message - // has changed. + // UpdateSentStatus is called whenever the sent status of a message has + // changed. + // + // Parameters: + // - messageID - The bytes of the [channel.MessageID] of the received + // message. + // - status - the [channels.SentStatus] of the message. // - // - Status is the status of the message. - // Statuses will be enumerated as such: - // Sent - 0 - // Delivered - 1 - // Failed - 2 + // Statuses will be enumerated as such: + // Sent = 0 + // Delivered = 1 + // Failed = 2 UpdateSentStatus(messageID []byte, status int64) // unimplemented @@ -867,9 +885,9 @@ func (tem *toEventModel) LeaveChannel(channelID *id.ID) { tem.em.LeaveChannel(channelID[:]) } -// ReceiveMessage is called whenever a message is received on a given channel -// It may be called multiple times on the same message, it is incumbent on -// the user of the API to filter such called by message ID. +// ReceiveMessage is called whenever a message is received on a given channel. +// It may be called multiple times on the same message. It is incumbent on the +// user of the API to filter such called by message ID. func (tem *toEventModel) ReceiveMessage(channelID *id.ID, messageID cryptoChannel.MessageID, senderUsername string, text string, timestamp time.Time, lease time.Duration, round rounds.Round, @@ -879,11 +897,12 @@ func (tem *toEventModel) ReceiveMessage(channelID *id.ID, timestamp.UnixNano(), int64(lease), int64(round.ID), int64(status)) } -// ReceiveReply is called whenever a message is received which is a reply -// on a given channel. It may be called multiple times on the same message, -// it is incumbent on the user of the API to filter such called by message ID -// Messages may arrive our of order, so a reply in theory can arrive before -// the initial message, as a result it may be important to buffer replies. +// ReceiveReply is called whenever a message is received that is a reply on a +// given channel. It may be called multiple times on the same message. It is +// incumbent on the user of the API to filter such called by message ID. +// +// Messages may arrive our of order, so a reply in theory can arrive before the +// initial message. As a result, it may be important to buffer replies. func (tem *toEventModel) ReceiveReply(channelID *id.ID, messageID cryptoChannel.MessageID, reactionTo cryptoChannel.MessageID, senderUsername string, @@ -896,11 +915,12 @@ func (tem *toEventModel) ReceiveReply(channelID *id.ID, } -// ReceiveReaction is called whenever a reaction to a message is received -// on a given channel. It may be called multiple times on the same reaction, -// it is incumbent on the user of the API to filter such called by message ID -// Messages may arrive our of order, so a reply in theory can arrive before -// the initial message, as a result it may be important to buffer reactions. +// ReceiveReaction is called whenever a reaction to a message is received on a +// given channel. It may be called multiple times on the same reaction. It is +// incumbent on the user of the API to filter such called by message ID. +// +// Messages may arrive our of order, so a reply in theory can arrive before the +// initial message. As a result, it may be important to buffer reactions. func (tem *toEventModel) ReceiveReaction(channelID *id.ID, messageID cryptoChannel.MessageID, reactionTo cryptoChannel.MessageID, senderUsername string, reaction string, timestamp time.Time, @@ -911,8 +931,7 @@ func (tem *toEventModel) ReceiveReaction(channelID *id.ID, int64(round.ID), int64(status)) } -// UpdateSentStatus is called whenever the sent status of a message -// has changed. +// UpdateSentStatus is called whenever the sent status of a message has changed. func (tem *toEventModel) UpdateSentStatus(messageID cryptoChannel.MessageID, status channels.SentStatus) { tem.em.UpdateSentStatus(messageID[:], int64(status)) diff --git a/channels/eventModel.go b/channels/eventModel.go index ba68e417cd823d1b22b5580dcdd159bb1909456f..d5cd20b7d007b4f71f93bf3867690533fe5944cf 100644 --- a/channels/eventModel.go +++ b/channels/eventModel.go @@ -23,7 +23,7 @@ import ( ) // AdminUsername defines the displayed username of admin messages, which are -// unique users for every channel defined by the channel's private key +// unique users for every channel defined by the channel's private key. const AdminUsername = "Admin" type SentStatus uint8 @@ -35,50 +35,55 @@ const ( ) // EventModel is an interface which an external party which uses the channels -// system passed an object which adheres to in order to get events on the channel +// system passed an object which adheres to in order to get events on the +// channel. type EventModel interface { - // JoinChannel is called whenever a channel is joined locally + // JoinChannel is called whenever a channel is joined locally. JoinChannel(channel *cryptoBroadcast.Channel) - // LeaveChannel is called whenever a channel is left locally + // LeaveChannel is called whenever a channel is left locally. LeaveChannel(channelID *id.ID) - // ReceiveMessage is called whenever a message is received on a given channel - // It may be called multiple times on the same message, it is incumbent on - // the user of the API to filter such called by message ID + // ReceiveMessage is called whenever a message is received on a given + // channel. It may be called multiple times on the same message. It is + // incumbent on the user of the API to filter such called by message ID. ReceiveMessage(channelID *id.ID, messageID cryptoChannel.MessageID, - senderUsername string, text string, timestamp time.Time, - lease time.Duration, round rounds.Round, status SentStatus) + senderUsername, text string, timestamp time.Time, lease time.Duration, + round rounds.Round, status SentStatus) - // ReceiveReply is called whenever a message is received which is a reply - // on a given channel. It may be called multiple times on the same message, - // it is incumbent on the user of the API to filter such called by message ID + // ReceiveReply is called whenever a message is received that is a reply on + // a given channel. It may be called multiple times on the same message. It + // is incumbent on the user of the API to filter such called by message ID. + // // Messages may arrive our of order, so a reply in theory can arrive before - // the initial message, as a result it may be important to buffer replies. + // the initial message. As a result, it may be important to buffer replies. ReceiveReply(channelID *id.ID, messageID cryptoChannel.MessageID, reactionTo cryptoChannel.MessageID, senderUsername string, text string, timestamp time.Time, lease time.Duration, round rounds.Round, status SentStatus) // ReceiveReaction is called whenever a reaction to a message is received - // on a given channel. It may be called multiple times on the same reaction, - // it is incumbent on the user of the API to filter such called by message ID + // on a given channel. It may be called multiple times on the same reaction. + // It is incumbent on the user of the API to filter such called by message + // ID. + // // Messages may arrive our of order, so a reply in theory can arrive before - // the initial message, as a result it may be important to buffer reactions. + // the initial message. As a result, it may be important to buffer + // reactions. ReceiveReaction(channelID *id.ID, messageID cryptoChannel.MessageID, reactionTo cryptoChannel.MessageID, senderUsername string, reaction string, timestamp time.Time, lease time.Duration, round rounds.Round, status SentStatus) - // UpdateSentStatus is called whenever the sent status of a message - // has changed + // UpdateSentStatus is called whenever the sent status of a message has + // changed. UpdateSentStatus(messageID cryptoChannel.MessageID, status SentStatus) - //unimplemented - //IgnoreMessage(ChannelID *id.ID, MessageID cryptoChannel.MessageID) - //UnIgnoreMessage(ChannelID *id.ID, MessageID cryptoChannel.MessageID) - //PinMessage(ChannelID *id.ID, MessageID cryptoChannel.MessageID, end time.Time) - //UnPinMessage(ChannelID *id.ID, MessageID cryptoChannel.MessageID) + // unimplemented + // IgnoreMessage(ChannelID *id.ID, MessageID cryptoChannel.MessageID) + // UnIgnoreMessage(ChannelID *id.ID, MessageID cryptoChannel.MessageID) + // PinMessage(ChannelID *id.ID, MessageID cryptoChannel.MessageID, end time.Time) + // UnPinMessage(ChannelID *id.ID, MessageID cryptoChannel.MessageID) } // MessageTypeReceiveMessage defines handlers for messages of various message @@ -88,12 +93,12 @@ type MessageTypeReceiveMessage func(channelID *id.ID, senderUsername string, content []byte, timestamp time.Time, lease time.Duration, round rounds.Round, status SentStatus) -// updateStatusFunc is a function type for EventModel.UpdateSentStatus so it -// can be mocked for testing where used +// updateStatusFunc is a function type for EventModel.UpdateSentStatus so it can +// be mocked for testing where used. type updateStatusFunc func(messageID cryptoChannel.MessageID, status SentStatus) -// events is an internal structure which processes events and stores the -// handlers for those events +// events is an internal structure that processes events and stores the handlers +// for those events. type events struct { model EventModel registered map[MessageType]MessageTypeReceiveMessage @@ -101,7 +106,7 @@ type events struct { } // initEvents initializes the event model and registers default message type -// handlers +// handlers. func initEvents(model EventModel) *events { e := &events{ model: model, @@ -109,7 +114,7 @@ func initEvents(model EventModel) *events { mux: sync.RWMutex{}, } - //set up default message types + // set up default message types e.registered[Text] = e.receiveTextMessage e.registered[AdminText] = e.receiveTextMessage e.registered[Reaction] = e.receiveReaction @@ -117,8 +122,9 @@ func initEvents(model EventModel) *events { } // RegisterReceiveHandler is used to register handlers for non default message -// types s they can be processed by modules. it is important that such modules +// types s they can be processed by modules. It is important that such modules // sync up with the event model implementation. +// // There can only be one handler per message type, and this will return an error // on a multiple registration. func (e *events) RegisterReceiveHandler(messageType MessageType, @@ -126,12 +132,12 @@ func (e *events) RegisterReceiveHandler(messageType MessageType, e.mux.Lock() defer e.mux.Unlock() - //check if the type is already registered + // check if the type is already registered if _, exists := e.registered[messageType]; exists { return MessageTypeAlreadyRegistered } - //register the message type + // register the message type e.registered[messageType] = listener jww.INFO.Printf("Registered Listener for Message Type %s", messageType) return nil @@ -140,8 +146,9 @@ func (e *events) RegisterReceiveHandler(messageType MessageType, type triggerEventFunc func(chID *id.ID, umi *userMessageInternal, receptionID receptionID.EphemeralIdentity, round rounds.Round, status SentStatus) -// triggerEvent is an internal function which is used to trigger message -// reception on a message received from a user (symmetric encryption) +// triggerEvent is an internal function that is used to trigger message +// reception on a message received from a user (symmetric encryption). +// // It will call the appropriate MessageTypeHandler assuming one exists. func (e *events) triggerEvent(chID *id.ID, umi *userMessageInternal, receptionID receptionID.EphemeralIdentity, round rounds.Round, @@ -150,7 +157,7 @@ func (e *events) triggerEvent(chID *id.ID, umi *userMessageInternal, cm := umi.GetChannelMessage() messageType := MessageType(cm.PayloadType) - //check if the type is already registered + // Check if the type is already registered e.mux.RLock() listener, exists := e.registered[messageType] e.mux.RUnlock() @@ -162,10 +169,10 @@ func (e *events) triggerEvent(chID *id.ID, umi *userMessageInternal, return } - //modify the timestamp to reduce the chance message order will be ambiguous + // Modify the timestamp to reduce the chance message order will be ambiguous ts := mutateTimestamp(round.Timestamps[states.QUEUED], umi.GetMessageID()) - //Call the listener. This is already in an instanced event, no new thread needed. + // Call the listener. This is already in an instanced event, no new thread needed. listener(chID, umi.GetMessageID(), messageType, um.Username, cm.Payload, ts, time.Duration(cm.Lease), round, status) return @@ -175,8 +182,9 @@ type triggerAdminEventFunc func(chID *id.ID, cm *ChannelMessage, messageID cryptoChannel.MessageID, receptionID receptionID.EphemeralIdentity, round rounds.Round, status SentStatus) -// triggerAdminEvent is an internal function which is used to trigger message -// reception on a message received from the admin (asymmetric encryption) +// triggerAdminEvent is an internal function that is used to trigger message +// reception on a message received from the admin (asymmetric encryption). +// // It will call the appropriate MessageTypeHandler assuming one exists. func (e *events) triggerAdminEvent(chID *id.ID, cm *ChannelMessage, messageID cryptoChannel.MessageID, @@ -184,7 +192,7 @@ func (e *events) triggerAdminEvent(chID *id.ID, cm *ChannelMessage, status SentStatus) { messageType := MessageType(cm.PayloadType) - //check if the type is already registered + // check if the type is already registered e.mux.RLock() listener, exists := e.registered[messageType] e.mux.RUnlock() @@ -196,20 +204,21 @@ func (e *events) triggerAdminEvent(chID *id.ID, cm *ChannelMessage, return } - //modify the timestamp to reduce the chance message order will be ambiguous + // Modify the timestamp to reduce the chance message order will be ambiguous ts := mutateTimestamp(round.Timestamps[states.QUEUED], messageID) - //Call the listener. This is already in an instanced event, no new thread needed. + // Call the listener. This is already in an instanced event, no new thread needed. listener(chID, messageID, messageType, AdminUsername, cm.Payload, ts, time.Duration(cm.Lease), round, status) return } -// receiveTextMessage is the internal function which handles the reception of +// receiveTextMessage is the internal function that handles the reception of // text messages. It handles both messages and replies and calls the correct // function on the event model. -// If the message has a reply but it is malformed, it will drop the reply and -// write to the log +// +// If the message has a reply, but it is malformed, it will drop the reply and +// write to the log. func (e *events) receiveTextMessage(channelID *id.ID, messageID cryptoChannel.MessageID, messageType MessageType, senderUsername string, content []byte, timestamp time.Time, @@ -250,12 +259,13 @@ func (e *events) receiveTextMessage(channelID *id.ID, timestamp, lease, round, status) } -// receiveReaction is the internal function which handles the reception of +// receiveReaction is the internal function that handles the reception of // Reactions. +// // It does edge checking to ensure the received reaction is just a single emoji. // If the received reaction is not, the reaction is dropped. -// If the messageID for the message the reaction is to is malformed, the reaction -// is dropped. +// If the messageID for the message the reaction is to is malformed, the +// reaction is dropped. func (e *events) receiveReaction(channelID *id.ID, messageID cryptoChannel.MessageID, messageType MessageType, senderUsername string, content []byte, timestamp time.Time, @@ -269,7 +279,7 @@ func (e *events) receiveReaction(channelID *id.ID, return } - //check that the reaction is a single emoji and ignore if it isn't + // check that the reaction is a single emoji and ignore if it isn't if err := ValidateReaction(react.Reaction); err != nil { jww.ERROR.Printf("Failed process reaction %s from %s on channel "+ "%s, type %s, ts: %s, lease: %s, round: %d, due to malformed "+