Commit f874b2d4 authored by ale's avatar ale

Quantize all timestamps stored in the db

Fixes issue #1.
parent 68195c87
Pipeline #2639 failed with stages
in 5 minutes and 48 seconds
...@@ -71,7 +71,7 @@ func (l *lastloginDB) AddLastLogin(entry *usermetadb.LastLoginEntry) error { ...@@ -71,7 +71,7 @@ func (l *lastloginDB) AddLastLogin(entry *usermetadb.LastLoginEntry) error {
args := []interface{}{ args := []interface{}{
entry.Username, entry.Username,
entry.Service, entry.Service,
entry.Timestamp, roundTimestamp(entry.Timestamp),
} }
if _, err = l.stmts.get(tx, stmt).Exec(args...); err != nil { if _, err = l.stmts.get(tx, stmt).Exec(args...); err != nil {
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"time" "time"
"git.autistici.org/id/usermetadb" "git.autistici.org/id/usermetadb"
"github.com/google/go-cmp/cmp"
) )
func generateLastLoginEntries() []*usermetadb.LastLoginEntry { func generateLastLoginEntries() []*usermetadb.LastLoginEntry {
...@@ -54,8 +55,10 @@ func TestLastlogin_LoginAdded(t *testing.T) { ...@@ -54,8 +55,10 @@ func TestLastlogin_LoginAdded(t *testing.T) {
t.Fatalf("Expected exactly one entry, found %v", out) t.Fatalf("Expected exactly one entry, found %v", out)
} }
if *in[0] != *out[0] { // Modify the entries so that the quantized timestamp matches.
t.Fatalf("Last login entries differ:\nSet %v\nGot %v", *in[0], *out[0]) in[0].Timestamp = roundTimestamp(in[0].Timestamp)
if diffs := cmp.Diff(in[0], out[0]); diffs != "" {
t.Fatalf("Last login entries differ:\n%s", diffs)
} }
} }
...@@ -90,8 +93,10 @@ func TestLastLogin_MultipleServices(t *testing.T) { ...@@ -90,8 +93,10 @@ func TestLastLogin_MultipleServices(t *testing.T) {
} }
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {
if *in[i] != *out[i] { // Modify the entries so that the quantized timestamp matches.
t.Fatalf("Last login entries #%d differ:\nSet %v\nGot %v", i, *in[i], *out[i]) in[i].Timestamp = roundTimestamp(in[i].Timestamp)
if diffs := cmp.Diff(in[0], out[0]); diffs != "" {
t.Fatalf("Last login entries #%d differ:\n%s", i, diffs)
} }
} }
} }
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"git.autistici.org/ai3/go-common/clientutil" "git.autistici.org/ai3/go-common/clientutil"
"git.autistici.org/id/usermetadb/client" "git.autistici.org/id/usermetadb/client"
"github.com/google/go-cmp/cmp"
) )
func TestServer_AddLog(t *testing.T) { func TestServer_AddLog(t *testing.T) {
...@@ -69,12 +70,13 @@ func TestServer_AddLastLogin(t *testing.T) { ...@@ -69,12 +70,13 @@ func TestServer_AddLastLogin(t *testing.T) {
} }
expResp := *entries[0] expResp := *entries[0]
expResp.Timestamp = roundTimestamp(expResp.Timestamp)
resp, err := c.GetLastLogin(context.Background(), "", expResp.Username, expResp.Service) resp, err := c.GetLastLogin(context.Background(), "", expResp.Username, expResp.Service)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if *resp[0] != expResp { if diffs := cmp.Diff(resp[0], &expResp); diffs != "" {
t.Fatalf("Last login entries differ:\nSet %v\nGot %v", expResp, *resp[0]) t.Fatalf("Last login entries differ:\n%s", diffs)
} }
} }
...@@ -164,7 +164,7 @@ func (u *userlogDB) Close() { ...@@ -164,7 +164,7 @@ func (u *userlogDB) Close() {
// Update or create an entry in the 'devices' table. // Update or create an entry in the 'devices' table.
func (u *userlogDB) updateDeviceInfo(tx *sql.Tx, username string, deviceInfo *auth.DeviceInfo) error { func (u *userlogDB) updateDeviceInfo(tx *sql.Tx, username string, deviceInfo *auth.DeviceInfo) error {
now := time.Now().UTC() now := roundTimestamp(time.Now().UTC())
var seen bool var seen bool
err := u.stmts.get(tx, "check_device_info").QueryRow(username, deviceInfo.ID).Scan(&seen) err := u.stmts.get(tx, "check_device_info").QueryRow(username, deviceInfo.ID).Scan(&seen)
...@@ -333,17 +333,19 @@ func (u *userlogDB) GetUserDevices(username string) ([]*usermetadb.MetaDeviceInf ...@@ -333,17 +333,19 @@ func (u *userlogDB) GetUserDevices(username string) ([]*usermetadb.MetaDeviceInf
return out, rows.Err() return out, rows.Err()
} }
var timestampRoundSeconds int64 = 7200 const timestampRoundSeconds = 7200
func roundTimestamp(t time.Time, r int64) time.Time { // Quantize timestamps to minimize time correlation possibilities.
return time.Unix((t.Unix()/r)*r, 0) func roundTimestamp(t time.Time) time.Time {
// Keep the original timezone information.
return time.Unix((t.Unix()/timestampRoundSeconds)*timestampRoundSeconds, 0).In(t.Location())
} }
// Minimize a log entry, removing all the data that we don't want to // Minimize a log entry, removing all the data that we don't want to
// store (even if it's already missing in the database schema). // store (even if it's already missing in the database schema).
func minimizeLogEntry(e *usermetadb.LogEntry) { func minimizeLogEntry(e *usermetadb.LogEntry) {
// Round timestamps to the nearest even hour. // Round timestamps to the nearest even hour.
e.Timestamp = roundTimestamp(e.Timestamp, timestampRoundSeconds) e.Timestamp = roundTimestamp(e.Timestamp)
// Drop fields in DeviceInfo that we don't want. // Drop fields in DeviceInfo that we don't want.
if e.DeviceInfo != nil { if e.DeviceInfo != nil {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment