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

Add storage of registrationTimestamp to User

parent c9363d0f
No related branches found
No related tags found
1 merge request!23Release
......@@ -8,14 +8,17 @@
package user
import (
"encoding/binary"
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/storage/versioned"
"gitlab.com/xx_network/primitives/netTime"
"time"
)
const currentRegValidationSigVersion = 0
const transmissionRegValidationSigKey = "transmissionRegistrationValidationSignature"
const receptionRegValidationSigKey = "receptionRegistrationValidationSignature"
const registrationTimestampKey = "registrationTimestamp"
// Returns the transmission Identity Validation Signature stored in RAM. May return
// nil of no signature is stored
......@@ -33,6 +36,20 @@ func (u *User) GetReceptionRegistrationValidationSignature() []byte {
return u.receptionRegValidationSig
}
// Returns the registration timestamp stored in RAM as int64
func (u *User) GetRegistrationTimestampNano() int64 {
u.rvsMux.RLock()
defer u.rvsMux.RUnlock()
return u.registrationTimestamp.UnixNano()
}
// Returns the registration timestamp stored in RAM as
func (u *User) GetRegistrationTimestamp() time.Time {
u.rvsMux.RLock()
defer u.rvsMux.RUnlock()
return u.registrationTimestamp
}
// Loads the transmission Identity Validation Signature if it exists in the ekv
func (u *User) loadTransmissionRegistrationValidationSignature() {
u.rvsMux.Lock()
......@@ -55,6 +72,18 @@ func (u *User) loadReceptionRegistrationValidationSignature() {
u.rvsMux.Unlock()
}
// Loads the registration timestamp if it exists in the ekv
func (u *User) loadRegistrationTimestamp() {
u.rvsMux.Lock()
obj, err := u.kv.Get(registrationTimestampKey,
currentRegValidationSigVersion)
if err == nil {
tsNano := binary.BigEndian.Uint64(obj.Data)
u.registrationTimestamp = time.Unix(0, int64(tsNano))
}
u.rvsMux.Unlock()
}
// Sets the Identity Validation Signature if it is not set and stores it in
// the ekv
func (u *User) SetTransmissionRegistrationValidationSignature(b []byte) {
......@@ -108,3 +137,34 @@ func (u *User) SetReceptionRegistrationValidationSignature(b []byte) {
u.receptionRegValidationSig = b
}
// Sets the Registration Timestamp if it is not set and stores it in
// the ekv
func (u *User) SetRegistrationTimestamp(tsNano int64) {
u.rvsMux.Lock()
defer u.rvsMux.Unlock()
//check if the signature already exists
if !u.registrationTimestamp.IsZero() {
jww.FATAL.Panicf("cannot overwrite existing registration timestamp")
}
// Serialize the timestamp
tsBytes := make([]byte, 8)
binary.BigEndian.PutUint64(tsBytes, uint64(tsNano))
obj := &versioned.Object{
Version: currentRegValidationSigVersion,
Timestamp: netTime.Now(),
Data: tsBytes,
}
err := u.kv.Set(registrationTimestampKey,
currentRegValidationSigVersion, obj)
if err != nil {
jww.FATAL.Panicf("Failed to store the reception timestamp: %s", err)
}
u.registrationTimestamp = time.Unix(0, tsNano)
}
......@@ -9,12 +9,14 @@ package user
import (
"bytes"
"encoding/binary"
"gitlab.com/elixxir/client/storage/versioned"
"gitlab.com/elixxir/ekv"
"gitlab.com/xx_network/crypto/signature/rsa"
"gitlab.com/xx_network/primitives/id"
"gitlab.com/xx_network/primitives/netTime"
"testing"
"time"
)
// Test User GetRegistrationValidationSignature function
......@@ -137,3 +139,88 @@ func TestUser_loadRegistrationValidationSignature(t *testing.T) {
t.Errorf("Expected sig did not match loaded. Expected: %+v, Received: %+v", sig, u.receptionRegValidationSig)
}
}
// Test User's getter/setter functions for TimeStamp
func TestUser_GetRegistrationTimestamp(t *testing.T) {
kv := versioned.NewKV(make(ekv.Memstore))
uid := id.NewIdFromString("test", id.User, t)
salt := []byte("salt")
u, err := NewUser(kv, uid, uid, salt, salt, &rsa.PrivateKey{}, &rsa.PrivateKey{}, false)
if err != nil || u == nil {
t.Errorf("Failed to create new user: %+v", err)
}
testTime, err := time.Parse(time.RFC3339,
"2012-12-21T22:08:41+00:00")
if err != nil {
t.Fatalf("Could not parse precanned time: %v", err.Error())
}
// Test that User has been modified for timestamp
u.SetRegistrationTimestamp(testTime.UnixNano())
if !testTime.Equal(u.registrationTimestamp) {
t.Errorf("SetRegistrationTimestamp did not set user's timestamp value."+
"\n\tExpected: %s\n\tReceieved: %s", testTime.String(), u.registrationTimestamp)
}
// Pull timestamp from kv
obj, err := u.kv.Get(registrationTimestampKey, 0)
if err != nil {
t.Errorf("Failed to get reg vaildation signature key: %+v", err)
}
// Check if kv data is expected
unixNano := binary.BigEndian.Uint64(obj.Data)
if testTime.UnixNano() != int64(unixNano) {
t.Errorf("Timestamp pulled from kv was not expected."+
"\n\tExpected: %d\n\tReceieved: %d", testTime.UnixNano(), unixNano)
}
if testTime.UnixNano() != u.GetRegistrationTimestampNano() {
t.Errorf("Timestamp from GetRegistrationTimestampNano was not expected."+
"\n\tExpected: %d\n\tReceieved: %d", testTime.UnixNano(), u.GetRegistrationTimestampNano())
}
if !testTime.Equal(u.GetRegistrationTimestamp()) {
t.Errorf("Timestamp from GetRegistrationTimestamp was not expected."+
"\n\tExpected: %s\n\tReceieved: %s", testTime, u.GetRegistrationTimestamp())
}
}
// Test loading registrationTimestamp from the KV store
func TestUser_loadRegistrationTimestamp(t *testing.T) {
kv := versioned.NewKV(make(ekv.Memstore))
uid := id.NewIdFromString("test", id.User, t)
salt := []byte("salt")
u, err := NewUser(kv, uid, uid, salt, salt, &rsa.PrivateKey{}, &rsa.PrivateKey{}, false)
if err != nil || u == nil {
t.Errorf("Failed to create new user: %+v", err)
}
testTime, err := time.Parse(time.RFC3339,
"2012-12-21T22:08:41+00:00")
if err != nil {
t.Fatalf("Could not parse precanned time: %v", err.Error())
}
data := make([]byte, 8)
binary.BigEndian.PutUint64(data, uint64(testTime.UnixNano()))
vo := &versioned.Object{
Version: currentRegValidationSigVersion,
Timestamp: netTime.Now(),
Data: data,
}
err = kv.Set(registrationTimestampKey,
currentRegValidationSigVersion, vo)
if err != nil {
t.Errorf("Failed to set reg validation sig key in kv store: %+v", err)
}
u.loadRegistrationTimestamp()
if !testTime.Equal(u.registrationTimestamp) {
t.Errorf("SetRegistrationTimestamp did not set user's timestamp value."+
"\n\tExpected: %s\n\tReceieved: %s", testTime.String(), u.registrationTimestamp)
}
}
......@@ -13,6 +13,7 @@ import (
"gitlab.com/xx_network/crypto/signature/rsa"
"gitlab.com/xx_network/primitives/id"
"sync"
"time"
)
type User struct {
......@@ -20,7 +21,9 @@ type User struct {
transmissionRegValidationSig []byte
receptionRegValidationSig []byte
rvsMux sync.RWMutex
// Time in which user registered with the network
registrationTimestamp time.Time
rvsMux sync.RWMutex
username string
usernameMux sync.RWMutex
......@@ -48,6 +51,7 @@ func LoadUser(kv *versioned.KV) (*User, error) {
u.loadTransmissionRegistrationValidationSignature()
u.loadReceptionRegistrationValidationSignature()
u.loadUsername()
u.loadRegistrationTimestamp()
return u, nil
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment