Skip to content
Snippets Groups Projects
Commit beaf4ced authored by Benjamin Wenger's avatar Benjamin Wenger
Browse files

Merge remote-tracking branch 'origin/channelsImpl' into channelsImpl

parents 25fd7afb 82c93936
No related branches found
No related tags found
5 merge requests!510Release,!419rewrote the health tracker to both consider if there are waiting rounds and...,!371[Channel RSAtoPrivate] Implement Reverse Asymmetric in Client/Broadcast,!354Channels impl,!340Project/channels
...@@ -10,8 +10,8 @@ import ( ...@@ -10,8 +10,8 @@ import (
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
) )
// the adminListener adheres to the broadcast listener interface and is used // adminListener adheres to the broadcast listener interface and is used when
// when admin messages are received on the channel // admin messages are received on the channel.
type adminListener struct { type adminListener struct {
chID *id.ID chID *id.ID
trigger triggerAdminEventFunc trigger triggerAdminEventFunc
...@@ -23,25 +23,25 @@ func (al *adminListener) Listen(payload []byte, ...@@ -23,25 +23,25 @@ func (al *adminListener) Listen(payload []byte,
// Remove the padding // Remove the padding
payloadUnpadded, err := broadcast.DecodeSizedBroadcast(payload) payloadUnpadded, err := broadcast.DecodeSizedBroadcast(payload)
if err != nil { if err != nil {
jww.WARN.Printf("Failed to strip the padding on User Message "+ jww.WARN.Printf(
"on channel %s", al.chID) "Failed to strip the padding on User Message on channel %s", al.chID)
return return
} }
//get the message ID // Get the message ID
msgID := channel.MakeMessageID(payloadUnpadded) msgID := channel.MakeMessageID(payloadUnpadded)
// Decode the message as a channel message // Decode the message as a channel message
cm := &ChannelMessage{} cm := &ChannelMessage{}
if err = proto.Unmarshal(payloadUnpadded, cm); err != nil { if err = proto.Unmarshal(payloadUnpadded, cm); err != nil {
jww.WARN.Printf("Failed to unmarshal Channel Message from Admin"+ jww.WARN.Printf("Failed to unmarshal Channel Message from Admin on "+
" on channel %s", al.chID) "channel %s", al.chID)
return return
} }
/* CRYPTOGRAPHICALLY RELEVANT CHECKS */ /* CRYPTOGRAPHICALLY RELEVANT CHECKS */
// check the round to ensure the message is not a replay // Check the round to ensure that the message is not a replay
if id.Round(cm.RoundID) != round.ID { if id.Round(cm.RoundID) != round.ID {
jww.WARN.Printf("The round message %s send on %s referenced "+ jww.WARN.Printf("The round message %s send on %s referenced "+
"(%d) was not the same as the round the message was found on (%d)", "(%d) was not the same as the round the message was found on (%d)",
......
...@@ -25,9 +25,9 @@ type triggerAdminEventDummy struct { ...@@ -25,9 +25,9 @@ type triggerAdminEventDummy struct {
round rounds.Round round rounds.Round
} }
func (taed *triggerAdminEventDummy) triggerAdminEvent(chID *id.ID, cm *ChannelMessage, func (taed *triggerAdminEventDummy) triggerAdminEvent(chID *id.ID,
messageID cryptoChannel.MessageID, receptionID receptionID.EphemeralIdentity, cm *ChannelMessage, messageID cryptoChannel.MessageID,
round rounds.Round) { receptionID receptionID.EphemeralIdentity, round rounds.Round) {
taed.gotData = true taed.gotData = true
taed.chID = chID taed.chID = chID
...@@ -37,10 +37,10 @@ func (taed *triggerAdminEventDummy) triggerAdminEvent(chID *id.ID, cm *ChannelMe ...@@ -37,10 +37,10 @@ func (taed *triggerAdminEventDummy) triggerAdminEvent(chID *id.ID, cm *ChannelMe
taed.round = round taed.round = round
} }
// Tests the happy path // Tests the happy path.
func TestAdminListener_Listen(t *testing.T) { func TestAdminListener_Listen(t *testing.T) {
//build inputs // Build inputs
chID := &id.ID{} chID := &id.ID{}
chID[0] = 1 chID[0] = 1
...@@ -67,7 +67,7 @@ func TestAdminListener_Listen(t *testing.T) { ...@@ -67,7 +67,7 @@ func TestAdminListener_Listen(t *testing.T) {
msgID := cryptoChannel.MakeMessageID(cmSerial) msgID := cryptoChannel.MakeMessageID(cmSerial)
//build the listener // Build the listener
dummy := &triggerAdminEventDummy{} dummy := &triggerAdminEventDummy{}
al := adminListener{ al := adminListener{
...@@ -75,10 +75,10 @@ func TestAdminListener_Listen(t *testing.T) { ...@@ -75,10 +75,10 @@ func TestAdminListener_Listen(t *testing.T) {
trigger: dummy.triggerAdminEvent, trigger: dummy.triggerAdminEvent,
} }
//call the listener // Call the listener
al.Listen(chMsgSerialSized, receptionID.EphemeralIdentity{}, r) al.Listen(chMsgSerialSized, receptionID.EphemeralIdentity{}, r)
//check the results // Check the results
if !dummy.gotData { if !dummy.gotData {
t.Fatalf("No data returned after valid listen") t.Fatalf("No data returned after valid listen")
} }
...@@ -103,8 +103,8 @@ func TestAdminListener_Listen(t *testing.T) { ...@@ -103,8 +103,8 @@ func TestAdminListener_Listen(t *testing.T) {
} }
} }
// Tests that the message is rejected when the round it came on doesnt // Tests that the message is rejected when the round it came on doesn't match
// match the round in the channel message // the round in the channel message.
func TestAdminListener_Listen_BadRound(t *testing.T) { func TestAdminListener_Listen_BadRound(t *testing.T) {
// build inputs // build inputs
...@@ -116,7 +116,7 @@ func TestAdminListener_Listen_BadRound(t *testing.T) { ...@@ -116,7 +116,7 @@ func TestAdminListener_Listen_BadRound(t *testing.T) {
cm := &ChannelMessage{ cm := &ChannelMessage{
Lease: int64(time.Hour), Lease: int64(time.Hour),
// different from the round above // Different from the round above
RoundID: 69, RoundID: 69,
PayloadType: 42, PayloadType: 42,
Payload: []byte("blarg"), Payload: []byte("blarg"),
...@@ -133,7 +133,7 @@ func TestAdminListener_Listen_BadRound(t *testing.T) { ...@@ -133,7 +133,7 @@ func TestAdminListener_Listen_BadRound(t *testing.T) {
t.Fatalf("Failed to size channel message: %+v", err) t.Fatalf("Failed to size channel message: %+v", err)
} }
//build the listener // Build the listener
dummy := &triggerAdminEventDummy{} dummy := &triggerAdminEventDummy{}
al := adminListener{ al := adminListener{
...@@ -141,7 +141,7 @@ func TestAdminListener_Listen_BadRound(t *testing.T) { ...@@ -141,7 +141,7 @@ func TestAdminListener_Listen_BadRound(t *testing.T) {
trigger: dummy.triggerAdminEvent, trigger: dummy.triggerAdminEvent,
} }
//call the listener // Call the listener
al.Listen(chMsgSerialSized, receptionID.EphemeralIdentity{}, r) al.Listen(chMsgSerialSized, receptionID.EphemeralIdentity{}, r)
// check the results // check the results
...@@ -152,10 +152,10 @@ func TestAdminListener_Listen_BadRound(t *testing.T) { ...@@ -152,10 +152,10 @@ func TestAdminListener_Listen_BadRound(t *testing.T) {
} }
// Tests that the message is rejected when the channel message is malformed // Tests that the message is rejected when the channel message is malformed.
func TestAdminListener_Listen_BadChannelMessage(t *testing.T) { func TestAdminListener_Listen_BadChannelMessage(t *testing.T) {
//build inputs // Build inputs
chID := &id.ID{} chID := &id.ID{}
chID[0] = 1 chID[0] = 1
...@@ -170,7 +170,7 @@ func TestAdminListener_Listen_BadChannelMessage(t *testing.T) { ...@@ -170,7 +170,7 @@ func TestAdminListener_Listen_BadChannelMessage(t *testing.T) {
t.Fatalf("Failed to size channel message: %+v", err) t.Fatalf("Failed to size channel message: %+v", err)
} }
//build the listener // Build the listener
dummy := &triggerAdminEventDummy{} dummy := &triggerAdminEventDummy{}
al := adminListener{ al := adminListener{
...@@ -178,10 +178,10 @@ func TestAdminListener_Listen_BadChannelMessage(t *testing.T) { ...@@ -178,10 +178,10 @@ func TestAdminListener_Listen_BadChannelMessage(t *testing.T) {
trigger: dummy.triggerAdminEvent, trigger: dummy.triggerAdminEvent,
} }
//call the listener // Call the listener
al.Listen(chMsgSerialSized, receptionID.EphemeralIdentity{}, r) al.Listen(chMsgSerialSized, receptionID.EphemeralIdentity{}, r)
//check the results // Check the results
if dummy.gotData { if dummy.gotData {
t.Fatalf("payload handled when it should have failed due to " + t.Fatalf("payload handled when it should have failed due to " +
"a malformed channel message") "a malformed channel message")
...@@ -190,7 +190,7 @@ func TestAdminListener_Listen_BadChannelMessage(t *testing.T) { ...@@ -190,7 +190,7 @@ func TestAdminListener_Listen_BadChannelMessage(t *testing.T) {
} }
// Tests that the message is rejected when the sized broadcast message is // Tests that the message is rejected when the sized broadcast message is
//malformed // malformed.
func TestAdminListener_Listen_BadSizedBroadcast(t *testing.T) { func TestAdminListener_Listen_BadSizedBroadcast(t *testing.T) {
// build inputs // build inputs
...@@ -202,7 +202,7 @@ func TestAdminListener_Listen_BadSizedBroadcast(t *testing.T) { ...@@ -202,7 +202,7 @@ func TestAdminListener_Listen_BadSizedBroadcast(t *testing.T) {
cm := &ChannelMessage{ cm := &ChannelMessage{
Lease: int64(time.Hour), Lease: int64(time.Hour),
// different from the round above // Different from the round above
RoundID: 69, RoundID: 69,
PayloadType: 42, PayloadType: 42,
Payload: []byte("blarg"), Payload: []byte("blarg"),
...@@ -219,10 +219,10 @@ func TestAdminListener_Listen_BadSizedBroadcast(t *testing.T) { ...@@ -219,10 +219,10 @@ func TestAdminListener_Listen_BadSizedBroadcast(t *testing.T) {
t.Fatalf("Failed to size channel message: %+v", err) t.Fatalf("Failed to size channel message: %+v", err)
} }
//remove half the sized broadcast to make it malformed // Remove half the sized broadcast to make it malformed
chMsgSerialSized = chMsgSerialSized[:broadcast.GetSizedBroadcastSize(chMsgSerialSized)/2] chMsgSerialSized = chMsgSerialSized[:broadcast.GetSizedBroadcastSize(chMsgSerialSized)/2]
//build the listener // Build the listener
dummy := &triggerAdminEventDummy{} dummy := &triggerAdminEventDummy{}
al := adminListener{ al := adminListener{
...@@ -230,10 +230,10 @@ func TestAdminListener_Listen_BadSizedBroadcast(t *testing.T) { ...@@ -230,10 +230,10 @@ func TestAdminListener_Listen_BadSizedBroadcast(t *testing.T) {
trigger: dummy.triggerAdminEvent, trigger: dummy.triggerAdminEvent,
} }
//call the listener // Call the listener
al.Listen(chMsgSerialSized, receptionID.EphemeralIdentity{}, r) al.Listen(chMsgSerialSized, receptionID.EphemeralIdentity{}, r)
//check the results // Check the results
if dummy.gotData { if dummy.gotData {
t.Fatalf("payload handled when it should have failed due to " + t.Fatalf("payload handled when it should have failed due to " +
"a malformed sized broadcast") "a malformed sized broadcast")
......
...@@ -10,40 +10,42 @@ syntax = "proto3"; ...@@ -10,40 +10,42 @@ syntax = "proto3";
package parse; package parse;
option go_package = "/channels"; option go_package = "/channels";
// ChannelMessage is transmitted by the channel. Effectively it is // ChannelMessage is transmitted by the channel. Effectively it is a command for
// a command for the channel sent by a user with admin access of the channel. // the channel sent by a user with admin access of the channel.
message ChannelMessage{ message ChannelMessage{
// Lease is the length that this channel message will take effect. // Lease is the length that this channel message will take effect.
int64 Lease = 1; int64 Lease = 1;
// The round this message was sent on // The round this message was sent on.
uint64 RoundID = 2; uint64 RoundID = 2;
// The type the below payload is. This may be some form of channel command, // The type the below payload is. This may be some form of channel command,
// such as BAN<username1>. // such as BAN<username1>.
uint32 PayloadType = 3; uint32 PayloadType = 3;
// Payload is the actual message payload. It will be processed differently based // Payload is the actual message payload. It will be processed differently
// on the PayloadType // based on the PayloadType.
bytes Payload = 4; bytes Payload = 4;
} }
// UserMessage is a message sent by a user who is a member within the channel. // UserMessage is a message sent by a user who is a member within the channel.
message UserMessage { message UserMessage {
// Message contains the contents of the message. This is typically what // Message contains the contents of the message. This is typically what the
// the end-user has submitted to the channel. This is a serialization of the // end-user has submitted to the channel. This is a serialization of the
// ChannelMessage. // ChannelMessage.
bytes Message = 1; bytes Message = 1;
// ValidationSignature is the signature validating this user owns // ValidationSignature is the signature validating this user owns their
// their username and may send messages to the channel under this username. // username and may send messages to the channel under this username. This
// This signature is provided by UD and may be validated by all members of // signature is provided by UD and may be validated by all members of the
// the channel. // channel.
//
// ValidationSignature = Sig(UD_ECCPrivKey, Username | ECCPublicKey | UsernameLease) // ValidationSignature = Sig(UD_ECCPrivKey, Username | ECCPublicKey | UsernameLease)
bytes ValidationSignature = 2; bytes ValidationSignature = 2;
// Signature is the signature proving this message has been // Signature is the signature proving this message has been sent by the
// sent by the owner of this user's public key. // owner of this user's public key.
//
// Signature = Sig(User_ECCPublicKey, Message) // Signature = Sig(User_ECCPublicKey, Message)
bytes Signature = 3; bytes Signature = 3;
...@@ -51,10 +53,11 @@ message UserMessage { ...@@ -51,10 +53,11 @@ message UserMessage {
// with UD. // with UD.
string Username = 4; string Username = 4;
// ECCPublicKey is the user's EC Public key. This is provided by the network. // ECCPublicKey is the user's EC Public key. This is provided by the
// network.
bytes ECCPublicKey = 5; bytes ECCPublicKey = 5;
// UsernameLease is the lease that has been provided to the username. // UsernameLease is the lease that has been provided to the username. This
// This value is provide by UD. // value is provide by UD.
int64 UsernameLease = 6; int64 UsernameLease = 6;
} }
...@@ -7,10 +7,10 @@ import ( ...@@ -7,10 +7,10 @@ import (
const findEmoji = "(\\\\u00a9|\\\\u00ae|[\\\\u2000-\\\\u3300]|\\\\ud83c[\\\\ud000-\\\\udfff]|\\\\ud83d[\\\\ud000-\\\\udfff]|\\\\ud83e[\\\\ud000-\\\\udfff])" const findEmoji = "(\\\\u00a9|\\\\u00ae|[\\\\u2000-\\\\u3300]|\\\\ud83c[\\\\ud000-\\\\udfff]|\\\\ud83d[\\\\ud000-\\\\udfff]|\\\\ud83e[\\\\ud000-\\\\udfff])"
var InvalidReaction = errors.New("The reaction is not valid, " + var InvalidReaction = errors.New(
"it must be a single emoji") "The reaction is not valid, it must be a single emoji")
// ValidateReaction checks that the reaction only contains a single Emoji // ValidateReaction checks that the reaction only contains a single emoji.
func ValidateReaction(reaction string) error { func ValidateReaction(reaction string) error {
reactRunes := []rune(reaction) reactRunes := []rune(reaction)
if len(reactRunes) > 1 { if len(reactRunes) > 1 {
......
...@@ -23,18 +23,17 @@ type manager struct { ...@@ -23,18 +23,17 @@ type manager struct {
// Events model // Events model
*events *events
// make the function used to create broadcasts be a pointer so it // Makes the function that is used to create broadcasts be a pointer so that
// can be replaced in tests // it can be replaced in tests
broadcastMaker broadcast.NewBroadcastChannelFunc broadcastMaker broadcast.NewBroadcastChannelFunc
} }
// NewManager Creates a new channel.Manager. // NewManager creates a new channel.Manager. It prefixes the KV with the
// Prefix's teh KV with the username so multiple instances for multiple // username so that multiple instances for multiple users will not error.
// users will not error.
func NewManager(kv *versioned.KV, client broadcast.Client, func NewManager(kv *versioned.KV, client broadcast.Client,
rng *fastRNG.StreamGenerator, name NameService, model EventModel) Manager { rng *fastRNG.StreamGenerator, name NameService, model EventModel) Manager {
//prefix the kv with the username so multiple can be run // Prefix the kv with the username so multiple can be run
kv = kv.Prefix(name.GetUsername()) kv = kv.Prefix(name.GetUsername())
m := manager{ m := manager{
...@@ -52,24 +51,28 @@ func NewManager(kv *versioned.KV, client broadcast.Client, ...@@ -52,24 +51,28 @@ func NewManager(kv *versioned.KV, client broadcast.Client,
return &m return &m
} }
// JoinChannel joins the given channel. Will fail if the channel // JoinChannel joins the given channel. It will fail if the channel has already
// has already been joined. // been joined.
func (m *manager) JoinChannel(channel cryptoBroadcast.Channel) error { func (m *manager) JoinChannel(channel cryptoBroadcast.Channel) error {
err := m.addChannel(channel) err := m.addChannel(channel)
if err != nil { if err != nil {
return err return err
} }
go m.events.model.JoinChannel(channel) go m.events.model.JoinChannel(channel)
return nil return nil
} }
// LeaveChannel leaves the given channel. It will return an error // LeaveChannel leaves the given channel. It will return an error if the channel
// if the channel was not previously joined. // was not previously joined.
func (m *manager) LeaveChannel(channelId *id.ID) error { func (m *manager) LeaveChannel(channelID *id.ID) error {
err := m.removeChannel(channelId) err := m.removeChannel(channelID)
if err != nil { if err != nil {
return err return err
} }
go m.events.model.LeaveChannel(channelId)
go m.events.model.LeaveChannel(channelID)
return nil return nil
} }
...@@ -8,7 +8,7 @@ import ( ...@@ -8,7 +8,7 @@ import (
) )
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
// many tests trigger warn prints, set the out threshold so the warns // Many tests trigger WARN prints;, set the out threshold so the WARN prints
// can be seen in the logs // can be seen in the logs
jww.SetStdoutThreshold(jww.LevelWarn) jww.SetStdoutThreshold(jww.LevelWarn)
os.Exit(m.Run()) os.Exit(m.Run())
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment