package app import ( "context" "encoding/json" "fmt" "net/http" "regexp" "go.etcd.io/bbolt" ) var clientPath = regexp.MustCompile("client/([^/]+)/(.*)") var UserInfo struct{} const VERSION = "4" func (a *App) client(rw http.ResponseWriter, req *http.Request) { matches := clientPath.FindStringSubmatch(req.URL.Path) if matches == nil { http.Error(rw, "Client token not found", http.StatusBadRequest) return } auth := false user := "" a.db.View(func(tx *bbolt.Tx) error { tb := tx.Bucket([]byte("tokens")) if tb == nil { return nil } userName := tb.Get([]byte(matches[1])) if userName == nil { return nil } ub := tx.Bucket([]byte("users")) if ub == nil { return nil } userRaw := ub.Get(userName) if userRaw == nil { return nil } u := User{} json.Unmarshal(userRaw, &u) if u.Auths.Has(AUTH_UPLOAD) { user = string(userName) auth = true } return nil }) if !auth { rw.WriteHeader(http.StatusUnauthorized) return } ctx := context.WithValue(req.Context(), UserInfo, user) req = req.WithContext(ctx) switch matches[2] { case "locate": a.locate(rw, req) case "gridUpdate": a.gridUpdate(rw, req) case "gridUpload": a.gridUpload(rw, req) case "positionUpdate": a.updatePositions(rw, req) case "markerUpdate": a.uploadMarkers(rw, req) case "": http.Redirect(rw, req, "/", 302) case "checkVersion": if req.FormValue("version") == VERSION { rw.WriteHeader(200) } else { rw.WriteHeader(http.StatusBadRequest) } default: rw.WriteHeader(http.StatusNotFound) } } func (a *App) locate(rw http.ResponseWriter, req *http.Request) { grid := req.FormValue("gridID") err := a.db.View(func(tx *bbolt.Tx) error { grids := tx.Bucket([]byte("grids")) if grids == nil { return nil } curRaw := grids.Get([]byte(grid)) cur := GridData{} if curRaw == nil { return fmt.Errorf("grid not found") } err := json.Unmarshal(curRaw, &cur) if err != nil { return err } fmt.Fprintf(rw, "%d;%d;%d", cur.Map, cur.Coord.X, cur.Coord.Y) return nil }) if err != nil { rw.WriteHeader(404) } }