Skip to content
Snippets Groups Projects
Select Git revision
  • e687051e2a3f1b35dfd400c1555adec588a8de2d
  • release default protected
  • 11-22-implement-kv-interface-defined-in-collectiveversionedkvgo
  • hotfix/TestHostPool_UpdateNdf_AddFilter
  • XX-4719/announcementChannels
  • xx-4717/logLevel
  • jonah/noob-channel
  • master protected
  • XX-4707/tagDiskJson
  • xx-4698/notification-retry
  • hotfix/notifylockup
  • syncNodes
  • hotfix/localCB
  • XX-4677/NewChanManagerMobile
  • XX-4689/DmSync
  • duplicatePrefix
  • XX-4601/HavenInvites
  • finalizedUICallbacks
  • XX-4673/AdminKeySync
  • debugNotifID
  • anne/test
  • v4.7.5
  • v4.7.4
  • v4.7.3
  • v4.7.2
  • v4.7.1
  • v4.6.3
  • v4.6.1
  • v4.5.0
  • v4.4.4
  • v4.3.11
  • v4.3.8
  • v4.3.7
  • v4.3.6
  • v4.3.5
  • v4.2.0
  • v4.3.0
  • v4.3.4
  • v4.3.3
  • v4.3.2
  • v4.3.1
41 results

single.go

