diff --git a/bindings/connect.go b/bindings/connect.go index 530aa13e5f1e90c655adf30eb3f24d274a092ffe..3c414bd8bfa376434e62a5d4db7cb02e7824601c 100644 --- a/bindings/connect.go +++ b/bindings/connect.go @@ -2,11 +2,9 @@ package bindings import ( "encoding/json" - jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/catalog" "gitlab.com/elixxir/client/connect" e2e2 "gitlab.com/elixxir/client/e2e" - "gitlab.com/elixxir/client/e2e/receive" "gitlab.com/elixxir/crypto/contact" ) @@ -51,8 +49,12 @@ func (c *Client) Connect(recipientContact []byte, myIdentity []byte) ( } // E2ESendReport is the bindings representation of the return values of SendE2E +// Example E2ESendReport: +// {"RoundList":{"Rounds":[1,5,9]}, +// "MessageID":"51Yy47uZbP0o2Y9B/kkreDLTB6opUol3M3mYiY2dcdQ=", +// "Timestamp":1653582683183384000} type E2ESendReport struct { - roundsList + RoundsList MessageID []byte Timestamp int64 } @@ -72,7 +74,7 @@ func (c *Connection) SendE2E(mt int, payload []byte) ([]byte, error) { Timestamp: ts.UnixNano(), } - sr.roundsList = makeRoundsList(rounds) + sr.RoundsList = makeRoundsList(rounds) return json.Marshal(&sr) } @@ -87,80 +89,9 @@ func (c *Connection) GetPartner() []byte { return c.connection.GetPartner().PartnerId().Marshal() } -// Listener provides a callback to hear a message -// An object implementing this interface can be called back when the client -// gets a message of the type that the registerer specified at registration -// time. -type Listener interface { - // Hear is called to receive a message in the UI - Hear(item []byte) - // Returns a name, used for debugging - Name() string -} - -// -type listener struct { - l Listener -} - -// Message is the bindings representation of a receive.Message -type Message struct { - MessageType int - ID []byte - Payload []byte - - Sender []byte - RecipientID []byte - EphemeralID int64 - Timestamp int64 // Message timestamp of when the user sent - - Encrypted bool - RoundId int -} - -// Hear is called to receive a message in the UI -func (l listener) Hear(item receive.Message) { - m := Message{ - MessageType: int(item.MessageType), - ID: item.ID.Marshal(), - Payload: item.Payload, - Sender: item.Sender.Marshal(), - RecipientID: item.RecipientID.Marshal(), - EphemeralID: item.EphemeralID.Int64(), - Timestamp: item.Timestamp.UnixNano(), - Encrypted: item.Encrypted, - RoundId: int(item.Round.ID), - } - result, err := json.Marshal(&m) - if err != nil { - jww.ERROR.Printf("Unable to marshal Message: %+v", err.Error()) - } - l.l.Hear(result) -} - -// Name used for debugging -func (l listener) Name() string { - return l.l.Name() -} - -// ListenerID represents the return type of RegisterListener -type ListenerID struct { - userID []byte - messageType int -} - // RegisterListener is used for E2E reception // and allows for reading data sent from the partner.Manager // Returns marshalled ListenerID -func (c *Connection) RegisterListener(messageType int, newListener Listener) []byte { - listenerId := c.connection.RegisterListener(catalog.MessageType(messageType), listener{l: newListener}) - newlistenerId := ListenerID{ - userID: listenerId.GetUserID().Marshal(), - messageType: int(listenerId.GetMessageType()), - } - result, err := json.Marshal(&newlistenerId) - if err != nil { - jww.ERROR.Printf("Unable to marshal listenerId: %+v", err.Error()) - } - return result +func (c *Connection) RegisterListener(messageType int, newListener Listener) { + _ = c.connection.RegisterListener(catalog.MessageType(messageType), listener{l: newListener}) } diff --git a/bindings/connect_test.go b/bindings/connect_test.go new file mode 100644 index 0000000000000000000000000000000000000000..9093dd3adff088bf82e7df4f9f28661a35b9a75d --- /dev/null +++ b/bindings/connect_test.go @@ -0,0 +1,37 @@ +package bindings + +import ( + "encoding/json" + "gitlab.com/elixxir/crypto/e2e" + "gitlab.com/xx_network/crypto/csprng" + "gitlab.com/xx_network/primitives/id" + "reflect" + "testing" + "time" +) + +func TestE2ESendReport_JSON(t *testing.T) { + rng := csprng.NewSystemRNG() + mid := e2e.MessageID{} + rng.Read(mid[:]) + origRL := []id.Round{1, 5, 9} + rl := makeRoundsList(origRL) + mrl, _ := json.Marshal(&rl) + sr := E2ESendReport{ + RoundsList: rl, + MessageID: mid[:], + Timestamp: time.Now().UnixNano(), + } + srm, _ := json.Marshal(&sr) + t.Log("Marshalled RoundsList") + t.Log(string(mrl)) + t.Log("Marshalled E2ESendReport") + t.Log(string(srm)) + unmarshalled, err := unmarshalRoundsList(srm) + if err != nil { + t.Errorf("Failed to unmarshal rounds list from e2esendreport: %+v", err) + } + if !reflect.DeepEqual(unmarshalled, origRL) { + t.Errorf("Did not receive expected rounds list\n\tExpected: %+v\n\tReceived: %+v\n", rl.Rounds, unmarshalled) + } +} diff --git a/bindings/contact.go b/bindings/contact.go index db84c5c25dce6a5b679dcc097ba93cfd521b7e7c..03234a6f22a6d4c73428c5fe7f9c6fe679a7039c 100644 --- a/bindings/contact.go +++ b/bindings/contact.go @@ -11,16 +11,6 @@ import ( "gitlab.com/xx_network/primitives/id" ) -// Example contact.Contact: -// {"ID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD", // User ID (base64) -// // DH Public key -// "DhPubKey": {"Value":5897856983236448841349236507987372549159552598715284610195378196051089368134573280466076038189672561458883294904902687846973238178822842233241860785766185816826285758360932391225518001053367819933965095474045876471502521426634463472280885866375056810295845912596776232660230744646657460711296721451092117848644200333013666241751893383151321460171904648894952567100917586408052597859524654581795844734383581139432945085822846793496012536562496524464153486043864392759112173594825221043729881090076151145795436552852351725727608490246482831755459144881209180199576801001999800444715698088783576119852633280838566256264123448817581650501316117908817592489368379136557137873340250734512199521378972799693841244968719164574541767128546852594550026407820738695953499407931441091576816112217698417722574592750265071234831071430050448725796700241505489986766630847142868559624597459165280989719389157750815411870806046789780648398173408766005145891531993469827100942349, -// "Fingerprint":16801541511233098363}, -// // Ownership proof for this contact -// "OwnershipProof":"Mjp8KAn7wK/VYYR2BOlG57a9Zh3HA/wHM8R6RnBdGnNCXMR5Mel9ESSYv3g/6b6RXKqTcDHDyd4aaP6g/Ju+dQ==", -// // List of associated facts -// "Facts":[{"Fact":"zezima","T":0}]} - // Identity struct // Example marshalled Identity: // {"ID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD", // User ID (base64) @@ -38,8 +28,7 @@ type Identity struct { DHKeyPrivate []byte } -// MakeIdentity generates a new cryptographic identity for receving -// messages +// MakeIdentity generates a new cryptographic identity for receiving messages func (c *Client) MakeIdentity() ([]byte, error) { stream := c.api.GetRng().GetStream() defer stream.Close() @@ -151,7 +140,9 @@ func GetPubkeyFromContact(marshaled []byte) ([]byte, error) { return json.Marshal(cnt.DhPubKey) } -// TODO: this seems completely pointless, as the FactList type is effectively the same thing +// Fact is an internal fact type for use in the bindings layer +// example marshalled Fact: +// {"Fact":"Zezima","Type":0} type Fact struct { Fact string Type int diff --git a/bindings/inputJson_test.go b/bindings/contact_test.go similarity index 69% rename from bindings/inputJson_test.go rename to bindings/contact_test.go index c636c9969358fc3251b44aa4a99e4009c9d470e5..adbf4d9c2a5d3c48e899ee5ba7f4123f44890034 100644 --- a/bindings/inputJson_test.go +++ b/bindings/contact_test.go @@ -2,12 +2,9 @@ package bindings import ( "encoding/json" - "gitlab.com/elixxir/client/restlike" "gitlab.com/elixxir/crypto/cmix" - "gitlab.com/elixxir/crypto/contact" "gitlab.com/elixxir/crypto/cyclic" dh "gitlab.com/elixxir/crypto/diffieHellman" - "gitlab.com/elixxir/primitives/fact" "gitlab.com/xx_network/crypto/csprng" "gitlab.com/xx_network/crypto/large" "gitlab.com/xx_network/crypto/signature/rsa" @@ -15,25 +12,7 @@ import ( "testing" ) -func getGroup() *cyclic.Group { - return cyclic.NewGroup( - large.NewIntFromString("E2EE983D031DC1DB6F1A7A67DF0E9A8E5561DB8E8D4941"+ - "3394C049B7A8ACCEDC298708F121951D9CF920EC5D146727AA4AE535B0922C688"+ - "B55B3DD2AEDF6C01C94764DAB937935AA83BE36E67760713AB44A6337C20E7861"+ - "575E745D31F8B9E9AD8412118C62A3E2E29DF46B0864D0C951C394A5CBBDC6ADC"+ - "718DD2A3E041023DBB5AB23EBB4742DE9C1687B5B34FA48C3521632C4A530E8FF"+ - "B1BC51DADDF453B0B2717C2BC6669ED76B4BDD5C9FF558E88F26E5785302BEDBC"+ - "A23EAC5ACE92096EE8A60642FB61E8F3D24990B8CB12EE448EEF78E184C7242DD"+ - "161C7738F32BF29A841698978825B4111B4BC3E1E198455095958333D776D8B2B"+ - "EEED3A1A1A221A6E37E664A64B83981C46FFDDC1A45E3D5211AAF8BFBC072768C"+ - "4F50D7D7803D2D4F278DE8014A47323631D7E064DE81C0C6BFA43EF0E6998860F"+ - "1390B5D3FEACAF1696015CB79C3F9C2D93D961120CD0E5F12CBB687EAB045241F"+ - "96789C38E89D796138E6319BE62E35D87B1048CA28BE389B575E994DCA7554715"+ - "84A09EC723742DC35873847AEF49F66E43873", 16), - large.NewIntFromString("2", 16)) -} - -func TestInputMarshalling(t *testing.T) { +func TestIdentity_JSON(t *testing.T) { rng := csprng.NewSystemRNG() uid := id.NewIdFromString("zezima", id.User, t) salt := cmix.NewSalt(rng, 32) @@ -41,7 +20,6 @@ func TestInputMarshalling(t *testing.T) { grp := getGroup() dhpk := dh.GeneratePrivateKey(64, grp, rng) dhpkJson, _ := dhpk.MarshalJSON() - dhpub := dh.GeneratePublicKey(dhpk, grp) op := make([]byte, 64) _, _ = rng.Read(op) identity := Identity{ @@ -50,35 +28,12 @@ func TestInputMarshalling(t *testing.T) { Salt: salt, DHKeyPrivate: dhpkJson, } - c := contact.Contact{ - ID: uid, - DhPubKey: dhpub, - OwnershipProof: op, - Facts: fact.FactList{ - { - Fact: "zezima", - T: fact.Username, - }, - }, - } - im, _ := json.Marshal(identity) - cm, _ := json.Marshal(c) - - rl := roundsList{ - 1001, 1003, 1006, - } - rm, _ := json.Marshal(rl) - - restlikeMessage := RestlikeMessage{ - Version: 1, - Headers: []byte("contents:application/json"), - Content: []byte("This is a restlike message"), - Method: int(restlike.Post), - URI: "xx://CmixRestlike/rest", - } - rlm, _ := json.Marshal(restlikeMessage) + t.Log("Marshalled Identity object") + t.Log(string(im)) +} +func TestFacts_JSON(t *testing.T) { fl := []Fact{ { Fact: "Zezima", @@ -90,14 +45,24 @@ func TestInputMarshalling(t *testing.T) { }, } flm, _ := json.Marshal(fl) - t.Log("Marshalled Identity object") - t.Log(string(im)) - t.Log("Marshalled contact.Contact object") - t.Log(string(cm)) - t.Log("Marshalled roundsList object") - t.Log(string(rm)) - t.Log("Marshalled RestlikeMessage object") - t.Log(string(rlm)) t.Log("Marshalled []Fact") t.Log(string(flm)) } + +func getGroup() *cyclic.Group { + return cyclic.NewGroup( + large.NewIntFromString("E2EE983D031DC1DB6F1A7A67DF0E9A8E5561DB8E8D4941"+ + "3394C049B7A8ACCEDC298708F121951D9CF920EC5D146727AA4AE535B0922C688"+ + "B55B3DD2AEDF6C01C94764DAB937935AA83BE36E67760713AB44A6337C20E7861"+ + "575E745D31F8B9E9AD8412118C62A3E2E29DF46B0864D0C951C394A5CBBDC6ADC"+ + "718DD2A3E041023DBB5AB23EBB4742DE9C1687B5B34FA48C3521632C4A530E8FF"+ + "B1BC51DADDF453B0B2717C2BC6669ED76B4BDD5C9FF558E88F26E5785302BEDBC"+ + "A23EAC5ACE92096EE8A60642FB61E8F3D24990B8CB12EE448EEF78E184C7242DD"+ + "161C7738F32BF29A841698978825B4111B4BC3E1E198455095958333D776D8B2B"+ + "EEED3A1A1A221A6E37E664A64B83981C46FFDDC1A45E3D5211AAF8BFBC072768C"+ + "4F50D7D7803D2D4F278DE8014A47323631D7E064DE81C0C6BFA43EF0E6998860F"+ + "1390B5D3FEACAF1696015CB79C3F9C2D93D961120CD0E5F12CBB687EAB045241F"+ + "96789C38E89D796138E6319BE62E35D87B1048CA28BE389B575E994DCA7554715"+ + "84A09EC723742DC35873847AEF49F66E43873", 16), + large.NewIntFromString("2", 16)) +} diff --git a/bindings/delivery.go b/bindings/delivery.go index 6b181741fb2c4ae6e68f182d190190e095e0bf5a..3066880c4ed27a9474b9cc8bcd4aedcb2ff5c194 100644 --- a/bindings/delivery.go +++ b/bindings/delivery.go @@ -12,33 +12,36 @@ import ( // Example marshalled roundList object: // [1001,1003,1006] -type roundsList []int +type RoundsList struct { + Rounds []int +} -func (rl roundsList) Marshal() ([]byte, error) { +func (rl RoundsList) Marshal() ([]byte, error) { return json.Marshal(&rl) } +// unmarshalRoundsList accepts a marshalled E2ESendReport object & unmarshalls it into a RoundsList object, returning a list of id.Round func unmarshalRoundsList(marshaled []byte) ([]id.Round, error) { - rl := roundsList{} - err := json.Unmarshal(marshaled, &rl) + sr := RoundsList{} + err := json.Unmarshal(marshaled, &sr) if err != nil { return nil, err } - realRl := make([]id.Round, len(rl)) + realRl := make([]id.Round, len(sr.Rounds)) - for _, rid := range rl { - realRl = append(realRl, id.Round(rid)) + for i, rid := range sr.Rounds { + realRl[i] = id.Round(rid) } return realRl, nil } -func makeRoundsList(rounds []id.Round) roundsList { - rl := make(roundsList, 0, len(rounds)) +func makeRoundsList(rounds []id.Round) RoundsList { + rl := RoundsList{} for _, rid := range rounds { - rl = append(rl, int(rid)) + rl.Rounds = append(rl.Rounds, int(rid)) } return rl } diff --git a/bindings/listener.go b/bindings/listener.go new file mode 100644 index 0000000000000000000000000000000000000000..b284687beadd802985b6023528989a5401b7dbd0 --- /dev/null +++ b/bindings/listener.go @@ -0,0 +1,74 @@ +package bindings + +import ( + "encoding/json" + jww "github.com/spf13/jwalterweatherman" + "gitlab.com/elixxir/client/e2e/receive" +) + +// Listener provides a callback to hear a message +// An object implementing this interface can be called back when the client +// gets a message of the type that the registerer specified at registration +// time. +type Listener interface { + // Hear is called to receive a message in the UI + // Accepts a marshalled Message object + Hear(item []byte) + // Name returns a name, used for debugging + Name() string +} + +// listener is an object internal to bindings which matches the interface expected by RegisterListener +// it wraps the Listener type, which is usable by the bindings layer +type listener struct { + l Listener +} + +// Message is the bindings representation of a receive.Message +// Example Message format: +// {"MessageType":1, +// "ID":"EB/70R5HYEw5htZ4Hg9ondrn3+cAc/lH2G0mjQMja3w=", +// "Payload":"7TzZKgNphT5UooNM7mDSwtVcIs8AIu4vMKm4ld6GSR8YX5GrHirixUBAejmsgdroRJyo06TkIVef7UM9FN8YfQ==", +// "Sender":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD", +// "RecipientID":"amFrZXh4MzYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD", +// "EphemeralID":17,"Timestamp":1653580439357351000, +// "Encrypted":false, +// "RoundId":19} +type Message struct { + MessageType int + ID []byte + Payload []byte + + Sender []byte + RecipientID []byte + EphemeralID int64 + Timestamp int64 // Message timestamp of when the user sent + + Encrypted bool + RoundId int +} + +// Hear is called to receive a message in the UI +func (l listener) Hear(item receive.Message) { + m := Message{ + MessageType: int(item.MessageType), + ID: item.ID.Marshal(), + Payload: item.Payload, + Sender: item.Sender.Marshal(), + RecipientID: item.RecipientID.Marshal(), + EphemeralID: item.EphemeralID.Int64(), + Timestamp: item.Timestamp.UnixNano(), + Encrypted: item.Encrypted, + RoundId: int(item.Round.ID), + } + result, err := json.Marshal(&m) + if err != nil { + jww.ERROR.Printf("Unable to marshal Message: %+v", err.Error()) + } + l.l.Hear(result) +} + +// Name used for debugging +func (l listener) Name() string { + return l.l.Name() +} diff --git a/bindings/listener_test.go b/bindings/listener_test.go new file mode 100644 index 0000000000000000000000000000000000000000..c8fd03ec88cfea35ab5cb7a5431f05fb7157907d --- /dev/null +++ b/bindings/listener_test.go @@ -0,0 +1,34 @@ +package bindings + +import ( + "encoding/json" + "gitlab.com/elixxir/crypto/e2e" + "gitlab.com/xx_network/crypto/csprng" + "gitlab.com/xx_network/primitives/id" + "testing" + "time" +) + +func TestMessage_Json(t *testing.T) { + rng := csprng.NewSystemRNG() + messageID := e2e.MessageID{} + rng.Read(messageID[:]) + payload := make([]byte, 64) + rng.Read(payload) + sender := id.NewIdFromString("zezima", id.User, t) + receiver := id.NewIdFromString("jakexx360", id.User, t) + m := Message{ + MessageType: 1, + ID: messageID[:], + Payload: payload, + Sender: sender.Marshal(), + RecipientID: receiver.Marshal(), + EphemeralID: 17, + Timestamp: time.Now().UnixNano(), + Encrypted: false, + RoundId: 19, + } + mm, _ := json.Marshal(m) + t.Log("Marshalled Message") + t.Log(string(mm)) +}