From 9df5f2d5f4275fd3748c0a6f39e291e78246774c Mon Sep 17 00:00:00 2001 From: garrettmills Date: Wed, 11 Nov 2020 12:23:31 -0600 Subject: [PATCH] Split API into multiple files & setup public user permissions --- app/controllers/Home.controller.js | 1 + app/controllers/api/v1/Session.controller.js | 1 + app/models/auth/PublicUser.model.js | 9 +++++++ app/models/auth/User.model.js | 3 +++ .../middleware/auth/ApiRoute.middleware.js | 6 ++--- app/routing/routers/api/v1/code.routes.js | 12 ++++------ app/routing/routers/api/v1/data.routes.js | 6 ++--- app/routing/routers/api/v1/db.routes.js | 20 +++++++--------- app/routing/routers/api/v1/files.routes.js | 14 +++++------ app/routing/routers/api/v1/menu.routes.js | 9 +++---- app/routing/routers/api/v1/offline.routes.js | 8 +++---- app/routing/routers/api/v1/page.routes.js | 24 +++++++++---------- app/routing/routers/api/v1/search.routes.js | 6 ++--- app/routing/routers/api/v1/session.routes.js | 20 +++++++++++----- 14 files changed, 74 insertions(+), 65 deletions(-) diff --git a/app/controllers/Home.controller.js b/app/controllers/Home.controller.js index 951e1b7..601f41f 100644 --- a/app/controllers/Home.controller.js +++ b/app/controllers/Home.controller.js @@ -43,6 +43,7 @@ class Home extends Controller { app_name: this.configs.get('app.name'), system_base: this.configs.get('app.url'), authenticated_user: !!req.user, + public_user: !!req?.user?.is_public_user(), }) } } diff --git a/app/controllers/api/v1/Session.controller.js b/app/controllers/api/v1/Session.controller.js index d89eac0..a8c0011 100644 --- a/app/controllers/api/v1/Session.controller.js +++ b/app/controllers/api/v1/Session.controller.js @@ -33,6 +33,7 @@ class SessionController extends Controller { id: user.id, username: user.uid, preferences: user.preferences || {}, + is_public_user: user.is_public_user(), }, app: { name: this.configs.get('app.name'), diff --git a/app/models/auth/PublicUser.model.js b/app/models/auth/PublicUser.model.js index 6bb45e7..b015320 100644 --- a/app/models/auth/PublicUser.model.js +++ b/app/models/auth/PublicUser.model.js @@ -94,6 +94,15 @@ class PublicUserModel extends User { return page } + + async can(permission) { + const PublicUserPermission = this.models.get('auth:PublicUserPermission') + return PublicUserPermission.can(permission) + } + + is_public_user() { + return true + } } module.exports = exports = PublicUserModel diff --git a/app/models/auth/User.model.js b/app/models/auth/User.model.js index 99521f5..85302d6 100644 --- a/app/models/auth/User.model.js +++ b/app/models/auth/User.model.js @@ -57,6 +57,9 @@ class User extends AuthUser { } // Other members and methods here + is_public_user() { + return false + } } module.exports = exports = User diff --git a/app/routing/middleware/auth/ApiRoute.middleware.js b/app/routing/middleware/auth/ApiRoute.middleware.js index e93dec2..3359029 100644 --- a/app/routing/middleware/auth/ApiRoute.middleware.js +++ b/app/routing/middleware/auth/ApiRoute.middleware.js @@ -15,9 +15,9 @@ class ApiRoute extends Middleware { req.user = await PublicUser.get_for_request(req) return next() } else { - // If not signed in, save the target url so we can redirect back here after auth - req.session.auth.flow = req.originalUrl - return res.redirect('/auth/login') + return res.status(401) + .message('API authentication required') + .api() } } } diff --git a/app/routing/routers/api/v1/code.routes.js b/app/routing/routers/api/v1/code.routes.js index 027ec45..a2f9640 100644 --- a/app/routing/routers/api/v1/code.routes.js +++ b/app/routing/routers/api/v1/code.routes.js @@ -2,23 +2,21 @@ module.exports = exports = { prefix: '/api/v1/code', - middleware: [ - 'auth:ApiRoute', - ], + middleware: [], get: { // Get the code ref node config for the specified code editor - '/:PageId/:NodeId/get/:CodiumId': ['controller::api:v1:FormCode.get_config'], + '/:PageId/:NodeId/get/:CodiumId': ['middleware::auth:ApiRoute', 'controller::api:v1:FormCode.get_config'], }, post: { // Create a new code ref config - '/:PageId/:NodeId/create': ['controller::api:v1:FormCode.create_new'], + '/:PageId/:NodeId/create': ['middleware::auth:ApiRoute', 'controller::api:v1:FormCode.create_new'], // Set the data for the specified code ref - '/:PageId/:NodeId/set/:CodiumId': ['controller::api:v1:FormCode.set_values'], + '/:PageId/:NodeId/set/:CodiumId': ['middleware::auth:ApiRoute', 'controller::api:v1:FormCode.set_values'], // delete the specified code ref - '/:PageId/:NodeId/delete/:CodiumId': ['controller::api:v1:FormCode.drop_code'], + '/:PageId/:NodeId/delete/:CodiumId': ['middleware::auth:ApiRoute', 'controller::api:v1:FormCode.drop_code'], }, } diff --git a/app/routing/routers/api/v1/data.routes.js b/app/routing/routers/api/v1/data.routes.js index b162b54..fc48598 100644 --- a/app/routing/routers/api/v1/data.routes.js +++ b/app/routing/routers/api/v1/data.routes.js @@ -2,13 +2,11 @@ module.exports = exports = { prefix: '/api/v1/data', - middleware: [ - 'auth:ApiRoute' - ], + middleware: [], get: { // Export the entire personal tree as HTML - '/export/html': ['controller::Export.html_export'], + '/export/html': ['middleware::auth:ApiRoute', 'controller::Export.html_export'], }, post: { diff --git a/app/routing/routers/api/v1/db.routes.js b/app/routing/routers/api/v1/db.routes.js index 1fa3c9c..791d32a 100644 --- a/app/routing/routers/api/v1/db.routes.js +++ b/app/routing/routers/api/v1/db.routes.js @@ -2,35 +2,33 @@ module.exports = exports = { prefix: '/api/v1/db', - middleware: [ - 'auth:ApiRoute' - ], + middleware: [], get: { // Get the database ref node config for the specified database - '/:PageId/:NodeId/get/:DatabaseId': ['controller::api:v1:FormDatabase.get_config'], + '/:PageId/:NodeId/get/:DatabaseId': ['middleware::auth:ApiRoute', 'controller::api:v1:FormDatabase.get_config'], // Get the column config records for the specified database - '/:PageId/:NodeId/get/:DatabaseId/columns': [ 'controller::api:v1:FormDatabase.get_columns' ], + '/:PageId/:NodeId/get/:DatabaseId/columns': [ 'middleware::auth:ApiRoute', 'controller::api:v1:FormDatabase.get_columns' ], // Get the row records for the specified database - '/:PageId/:NodeId/get/:DatabaseId/data': [ 'controller::api:v1:FormDatabase.get_data' ], + '/:PageId/:NodeId/get/:DatabaseId/data': [ 'middleware::auth:ApiRoute', 'controller::api:v1:FormDatabase.get_data' ], }, post: { // Create a new database ref config - '/:PageId/:NodeId/create': ['controller::api:v1:FormDatabase.create_new'], + '/:PageId/:NodeId/create': ['middleware::auth:ApiRoute', 'controller::api:v1:FormDatabase.create_new'], // Set the column configs for a database ref - '/:PageId/:NodeId/set/:DatabaseId/columns': [ 'controller::api:v1:FormDatabase.set_columns' ], + '/:PageId/:NodeId/set/:DatabaseId/columns': [ 'middleware::auth:ApiRoute', 'controller::api:v1:FormDatabase.set_columns' ], // Set the database name - '/:PageId/:NodeId/set/:DatabaseId/Name': [ 'controller::api:v1:FormDatabase.set_name' ], + '/:PageId/:NodeId/set/:DatabaseId/Name': [ 'middleware::auth:ApiRoute', 'controller::api:v1:FormDatabase.set_name' ], // Delete the specified database ref - '/:PageId/:NodeId/drop/:DatabaseId': [ 'controller::api:v1:FormDatabase.drop_database' ], + '/:PageId/:NodeId/drop/:DatabaseId': [ 'middleware::auth:ApiRoute', 'controller::api:v1:FormDatabase.drop_database' ], // Set the row data for the specified database ref - '/:PageId/:NodeId/set/:DatabaseId/data': ['controller::api:v1:FormDatabase.set_data'], + '/:PageId/:NodeId/set/:DatabaseId/data': ['middleware::auth:ApiRoute', 'controller::api:v1:FormDatabase.set_data'], }, } diff --git a/app/routing/routers/api/v1/files.routes.js b/app/routing/routers/api/v1/files.routes.js index 5e7b3f6..da5a19f 100644 --- a/app/routing/routers/api/v1/files.routes.js +++ b/app/routing/routers/api/v1/files.routes.js @@ -2,27 +2,25 @@ module.exports = exports = { prefix: '/api/v1/files', - middleware: [ - 'auth:ApiRoute', - ], + middleware: [], get: { // Get the file ref node config for the specified file ref - '/:PageId/:NodeId/get/:FilesId': ['controller::api:v1:File.get_config'], + '/:PageId/:NodeId/get/:FilesId': ['middleware::auth:ApiRoute', 'controller::api:v1:File.get_config'], // Download the specified file ID from the specified file ref node - '/:PageId/:NodeId/get/:FilesId/:FileId': ['controller::api:v1:File.download'], + '/:PageId/:NodeId/get/:FilesId/:FileId': ['middleware::auth:ApiRoute', 'controller::api:v1:File.download'], }, post: { // FIXME - files, not file. Fix in front-end! // Upload the file in the 'uploaded_file' key to the specified file ref node - '/file/upload/:PageId/:NodeId/:FilesId': ['middleware::upload:UploadFile', 'controller::api:v1:File.save_upload'], + '/file/upload/:PageId/:NodeId/:FilesId': ['middleware::auth:ApiRoute', 'middleware::upload:UploadFile', 'controller::api:v1:File.save_upload'], // Create a new file ref node - '/:PageId/:NodeId/create': ['controller::api:v1:File.create_config'], + '/:PageId/:NodeId/create': ['middleware::auth:ApiRoute', 'controller::api:v1:File.create_config'], // Delete a file ref node and its files - '/:PageId/:NodeId/delete/:FilesId': ['controller::api:v1:File.delete_group'], + '/:PageId/:NodeId/delete/:FilesId': ['middleware::auth:ApiRoute', 'controller::api:v1:File.delete_group'], }, } diff --git a/app/routing/routers/api/v1/menu.routes.js b/app/routing/routers/api/v1/menu.routes.js index 8669feb..a660ddd 100644 --- a/app/routing/routers/api/v1/menu.routes.js +++ b/app/routing/routers/api/v1/menu.routes.js @@ -2,13 +2,14 @@ module.exports = exports = { prefix: '/api/v1/menu', - middleware: [ - 'auth:ApiRoute', - ], + middleware: [], get: { // Get the user's menu tree - '/items': ['controller::api:v1:Menu.get_items'], + '/items': [ + ['middleware::auth:ApiRoute', { allow_public: true }], + 'controller::api:v1:Menu.get_items', + ], }, post: { diff --git a/app/routing/routers/api/v1/offline.routes.js b/app/routing/routers/api/v1/offline.routes.js index 5ead098..08673bf 100644 --- a/app/routing/routers/api/v1/offline.routes.js +++ b/app/routing/routers/api/v1/offline.routes.js @@ -2,16 +2,14 @@ module.exports = exports = { prefix: '/api/v1/offline', - middleware: [ - 'auth:ApiRoute', - ], + middleware: [], get: { - '/prefetch': ['controller::api:v1:Offline.do_prefetch'], + '/prefetch': ['middleware::auth:ApiRoute', 'controller::api:v1:Offline.do_prefetch'], }, post: { // re-sync data when an offline client goes back online - '/sync': ['controller::api:v1:Offline.do_sync'], + '/sync': ['middleware::auth:ApiRoute', 'controller::api:v1:Offline.do_sync'], }, } diff --git a/app/routing/routers/api/v1/page.routes.js b/app/routing/routers/api/v1/page.routes.js index 6cba76a..e74cdd8 100644 --- a/app/routing/routers/api/v1/page.routes.js +++ b/app/routing/routers/api/v1/page.routes.js @@ -1,40 +1,38 @@ module.exports = exports = { prefix: '/api/v1/page', - middleware: [ - 'auth:ApiRoute', - ], + middleware: [], get: { // Get the data for the specified page - '/:PageId': ['controller::api:v1:Page.get_page'], + '/:PageId': ['middleware::auth:ApiRoute', 'controller::api:v1:Page.get_page'], // Get the available versions of the given page - '/:PageId/versions': ['controller::api:v1:Page.get_page_versions'], + '/:PageId/versions': ['middleware::auth:ApiRoute', 'controller::api:v1:Page.get_page_versions'], // Get the nodes present on the specified page - '/:PageId/nodes': ['controller::api:v1:Page.get_nodes'], + '/:PageId/nodes': ['middleware::auth:ApiRoute', 'controller::api:v1:Page.get_nodes'], }, post: { // Save the data for the specified page - '/:PageId/save': ['controller::api:v1:Page.save_page'], + '/:PageId/save': ['middleware::auth:ApiRoute', 'controller::api:v1:Page.save_page'], // Revert the page to a previous version - '/:PageId/versions/revert': ['controller::api:v1:Page.revert_version'], + '/:PageId/versions/revert': ['middleware::auth:ApiRoute', 'controller::api:v1:Page.revert_version'], // Save the node data for the specified page - '/:PageId/nodes/save': ['controller::api:v1:Page.save_nodes'], + '/:PageId/nodes/save': ['middleware::auth:ApiRoute', 'controller::api:v1:Page.save_nodes'], - '/:PageId/nodes/save_one': ['controller::api:v1:Page.save_node_to_page'], + '/:PageId/nodes/save_one': ['middleware::auth:ApiRoute', 'controller::api:v1:Page.save_node_to_page'], // Create a new page in the personal root - '/create': ['controller::api:v1:Page.create_top_level'], + '/create': ['middleware::auth:ApiRoute', 'controller::api:v1:Page.create_top_level'], // Create a new page as a child of the specified page - '/create-child': ['controller::api:v1:Page.create_child'], + '/create-child': ['middleware::auth:ApiRoute', 'controller::api:v1:Page.create_child'], // Delete the specified page - '/delete/:PageId': ['controller::api:v1:Page.delete_page'], + '/delete/:PageId': ['middleware::auth:ApiRoute', 'controller::api:v1:Page.delete_page'], }, } diff --git a/app/routing/routers/api/v1/search.routes.js b/app/routing/routers/api/v1/search.routes.js index d026e31..65edbda 100644 --- a/app/routing/routers/api/v1/search.routes.js +++ b/app/routing/routers/api/v1/search.routes.js @@ -2,12 +2,10 @@ module.exports = exports = { prefix: '/api/v1/search', - middleware: [ - 'auth:ApiRoute', - ], + middleware: [], get: { - '/': ['controller::api:v1:Misc.get_search'], + '/': ['middleware::auth:ApiRoute', 'controller::api:v1:Misc.get_search'], }, post: { diff --git a/app/routing/routers/api/v1/session.routes.js b/app/routing/routers/api/v1/session.routes.js index f2f05d8..26469f5 100644 --- a/app/routing/routers/api/v1/session.routes.js +++ b/app/routing/routers/api/v1/session.routes.js @@ -2,17 +2,25 @@ const index = { prefix: '/api/v1/session', - middleware: [ - 'auth:UserOnly', - ], + middleware: [], get: { - '/': [ 'controller::api:v1:Session.get_session' ], - '/device-token': [ 'controller::api:v1:Session.get_device_token' ], + '/': [ + ['middleware::auth:ApiRoute', { allow_public: true }], + 'controller::api:v1:Session.get_session', + ], + + '/device-token': [ + 'middleware::auth:ApiRoute', + 'controller::api:v1:Session.get_device_token', + ], }, post: { - '/': [ 'controller::api:v1:Session.save_session' ], + '/': [ + ['middleware::auth:ApiRoute', { allow_public: true }], + 'controller::api:v1:Session.save_session', + ], }, }