From ac52f6520a6e256489828bd2967f0c5ea87afff1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mikl=C3=B3s=20T=C3=B3th?= <tothmiklostibor@gmail.com>
Date: Tue, 16 Feb 2021 16:12:30 +0100
Subject: [PATCH] switch to milliseconds

---
 aggregator/clean.go   |  2 +-
 aggregator/collect.go | 21 +++++++++++++------
 aggregator/serve.go   |  3 +--
 db/methods.go         | 13 ++++++++++++
 db/models.go          |  5 +++--
 input/ws.go           | 49 +++++++++++++++++++++++++++++++++----------
 6 files changed, 71 insertions(+), 22 deletions(-)

diff --git a/aggregator/clean.go b/aggregator/clean.go
index 71a3fe9..f37f930 100644
--- a/aggregator/clean.go
+++ b/aggregator/clean.go
@@ -3,7 +3,7 @@ package aggregator
 import "time"
 
 func clean() {
-	t := time.Now().Unix() % (bucket * 2)
+	t := getTime() % (bucket * 2)
 	for i := (t + 2) % (bucket * 2); i != (t+bucket/2)%(bucket*2); i = (i + 1) % (bucket * 2) {
 		for k := range data[i] {
 			delete(data[i], k)
diff --git a/aggregator/collect.go b/aggregator/collect.go
index b0c8843..9695ea6 100644
--- a/aggregator/collect.go
+++ b/aggregator/collect.go
@@ -1,13 +1,24 @@
 package aggregator
 
 import (
-	"sync"
+	"flag"
 	"time"
 )
 
-const bucket = 10
+var bucketFlag = flag.Int64("bucket", 10000, "Bucket size")
 
-// data[time][user] = choice
+var bucket int64 = 10000
+
+func init() {
+	flag.Parse()
+	bucket = *bucketFlag
+}
+
+func getTime() int64 {
+	return time.Now().UnixNano() / 1e6
+}
+
+// data[getTime][user] = choice
 var data = make([]map[string]string, bucket*2)
 
 func init() {
@@ -16,9 +27,7 @@ func init() {
 	}
 }
 
-var createTeamMutex sync.Mutex
-
 func Vote(UserID, Choice string) {
-	t := time.Now().Unix() % (bucket * 2)
+	t := getTime() % (bucket * 2)
 	data[t][UserID] = Choice
 }
diff --git a/aggregator/serve.go b/aggregator/serve.go
index 0b23f7b..31bd505 100644
--- a/aggregator/serve.go
+++ b/aggregator/serve.go
@@ -2,11 +2,10 @@ package aggregator
 
 import (
 	"git.sch.bme.hu/mikewashere/matrix-backend/db"
-	"time"
 )
 
 func GetCurrentChoices() (map[string]map[string]int, error) {
-	t := time.Now().Unix() % (bucket * 2)
+	t := getTime() % (bucket * 2)
 	ret := make(map[string]map[string]int)
 
 	teams, e := db.GetTeamsWithMembers()
diff --git a/db/methods.go b/db/methods.go
index c7b5344..905698d 100644
--- a/db/methods.go
+++ b/db/methods.go
@@ -34,3 +34,16 @@ func GetTeamsWithMembers() ([]*Team, error) {
 	e := db.Model(&t).Relation("Members").Select()
 	return t, e
 }
+
+func GetUser(ID string) (*User, error) {
+	var u = &User{
+		ID: ID,
+	}
+
+	e := db.Model(u).WherePK().First()
+	if e != nil {
+		return nil, e
+	}
+
+	return u, nil
+}
diff --git a/db/models.go b/db/models.go
index 138e68e..0feefe6 100644
--- a/db/models.go
+++ b/db/models.go
@@ -40,7 +40,7 @@ var db = pg.Connect(&pg.Options{
 })
 
 // special magic to run db init before other inits
-var _ = func() {
+var _ = func() error {
 	models := []interface{}{
 		(*Choice)(nil),
 		(*Team)(nil),
@@ -56,4 +56,5 @@ var _ = func() {
 			panic(err)
 		}
 	}
-}
+	return nil
+}()
diff --git a/input/ws.go b/input/ws.go
index 82f19d8..b321c9c 100644
--- a/input/ws.go
+++ b/input/ws.go
@@ -6,11 +6,14 @@ import (
 	"git.sch.bme.hu/mikewashere/matrix-backend/aggregator"
 	"git.sch.bme.hu/mikewashere/matrix-backend/db"
 	"github.com/igm/sockjs-go/v3/sockjs"
+	"net/http"
 	"strings"
 )
 
 type SockState int
 
+const CookieName = "session"
+
 const (
 	Connected SockState = iota
 	Authenticated
@@ -21,27 +24,51 @@ type Message struct {
 	Msg  interface{} `json:"msg"`
 }
 
+func getUserFromCookie(r *http.Request) (*db.User, error) {
+	c, e := r.Cookie(CookieName)
+	if e != nil {
+		return nil, e
+	}
+
+	return db.GetUser(c.Value)
+}
+
 func InputHandler(session sockjs.Session) {
 	sendError := func(e error) {
-		session.Send(fmt.Sprintf(`{ "type": "error", "msg": "%s" }`, e.Error()))
+		_ = session.Send(fmt.Sprintf(`{ "type": "error", "msg": "%s" }`, e.Error()))
 	}
 
-	state := Connected
-	session.Send(`{ "type": "error", "msg": "team or user code needed" }`)
 	var u *db.User
+	var e error
+	state := Connected
+
+	u, e = getUserFromCookie(session.Request())
+	if e != nil && u != nil && u.TeamID != "" {
+		state = Authenticated
+	}
+
+	_ = session.Send(`{ "type": "error", "msg": "team or user code needed" }`)
+
 	for {
 		if msg, err := session.Recv(); err == nil {
 			msg = strings.TrimSpace(msg)
 			switch state {
 
 			case Connected:
-				var e error
-				u, e = db.CreateUser(msg)
-				if e != nil {
-					sendError(e)
-					continue
+				if len(msg) > 2 && msg[0:2] == "u " {
+					u, e = db.GetUser(msg[2:])
+					if e != nil {
+						sendError(e)
+						continue
+					}
+				} else {
+					u, e = db.CreateUser(msg)
+					if e != nil {
+						sendError(e)
+						continue
+					}
 				}
-				session.Send(fmt.Sprintf(`{ "type": "userid", "msg": "%v" }`, u.ID))
+				_ = session.Send(fmt.Sprintf(`{ "type": "userid", "msg": "%v" }`, u.ID))
 				state = Authenticated
 
 			case Authenticated:
@@ -63,10 +90,10 @@ func InputHandler(session sockjs.Session) {
 						continue
 					}
 
-					session.Send(string(b))
+					_ = session.Send(string(b))
 				} else {
 					aggregator.Vote(u.ID, msg)
-					session.Send(`{ "type": "success", "msg": "" }`)
+					_ = session.Send(`{ "type": "success", "msg": "" }`)
 				}
 
 			}
-- 
GitLab