fix up map image switching, security fixes, skeleton for image deletion

This commit is contained in:
Iris Lightshard 2023-07-04 01:08:01 -06:00
parent 17310f21cf
commit b125b3c3ec
Signed by: Iris Lightshard
GPG key ID: 3B7FBC22144E6398
6 changed files with 120 additions and 40 deletions

View file

@ -170,7 +170,7 @@ func apiUploadImg(next http.Handler, dbAdapter mongodb.DbAdapter, uploads, uploa
// check if this table exists // check if this table exists
if !dbAdapter.CheckTable(tableKey) { if !dbAdapter.CheckTable(tableKey) {
w.WriteHeader(401) w.WriteHeader(404)
next.ServeHTTP(w, req) next.ServeHTTP(w, req)
return return
} }
@ -226,10 +226,31 @@ func apiUploadImg(next http.Handler, dbAdapter mongodb.DbAdapter, uploads, uploa
return http.HandlerFunc(handlerFunc) return http.HandlerFunc(handlerFunc)
} }
func apiListImages(next http.Handler, uploads string, uploadType string) http.Handler { func apiListImages(next http.Handler, uploads string, uploadType string, udb auth.UserStore, dbAdapter mongodb.DbAdapter) http.Handler {
handlerFunc := func(w http.ResponseWriter, req *http.Request) { handlerFunc := func(w http.ResponseWriter, req *http.Request) {
urlParams := req.Context().Value("params").(map[string]string) urlParams := req.Context().Value("params").(map[string]string)
tableName := urlParams["Slug"] tableName := urlParams["Slug"]
tableKey := models.TableKey{
Name: tableName,
Passcode: req.FormValue("passcode"),
}
// check table actually belongs to this user
user := util.GetUserFromToken(req)
tables, err := util.GetTablesByUser(user, udb)
if err == nil {
ok := false
for _, t := range tables {
if t.Name == tableKey.Name && t.Passcode == tableKey.Passcode {
ok = true
}
}
if ok {
if dbAdapter.CheckTable(tableKey) {
destPath := filepath.Join(uploads, tableName, uploadType) destPath := filepath.Join(uploads, tableName, uploadType)
files, err := ioutil.ReadDir(destPath) files, err := ioutil.ReadDir(destPath)
@ -248,15 +269,50 @@ func apiListImages(next http.Handler, uploads string, uploadType string) http.Ha
AddContextValue(req, "files", fileNames) AddContextValue(req, "files", fileNames)
next.ServeHTTP(w, req) next.ServeHTTP(w, req)
return
} }
}
}
w.WriteHeader(422)
next.ServeHTTP(w, req)
return
}
return http.HandlerFunc(handlerFunc) return http.HandlerFunc(handlerFunc)
} }
func apiDeleteImage(next http.Handler, uploads string, uploadType string) http.Handler { func apiDeleteImage(next http.Handler, uploads string, uploadType string, udb auth.UserStore, dbAdapter mongodb.DbAdapter) http.Handler {
handlerFunc := func(w http.ResponseWriter, req *http.Request) { handlerFunc := func(w http.ResponseWriter, req *http.Request) {
// put the path together // put the path together
urlParams := req.Context().Value("params").(map[string]string)
tableName := urlParams["Slug"]
tableKey := models.TableKey{
Name: tableName,
Passcode: req.FormValue("passcode"),
}
// check table actually belongs to this user
user := util.GetUserFromToken(req)
tables, err := util.GetTablesByUser(user, udb)
if err == nil {
ok := false
for _, t := range tables {
if t.Name == tableKey.Name && t.Passcode == tableKey.Passcode {
ok = true
}
}
if ok {
if dbAdapter.CheckTable(tableKey) {
// if the file exists, delete it and return the deleted path // if the file exists, delete it and return the deleted path
}
}
}
// otherwise, return an error // otherwise, return an error
} }
@ -279,11 +335,11 @@ func CreateAdminInterface(udb auth.UserStore, dbAdapter mongodb.DbAdapter, uploa
// asset management // asset management
rtr.Post(`/api/upload/(?P<Slug>\S+)/map/`, Validate(apiUploadImg(renderer.JSON("location"), dbAdapter, uploads, "map", uploadMaxMB), udb, scopes)) rtr.Post(`/api/upload/(?P<Slug>\S+)/map/`, Validate(apiUploadImg(renderer.JSON("location"), dbAdapter, uploads, "map", uploadMaxMB), udb, scopes))
// GET /api/upload/<table>/map/ rtr.Get(`/api/upload/(?P<Slug>\S+)/map/`, Validate(apiListImages(renderer.JSON("files"), uploads, "map", udb, dbAdapter), udb, scopes))
rtr.Get(`/api/upload/(?P<Slug>\S+)/map/`, Validate(apiListImages(renderer.JSON("files"), uploads, "map"), udb, scopes)) rtr.Delete(`/api/upload/(?P<table>\S+)/map/(?P<file>\S+)`, Validate(apiDeleteImage(renderer.JSON("deleted"), uploads, "map", udb, dbAdapter), udb, scopes))
// DELETE /api/upload/<table>/map/<map> rtr.Delete(`/api/upload/(?P<table>\S+)/token/(?P<file>\S+)`, Validate(apiDeleteImage(renderer.JSON("deleted"), uploads, "token", udb, dbAdapter), udb, scopes))
rtr.Post(`/api/upload/(?P<Slug>\S+)/token/`, Validate(apiUploadImg(renderer.JSON("location"), dbAdapter, uploads, "token", uploadMaxMB), udb, scopes)) rtr.Post(`/api/upload/(?P<Slug>\S+)/token/`, Validate(apiUploadImg(renderer.JSON("location"), dbAdapter, uploads, "token", uploadMaxMB), udb, scopes))
rtr.Get(`/api/upload/(?P<Slug>\S+)/token/`, Validate(apiListImages(renderer.JSON("files"), uploads, "token"), udb, scopes)) rtr.Get(`/api/upload/(?P<Slug>\S+)/token/`, Validate(apiListImages(renderer.JSON("files"), uploads, "token", udb, dbAdapter), udb, scopes))
// DELETE /api/upload/<table>/token/<token> // DELETE /api/upload/<table>/token/<token>
return http.HandlerFunc(rtr.ServeHTTP) return http.HandlerFunc(rtr.ServeHTTP)

View file

@ -164,8 +164,10 @@ func (self *GameTableServer) publish(msg []byte) {
return return
} }
err = self.writeToDB(tableMsg) err = self.writeToDB(&tableMsg)
tableMsg.Auth = nil
clean, err := json.Marshal(tableMsg)
fmt.Println(string(clean[:]))
if err != nil { if err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
return return
@ -175,7 +177,7 @@ func (self *GameTableServer) publish(msg []byte) {
for s, k := range self.subscribers { for s, k := range self.subscribers {
if k == *tableMsg.Key { if k == *tableMsg.Key {
select { select {
case s.msgs <- msg: case s.msgs <- clean:
default: default:
go s.closeSlow() go s.closeSlow()
} }
@ -212,7 +214,7 @@ func (self *GameTableServer) getCurrentState(tableKey models.TableKey) []byte {
return []byte("{\"error\": \"table not found\"}") return []byte("{\"error\": \"table not found\"}")
} }
func (self *GameTableServer) writeToDB(tableMsg models.TableMessage) error { func (self *GameTableServer) writeToDB(tableMsg *models.TableMessage) error {
key := *tableMsg.Key key := *tableMsg.Key
if tableMsg.DiceRoll != nil { if tableMsg.DiceRoll != nil {
err := self.dbAdapter.InsertDiceRoll(key, *tableMsg.DiceRoll) err := self.dbAdapter.InsertDiceRoll(key, *tableMsg.DiceRoll)
@ -239,6 +241,8 @@ func (self *GameTableServer) writeToDB(tableMsg models.TableMessage) error {
} }
} }
} }
tableMsg.Auth = nil
return nil return nil
} }

View file

@ -36,7 +36,7 @@ type Table struct {
} }
type TableMessage struct { type TableMessage struct {
Auth *string `json:"auth"` Auth *string `json:"auth,omitempty"`
Key *TableKey `json:"key"` Key *TableKey `json:"key"`
DiceRoll *DiceRoll `json:"diceRoll"` DiceRoll *DiceRoll `json:"diceRoll"`
Token *Token `json:"token"` Token *Token `json:"token"`

View file

@ -14,7 +14,7 @@ async function getTable(name, pass) {
headers: headers, headers: headers,
}); });
const mapImgs = await fetch (`/admin/api/upload/${name}/map/`, { const mapImgs = await fetch (`/admin/api/upload/${name}/map/?passcode=${pass}`, {
method: 'GET', method: 'GET',
headers: headers, headers: headers,
}); });
@ -33,7 +33,7 @@ async function getTable(name, pass) {
infoHtml += "<ul>"; infoHtml += "<ul>";
for (const i of imgs) { for (const i of imgs) {
const parts = i.split("/"); const parts = i.split("/");
infoHtml += `<li>${parts[parts.length - 1]} <a href="${i}">view</a> <button onclick="sendMapImg(${i});">Set</button> <button onclick="deleteMapImg(${i})">Delete</button></li>\n`; infoHtml += `<li>${parts[parts.length - 1]} <a href="${i}">view</a> <button onclick="sendMapImg('${i}');">Set</button> <button onclick="deleteMapImg('${i}')">Delete</button></li>\n`;
} }
infoHtml += "</ul>"; infoHtml += "</ul>";
} else { } else {
@ -57,6 +57,7 @@ function publishAuxMsg() {
} }
function sendMapImg(url) { function sendMapImg(url) {
console.log("sending " + url);
publish({mapImg: url, auth: adminToken.access_token}); publish({mapImg: url, auth: adminToken.access_token});
} }
@ -75,6 +76,7 @@ async function uploadMapImg() {
body: data, body: data,
}); });
if (res.ok) { if (res.ok) {
// refresh so we can see the new entry in the list
getTable(tableKey.name, tableKey.passcode); getTable(tableKey.name, tableKey.passcode);
} else { } else {
throw new Error("Something went wrong uploading the map BG..."); throw new Error("Something went wrong uploading the map BG...");
@ -84,6 +86,12 @@ async function uploadMapImg() {
} }
} }
async function deleteMapImg() {
try {
} catch {
}
}
async function destroyTable() { async function destroyTable() {
try { try {
if (confirm("You really want to destroy this table?")) { if (confirm("You really want to destroy this table?")) {

View file

@ -1,8 +1,15 @@
let map = null; let map = null;
let mapImg = null;
function initializeMap(mapImgUrl) { function initializeMap(mapImgUrl) {
if (!map) {
map = L.map('map', { minZoom: 0, maxZoom: 4, crs: L.CRS.Simple }); map = L.map('map', { minZoom: 0, maxZoom: 4, crs: L.CRS.Simple });
L.imageOverlay(mapImgUrl, [[-180, 180],[180, -180]]).addTo(map); }
if (mapImg) {
mapImg.removeFrom(map);
}
mapImg = L.imageOverlay(mapImgUrl, [[-180, 180],[180, -180]]);
mapImg.addTo(map);
map.setMaxBounds([[-180,180],[180,-180]]); map.setMaxBounds([[-180,180],[180,-180]]);
map.setView([0,0], 2); map.setView([0,0], 2);
} }

View file

@ -17,8 +17,10 @@ function closeErr() {
} }
function saveName() { function saveName() {
console.log("saving username");
const username = document.getElementById("name_entry"); const username = document.getElementById("name_entry");
if (username) { if (username) {
console.log(username.value + "input found");
document.cookie = "username=" + username.value; document.cookie = "username=" + username.value;
} }
} }
@ -27,9 +29,12 @@ function loadName() {
const username = document.getElementById("name_entry"); const username = document.getElementById("name_entry");
if (username) { if (username) {
const cookies = document.cookie.split(";") const cookies = document.cookie.split(";")
if (cookies[0].trim().startsWith("username=")) { cookies.forEach(c=>{
username.value = cookies[0].trim().split("=")[1]; console.log(c);
if (c.trim().startsWith("username=")) {
username.value = c.trim().split("=")[1];
} }
});
} }
} }