Skip to content
Snippets Groups Projects
Commit 2c6a5951 authored by Josh Brooks's avatar Josh Brooks
Browse files

Merge branch 'hotfix/StoreUsernameUd' into 'release'

Hotfix/store username ud

See merge request !337
parents 62e6f99f 7a01ddb2
Branches
Tags
2 merge requests!510Release,!337Hotfix/store username ud
...@@ -208,6 +208,9 @@ func NewOrLoadUd(e2eID int, follower UdNetworkStatus, username string, ...@@ -208,6 +208,9 @@ func NewOrLoadUd(e2eID int, follower UdNetworkStatus, username string,
// Parameters: // Parameters:
// - e2eID - e2e object ID in the tracker // - e2eID - e2e object ID in the tracker
// - follower - network follower func wrapped in UdNetworkStatus // - follower - network follower func wrapped in UdNetworkStatus
// - username - The username this user registered with initially. This should
// not be nullable, and be JSON marshalled as retrieved from
// UserDiscovery.GetFacts().
// - emailFactJson - nullable JSON marshalled email [fact.Fact] // - emailFactJson - nullable JSON marshalled email [fact.Fact]
// - phoneFactJson - nullable JSON marshalled phone [fact.Fact] // - phoneFactJson - nullable JSON marshalled phone [fact.Fact]
// - cert - the TLS certificate for the UD server this call will connect with. // - cert - the TLS certificate for the UD server this call will connect with.
...@@ -220,8 +223,9 @@ func NewOrLoadUd(e2eID int, follower UdNetworkStatus, username string, ...@@ -220,8 +223,9 @@ func NewOrLoadUd(e2eID int, follower UdNetworkStatus, username string,
// - address - the IP address of the UD server this call will connect with. You // - address - 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 // may use the UD server run by the xx network team by using
// E2e.GetUdAddressFromNdf. // E2e.GetUdAddressFromNdf.
func NewUdManagerFromBackup(e2eID int, follower UdNetworkStatus, emailFactJson, func NewUdManagerFromBackup(e2eID int, follower UdNetworkStatus,
phoneFactJson, cert, contactFile []byte, address string) (*UserDiscovery, error) { usernameJson, emailFactJson, phoneFactJson,
cert, contactFile []byte, address string) (*UserDiscovery, error) {
// Get user from singleton // Get user from singleton
user, err := e2eTrackerSingleton.get(e2eID) user, err := e2eTrackerSingleton.get(e2eID)
...@@ -229,7 +233,9 @@ func NewUdManagerFromBackup(e2eID int, follower UdNetworkStatus, emailFactJson, ...@@ -229,7 +233,9 @@ func NewUdManagerFromBackup(e2eID int, follower UdNetworkStatus, emailFactJson,
return nil, err return nil, err
} }
var email, phone fact.Fact var email, phone, username fact.Fact
// Parse email if non-nil
if emailFactJson != nil { if emailFactJson != nil {
err = json.Unmarshal(emailFactJson, &email) err = json.Unmarshal(emailFactJson, &email)
if err != nil { if err != nil {
...@@ -237,6 +243,7 @@ func NewUdManagerFromBackup(e2eID int, follower UdNetworkStatus, emailFactJson, ...@@ -237,6 +243,7 @@ func NewUdManagerFromBackup(e2eID int, follower UdNetworkStatus, emailFactJson,
} }
} }
// Parse phone if non-nil
if phoneFactJson != nil { if phoneFactJson != nil {
err = json.Unmarshal(phoneFactJson, &phone) err = json.Unmarshal(phoneFactJson, &phone)
if err != nil { if err != nil {
...@@ -244,13 +251,19 @@ func NewUdManagerFromBackup(e2eID int, follower UdNetworkStatus, emailFactJson, ...@@ -244,13 +251,19 @@ func NewUdManagerFromBackup(e2eID int, follower UdNetworkStatus, emailFactJson,
} }
} }
// Parse username
err = json.Unmarshal(usernameJson, &username)
if err != nil {
return nil, err
}
UdNetworkStatusFn := func() xxdk.Status { UdNetworkStatusFn := func() xxdk.Status {
return xxdk.Status(follower.UdNetworkStatus()) return xxdk.Status(follower.UdNetworkStatus())
} }
u, err := ud.NewManagerFromBackup( u, err := ud.NewManagerFromBackup(
user.api, user.api.GetComms(), UdNetworkStatusFn, user.api, user.api.GetComms(), UdNetworkStatusFn,
email, phone, username, email, phone,
cert, contactFile, address) cert, contactFile, address)
if err != nil { if err != nil {
return nil, err return nil, err
......
...@@ -102,6 +102,13 @@ func NewOrLoad(user udE2e, comms Comms, follower udNetworkStatus, ...@@ -102,6 +102,13 @@ func NewOrLoad(user udE2e, comms Comms, follower udNetworkStatus,
return nil, err return nil, err
} }
usernameFact, err := fact.NewFact(fact.Username, username)
if err != nil {
return nil, err
}
err = m.store.StoreUsername(usernameFact)
return m, nil return m, nil
} }
...@@ -127,7 +134,8 @@ func NewOrLoad(user udE2e, comms Comms, follower udNetworkStatus, ...@@ -127,7 +134,8 @@ func NewOrLoad(user udE2e, comms Comms, follower udNetworkStatus,
// Returns // Returns
// - A Manager object which is registered to the specified UD service. // - A Manager object which is registered to the specified UD service.
func NewManagerFromBackup(user udE2e, comms Comms, follower udNetworkStatus, func NewManagerFromBackup(user udE2e, comms Comms, follower udNetworkStatus,
email, phone fact.Fact, cert, contactFile []byte, address string) (*Manager, error) { username, email, phone fact.Fact,
cert, contactFile []byte, address string) (*Manager, error) {
jww.INFO.Println("ud.NewManagerFromBackup()") jww.INFO.Println("ud.NewManagerFromBackup()")
if follower() != xxdk.Running { if follower() != xxdk.Running {
return nil, errors.New( return nil, errors.New(
...@@ -149,7 +157,7 @@ func NewManagerFromBackup(user udE2e, comms Comms, follower udNetworkStatus, ...@@ -149,7 +157,7 @@ func NewManagerFromBackup(user udE2e, comms Comms, follower udNetworkStatus,
} }
// Put any passed in missing facts into store // Put any passed in missing facts into store
err = m.store.BackUpMissingFacts(email, phone) err = m.store.BackUpMissingFacts(username, email, phone)
if err != nil { if err != nil {
return nil, errors.WithMessage(err, "Failed to restore UD store "+ return nil, errors.WithMessage(err, "Failed to restore UD store "+
"from backup") "from backup")
...@@ -180,7 +188,7 @@ func InitStoreFromBackup(kv *versioned.KV, ...@@ -180,7 +188,7 @@ func InitStoreFromBackup(kv *versioned.KV,
} }
// Put any passed in missing facts into store // Put any passed in missing facts into store
err = udStore.BackUpMissingFacts(email, phone) err = udStore.BackUpMissingFacts(username, email, phone)
if err != nil { if err != nil {
return errors.WithMessage(err, "Failed to restore UD store "+ return errors.WithMessage(err, "Failed to restore UD store "+
"from backup") "from backup")
......
...@@ -42,6 +42,42 @@ func (s *Store) RestoreFromBackUp(backupData fact.FactList) error { ...@@ -42,6 +42,42 @@ func (s *Store) RestoreFromBackUp(backupData fact.FactList) error {
return s.save() return s.save()
} }
// StoreUsername forces the storage of a username fact.Fact into the
// Store's confirmedFacts map. The passed in fact.Fact must be of
// type fact.Username or this will not store the username.
func (s *Store) StoreUsername(f fact.Fact) error {
s.mux.Lock()
defer s.mux.Unlock()
if f.T != fact.Username {
return errors.Errorf("Fact (%s) is not of type username", f.Stringify())
}
s.confirmedFacts[f] = struct{}{}
return s.saveUnconfirmedFacts()
}
// GetUsername retrieves the username from the Store object.
// If it is not directly in the Store's username field, it is
// searched for in the map.
func (s *Store) GetUsername() (string, error) {
s.mux.RLock()
defer s.mux.RUnlock()
// todo: refactor this in the future so that
// it's an O(1) lookup (place this object in another map
// or have it's own field)
for f := range s.confirmedFacts {
if f.T == fact.Username {
return f.Fact, nil
}
}
return "", errors.New("Could not find username in store")
}
// StoreUnconfirmedFact stores a fact that has been added to UD but has not been // StoreUnconfirmedFact stores a fact that has been added to UD but has not been
// confirmed by the user. It is keyed on the confirmation ID given by UD. // confirmed by the user. It is keyed on the confirmation ID given by UD.
func (s *Store) StoreUnconfirmedFact(confirmationId string, f fact.Fact) error { func (s *Store) StoreUnconfirmedFact(confirmationId string, f fact.Fact) error {
...@@ -84,11 +120,11 @@ func (s *Store) ConfirmFact(confirmationId string) error { ...@@ -84,11 +120,11 @@ func (s *Store) ConfirmFact(confirmationId string) error {
// If you attempt to back up a fact type that has already been backed up, // If you attempt to back up a fact type that has already been backed up,
// an error will be returned and nothing will be backed up. // an error will be returned and nothing will be backed up.
// Otherwise, it adds the fact and returns whether the Store saved successfully. // Otherwise, it adds the fact and returns whether the Store saved successfully.
func (s *Store) BackUpMissingFacts(email, phone fact.Fact) error { func (s *Store) BackUpMissingFacts(username, email, phone fact.Fact) error {
s.mux.Lock() s.mux.Lock()
defer s.mux.Unlock() defer s.mux.Unlock()
modifiedEmail, modifiedPhone := false, false modified := false
// Handle email if it is not zero (empty string) // Handle email if it is not zero (empty string)
if !isFactZero(email) { if !isFactZero(email) {
...@@ -102,10 +138,12 @@ func (s *Store) BackUpMissingFacts(email, phone fact.Fact) error { ...@@ -102,10 +138,12 @@ func (s *Store) BackUpMissingFacts(email, phone fact.Fact) error {
// If an email exists in memory, return an error // If an email exists in memory, return an error
return errors.Errorf(factTypeExistsErr, email, fact.Email) return errors.Errorf(factTypeExistsErr, email, fact.Email)
} else { } else {
modifiedEmail = true s.confirmedFacts[email] = struct{}{}
modified = true
} }
} }
// Handle phone if it is not an empty string
if !isFactZero(phone) { if !isFactZero(phone) {
// check if fact is expected type // check if fact is expected type
if phone.T != fact.Phone { if phone.T != fact.Phone {
...@@ -117,19 +155,24 @@ func (s *Store) BackUpMissingFacts(email, phone fact.Fact) error { ...@@ -117,19 +155,24 @@ func (s *Store) BackUpMissingFacts(email, phone fact.Fact) error {
// If a phone exists in memory, return an error // If a phone exists in memory, return an error
return errors.Errorf(factTypeExistsErr, phone, fact.Phone) return errors.Errorf(factTypeExistsErr, phone, fact.Phone)
} else { } else {
modifiedPhone = true s.confirmedFacts[phone] = struct{}{}
modified = true
} }
} }
if modifiedPhone || modifiedEmail { if !isFactZero(username) {
if modifiedEmail { // Check if fact type is already in map. You should not be able to
s.confirmedFacts[email] = struct{}{} // overwrite your username.
if isFactTypeInMap(fact.Username, s.confirmedFacts) {
// If a username exists in memory, return an error
return errors.Errorf(factTypeExistsErr, username, fact.Username)
} else {
s.confirmedFacts[username] = struct{}{}
modified = true
} }
if modifiedPhone {
s.confirmedFacts[phone] = struct{}{}
} }
if modified {
return s.saveConfirmedFacts() return s.saveConfirmedFacts()
} }
......
...@@ -203,7 +203,12 @@ func TestStore_BackUpMissingFacts(t *testing.T) { ...@@ -203,7 +203,12 @@ func TestStore_BackUpMissingFacts(t *testing.T) {
T: fact.Phone, T: fact.Phone,
} }
err = expectedStore.BackUpMissingFacts(email, phone) username := fact.Fact{
Fact: "admin",
T: fact.Username,
}
err = expectedStore.BackUpMissingFacts(username, email, phone)
if err != nil { if err != nil {
t.Fatalf("BackUpMissingFacts() produced an error: %v", err) t.Fatalf("BackUpMissingFacts() produced an error: %v", err)
} }
...@@ -238,18 +243,23 @@ func TestStore_BackUpMissingFacts_DuplicateFactType(t *testing.T) { ...@@ -238,18 +243,23 @@ func TestStore_BackUpMissingFacts_DuplicateFactType(t *testing.T) {
T: fact.Phone, T: fact.Phone,
} }
err = expectedStore.BackUpMissingFacts(email, phone) username := fact.Fact{
Fact: "admin",
T: fact.Username,
}
err = expectedStore.BackUpMissingFacts(username, email, phone)
if err != nil { if err != nil {
t.Fatalf("BackUpMissingFacts() produced an error: %v", err) t.Fatalf("BackUpMissingFacts() produced an error: %v", err)
} }
err = expectedStore.BackUpMissingFacts(email, fact.Fact{}) err = expectedStore.BackUpMissingFacts(username, email, fact.Fact{})
if err == nil { if err == nil {
t.Fatalf("BackUpMissingFacts() should not allow backing up an "+ t.Fatalf("BackUpMissingFacts() should not allow backing up an "+
"email when an email has already been backed up: %v", err) "email when an email has already been backed up: %v", err)
} }
err = expectedStore.BackUpMissingFacts(fact.Fact{}, phone) err = expectedStore.BackUpMissingFacts(username, fact.Fact{}, phone)
if err == nil { if err == nil {
t.Fatalf("BackUpMissingFacts() should not allow backing up a "+ t.Fatalf("BackUpMissingFacts() should not allow backing up a "+
"phone number when a phone number has already been backed up: %v", err) "phone number when a phone number has already been backed up: %v", err)
...@@ -272,7 +282,12 @@ func TestStore_GetFacts(t *testing.T) { ...@@ -272,7 +282,12 @@ func TestStore_GetFacts(t *testing.T) {
emptyFact := fact.Fact{} emptyFact := fact.Fact{}
err = testStore.BackUpMissingFacts(emailFact, emptyFact) username := fact.Fact{
Fact: "admin",
T: fact.Username,
}
err = testStore.BackUpMissingFacts(username, emailFact, emptyFact)
if err != nil { if err != nil {
t.Fatalf("Faild to add fact %v: %v", emailFact, err) t.Fatalf("Faild to add fact %v: %v", emailFact, err)
} }
...@@ -282,12 +297,12 @@ func TestStore_GetFacts(t *testing.T) { ...@@ -282,12 +297,12 @@ func TestStore_GetFacts(t *testing.T) {
T: fact.Phone, T: fact.Phone,
} }
err = testStore.BackUpMissingFacts(emptyFact, phoneFact) err = testStore.BackUpMissingFacts(emptyFact, emptyFact, phoneFact)
if err != nil { if err != nil {
t.Fatalf("Faild to add fact %v: %v", phoneFact, err) t.Fatalf("Faild to add fact %v: %v", phoneFact, err)
} }
expectedFacts := []fact.Fact{emailFact, phoneFact} expectedFacts := []fact.Fact{username, emailFact, phoneFact}
receivedFacts := testStore.GetFacts() receivedFacts := testStore.GetFacts()
...@@ -318,10 +333,14 @@ func TestStore_GetFactStrings(t *testing.T) { ...@@ -318,10 +333,14 @@ func TestStore_GetFactStrings(t *testing.T) {
Fact: "josh@elixxir.io", Fact: "josh@elixxir.io",
T: fact.Email, T: fact.Email,
} }
username := fact.Fact{
Fact: "admin",
T: fact.Username,
}
emptyFact := fact.Fact{} emptyFact := fact.Fact{}
err = testStore.BackUpMissingFacts(emailFact, emptyFact) err = testStore.BackUpMissingFacts(username, emailFact, emptyFact)
if err != nil { if err != nil {
t.Fatalf("Faild to add fact %v: %v", emailFact, err) t.Fatalf("Faild to add fact %v: %v", emailFact, err)
} }
...@@ -331,12 +350,12 @@ func TestStore_GetFactStrings(t *testing.T) { ...@@ -331,12 +350,12 @@ func TestStore_GetFactStrings(t *testing.T) {
T: fact.Phone, T: fact.Phone,
} }
err = testStore.BackUpMissingFacts(emptyFact, phoneFact) err = testStore.BackUpMissingFacts(emptyFact, emptyFact, phoneFact)
if err != nil { if err != nil {
t.Fatalf("Faild to add fact %v: %v", phoneFact, err) t.Fatalf("Faild to add fact %v: %v", phoneFact, err)
} }
expectedFacts := []string{emailFact.Stringify(), phoneFact.Stringify()} expectedFacts := []string{username.Stringify(), emailFact.Stringify(), phoneFact.Stringify()}
receivedFacts := testStore.GetStringifiedFacts() receivedFacts := testStore.GetStringifiedFacts()
sort.SliceStable(receivedFacts, func(i, j int) bool { sort.SliceStable(receivedFacts, func(i, j int) bool {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment