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

fixed the implementation of the bindings so everything should be avalible

parent a64a0910
Branches
Tags
No related merge requests found
...@@ -59,8 +59,7 @@ func (c *Client) RegisterAuthCallbacks(request auth.RequestCallback, ...@@ -59,8 +59,7 @@ func (c *Client) RegisterAuthCallbacks(request auth.RequestCallback,
// An error will be returned if a channel already exists, if a request doest // An error will be returned if a channel already exists, if a request doest
// exist, or if the passed in contact does not exactly match the received // exist, or if the passed in contact does not exactly match the received
// request // request
func (c *Client) ConfirmAuthenticatedChannel(recipient, me contact.Contact, func (c *Client) ConfirmAuthenticatedChannel(recipient contact.Contact) error {
message string) error {
jww.INFO.Printf("RequestAuthenticatedChannel(%s)", recipient.ID) jww.INFO.Printf("RequestAuthenticatedChannel(%s)", recipient.ID)
if !c.network.GetHealthTracker().IsHealthy() { if !c.network.GetHealthTracker().IsHealthy() {
......
...@@ -153,7 +153,7 @@ func handleRequest(cmixMsg format.Message, myHistoricalPrivKey *cyclic.Int, ...@@ -153,7 +153,7 @@ func handleRequest(cmixMsg format.Message, myHistoricalPrivKey *cyclic.Int,
} }
//process the inner payload //process the inner payload
facts, msg, err := contact.UnstringifyFacts( facts, msg, err := contact.UnstringifyFactList(
string(requestFmt.msgPayload)) string(requestFmt.msgPayload))
if err != nil { if err != nil {
jww.WARN.Printf("failed to parse facts and message "+ jww.WARN.Printf("failed to parse facts and message "+
......
...@@ -75,7 +75,7 @@ func RequestAuth(partner, me contact.Contact, message string, rng io.Reader, ...@@ -75,7 +75,7 @@ func RequestAuth(partner, me contact.Contact, message string, rng io.Reader,
} }
//check the payload fits //check the payload fits
facts := me.StringifyFacts() facts := me.Facts.Stringify()
msgPayload := facts + message + eol msgPayload := facts + message + eol
msgPayloadBytes := []byte(msgPayload) msgPayloadBytes := []byte(msgPayload)
......
package bindings package bindings
import "gitlab.com/elixxir/client/interfaces/bind" import (
"errors"
"fmt"
"gitlab.com/elixxir/client/interfaces/contact"
)
// Create an insecure e2e relationship with a precanned user // Create an insecure e2e relationship with a precanned user
func (c *Client) MakePrecannedAuthenticatedChannel(precannedID int) bind.Contact { func (c *Client) MakePrecannedAuthenticatedChannel(precannedID int) (*Contact, error) {
return c.api.MakePrecannedContact(uint(precannedID)) precannedContact, err := c.api.MakePrecannedAuthenticatedChannel(uint(precannedID))
if err != nil {
return nil, errors.New(fmt.Sprintf("Failed to "+
"MakePrecannedAuthenticatedChannel: %+v", err))
}
return &Contact{c: &precannedContact}, nil
}
// RequestAuthenticatedChannel sends a request to another party to establish an
// authenticated channel
// It will not run if the network status is not healthy
// An error will be returned if a channel already exists, if a request was
// already received, or if a request was already sent
// When a confirmation occurs, the channel will be created and the callback
// will be called
//
// This function takes the marshaled send report to ensure a memory leak does
// not occur as a result of both sides of the bindings holding a refrence to
// the same pointer.
func (c *Client) RequestAuthenticatedChannel(recipientMarshaled,
meMarshaled []byte, message string) error {
recipent, err := contact.Unmarshal(recipientMarshaled)
if err != nil {
return errors.New(fmt.Sprintf("Failed to "+
"RequestAuthenticatedChannel: Failed to Unmarshal Recipent: "+
"%+v", err))
}
me, err := contact.Unmarshal(meMarshaled)
if err != nil {
return errors.New(fmt.Sprintf("Failed to "+
"RequestAuthenticatedChannel: Failed to Unmarshal Me: %+v", err))
}
return c.api.RequestAuthenticatedChannel(recipent, me, message)
}
// RegisterAuthCallbacks registers both callbacks for authenticated channels.
// This can only be called once
func (c *Client) RegisterAuthCallbacks(request AuthRequestCallback,
confirm AuthConfirmCallback) error {
requestFunc := func(requestor contact.Contact, message string) {
requestorBind := &Contact{c: &requestor}
request.Callback(requestorBind, message)
}
confirmFunc := func(partner contact.Contact) {
partnerBind := &Contact{c: &partner}
confirm.Callback(partnerBind)
}
return c.api.RegisterAuthCallbacks(requestFunc, confirmFunc)
}
// ConfirmAuthenticatedChannel creates an authenticated channel out of a valid
// received request and sends a message to the requestor that the request has
// been confirmed
// It will not run if the network status is not healthy
// An error will be returned if a channel already exists, if a request doest
// exist, or if the passed in contact does not exactly match the received
// request
func (c *Client) ConfirmAuthenticatedChannel(recipientMarshaled []byte) error {
recipent, err := contact.Unmarshal(recipientMarshaled)
if err != nil {
return errors.New(fmt.Sprintf("Failed to "+
"ConfirmAuthenticatedChannel: Failed to Unmarshal Recipient: "+
"%+v", err))
}
return c.api.ConfirmAuthenticatedChannel(recipent)
}
// VerifyOwnership checks if the ownership proof on a passed contact matches the
// identity in a verified contact
func (c *Client) VerifyOwnership(receivedMarshaled, verifiedMarshaled []byte) (bool, error) {
received, err := contact.Unmarshal(receivedMarshaled)
if err != nil {
return false, errors.New(fmt.Sprintf("Failed to "+
"VerifyOwnership: Failed to Unmarshal Received: %+v", err))
}
verified, err := contact.Unmarshal(verifiedMarshaled)
if err != nil {
return false, errors.New(fmt.Sprintf("Failed to "+
"VerifyOwnership: Failed to Unmarshal Verified: %+v", err))
}
return c.api.VerifyOwnership(received, verified), nil
} }
\ No newline at end of file
...@@ -30,6 +30,23 @@ type RoundEventCallback interface { ...@@ -30,6 +30,23 @@ type RoundEventCallback interface {
EventCallback(rid, state int, timedOut bool) EventCallback(rid, state int, timedOut bool)
} }
// RoundEventHandler handles round events happening on the cMix network.
type MessageDeliveryCallback interface {
EventCallback(msgID []byte, delivered, timedOut bool)
}
// AuthRequestCallback notifies the register whenever they receive an auth
// request
type AuthRequestCallback interface {
Callback(requestor *Contact, message string)
}
// AuthConfirmCallback notifies the register whenever they receive an auth
// request confirmation
type AuthConfirmCallback interface {
Callback(partner *Contact)
}
// Generic Unregister - a generic return used for all callbacks which can be // Generic Unregister - a generic return used for all callbacks which can be
// unregistered // unregistered
// Interface which allows the un-registration of a listener // Interface which allows the un-registration of a listener
...@@ -38,23 +55,34 @@ type Unregister struct { ...@@ -38,23 +55,34 @@ type Unregister struct {
} }
//Call unregisters a callback //Call unregisters a callback
func (u Unregister) Unregister() { func (u *Unregister) Unregister() {
u.f() u.f()
} }
//creates an unregister interface for listeners //creates an unregister interface for listeners
func newListenerUnregister(lid switchboard.ListenerID, sw interfaces.Switchboard) Unregister { func newListenerUnregister(lid switchboard.ListenerID, sw interfaces.Switchboard) *Unregister {
f := func() { f := func() {
sw.Unregister(lid) sw.Unregister(lid)
} }
return Unregister{f: f} return &Unregister{f: f}
} }
//creates an unregister interface for round events //creates an unregister interface for round events
func newRoundUnregister(rid id.Round, ec *dataStructures.EventCallback, func newRoundUnregister(rid id.Round, ec *dataStructures.EventCallback,
re interfaces.RoundEvents) Unregister { re interfaces.RoundEvents) *Unregister {
f := func() { f := func() {
re.Remove(rid, ec) re.Remove(rid, ec)
} }
return Unregister{f: f} return &Unregister{f: f}
}
//creates an unregister interface for round events
func newRoundListUnregister(rounds []id.Round, ec []*dataStructures.EventCallback,
re interfaces.RoundEvents) *Unregister {
f := func() {
for i, r := range rounds {
re.Remove(r, ec[i])
}
}
return &Unregister{f: f}
} }
...@@ -7,17 +7,22 @@ ...@@ -7,17 +7,22 @@
package bindings package bindings
import ( import (
"encoding/json"
"errors" "errors"
"fmt"
"github.com/spf13/jwalterweatherman" "github.com/spf13/jwalterweatherman"
jww "github.com/spf13/jwalterweatherman" jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/api" "gitlab.com/elixxir/client/api"
"gitlab.com/elixxir/client/interfaces/bind"
"gitlab.com/elixxir/client/interfaces/contact" "gitlab.com/elixxir/client/interfaces/contact"
"gitlab.com/elixxir/client/interfaces/message" "gitlab.com/elixxir/client/interfaces/message"
"gitlab.com/elixxir/client/interfaces/utility"
"gitlab.com/elixxir/client/storage"
"gitlab.com/elixxir/comms/mixmessages" "gitlab.com/elixxir/comms/mixmessages"
"gitlab.com/elixxir/primitives/states" "gitlab.com/elixxir/primitives/states"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"time" "time"
ds "gitlab.com/elixxir/comms/network/dataStructures"
) )
// BindingsClient wraps the api.Client, implementing additional functions // BindingsClient wraps the api.Client, implementing additional functions
...@@ -34,7 +39,12 @@ type Client struct { ...@@ -34,7 +39,12 @@ type Client struct {
// Users of this function should delete the storage directory on error. // Users of this function should delete the storage directory on error.
func NewClient(network, storageDir string, password []byte, regCode string) error { func NewClient(network, storageDir string, password []byte, regCode string) error {
jwalterweatherman.SetLogThreshold(jwalterweatherman.LevelInfo) jwalterweatherman.SetLogThreshold(jwalterweatherman.LevelInfo)
return api.NewClient(network, storageDir, password, regCode)
if err := api.NewClient(network, storageDir, password, regCode); err != nil {
return errors.New(fmt.Sprintf("Failed to create new client: %+v",
err))
}
return nil
} }
// NewPrecannedClient creates an insecure user with predetermined keys with nodes // NewPrecannedClient creates an insecure user with predetermined keys with nodes
...@@ -50,7 +60,11 @@ func NewPrecannedClient(precannedID int, network, storageDir string, password [] ...@@ -50,7 +60,11 @@ func NewPrecannedClient(precannedID int, network, storageDir string, password []
return errors.New("Cannot create precanned client with negative ID") return errors.New("Cannot create precanned client with negative ID")
} }
return api.NewPrecannedClient(uint(precannedID), network, storageDir, password) if err := api.NewPrecannedClient(uint(precannedID), network, storageDir, password); err != nil {
return errors.New(fmt.Sprintf("Failed to create new precanned "+
"client: %+v", err))
}
return nil
} }
// Login will load an existing client from the storageDir // Login will load an existing client from the storageDir
...@@ -67,14 +81,29 @@ func Login(storageDir string, password []byte) (*Client, error) { ...@@ -67,14 +81,29 @@ func Login(storageDir string, password []byte) (*Client, error) {
client, err := api.Login(storageDir, password) client, err := api.Login(storageDir, password)
if err != nil { if err != nil {
return nil, err return nil, errors.New(fmt.Sprintf("Failed to login: %+v", err))
} }
return &Client{*client}, nil return &Client{*client}, nil
} }
//Unmarshals a marshaled contact object //Unmarshals a marshaled contact object, returns an error if it fails
func UnmarshalContact(b []byte) (bind.Contact, error) { func UnmarshalContact(b []byte) (*Contact, error) {
return contact.Unmarshal(b) c, err := contact.Unmarshal(b)
if err != nil {
return nil, errors.New(fmt.Sprintf("Failed to Unmarshal "+
"Contact: %+v", err))
}
return &Contact{c: &c}, nil
}
//Unmarshals a marshaled send report object, returns an error if it fails
func UnmarshalSendReport(b []byte) (*SendReport, error) {
sr := &SendReport{}
if err := json.Unmarshal(b, sr); err != nil {
return nil, errors.New(fmt.Sprintf("Failed to Unmarshal "+
"Send Report: %+v", err))
}
return sr, nil
} }
// StartNetworkFollower kicks off the tracking of the network. It starts // StartNetworkFollower kicks off the tracking of the network. It starts
...@@ -106,7 +135,11 @@ func UnmarshalContact(b []byte) (bind.Contact, error) { ...@@ -106,7 +135,11 @@ func UnmarshalContact(b []byte) (bind.Contact, error) {
// - KeyExchange Confirm (/keyExchange/confirm.go) // - KeyExchange Confirm (/keyExchange/confirm.go)
// Responds to confirmations of successful rekey operations // Responds to confirmations of successful rekey operations
func (c *Client) StartNetworkFollower() error { func (c *Client) StartNetworkFollower() error {
return c.api.StartNetworkFollower() if err := c.api.StartNetworkFollower(); err != nil {
return errors.New(fmt.Sprintf("Failed to start the "+
"network follower: %+v", err))
}
return nil
} }
// StopNetworkFollower stops the network follower if it is running. // StopNetworkFollower stops the network follower if it is running.
...@@ -116,7 +149,11 @@ func (c *Client) StartNetworkFollower() error { ...@@ -116,7 +149,11 @@ func (c *Client) StartNetworkFollower() error {
// most likely be in an unrecoverable state and need to be trashed. // most likely be in an unrecoverable state and need to be trashed.
func (c *Client) StopNetworkFollower(timeoutMS int) error { func (c *Client) StopNetworkFollower(timeoutMS int) error {
timeout := time.Duration(timeoutMS) * time.Millisecond timeout := time.Duration(timeoutMS) * time.Millisecond
return c.api.StopNetworkFollower(timeout) if err := c.api.StopNetworkFollower(timeout); err != nil {
return errors.New(fmt.Sprintf("Failed to stop the "+
"network follower: %+v", err))
}
return nil
} }
// Gets the state of the network follower. Returns: // Gets the state of the network follower. Returns:
...@@ -144,25 +181,39 @@ func (c *Client) RegisterNetworkHealthCB(nhc NetworkHealthCallback) { ...@@ -144,25 +181,39 @@ func (c *Client) RegisterNetworkHealthCB(nhc NetworkHealthCallback) {
// matching specific uid, msgType, and/or username // matching specific uid, msgType, and/or username
// Returns a ListenerUnregister interface which can be // Returns a ListenerUnregister interface which can be
// //
// to register for any userID, pass in an id with length 0 or an id with
// all zeroes
//
// to register for any message type, pass in a message type of 0
//
// Message Types can be found in client/interfaces/message/type.go // Message Types can be found in client/interfaces/message/type.go
// Make sure to not conflict with ANY default message types // Make sure to not conflict with ANY default message types
func (c *Client) RegisterListener(uid []byte, msgType int, func (c *Client) RegisterListener(uid []byte, msgType int,
listener Listener) error { listener Listener) (*Unregister, error) {
name := listener.Name() name := listener.Name()
u, err := id.Unmarshal(uid)
var u *id.ID
if len(uid) == 0 {
u = &id.ID{}
} else {
var err error
u, err = id.Unmarshal(uid)
if err != nil { if err != nil {
return err return nil, errors.New(fmt.Sprintf("Failed to "+
"ResgisterListener: %+v", err))
} }
}
mt := message.Type(msgType) mt := message.Type(msgType)
f := func(item message.Receive) { f := func(item message.Receive) {
listener.Hear(item) listener.Hear(item)
} }
c.api.GetSwitchboard().RegisterFunc(name, u, mt, f) lid := c.api.GetSwitchboard().RegisterFunc(name, u, mt, f)
return nil return newListenerUnregister(lid, c.api.GetSwitchboard()), nil
} }
// RegisterRoundEventsHandler registers a callback interface for round // RegisterRoundEventsHandler registers a callback interface for round
...@@ -181,7 +232,7 @@ func (c *Client) RegisterListener(uid []byte, msgType int, ...@@ -181,7 +232,7 @@ func (c *Client) RegisterListener(uid []byte, msgType int,
// 0x06 - FAILED // 0x06 - FAILED
// These states are defined in elixxir/primitives/states/state.go // These states are defined in elixxir/primitives/states/state.go
func (c *Client) RegisterRoundEventsHandler(rid int, cb RoundEventCallback, func (c *Client) RegisterRoundEventsHandler(rid int, cb RoundEventCallback,
timeoutMS int, il *IntList) Unregister { timeoutMS int, il *IntList) *Unregister {
rcb := func(ri *mixmessages.RoundInfo, timedOut bool) { rcb := func(ri *mixmessages.RoundInfo, timedOut bool) {
cb.EventCallback(int(ri.ID), int(ri.State), timedOut) cb.EventCallback(int(ri.ID), int(ri.State), timedOut)
...@@ -201,11 +252,55 @@ func (c *Client) RegisterRoundEventsHandler(rid int, cb RoundEventCallback, ...@@ -201,11 +252,55 @@ func (c *Client) RegisterRoundEventsHandler(rid int, cb RoundEventCallback,
return newRoundUnregister(roundID, ec, c.api.GetRoundEvents()) return newRoundUnregister(roundID, ec, c.api.GetRoundEvents())
} }
// RegisterMessageDeliveryCB allows the caller to get notified if the rounds a
// message was sent in sucesfully completed. Under the hood, this uses the same
// interface as RegisterRoundEventsHandler, but provides a convienet way to use
// the interface in its most common form, looking up the result of message
// retreval
//
// The callbacks will return at timeoutMS if no state update occurs
//
// This function takes the marshaled send report to ensure a memory leak does
// not occur as a result of both sides of the bindings holding a refrence to
// the same pointer.
func (c *Client) RegisterMessageDeliveryCB(marshaledSendReport []byte,
mdc MessageDeliveryCallback, timeoutMS int) (*Unregister, error) {
sr, err := UnmarshalSendReport(marshaledSendReport)
if err != nil {
return nil, errors.New(fmt.Sprintf("Failed to "+
"RegisterMessageDeliveryCB: %+v", err))
}
/*check message delivery*/
sendResults := make(chan ds.EventReturn, len(sr.rl.list))
roundEvents := c.api.GetRoundEvents()
reventObjs := make([]*ds.EventCallback, len(sr.rl.list))
for i, r := range sr.rl.list {
reventObjs[i] = roundEvents.AddRoundEventChan(r, sendResults,
time.Duration(timeoutMS)*time.Millisecond, states.COMPLETED,
states.FAILED)
}
go func() {
success, _, numTmeout := utility.TrackResults(sendResults, len(sr.rl.list))
if !success {
mdc.EventCallback(sr.mid[:], false, numTmeout > 0)
} else {
mdc.EventCallback(sr.mid[:], true, false)
}
}()
return newRoundListUnregister(sr.rl.list, reventObjs, roundEvents), nil
}
// Returns a user object from which all information about the current user // Returns a user object from which all information about the current user
// can be gleaned // can be gleaned
func (c *Client) GetUser() User { func (c *Client) GetUser() *User {
u := c.api.GetUser() u := c.api.GetUser()
return &u return &User{u: &u}
} }
/* /*
......
package bindings package bindings
import ( import (
"encoding/json"
"errors" "errors"
"gitlab.com/elixxir/client/interfaces/contact" "gitlab.com/elixxir/client/interfaces/contact"
) )
...@@ -19,6 +18,7 @@ func (f *Fact) Type() int { ...@@ -19,6 +18,7 @@ func (f *Fact) Type() int {
return int(f.f.T) return int(f.f.T)
} }
/* contact object*/ /* contact object*/
type Contact struct { type Contact struct {
c *contact.Contact c *contact.Contact
...@@ -44,6 +44,11 @@ func (c *Contact) GetFactList() *FactList { ...@@ -44,6 +44,11 @@ func (c *Contact) GetFactList() *FactList {
return &FactList{c: c.c} return &FactList{c: c.c}
} }
func (c *Contact) Marshal() ([]byte, error) {
return c.c.Marshal()
}
/* FactList object*/
type FactList struct { type FactList struct {
c *contact.Contact c *contact.Contact
} }
...@@ -69,7 +74,5 @@ func (fl *FactList) Add(fact string, factType int) error { ...@@ -69,7 +74,5 @@ func (fl *FactList) Add(fact string, factType int) error {
} }
func (fl *FactList) Marshal() ([]byte, error) { func (fl *FactList) Marshal() ([]byte, error) {
return json.Marshal(&fl.c.Facts) return []byte(fl.c.Facts.Stringify()), nil
} }
func unmarshalFactList
...@@ -199,15 +199,3 @@ type Message interface { ...@@ -199,15 +199,3 @@ type Message interface {
// Returns the message's timestamp in ns since unix epoc // Returns the message's timestamp in ns since unix epoc
GetTimestampNano() int GetTimestampNano() int
} }
type User interface {
GetID() []byte
GetSalt() []byte
GetRSAPrivateKeyPem() []byte
GetRSAPublicKeyPem() []byte
//IsPrecanned() int
GetCmixDhPrivateKey() []byte
GetCmixDhPublicKey() []byte
GetE2EDhPrivateKey() []byte
GetE2EDhPublicKey() []byte
}
\ No newline at end of file
...@@ -28,25 +28,17 @@ func (il *IntList) Get(i int) (int, error) { ...@@ -28,25 +28,17 @@ func (il *IntList) Get(i int) (int, error) {
return il.lst[i], nil return il.lst[i], nil
} }
type roundList struct { type RoundList struct {
list []id.Round list []id.Round
} }
// RoundList contains a list of contacts
type RoundList interface {
// Len returns the number of contacts in the list
Len() int
// Get returns the round ID at index i
Get(i int) (int, error)
}
// Gets the number of round IDs stored // Gets the number of round IDs stored
func (rl *roundList) Len() int { func (rl *RoundList) Len() int {
return len(rl.list) return len(rl.list)
} }
// Gets a stored round ID at the given index // Gets a stored round ID at the given index
func (rl *roundList) Get(i int) (int, error) { func (rl *RoundList) Get(i int) (int, error) {
if i < 0 || i > len(rl.list) { if i < 0 || i > len(rl.list) {
return -1, errors.New("round ID cannot be under 0 or over" + return -1, errors.New("round ID cannot be under 0 or over" +
" list len") " list len")
......
package bindings package bindings
import ( import (
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"gitlab.com/elixxir/client/interfaces/message" "gitlab.com/elixxir/client/interfaces/message"
...@@ -25,19 +26,22 @@ import ( ...@@ -25,19 +26,22 @@ import (
func (c *Client) SendCmix(recipient, contents []byte) (int, error) { func (c *Client) SendCmix(recipient, contents []byte) (int, error) {
u, err := id.Unmarshal(recipient) u, err := id.Unmarshal(recipient)
if err != nil { if err != nil {
return -1, err return -1, errors.New(fmt.Sprintf("Failed to sendCmix: %+v",
err))
} }
msg, err := c.api.NewCMIXMessage(u, contents) msg, err := c.api.NewCMIXMessage(u, contents)
if err != nil { if err != nil {
return -1, err return -1, errors.New(fmt.Sprintf("Failed to sendCmix: %+v",
err))
} }
rid, err := c.api.SendCMIX(msg, params.GetDefaultCMIX()) rid, err := c.api.SendCMIX(msg, params.GetDefaultCMIX())
if err != nil { if err != nil {
return -1, err return -1, errors.New(fmt.Sprintf("Failed to sendCmix: %+v",
err))
} }
return int(rid), err return int(rid), nil
} }
// SendUnsafe sends an unencrypted payload to the provided recipient // SendUnsafe sends an unencrypted payload to the provided recipient
...@@ -49,10 +53,10 @@ func (c *Client) SendCmix(recipient, contents []byte) (int, error) { ...@@ -49,10 +53,10 @@ func (c *Client) SendCmix(recipient, contents []byte) (int, error) {
// Message Types can be found in client/interfaces/message/type.go // Message Types can be found in client/interfaces/message/type.go
// Make sure to not conflict with ANY default message types with custom types // Make sure to not conflict with ANY default message types with custom types
func (c *Client) SendUnsafe(recipient, payload []byte, func (c *Client) SendUnsafe(recipient, payload []byte,
messageType int) (RoundList, error) { messageType int) (*RoundList, error) {
u, err := id.Unmarshal(recipient) u, err := id.Unmarshal(recipient)
if err != nil { if err != nil {
return nil, errors.New(fmt.Sprintf("Failed to sendUnsafew: %+v", return nil, errors.New(fmt.Sprintf("Failed to sendUnsafe: %+v",
err)) err))
} }
...@@ -64,11 +68,11 @@ func (c *Client) SendUnsafe(recipient, payload []byte, ...@@ -64,11 +68,11 @@ func (c *Client) SendUnsafe(recipient, payload []byte,
rids, err := c.api.SendUnsafe(m, params.GetDefaultUnsafe()) rids, err := c.api.SendUnsafe(m, params.GetDefaultUnsafe())
if err != nil { if err != nil {
return nil, errors.New(fmt.Sprintf("Failed to sendUnsafew: %+v", return nil, errors.New(fmt.Sprintf("Failed to sendUnsafe: %+v",
err)) err))
} }
return &roundList{list: rids}, nil return &RoundList{list: rids}, nil
} }
...@@ -78,11 +82,10 @@ func (c *Client) SendUnsafe(recipient, payload []byte, ...@@ -78,11 +82,10 @@ func (c *Client) SendUnsafe(recipient, payload []byte,
// //
// Message Types can be found in client/interfaces/message/type.go // Message Types can be found in client/interfaces/message/type.go
// Make sure to not conflict with ANY default message types // Make sure to not conflict with ANY default message types
func (c *Client) SendE2E(recipient, payload []byte, func (c *Client) SendE2E(recipient, payload []byte, messageType int) (*SendReport, error) {
messageType int) (*SendReport, error) {
u, err := id.Unmarshal(recipient) u, err := id.Unmarshal(recipient)
if err != nil { if err != nil {
return nil, err return nil, errors.New(fmt.Sprintf("Failed SendE2E: %+v", err))
} }
m := message.Send{ m := message.Send{
...@@ -93,26 +96,31 @@ func (c *Client) SendE2E(recipient, payload []byte, ...@@ -93,26 +96,31 @@ func (c *Client) SendE2E(recipient, payload []byte,
rids, mid, err := c.api.SendE2E(m, params.GetDefaultE2E()) rids, mid, err := c.api.SendE2E(m, params.GetDefaultE2E())
if err != nil { if err != nil {
return nil, err return nil, errors.New(fmt.Sprintf("Failed SendE2E: %+v", err))
} }
sr := SendReport{ sr := SendReport{
rl: &roundList{list: rids}, rl: &RoundList{list: rids},
mid: mid, mid: mid,
} }
return &sr, nil return &sr, nil
} }
// the send report is the mechanisim by which sendE2E returns a single
type SendReport struct { type SendReport struct {
rl RoundList rl *RoundList
mid e2e.MessageID mid e2e.MessageID
} }
func (sr *SendReport) GetRoundList() RoundList { func (sr *SendReport) GetRoundList() *RoundList {
return sr.rl return sr.rl
} }
func (sr *SendReport) GetMessageID() []byte { func (sr *SendReport) GetMessageID() []byte {
return sr.mid[:] return sr.mid[:]
} }
func (sr *SendReport) Marshal() ([]byte, error) {
return json.Marshal(sr)
}
\ No newline at end of file
package bindings
import (
"gitlab.com/elixxir/client/interfaces/user"
"gitlab.com/xx_network/crypto/signature/rsa"
)
type User struct {
u *user.User
}
func (u *User) GetID() []byte {
return u.u.ID.Marshal()
}
func (u *User) GetSalt() []byte {
return u.u.Salt
}
func (u *User) GetRSAPrivateKeyPem() []byte {
return rsa.CreatePrivateKeyPem(u.u.RSA)
}
func (u *User) GetRSAPublicKeyPem() []byte {
return rsa.CreatePublicKeyPem(u.u.RSA.GetPublic())
}
func (u *User) IsPrecanned() bool {
return u.u.Precanned
}
func (u *User) GetCmixDhPrivateKey() []byte {
return u.u.CmixDhPrivateKey.Bytes()
}
func (u *User) GetCmixDhPublicKey() []byte {
return u.u.CmixDhPublicKey.Bytes()
}
func (u *User) GetE2EDhPrivateKey() []byte {
return u.u.E2eDhPrivateKey.Bytes()
}
func (u *User) GetE2EDhPublicKey() []byte {
return u.u.E2eDhPublicKey.Bytes()
}
func (u *User) GetContact() *Contact {
c := u.u.GetContact()
return &Contact{c: &c}
}
package bind
type Contact interface {
GetID() []byte
GetDHPublicKey() []byte
GetOwnershipProof() []byte
GetFactList() FactList
Marshal() ([]byte, error)
}
type FactList interface {
Num() int
Get(int) Fact
Add(string, int) error
}
type Fact interface {
Get() string
Type() int
}
...@@ -3,11 +3,8 @@ package contact ...@@ -3,11 +3,8 @@ package contact
import ( import (
"encoding/json" "encoding/json"
"github.com/pkg/errors" "github.com/pkg/errors"
"gitlab.com/elixxir/client/interfaces/bind"
"gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"strings"
jww "github.com/spf13/jwalterweatherman"
) )
const factDelimiter = "," const factDelimiter = ","
...@@ -21,45 +18,13 @@ type Contact struct { ...@@ -21,45 +18,13 @@ type Contact struct {
ID *id.ID ID *id.ID
DhPubKey *cyclic.Int DhPubKey *cyclic.Int
OwnershipProof []byte OwnershipProof []byte
Facts []Fact Facts FactList
} }
// GetID returns the user ID for this user.
func (c Contact) GetID() []byte {
return c.ID.Bytes()
}
// GetDHPublicKey returns the public key associated with the Contact.
func (c Contact) GetDHPublicKey() []byte {
return c.DhPubKey.Bytes()
}
// GetDHPublicKey returns hash of a DH proof of key ownership.
func (c Contact) GetOwnershipProof() []byte {
return c.OwnershipProof
}
// Returns a fact list for adding and getting facts to and from the contact
func (c Contact) GetFactList() bind.FactList {
return factList{source: &c}
}
// json marshals the contact
func (c Contact) Marshal() ([]byte, error) { func (c Contact) Marshal() ([]byte, error) {
return json.Marshal(&c) return json.Marshal(&c)
} }
// converts facts to a delineated string with an ending character for transfer
// over the network
func (c Contact) StringifyFacts() string {
stringList := make([]string, len(c.Facts))
for index, f := range c.Facts {
stringList[index] = f.Stringify()
}
return strings.Join(stringList, factDelimiter) + factBreak
}
func Unmarshal(b []byte) (Contact, error) { func Unmarshal(b []byte) (Contact, error) {
c := Contact{} c := Contact{}
err := json.Unmarshal(b, &c) err := json.Unmarshal(b, &c)
...@@ -74,26 +39,3 @@ func Unmarshal(b []byte) (Contact, error) { ...@@ -74,26 +39,3 @@ func Unmarshal(b []byte) (Contact, error) {
} }
return c, nil return c, nil
} }
\ No newline at end of file
// splits the "facts" portion of the payload from the rest and returns them as
// facts
func UnstringifyFacts(s string) ([]Fact, string, error) {
parts := strings.SplitN(s, factBreak, 1)
if len(parts) != 2 {
return nil, "", errors.New("Invalid fact string passed")
}
factStrings := strings.Split(parts[0], factDelimiter)
var factList []Fact
for _, fString := range factStrings {
fact, err := UnstringifyFact(fString)
if err != nil {
jww.WARN.Printf("Fact failed to unstringify, dropped: %s",
err)
} else {
factList = append(factList, fact)
}
}
return factList, parts[1], nil
}
...@@ -13,14 +13,6 @@ func NewFact(ft FactType, fact string) (Fact, error) { ...@@ -13,14 +13,6 @@ func NewFact(ft FactType, fact string) (Fact, error) {
}, nil }, nil
} }
func (f Fact) Get() string {
return f.Fact
}
func (f Fact) Type() int {
return int(f.T)
}
// marshal is for transmission for UDB, not a part of the fact interface // marshal is for transmission for UDB, not a part of the fact interface
func (f Fact) Stringify() string { func (f Fact) Stringify() string {
return f.T.Stringify() + f.Fact return f.T.Stringify() + f.Fact
......
...@@ -2,31 +2,40 @@ package contact ...@@ -2,31 +2,40 @@ package contact
import ( import (
"github.com/pkg/errors" "github.com/pkg/errors"
"gitlab.com/elixxir/client/interfaces/bind" "strings"
jww "github.com/spf13/jwalterweatherman"
) )
type factList struct { type FactList []Fact
source *Contact
}
func (fl factList) Num() int { func (fl FactList) Stringify() string {
return len(fl.source.Facts) stringList := make([]string, len(fl))
for index, f := range fl {
stringList[index] = f.Stringify()
} }
func (fl factList) Get(i int) bind.Fact { return strings.Join(stringList, factDelimiter) + factBreak
return fl.source.Facts[i]
} }
func (fl factList) Add(fact string, factType int) error { // unstrignifys facts followed by a facts break and with arbatrary data
ft := FactType(factType) // atttached at the end
if !ft.IsValid() { func UnstringifyFactList(s string) ([]Fact, string, error) {
return errors.New("Invalid fact type") parts := strings.SplitN(s, factBreak, 1)
if len(parts) != 2 {
return nil, "", errors.New("Invalid fact string passed")
} }
f, err := NewFact(ft, fact) factStrings := strings.Split(parts[0], factDelimiter)
var factList []Fact
for _, fString := range factStrings {
fact, err := UnstringifyFact(fString)
if err != nil { if err != nil {
return err jww.WARN.Printf("Fact failed to unstringify, dropped: %s",
err)
} else {
factList = append(factList, fact)
} }
fl.source.Facts = append(fl.source.Facts, f) }
return nil return factList, parts[1], nil
} }
\ No newline at end of file
package user package user
import ( import (
"gitlab.com/elixxir/client/interfaces/bind"
"gitlab.com/elixxir/client/interfaces/contact" "gitlab.com/elixxir/client/interfaces/contact"
"gitlab.com/elixxir/crypto/cyclic" "gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/xx_network/crypto/signature/rsa" "gitlab.com/xx_network/crypto/signature/rsa"
...@@ -24,43 +23,7 @@ type User struct { ...@@ -24,43 +23,7 @@ type User struct {
E2eDhPublicKey *cyclic.Int E2eDhPublicKey *cyclic.Int
} }
func (u *User) GetID() []byte { func (u *User) GetContact() contact.Contact {
return u.ID.Marshal()
}
func (u *User) GetSalt() []byte {
return u.Salt
}
func (u *User) GetRSAPrivateKeyPem() []byte {
return rsa.CreatePrivateKeyPem(u.RSA)
}
func (u *User) GetRSAPublicKeyPem() []byte {
return rsa.CreatePublicKeyPem(u.RSA.GetPublic())
}
func (u *User) IsPrecanned() bool {
return u.Precanned
}
func (u *User) GetCmixDhPrivateKey() []byte {
return u.CmixDhPrivateKey.Bytes()
}
func (u *User) GetCmixDhPublicKey() []byte {
return u.CmixDhPublicKey.Bytes()
}
func (u *User) GetE2EDhPrivateKey() []byte {
return u.E2eDhPrivateKey.Bytes()
}
func (u *User) GetE2EDhPublicKey() []byte {
return u.E2eDhPublicKey.Bytes()
}
func (u *User) GetContact() bind.Contact {
return contact.Contact{ return contact.Contact{
ID: u.ID.DeepCopy(), ID: u.ID.DeepCopy(),
DhPubKey: u.E2eDhPublicKey, DhPubKey: u.E2eDhPublicKey,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment