From 29b40ad824ec6346c86281b69fd2ee3de4643763 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Wed, 5 Jul 2017 14:32:55 +0100 Subject: [PATCH 1/5] add public api router --- .../app/coffee/infrastructure/ExpressLocals.coffee | 5 +++-- .../web/app/coffee/infrastructure/Modules.coffee | 10 +++++----- .../web/app/coffee/infrastructure/Server.coffee | 14 ++++++++------ services/web/app/coffee/router.coffee | 4 ++-- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/services/web/app/coffee/infrastructure/ExpressLocals.coffee b/services/web/app/coffee/infrastructure/ExpressLocals.coffee index 100fd28bd6..4c6b3a7722 100644 --- a/services/web/app/coffee/infrastructure/ExpressLocals.coffee +++ b/services/web/app/coffee/infrastructure/ExpressLocals.coffee @@ -66,7 +66,7 @@ logger.log "Finished generating file fingerprints" cdnAvailable = Settings.cdn?.web?.host? darkCdnAvailable = Settings.cdn?.web?.darkHost? -module.exports = (app, webRouter, apiRouter)-> +module.exports = (app, webRouter, privateApiRouter, publicApiRouter)-> webRouter.use (req, res, next)-> res.locals.session = req.session next() @@ -82,7 +82,8 @@ module.exports = (app, webRouter, apiRouter)-> ) next() webRouter.use addSetContentDisposition - apiRouter.use addSetContentDisposition + privateApiRouter.use addSetContentDisposition + publicApiRouter.use addSetContentDisposition webRouter.use (req, res, next)-> req.externalAuthenticationSystemUsed = res.locals.externalAuthenticationSystemUsed = -> diff --git a/services/web/app/coffee/infrastructure/Modules.coffee b/services/web/app/coffee/infrastructure/Modules.coffee index 044b096c35..8c2e1756b6 100644 --- a/services/web/app/coffee/infrastructure/Modules.coffee +++ b/services/web/app/coffee/infrastructure/Modules.coffee @@ -15,14 +15,14 @@ module.exports = Modules = @modules.push loadedModule Modules.attachHooks() - applyRouter: (webRouter, apiRouter) -> + applyRouter: (webRouter, apiRouter, publicApiRouter) -> for module in @modules - module.router?.apply?(webRouter, apiRouter) + module.router?.apply?(webRouter, apiRouter, publicApiRouter) - applyNonCsrfRouter: (webRouter, apiRouter) -> + applyNonCsrfRouter: (webRouter, apiRouter, publicApiRouter) -> for module in @modules - module.nonCsrfRouter?.apply(webRouter, apiRouter) - module.router?.applyNonCsrfRouter?(webRouter, apiRouter) + module.nonCsrfRouter?.apply(webRouter, apiRouter, publicApiRouter) + module.router?.applyNonCsrfRouter?(webRouter, apiRouter, publicApiRouter) viewIncludes: {} loadViewIncludes: (app) -> diff --git a/services/web/app/coffee/infrastructure/Server.coffee b/services/web/app/coffee/infrastructure/Server.coffee index de467503bf..12172aa94d 100644 --- a/services/web/app/coffee/infrastructure/Server.coffee +++ b/services/web/app/coffee/infrastructure/Server.coffee @@ -52,7 +52,8 @@ else app = express() webRouter = express.Router() -apiRouter = express.Router() +privateApiRouter = express.Router() +publicApiRouter = express.Router() if Settings.behindProxy app.enable('trust proxy') @@ -108,7 +109,7 @@ Modules.hooks.fire 'passportSetup', passport, (err) -> if err? logger.err {err}, "error setting up passport in modules" -Modules.applyNonCsrfRouter(webRouter, apiRouter) +Modules.applyNonCsrfRouter(webRouter, privateApiRouter, publicApiRouter) webRouter.use csrfProtection webRouter.use translations.expressMiddlewear @@ -122,7 +123,7 @@ webRouter.use (req, res, next) -> next() webRouter.use ReferalConnect.use -expressLocals(app, webRouter, apiRouter) +expressLocals(app, webRouter, privateApiRouter, publicApiRouter) if app.get('env') == 'production' logger.info "Production Enviroment" @@ -143,7 +144,7 @@ webRouter.use (req, res, next) -> res.render("general/closed", {title:"maintenance"}) profiler = require "v8-profiler" -apiRouter.get "/profile", (req, res) -> +privateApiRouter.get "/profile", (req, res) -> time = parseInt(req.query.time || "1000") profiler.startProfiling("test") setTimeout () -> @@ -165,16 +166,17 @@ notDefined = (x) -> !x? enableApiRouter = Settings.web?.enableApiRouter if enableApiRouter or notDefined(enableApiRouter) logger.info("providing api router"); - app.use(apiRouter) + app.use(privateApiRouter) app.use(ErrorController.handleApiError) enableWebRouter = Settings.web?.enableWebRouter if enableWebRouter or notDefined(enableWebRouter) logger.info("providing web router"); + app.use(publicApiRouter) # public API goes with web router for public access app.use(webRouter) app.use(ErrorController.handleError) -router = new Router(webRouter, apiRouter) +router = new Router(webRouter, privateApiRouter, publicApiRouter) module.exports = app: app diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index d9bfece40a..7658caaf0a 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -49,7 +49,7 @@ logger = require("logger-sharelatex") _ = require("underscore") module.exports = class Router - constructor: (webRouter, apiRouter)-> + constructor: (webRouter, apiRouter, publicApiRouter)-> if !Settings.allowPublicAccess webRouter.all '*', AuthenticationController.requireGlobalLogin @@ -77,7 +77,7 @@ module.exports = class Router ContactRouter.apply(webRouter, apiRouter) AnalyticsRouter.apply(webRouter, apiRouter) - Modules.applyRouter(webRouter, apiRouter) + Modules.applyRouter(webRouter, apiRouter, publicApiRouter) if Settings.enableSubscriptions From bd83d94f6482946a3d10f52be0d5b4fa7c02ebf3 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Wed, 5 Jul 2017 14:41:14 +0100 Subject: [PATCH 2/5] rename apiRouter -> privateApiRouter in Modules --- services/web/app/coffee/infrastructure/Modules.coffee | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/services/web/app/coffee/infrastructure/Modules.coffee b/services/web/app/coffee/infrastructure/Modules.coffee index 8c2e1756b6..9d4da24c8b 100644 --- a/services/web/app/coffee/infrastructure/Modules.coffee +++ b/services/web/app/coffee/infrastructure/Modules.coffee @@ -15,14 +15,14 @@ module.exports = Modules = @modules.push loadedModule Modules.attachHooks() - applyRouter: (webRouter, apiRouter, publicApiRouter) -> + applyRouter: (webRouter, privateApiRouter, publicApiRouter) -> for module in @modules - module.router?.apply?(webRouter, apiRouter, publicApiRouter) + module.router?.apply?(webRouter, privateApiRouter, publicApiRouter) - applyNonCsrfRouter: (webRouter, apiRouter, publicApiRouter) -> + applyNonCsrfRouter: (webRouter, privateApiRouter, publicApiRouter) -> for module in @modules - module.nonCsrfRouter?.apply(webRouter, apiRouter, publicApiRouter) - module.router?.applyNonCsrfRouter?(webRouter, apiRouter, publicApiRouter) + module.nonCsrfRouter?.apply(webRouter, privateApiRouter, publicApiRouter) + module.router?.applyNonCsrfRouter?(webRouter, privateApiRouter, publicApiRouter) viewIncludes: {} loadViewIncludes: (app) -> From 845ee51a67a226917bab300e2a4f0e5a983aac1c Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Wed, 5 Jul 2017 14:43:41 +0100 Subject: [PATCH 3/5] rename apiRouter -> privateApiRouter in router --- services/web/app/coffee/router.coffee | 58 +++++++++++++-------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index 7658caaf0a..1a5535026e 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -49,7 +49,7 @@ logger = require("logger-sharelatex") _ = require("underscore") module.exports = class Router - constructor: (webRouter, apiRouter, publicApiRouter)-> + constructor: (webRouter, privateApiRouter, publicApiRouter)-> if !Settings.allowPublicAccess webRouter.all '*', AuthenticationController.requireGlobalLogin @@ -67,17 +67,17 @@ module.exports = class Router AuthenticationController.addEndpointToLoginWhitelist '/register' - EditorRouter.apply(webRouter, apiRouter) - CollaboratorsRouter.apply(webRouter, apiRouter) - SubscriptionRouter.apply(webRouter, apiRouter) - UploadsRouter.apply(webRouter, apiRouter) - PasswordResetRouter.apply(webRouter, apiRouter) - StaticPagesRouter.apply(webRouter, apiRouter) - RealTimeProxyRouter.apply(webRouter, apiRouter) - ContactRouter.apply(webRouter, apiRouter) - AnalyticsRouter.apply(webRouter, apiRouter) + EditorRouter.apply(webRouter, privateApiRouter) + CollaboratorsRouter.apply(webRouter, privateApiRouter) + SubscriptionRouter.apply(webRouter, privateApiRouter) + UploadsRouter.apply(webRouter, privateApiRouter) + PasswordResetRouter.apply(webRouter, privateApiRouter) + StaticPagesRouter.apply(webRouter, privateApiRouter) + RealTimeProxyRouter.apply(webRouter, privateApiRouter) + ContactRouter.apply(webRouter, privateApiRouter) + AnalyticsRouter.apply(webRouter, privateApiRouter) - Modules.applyRouter(webRouter, apiRouter, publicApiRouter) + Modules.applyRouter(webRouter, privateApiRouter, publicApiRouter) if Settings.enableSubscriptions @@ -106,7 +106,7 @@ module.exports = class Router webRouter.post '/user/delete', AuthenticationController.requireLogin(), UserController.tryDeleteUser webRouter.get '/user/personal_info', AuthenticationController.requireLogin(), UserInfoController.getLoggedInUsersPersonalInfo - apiRouter.get '/user/:user_id/personal_info', AuthenticationController.httpAuth, UserInfoController.getPersonalInfo + privateApiRouter.get '/user/:user_id/personal_info', AuthenticationController.httpAuth, UserInfoController.getPersonalInfo webRouter.get '/project', AuthenticationController.requireLogin(), ProjectController.projectListPage webRouter.post '/project/new', AuthenticationController.requireLogin(), ProjectController.newProject @@ -211,15 +211,15 @@ module.exports = class Router # Deprecated in favour of /internal/project/:project_id but still used by versioning - apiRouter.get '/project/:project_id/details', AuthenticationController.httpAuth, ProjectApiController.getProjectDetails + privateApiRouter.get '/project/:project_id/details', AuthenticationController.httpAuth, ProjectApiController.getProjectDetails # New 'stable' /internal API end points - apiRouter.get '/internal/project/:project_id', AuthenticationController.httpAuth, ProjectApiController.getProjectDetails - apiRouter.get '/internal/project/:Project_id/zip', AuthenticationController.httpAuth, ProjectDownloadsController.downloadProject - apiRouter.get '/internal/project/:project_id/compile/pdf', AuthenticationController.httpAuth, CompileController.compileAndDownloadPdf + privateApiRouter.get '/internal/project/:project_id', AuthenticationController.httpAuth, ProjectApiController.getProjectDetails + privateApiRouter.get '/internal/project/:Project_id/zip', AuthenticationController.httpAuth, ProjectDownloadsController.downloadProject + privateApiRouter.get '/internal/project/:project_id/compile/pdf', AuthenticationController.httpAuth, CompileController.compileAndDownloadPdf - apiRouter.post '/internal/deactivateOldProjects', AuthenticationController.httpAuth, InactiveProjectController.deactivateOldProjects - apiRouter.post '/internal/project/:project_id/deactivate', AuthenticationController.httpAuth, InactiveProjectController.deactivateProject + privateApiRouter.post '/internal/deactivateOldProjects', AuthenticationController.httpAuth, InactiveProjectController.deactivateOldProjects + privateApiRouter.post '/internal/project/:project_id/deactivate', AuthenticationController.httpAuth, InactiveProjectController.deactivateProject webRouter.get /^\/internal\/project\/([^\/]*)\/output\/(.*)$/, ((req, res, next) -> @@ -230,14 +230,14 @@ module.exports = class Router next() ), AuthenticationController.httpAuth, CompileController.getFileFromClsi - apiRouter.get '/project/:Project_id/doc/:doc_id', AuthenticationController.httpAuth, DocumentController.getDocument - apiRouter.post '/project/:Project_id/doc/:doc_id', AuthenticationController.httpAuth, DocumentController.setDocument + privateApiRouter.get '/project/:Project_id/doc/:doc_id', AuthenticationController.httpAuth, DocumentController.getDocument + privateApiRouter.post '/project/:Project_id/doc/:doc_id', AuthenticationController.httpAuth, DocumentController.setDocument - apiRouter.post '/user/:user_id/update/*', AuthenticationController.httpAuth, TpdsController.mergeUpdate - apiRouter.delete '/user/:user_id/update/*', AuthenticationController.httpAuth, TpdsController.deleteUpdate + privateApiRouter.post '/user/:user_id/update/*', AuthenticationController.httpAuth, TpdsController.mergeUpdate + privateApiRouter.delete '/user/:user_id/update/*', AuthenticationController.httpAuth, TpdsController.deleteUpdate - apiRouter.post '/project/:project_id/contents/*', AuthenticationController.httpAuth, TpdsController.updateProjectContents - apiRouter.delete '/project/:project_id/contents/*', AuthenticationController.httpAuth, TpdsController.deleteProjectContents + privateApiRouter.post '/project/:project_id/contents/*', AuthenticationController.httpAuth, TpdsController.updateProjectContents + privateApiRouter.delete '/project/:project_id/contents/*', AuthenticationController.httpAuth, TpdsController.deleteProjectContents webRouter.post "/spelling/check", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi webRouter.post "/spelling/learn", AuthenticationController.requireLogin(), SpellingController.proxyRequestToSpellingApi @@ -268,22 +268,22 @@ module.exports = class Router webRouter.post '/admin/messages', AuthorizationMiddlewear.ensureUserIsSiteAdmin, AdminController.createMessage webRouter.post '/admin/messages/clear', AuthorizationMiddlewear.ensureUserIsSiteAdmin, AdminController.clearMessages - apiRouter.get '/perfTest', (req,res)-> + privateApiRouter.get '/perfTest', (req,res)-> res.send("hello") webRouter.get '/status', (req,res)-> res.send("web sharelatex is alive (web)") - apiRouter.get '/status', (req,res)-> + privateApiRouter.get '/status', (req,res)-> res.send("web sharelatex is alive (api)") webRouter.get '/dev/csrf', (req, res) -> res.send res.locals.csrfToken webRouter.get '/health_check', HealthCheckController.check - apiRouter.get '/health_check', HealthCheckController.check + privateApiRouter.get '/health_check', HealthCheckController.check webRouter.get '/health_check/redis', HealthCheckController.checkRedis - apiRouter.get '/health_check/redis', HealthCheckController.checkRedis + privateApiRouter.get '/health_check/redis', HealthCheckController.checkRedis webRouter.get "/status/compiler/:Project_id", AuthorizationMiddlewear.ensureUserCanReadProject, (req, res) -> project_id = req.params.Project_id @@ -321,7 +321,7 @@ module.exports = class Router require("./models/Project").Project.findOne {}, () -> throw new Error("Test error") - apiRouter.get '/opps-small', (req, res, next)-> + privateApiRouter.get '/opps-small', (req, res, next)-> logger.err "test error occured" res.send() From 1dbeebabd26a3c80f9c60c178bf5fb17ce0dec5f Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Wed, 5 Jul 2017 14:50:38 +0100 Subject: [PATCH 4/5] move status and health checks to public api router --- services/web/app/coffee/router.coffee | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee index 1a5535026e..28b42cc5c1 100644 --- a/services/web/app/coffee/router.coffee +++ b/services/web/app/coffee/router.coffee @@ -271,7 +271,7 @@ module.exports = class Router privateApiRouter.get '/perfTest', (req,res)-> res.send("hello") - webRouter.get '/status', (req,res)-> + publicApiRouter.get '/status', (req,res)-> res.send("web sharelatex is alive (web)") privateApiRouter.get '/status', (req,res)-> res.send("web sharelatex is alive (api)") @@ -279,10 +279,10 @@ module.exports = class Router webRouter.get '/dev/csrf', (req, res) -> res.send res.locals.csrfToken - webRouter.get '/health_check', HealthCheckController.check + publicApiRouter.get '/health_check', HealthCheckController.check privateApiRouter.get '/health_check', HealthCheckController.check - webRouter.get '/health_check/redis', HealthCheckController.checkRedis + publicApiRouter.get '/health_check/redis', HealthCheckController.checkRedis privateApiRouter.get '/health_check/redis', HealthCheckController.checkRedis webRouter.get "/status/compiler/:Project_id", AuthorizationMiddlewear.ensureUserCanReadProject, (req, res) -> From 0ae93db08bb838a424dc06007ca0506773b76238 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Wed, 5 Jul 2017 15:06:23 +0100 Subject: [PATCH 5/5] use ApiErrorHandler on public api --- services/web/app/coffee/infrastructure/Server.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/services/web/app/coffee/infrastructure/Server.coffee b/services/web/app/coffee/infrastructure/Server.coffee index 12172aa94d..48f7fd3e65 100644 --- a/services/web/app/coffee/infrastructure/Server.coffee +++ b/services/web/app/coffee/infrastructure/Server.coffee @@ -173,6 +173,7 @@ enableWebRouter = Settings.web?.enableWebRouter if enableWebRouter or notDefined(enableWebRouter) logger.info("providing web router"); app.use(publicApiRouter) # public API goes with web router for public access + app.use(ErrorController.handleApiError) app.use(webRouter) app.use(ErrorController.handleError)