From 0b7502ba7ee4da3df6a598e00b23e37896ef837d Mon Sep 17 00:00:00 2001
From: mike12345567 <me@michaeldrury.co.uk>
Date: Thu, 1 Apr 2021 14:38:31 +0100
Subject: [PATCH] Updating some route middleware security.

---
 .../server/src/api/controllers/search/index.js     | 11 ++++++-----
 packages/server/src/api/routes/auth.js             |  1 +
 packages/server/src/api/routes/search.js           | 13 ++++++++++++-
 packages/server/src/api/routes/static.js           | 14 ++++++++++++--
 packages/server/src/middleware/authorized.js       |  1 -
 5 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/packages/server/src/api/controllers/search/index.js b/packages/server/src/api/controllers/search/index.js
index 1810f07198..94b06db722 100644
--- a/packages/server/src/api/controllers/search/index.js
+++ b/packages/server/src/api/controllers/search/index.js
@@ -3,14 +3,15 @@ const { QueryBuilder, buildSearchUrl, search } = require("./utils")
 exports.rowSearch = async ctx => {
   // this can't be done through pouch, have to reach for trusty node-fetch
   const appId = ctx.user.appId
-  const bookmark = ctx.params.bookmark
+  const { tableId } = ctx.params
+  const { bookmark, query, raw } = ctx.request.body
   let url
-  if (ctx.params.query) {
-    url = new QueryBuilder(appId, ctx.params.query, bookmark).complete()
-  } else if (ctx.params.raw) {
+  if (query) {
+    url = new QueryBuilder(appId, query, bookmark).addTable(tableId).complete()
+  } else if (raw) {
     url = buildSearchUrl({
       appId,
-      query: ctx.params.raw,
+      query: raw,
       bookmark,
     })
   }
diff --git a/packages/server/src/api/routes/auth.js b/packages/server/src/api/routes/auth.js
index 83053305c9..ae640952ed 100644
--- a/packages/server/src/api/routes/auth.js
+++ b/packages/server/src/api/routes/auth.js
@@ -4,6 +4,7 @@ const controller = require("../controllers/auth")
 const router = Router()
 
 router.post("/api/authenticate", controller.authenticate)
+// doesn't need authorization as can only fetch info about self
 router.get("/api/self", controller.fetchSelf)
 
 module.exports = router
diff --git a/packages/server/src/api/routes/search.js b/packages/server/src/api/routes/search.js
index 8858a72d6e..63493078b7 100644
--- a/packages/server/src/api/routes/search.js
+++ b/packages/server/src/api/routes/search.js
@@ -1,8 +1,19 @@
 const Router = require("@koa/router")
 const controller = require("../controllers/search")
+const {
+  PermissionTypes,
+  PermissionLevels,
+} = require("../../utilities/security/permissions")
+const authorized = require("../../middleware/authorized")
+const { paramResource } = require("../../middleware/resourceId")
 
 const router = Router()
 
-router.get("/api/search/rows", controller.rowSearch)
+router.post(
+  "/api/search/:tableId/rows",
+  paramResource("tableId"),
+  authorized(PermissionTypes.TABLE, PermissionLevels.READ),
+  controller.rowSearch
+)
 
 module.exports = router
diff --git a/packages/server/src/api/routes/static.js b/packages/server/src/api/routes/static.js
index 14465f32a4..21c14f87a1 100644
--- a/packages/server/src/api/routes/static.js
+++ b/packages/server/src/api/routes/static.js
@@ -2,7 +2,11 @@ const Router = require("@koa/router")
 const controller = require("../controllers/static")
 const { budibaseTempDir } = require("../../utilities/budibaseDir")
 const authorized = require("../../middleware/authorized")
-const { BUILDER } = require("../../utilities/security/permissions")
+const {
+  BUILDER,
+  PermissionTypes,
+  PermissionLevels,
+} = require("../../utilities/security/permissions")
 const usage = require("../../middleware/usageQuota")
 const env = require("../../environment")
 
@@ -34,8 +38,14 @@ router
   // TODO: for now this builder endpoint is not authorized/secured, will need to be
   .get("/builder/:file*", controller.serveBuilder)
   .post("/api/attachments/process", authorized(BUILDER), controller.uploadFile)
-  .post("/api/attachments/upload", usage, controller.uploadFile)
+  .post(
+    "/api/attachments/upload",
+    authorized(PermissionTypes.TABLE, PermissionLevels.WRITE),
+    usage,
+    controller.uploadFile
+  )
   .get("/componentlibrary", controller.serveComponentLibrary)
+  // TODO: this likely needs to be secured in some way
   .get("/:appId/:path*", controller.serveApp)
 
 module.exports = router
diff --git a/packages/server/src/middleware/authorized.js b/packages/server/src/middleware/authorized.js
index 04ae9291d1..c36e3c5b92 100644
--- a/packages/server/src/middleware/authorized.js
+++ b/packages/server/src/middleware/authorized.js
@@ -39,7 +39,6 @@ module.exports = (permType, permLevel = null) => async (ctx, next) => {
   }
 
   const role = ctx.user.role
-  const isBuilder = role._id === BUILTIN_ROLE_IDS.BUILDER
   const isAdmin = ADMIN_ROLES.includes(role._id)
   const isAuthed = ctx.auth.authenticated