Blame
  • user.go 5.44 KiB
    ////////////////////////////////////////////////////////////////////////////////
    // Copyright © 2019 Privategrity Corporation                                   /
    //                                                                             /
    // All rights reserved.                                                        /
    ////////////////////////////////////////////////////////////////////////////////
    
    package user
    
    import (
    	"crypto/sha256"
    	"gitlab.com/elixxir/client/globals"
    	"gitlab.com/elixxir/crypto/cyclic"
    	"gitlab.com/elixxir/primitives/id"
    )
    
    // Globally instantiated Registry
    var Users Registry
    
    const NumDemoUsers = 40
    
    var DemoUserNicks = []string{"David", "Payments", "UDB", "Jim", "Ben", "Steph",
    	"Rick", "Jake", "Spencer", "Stephanie", "Mario", "Jono", "Amanda",
    	"Margaux", "Kevin", "Bruno", "Konstantino", "Bernardo", "Tigran",
    	"Kate", "Will", "Katie", "Bryan"}
    var DemoChannelNames = []string{"#General", "#Engineering", "#Lunch",
    	"#Random"}
    
    func InitUserRegistry(grp *cyclic.Group) {
    	Users = newRegistry(grp)
    }
    
    // Interface for User Registry operations
    type Registry interface {
    	NewUser(id *id.User, nickname string) *User
    	DeleteUser(id *id.User)
    	GetUser(id *id.User) (user *User, ok bool)
    	UpsertUser(user *User)
    	CountUsers() int
    	LookupUser(hid string) (uid *id.User, ok bool)
    	LookupKeys(uid *id.User) (*NodeKeys, bool)
    }
    
    type UserMap struct {
    	// Map acting as the User Registry containing User -> ID mapping
    	userCollection map[id.User]*User
    	// Increments sequentially for User.ID values
    	idCounter uint64
    	// Temporary map acting as a lookup table for demo user registration codes
    	// Key type is string because keys must implement == and []byte doesn't
    	userLookup map[string]*id.User
    	//Temporary placed to store the keys for each user
    	keysLookup map[id.User]*NodeKeys
    }
    
    // newRegistry creates a new Registry interface
    func newRegistry(grp *cyclic.Group) Registry {
    	if len(DemoChannelNames) > 10 || len(DemoUserNicks) > 30 {
    		globals.Log.ERROR.Print("Not enough demo users have been hardcoded.")
    	}
    	userUserIdMap := make(map[id.User]*User)
    	userRegCodeMap := make(map[string]*id.User)
    	nk := make(map[id.User]*NodeKeys)
    
    	// Deterministically create NumDemoUsers users
    	// TODO Replace this with real user registration/discovery
    	for i := uint64(1); i <= NumDemoUsers; i++ {
    		currentID := id.NewUserFromUints(&[4]uint64{0, 0, 0, i})
    		newUsr := new(User)
    		nodeKey := new(NodeKeys)
    
    		// Generate user parameters
    		newUsr.User = currentID
    		newUsr.Precan = true
    		currentID.RegistrationCode()
    		// TODO We need a better way to generate base/recursive keys
    		h := sha256.New()
    		h.Write([]byte(string(40000 + i)))
    		nodeKey.TransmissionKey = grp.NewIntFromBytes(h.Sum(nil))
    		h = sha256.New()
    		h.Write([]byte(string(60000 + i)))
    		nodeKey.ReceptionKey = grp.NewIntFromBytes(h.Sum(nil))
    
    		// Add user to collection and lookup table
    		userUserIdMap[*newUsr.User] = newUsr
    		// Detect collisions in the registration code
    		if _, ok := userRegCodeMap[newUsr.User.RegistrationCode()]; ok {
    			globals.Log.ERROR.Printf(
    				"Collision in demo user list creation at %v. "+
    					"Please fix ASAP (include more bits to the reg code.", i)
    		}
    		userRegCodeMap[newUsr.User.RegistrationCode()] = newUsr.User
    		nk[*newUsr.User] = nodeKey
    	}
    
    	// Channels have been hardcoded to users starting with 31
    	for i := 0; i < len(DemoUserNicks); i++ {
    		currentID := id.NewUserFromUints(&[4]uint64{0, 0, 0, uint64(i) + 1})
    		userUserIdMap[*currentID].Username = DemoUserNicks[i]
    	}
    
    	for i := 0; i < len(DemoChannelNames); i++ {
    		currentID := id.NewUserFromUints(&[4]uint64{0, 0, 0, uint64(i) + 31})
    		userUserIdMap[*currentID].Username = DemoChannelNames[i]
    	}
    
    	// With an underlying UserMap data structure
    	return Registry(&UserMap{userCollection: userUserIdMap,
    		idCounter:  uint64(NumDemoUsers),
    		userLookup: userRegCodeMap,
    		keysLookup: nk})
    }
    
    // Struct representing a User in the system
    type User struct {
    	User     *id.User
    	Username string
    	Precan   bool
    }
    
    // DeepCopy performs a deep copy of a user and returns a pointer to the new copy
    func (u *User) DeepCopy() *User {
    	if u == nil {
    		return nil
    	}
    	nu := new(User)
    	nu.User = u.User
    	nu.Username = u.Username
    	nu.Precan = u.Precan
    	return nu
    }
    
    // NewUser creates a new User object with default fields and given address.
    func (m *UserMap) NewUser(id *id.User, username string) *User {
    	return &User{User: id, Username: username}
    }
    
    // GetUser returns a user with the given ID from userCollection
    // and a boolean for whether the user exists
    func (m *UserMap) GetUser(id *id.User) (user *User, ok bool) {
    	user, ok = m.userCollection[*id]
    	user = user.DeepCopy()
    	return
    }
    
    // DeleteContactKeys deletes a user with the given ID from userCollection.
    func (m *UserMap) DeleteUser(id *id.User) {
    	// If key does not exist, do nothing
    	delete(m.userCollection, *id)
    }
    
    // UpsertUser inserts given user into userCollection or update the user if it
    // already exists (Upsert operation).
    func (m *UserMap) UpsertUser(user *User) {
    	m.userCollection[*user.User] = user
    }
    
    // CountUsers returns a count of the users in userCollection
    func (m *UserMap) CountUsers() int {
    	return len(m.userCollection)
    }
    
    // LookupUser returns the user id corresponding to the demo registration code
    func (m *UserMap) LookupUser(hid string) (*id.User, bool) {
    	uid, ok := m.userLookup[hid]
    	return uid, ok
    }
    
    // LookupKeys returns the keys for the given user from the temporary key map
    func (m *UserMap) LookupKeys(uid *id.User) (*NodeKeys, bool) {
    	nk, t := m.keysLookup[*uid]
    	return nk, t
    }