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
if !dbAdapter.CheckTable(tableKey) {
w.WriteHeader(401)
w.WriteHeader(404)
next.ServeHTTP(w, req)
return
}
@ -226,10 +226,31 @@ func apiUploadImg(next http.Handler, dbAdapter mongodb.DbAdapter, uploads, uploa
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) {
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) {
destPath := filepath.Join(uploads, tableName, uploadType)
files, err := ioutil.ReadDir(destPath)
@ -248,15 +269,50 @@ func apiListImages(next http.Handler, uploads string, uploadType string) http.Ha
AddContextValue(req, "files", fileNames)
next.ServeHTTP(w, req)
return
}
}
}
w.WriteHeader(422)
next.ServeHTTP(w, req)
return
}
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) {
// 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
}
}
}
// otherwise, return an error
}
@ -279,11 +335,11 @@ func CreateAdminInterface(udb auth.UserStore, dbAdapter mongodb.DbAdapter, uploa
// asset management
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, scopes))
// DELETE /api/upload/<table>/map/<map>
rtr.Get(`/api/upload/(?P<Slug>\S+)/map/`, Validate(apiListImages(renderer.JSON("files"), uploads, "map", udb, dbAdapter), udb, scopes))
rtr.Delete(`/api/upload/(?P<table>\S+)/map/(?P<file>\S+)`, Validate(apiDeleteImage(renderer.JSON("deleted"), uploads, "map", udb, dbAdapter), udb, scopes))
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.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>
return http.HandlerFunc(rtr.ServeHTTP)

View file

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

View file

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

View file

@ -14,7 +14,7 @@ async function getTable(name, pass) {
headers: headers,
});
const mapImgs = await fetch (`/admin/api/upload/${name}/map/`, {
const mapImgs = await fetch (`/admin/api/upload/${name}/map/?passcode=${pass}`, {
method: 'GET',
headers: headers,
});
@ -33,7 +33,7 @@ async function getTable(name, pass) {
infoHtml += "<ul>";
for (const i of imgs) {
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>";
} else {
@ -57,6 +57,7 @@ function publishAuxMsg() {
}
function sendMapImg(url) {
console.log("sending " + url);
publish({mapImg: url, auth: adminToken.access_token});
}
@ -75,6 +76,7 @@ async function uploadMapImg() {
body: data,
});
if (res.ok) {
// refresh so we can see the new entry in the list
getTable(tableKey.name, tableKey.passcode);
} else {
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() {
try {
if (confirm("You really want to destroy this table?")) {

View file

@ -1,8 +1,15 @@
let map = null;
let mapImg = null;
function initializeMap(mapImgUrl) {
if (!map) {
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.setView([0,0], 2);
}

View file

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