diff --git a/aggregator/clean.go b/aggregator/clean.go index 71a3fe93fb933b7babda87c21885c64a20137895..f37f93008d0af750bc9d29365cc1ea9ffd2ae42a 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 b0c8843b7f8341e554ae348f814cfd1b9ad41e97..9695ea663e27bdbed3931153435007d7efcf1078 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 0b23f7b507f7015ff7ee8e470aa089379f41104c..31bd5054611866c069b4afaf4ba47bfad51857b0 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 c7b53441f5eb95ec1d7844d345711624fa5b9cf3..905698d41cc6338d0b9a2f830a33e0708e56fb48 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 138e68ebf4aef2ff70f3afb45b1c7c378d717c06..0feefe62e0516e3eeaa68377e3a65b7ab6a3e2cf 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 82f19d86695b2865cdc78e96689926af786d1d94..b321c9ca7e50bdedca9a31a62c7898d2b62e6565 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": "" }`) } }