Skip to content
Snippets Groups Projects
Commit e2d31b32 authored by Jake Taylor's avatar Jake Taylor :lips:
Browse files

Merge branch 'hotfix/UnifyBindingUdCalls' into 'XX-4019/NewOrLoadAltUd'

Support a single call for ud.NewOrLoad

See merge request !325
parents df3cf987 04343023
No related branches found
No related tags found
3 merge requests!510Release,!325Support a single call for ud.NewOrLoad,!323Xx 4019/new or load alt ud
......@@ -8,6 +8,8 @@
package bindings
import (
"gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/xx_network/primitives/id"
"sync"
"github.com/pkg/errors"
......@@ -125,6 +127,44 @@ func (e *E2e) GetContact() []byte {
return e.api.GetReceptionIdentity().GetContact().Marshal()
}
// GetUdAddressFromNdf retrieve the User Discovery's network address fom the NDF.
func (e *E2e) GetUdAddressFromNdf() string {
return e.api.GetCmix().GetInstance().GetPartialNdf().
Get().UDB.Address
}
// GetUdCertFromNdf retrieves the User Discovery's TLS certificate from the NDF.
func (e *E2e) GetUdCertFromNdf() []byte {
return []byte(e.api.GetCmix().GetInstance().GetPartialNdf().Get().UDB.Cert)
}
// GetUdContactFromNdf assembles the User Discovery's contact file from the data
// within the NDF.
//
// Returns
// - []byte - A byte marshalled contact.Contact.
func (e *E2e) GetUdContactFromNdf() ([]byte, error) {
udIdData := e.api.GetCmix().GetInstance().GetPartialNdf().Get().UDB.ID
udId, err := id.Unmarshal(udIdData)
if err != nil {
return nil, err
}
udDhPubKeyData := e.api.GetCmix().GetInstance().GetPartialNdf().Get().UDB.DhPubKey
var udDhPubKey *cyclic.Int
err = udDhPubKey.UnmarshalJSON(udDhPubKeyData)
if err != nil {
return nil, err
}
udContact := contact.Contact{
ID: udId,
DhPubKey: udDhPubKey,
}
return udContact.Marshal(), nil
}
// AuthCallbacks is the bindings-specific interface for auth.Callbacks methods.
type AuthCallbacks interface {
Request(contact, receptionId []byte, ephemeralId, roundId int64)
......
......@@ -105,50 +105,12 @@ type UdNetworkStatus interface {
// Manager functions //
////////////////////////////////////////////////////////////////////////////////
// NewOrLoadUdFromNdf loads an existing Manager from storage or creates a
// new one if there is no extant storage information. This will default to connecting with
// the xx network's UD server as found in the NDF. For connecting to a custom server, use
// NewOrLoadUd.
//
// Parameters:
// - e2eID - e2e object ID in the tracker
// - follower - network follower func wrapped in UdNetworkStatus
// - username - the username the user wants to register with UD.
// If the user is already registered, this field may be blank
// - registrationValidationSignature - the signature provided by the xx network.
// This may be nil, however UD may return an error in some cases (e.g. in a production level
// environment).
func NewOrLoadUdFromNdf(e2eID int, follower UdNetworkStatus,
username string, registrationValidationSignature []byte) (
*UserDiscovery, error) {
// Get user from singleton
user, err := e2eTrackerSingleton.get(e2eID)
if err != nil {
return nil, err
}
// Construct callback
UdNetworkStatusFn := func() xxdk.Status {
return xxdk.Status(follower.UdNetworkStatus())
}
// Build manager
u, err := ud.NewOrLoadFromNdf(user.api, user.api.GetComms(),
UdNetworkStatusFn, username, registrationValidationSignature)
if err != nil {
return nil, err
}
// Track and return manager
return udTrackerSingleton.make(u), nil
}
// NewOrLoadUd loads an existing Manager from storage or creates a
// new one if there is no extant storage information. This is different from NewOrLoadUdFromNdf
// in that it allows the user to provide alternate User Discovery contact information.
// These parameters may be used to contact a separate UD server than the one run by the
// xx network team, one the user or a third-party may operate.
// new one if there is no extant storage information. Parameters need be provided
// to specify how to connect to the User Discovery service. These parameters may be used
// to contact either the UD server hosted by the xx network team or a custom
// third-party operated server. For the former, all the information may be pulled from the
// NDF using the bindings.
//
// Params
// - e2eID - e2e object ID in the tracker
......@@ -158,15 +120,19 @@ func NewOrLoadUdFromNdf(e2eID int, follower UdNetworkStatus,
// - networkValidationSig is a signature provided by the network (i.e. the client registrar).
// This may be nil, however UD may return an error in some cases (e.g. in a production level
// environment).
// - customCert is the TLS certificate for the alternate UD server.
// - customAddress is the IP address of the alternate UD server.
// - customContactFile is the data within a marshalled contact.Contact.
// - cert is the TLS certificate for the UD server this call will connect with.
// You may use the UD server run by the xx network team by using E2e.GetUdCertFromNdf.
// - contactFile is the data within a marshalled contact.Contact. This represents the
// contact file of the server this call will connect with.
// You may use the UD server run by the xx network team by using E2e.GetUdContactFromNdf.
// - address is the IP address of the UD server this call will connect with.
// You may use the UD server run by the xx network team by using E2e.GetUdAddressFromNdf.
//
// Returns
// - A Manager object which is registered to the specified alternate UD service.
func NewOrLoadUd(e2eID int, follower UdNetworkStatus,
username string, registrationValidationSignature,
customCert, customAddress, customContactFile []byte) (
cert, contactFile []byte, address string) (
*UserDiscovery, error) {
// Get user from singleton
......@@ -183,7 +149,7 @@ func NewOrLoadUd(e2eID int, follower UdNetworkStatus,
// Build manager
u, err := ud.NewOrLoad(user.api, user.api.GetComms(),
UdNetworkStatusFn, username, registrationValidationSignature,
customCert, customAddress, customContactFile)
cert, contactFile, address)
if err != nil {
return nil, err
}
......
......@@ -10,6 +10,9 @@ package cmd
import (
"fmt"
"gitlab.com/elixxir/client/xxdk"
"gitlab.com/elixxir/crypto/cyclic"
"gitlab.com/xx_network/primitives/id"
"time"
"gitlab.com/elixxir/client/single"
......@@ -60,11 +63,17 @@ var udCmd = &cobra.Command{
jww.TRACE.Printf("[UD] Connected!")
cert, contactFile, address, err := getUdContactInfo(user)
if err != nil {
jww.FATAL.Panicf("Failed to load UD contact information from NDF: %+v", err)
}
// Make user discovery manager
userToRegister := viper.GetString(udRegisterFlag)
jww.TRACE.Printf("[UD] Registering identity %v...", userToRegister)
userDiscoveryMgr, err := ud.NewOrLoadFromNdf(user, user.GetComms(),
user.NetworkFollowerStatus, userToRegister, nil)
userDiscoveryMgr, err := ud.NewOrLoad(user, user.GetComms(),
user.NetworkFollowerStatus, userToRegister, nil,
cert, contactFile, address)
if err != nil {
jww.FATAL.Panicf("Failed to load or create new UD manager: %+v", err)
}
......@@ -243,6 +252,42 @@ var udCmd = &cobra.Command{
},
}
// getUdContactInfo is a helper function which retrieves the necessary information
// to contact UD.
func getUdContactInfo(user *xxdk.E2e) (cert, contactFile []byte, address string, err error) {
// Retrieve address
address = string([]byte(user.GetCmix().GetInstance().GetPartialNdf().
Get().UDB.Address))
// Retrieve certificate
cert = []byte(user.GetCmix().GetInstance().GetPartialNdf().Get().UDB.Cert)
// Retrieve ID
udIdData := user.GetCmix().GetInstance().GetPartialNdf().Get().UDB.ID
udId, err := id.Unmarshal(udIdData)
if err != nil {
return nil, nil, "", err
}
// Retrieve DH Pub Key
udDhPubKeyData := user.GetCmix().GetInstance().GetPartialNdf().Get().UDB.DhPubKey
var udDhPubKey *cyclic.Int
err = udDhPubKey.UnmarshalJSON(udDhPubKeyData)
if err != nil {
return nil, nil, "", err
}
// Construct contact
udContact := contact.Contact{
ID: udId,
DhPubKey: udDhPubKey,
}
contactFile = udContact.Marshal()
return
}
func init() {
// User Discovery subcommand Options
udCmd.Flags().StringP(udRegisterFlag, "r", "",
......
......@@ -21,8 +21,8 @@ type alternateUd struct {
// user discovery service.
//
// To undo this operation, use UnsetAlternativeUserDiscovery.
func (m *Manager) setAlternateUserDiscovery(altCert, altAddress,
contactFile []byte) error {
func (m *Manager) setAlternateUserDiscovery(altCert,
contactFile []byte, altAddress string) error {
params := connect.GetDefaultHostParams()
params.AuthEnabled = false
......@@ -37,7 +37,7 @@ func (m *Manager) setAlternateUserDiscovery(altCert, altAddress,
}
// Add a new host and return it if it does not already exist
host, err := m.comms.AddHost(udID, string(altAddress),
host, err := m.comms.AddHost(udID, altAddress,
altCert, params)
if err != nil {
return errors.WithMessage(err, "User Discovery host object could "+
......
......@@ -43,23 +43,31 @@ type Manager struct {
alternativeUd *alternateUd
}
// NewOrLoadFromNdf loads an existing Manager from storage or creates a
// new one if there is no extant storage information. This will default to connecting with
// the xx network's UD server as found in the NDF. For connecting to a custom server, use
// NewOrLoad.
// NewOrLoad loads an existing Manager from storage or creates a
// new one if there is no extant storage information. Parameters need be provided
// to specify how to connect to the User Discovery service. These parameters may be used
// to contact either the UD server hosted by the xx network team or a custom
// third-party operated server.
//
// Params
// - user is an interface that adheres to the xxdk.E2e object.
// - comms is an interface that adheres to client.Comms object.
// - follower is a method off of xxdk.Cmix which returns the network follower's status.
// - username is the name of the user as it is registered with UD. This will be what
// the end user provides if through the bindings.
// - networkValidationSig is a signature provided by the network (i.e. the client registrar).
// This may be nil, however UD may return an error in some cases (e.g. in a production level
// environment).
func NewOrLoadFromNdf(user udE2e, comms Comms, follower udNetworkStatus,
username string, networkValidationSig []byte) (*Manager, error) {
jww.INFO.Println("ud.NewOrLoadFromNdf()")
// - username is the name of the user as it is registered with UD. This will be what the end user
// provides if through the bindings.
// - networkValidationSig is a signature provided by the network (i.e. the client registrar). This may
// be nil, however UD may return an error in some cases (e.g. in a production level environment).
// - customCert is the TLS certificate for the alternate UD server.
// - customContactFile is the data within a marshalled contact.Contact.
// - customAddress is the IP address of the alternate UD server.
//
// Returns
// - A Manager object which is registered to the specified alternate UD service.
func NewOrLoad(user udE2e, comms Comms, follower udNetworkStatus,
username string, networkValidationSig,
customCert, customContactFile []byte, customAddress string) (*Manager, error) {
jww.INFO.Println("ud.NewOrLoad()")
// Construct manager
m, err := loadOrNewManager(user, comms, follower)
......@@ -67,6 +75,12 @@ func NewOrLoadFromNdf(user udE2e, comms Comms, follower udNetworkStatus,
return nil, err
}
// Set alternative user discovery
err = m.setAlternateUserDiscovery(customCert, customContactFile, customAddress)
if err != nil {
return nil, err
}
// Register manager
rng := m.getRng().GetStream()
defer rng.Close()
......@@ -128,54 +142,6 @@ func NewManagerFromBackup(user udE2e, comms Comms, follower udNetworkStatus,
return m, nil
}
// NewOrLoad loads an existing Manager from storage or creates a
// new one if there is no extant storage information. This call allows the user to provide
// custom UD contact information. These parameters may be used to contact a separate UD server
// than the one hosted by the xx network team, i.e. one the user or a third-party may operate.
//
// Params
// - user is an interface that adheres to the xxdk.E2e object.
// - comms is an interface that adheres to client.Comms object.
// - follower is a method off of xxdk.Cmix which returns the network follower's status.
// - username is the name of the user as it is registered with UD. This will be what the end user
// provides if through the bindings.
// - networkValidationSig is a signature provided by the network (i.e. the client registrar). This may
// be nil, however UD may return an error in some cases (e.g. in a production level environment).
// - customCert is the TLS certificate for the alternate UD server.
// - customAddress is the IP address of the alternate UD server.
// - customContactFile is the data within a marshalled contact.Contact.
//
// Returns
// - A Manager object which is registered to the specified alternate UD service.
func NewOrLoad(user udE2e, comms Comms, follower udNetworkStatus,
username string, networkValidationSig []byte,
customCert, customAddress, customContactFile []byte) (*Manager, error) {
jww.INFO.Println("ud.NewOrLoad()")
// Construct manager
m, err := loadOrNewManager(user, comms, follower)
if err != nil {
return nil, err
}
// Set alternative user discovery
err = m.setAlternateUserDiscovery(customCert, customAddress, customContactFile)
if err != nil {
return nil, err
}
// Register manager
rng := m.getRng().GetStream()
defer rng.Close()
err = m.register(username, networkValidationSig, rng, comms)
if err != nil {
return nil, err
}
return m, nil
}
// InitStoreFromBackup initializes the UD storage from the backup subsystem.
func InitStoreFromBackup(kv *versioned.KV,
username, email, phone fact.Fact) error {
......
......@@ -53,7 +53,7 @@ func TestManager_SetAlternativeUserDiscovery(t *testing.T) {
m, _ := newTestManager(t)
altAddr := "0.0.0.0:11420"
err := m.setAlternateUserDiscovery([]byte(testCert), []byte(altAddr), []byte(testContact))
err := m.setAlternateUserDiscovery([]byte(testCert), []byte(testContact), string([]byte(altAddr)))
if err != nil {
t.Fatalf("Unexpected error in setAlternateUserDiscovery: %v", err)
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment