package admin import ( "encoding/json" _ "fmt" "hacklab.nilfm.cc/felt/admin/util" "hacklab.nilfm.cc/felt/models" "hacklab.nilfm.cc/felt/mongodb" "hacklab.nilfm.cc/quartzgun/auth" . "hacklab.nilfm.cc/quartzgun/middleware" "hacklab.nilfm.cc/quartzgun/renderer" "hacklab.nilfm.cc/quartzgun/router" . "hacklab.nilfm.cc/quartzgun/util" "html/template" "net/http" ) func apiGetTableList(next http.Handler, udb auth.UserStore) http.Handler { handlerFunc := func(w http.ResponseWriter, req *http.Request) { user := util.GetUserFromToken(req) self, err := util.GetTablesByUser(user, udb) if err != nil { w.WriteHeader(404) } else { AddContextValue(req, "tableList", self) } next.ServeHTTP(w, req) } return http.HandlerFunc(handlerFunc) } func apiGetTableData(next http.Handler, udb auth.UserStore, dbAdapter mongodb.DbAdapter) http.Handler { handlerFunc := func(w http.ResponseWriter, req *http.Request) { urlParams := req.Context().Value("params").(map[string]string) tableName := urlParams["Slug"] tableKey := models.TableKey{ Name: tableName, Passcode: req.FormValue("passcode"), } if dbAdapter.CheckTable(tableKey) { mapUrl, _ := dbAdapter.GetMapImageUrl(tableKey) auxMessage, _ := dbAdapter.GetAuxMessage(tableKey) availableTokens, _ := dbAdapter.GetTokens(tableKey, true) activeTokens, _ := dbAdapter.GetTokens(tableKey, false) diceRolls, _ := dbAdapter.GetDiceRolls(tableKey) AddContextValue(req, "tableData", models.Table{ Name: tableKey.Name, Passcode: tableKey.Passcode, DiceRolls: diceRolls, MapImageUrl: mapUrl, Tokens: activeTokens, AvailableTokens: availableTokens, AuxMessage: auxMessage, }) } else { w.WriteHeader(404) } next.ServeHTTP(w, req) } return http.HandlerFunc(handlerFunc) } func apiCreateTable(next http.Handler, udb auth.UserStore, dbAdapter mongodb.DbAdapter) http.Handler { handlerFunc := func(w http.ResponseWriter, req *http.Request) { tableKey := models.TableKey{} err := json.NewDecoder(req.Body).Decode(&tableKey) if err != nil { w.WriteHeader(400) next.ServeHTTP(w, req) return } // table name is primary key so w edon't need to check err = dbAdapter.CreateTable(tableKey) if err != nil { AddContextValue(req, "result", err.Error()) // TODO: parse error and change the status w.WriteHeader(500) } else { user := util.GetUserFromToken(req) tables, err := util.GetTablesByUser(user, udb) tables = append(tables, tableKey) err = util.SetTablesForUser(user, tables, udb) if err != nil { w.WriteHeader(500) } else { w.WriteHeader(201) } } next.ServeHTTP(w, req) } return http.HandlerFunc(handlerFunc) } func apiDestroyTable(next http.Handler, udb auth.UserStore, dbAdapter mongodb.DbAdapter) http.Handler { handlerFunc := func(w http.ResponseWriter, req *http.Request) { // check table actually belongs to this user user := util.GetUserFromToken(req) tables, err := util.GetTablesByUser(user, udb) if err == nil { destroy := false i := 0 table := models.TableKey{} err = json.NewDecoder(req.Body).Decode(&table) if err != nil { w.WriteHeader(400) } for j, t := range tables { if t.Name == table.Name && t.Passcode == table.Passcode { // try to destroy it destroy = dbAdapter.DestroyTable(table) == nil i = j break } } if destroy { newTables := append(tables[:i], tables[i+1:]...) util.SetTablesForUser(user, newTables, udb) w.WriteHeader(204) } else { w.WriteHeader(404) } } else { w.WriteHeader(500) } next.ServeHTTP(w, req) } return http.HandlerFunc(handlerFunc) } func apiUploadMapImg(next http.Handler, udb auth.UserStore, dbAdapter mongodb.DbAdapter) http.Handler { handlerFunc := func(w http.ResponseWriter, req *http.Request) { // ensure data storage dir exists // check for filename; call create to overwrite regardless // get file data from multipart form // write to file // respond with URL? } return handlerFunc } func CreateAdminInterface(udb auth.UserStore, dbAdapter mongodb.DbAdapter) http.Handler { // create quartzgun router rtr := &router.Router{Fallback: *template.Must(template.ParseFiles("static/error.html"))} scopes := map[string]string{} rtr.Post("/api/auth/", Provision(udb, 84)) rtr.Get("/api/table/", Validate(apiGetTableList(renderer.JSON("tableList"), udb), udb, scopes)) rtr.Get(`/api/table/(?P\S+)`, Validate(apiGetTableData(renderer.JSON("tableData"), udb, dbAdapter), udb, scopes)) rtr.Post("/api/table/", Validate(apiCreateTable(renderer.JSON("result"), udb, dbAdapter), udb, scopes)) rtr.Delete(`/api/table/(?P\S+)`, Validate(apiDestroyTable(renderer.JSON("result"), udb, dbAdapter), udb, scopes)) return http.HandlerFunc(rtr.ServeHTTP) }