| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- let AuthorizationMiddleware
- const AuthorizationManager = require('./AuthorizationManager')
- const async = require('async')
- const logger = require('logger-sharelatex')
- const { ObjectId } = require('mongodb')
- const Errors = require('../Errors/Errors')
- const HttpErrorHandler = require('../Errors/HttpErrorHandler')
- const AuthenticationController = require('../Authentication/AuthenticationController')
- const TokenAccessHandler = require('../TokenAccess/TokenAccessHandler')
- module.exports = AuthorizationMiddleware = {
- ensureUserCanReadMultipleProjects(req, res, next) {
- const projectIds = (req.query.project_ids || '').split(',')
- AuthorizationMiddleware._getUserId(req, function (error, userId) {
- if (error) {
- return next(error)
- }
- // Remove the projects we have access to. Note rejectSeries doesn't use
- // errors in callbacks
- async.rejectSeries(
- projectIds,
- function (projectId, cb) {
- const token = TokenAccessHandler.getRequestToken(req, projectId)
- AuthorizationManager.canUserReadProject(
- userId,
- projectId,
- token,
- function (error, canRead) {
- if (error) {
- return next(error)
- }
- cb(canRead)
- }
- )
- },
- function (unauthorizedProjectIds) {
- if (unauthorizedProjectIds.length > 0) {
- return AuthorizationMiddleware.redirectToRestricted(req, res, next)
- }
- next()
- }
- )
- })
- },
- blockRestrictedUserFromProject(req, res, next) {
- AuthorizationMiddleware._getUserAndProjectId(
- req,
- function (error, userId, projectId) {
- if (error) {
- return next(error)
- }
- const token = TokenAccessHandler.getRequestToken(req, projectId)
- AuthorizationManager.isRestrictedUserForProject(
- userId,
- projectId,
- token,
- (err, isRestrictedUser) => {
- if (err) {
- return next(err)
- }
- if (isRestrictedUser) {
- return res.sendStatus(403)
- }
- next()
- }
- )
- }
- )
- },
- ensureUserCanReadProject(req, res, next) {
- AuthorizationMiddleware._getUserAndProjectId(
- req,
- function (error, userId, projectId) {
- if (error) {
- return next(error)
- }
- const token = TokenAccessHandler.getRequestToken(req, projectId)
- AuthorizationManager.canUserReadProject(
- userId,
- projectId,
- token,
- function (error, canRead) {
- if (error) {
- return next(error)
- }
- if (canRead) {
- logger.log(
- { userId, projectId },
- 'allowing user read access to project'
- )
- return next()
- }
- logger.log(
- { userId, projectId },
- 'denying user read access to project'
- )
- HttpErrorHandler.forbidden(req, res)
- }
- )
- }
- )
- },
- ensureUserCanWriteProjectSettings(req, res, next) {
- AuthorizationMiddleware._getUserAndProjectId(
- req,
- function (error, userId, projectId) {
- if (error) {
- return next(error)
- }
- const token = TokenAccessHandler.getRequestToken(req, projectId)
- AuthorizationManager.canUserWriteProjectSettings(
- userId,
- projectId,
- token,
- function (error, canWrite) {
- if (error) {
- return next(error)
- }
- if (canWrite) {
- logger.log(
- { userId, projectId },
- 'allowing user write access to project settings'
- )
- return next()
- }
- logger.log(
- { userId, projectId },
- 'denying user write access to project settings'
- )
- HttpErrorHandler.forbidden(req, res)
- }
- )
- }
- )
- },
- ensureUserCanWriteProjectContent(req, res, next) {
- AuthorizationMiddleware._getUserAndProjectId(
- req,
- function (error, userId, projectId) {
- if (error) {
- return next(error)
- }
- const token = TokenAccessHandler.getRequestToken(req, projectId)
- AuthorizationManager.canUserWriteProjectContent(
- userId,
- projectId,
- token,
- function (error, canWrite) {
- if (error) {
- return next(error)
- }
- if (canWrite) {
- logger.log(
- { userId, projectId },
- 'allowing user write access to project content'
- )
- return next()
- }
- logger.log(
- { userId, projectId },
- 'denying user write access to project settings'
- )
- HttpErrorHandler.forbidden(req, res)
- }
- )
- }
- )
- },
- ensureUserCanAdminProject(req, res, next) {
- AuthorizationMiddleware._getUserAndProjectId(
- req,
- function (error, userId, projectId) {
- if (error) {
- return next(error)
- }
- const token = TokenAccessHandler.getRequestToken(req, projectId)
- AuthorizationManager.canUserAdminProject(
- userId,
- projectId,
- token,
- function (error, canAdmin) {
- if (error) {
- return next(error)
- }
- if (canAdmin) {
- logger.log(
- { userId, projectId },
- 'allowing user admin access to project'
- )
- return next()
- }
- logger.log(
- { userId, projectId },
- 'denying user admin access to project'
- )
- HttpErrorHandler.forbidden(req, res)
- }
- )
- }
- )
- },
- ensureUserIsSiteAdmin(req, res, next) {
- AuthorizationMiddleware._getUserId(req, function (error, userId) {
- if (error) {
- return next(error)
- }
- AuthorizationManager.isUserSiteAdmin(userId, function (error, isAdmin) {
- if (error) {
- return next(error)
- }
- if (isAdmin) {
- logger.log({ userId }, 'allowing user admin access to site')
- return next()
- }
- logger.log({ userId }, 'denying user admin access to site')
- AuthorizationMiddleware.redirectToRestricted(req, res, next)
- })
- })
- },
- _getUserAndProjectId(req, callback) {
- const projectId = req.params.project_id || req.params.Project_id
- if (!projectId) {
- return callback(new Error('Expected project_id in request parameters'))
- }
- if (!ObjectId.isValid(projectId)) {
- return callback(
- new Errors.NotFoundError(`invalid projectId: ${projectId}`)
- )
- }
- AuthorizationMiddleware._getUserId(req, function (error, userId) {
- if (error) {
- return callback(error)
- }
- callback(null, userId, projectId)
- })
- },
- _getUserId(req, callback) {
- const userId =
- AuthenticationController.getLoggedInUserId(req) ||
- (req.oauth_user && req.oauth_user._id) ||
- null
- callback(null, userId)
- },
- redirectToRestricted(req, res, next) {
- // TODO: move this to throwing ForbiddenError
- res.redirect(
- `/restricted?from=${encodeURIComponent(res.locals.currentUrl)}`
- )
- },
- restricted(req, res, next) {
- if (AuthenticationController.isUserLoggedIn(req)) {
- return res.render('user/restricted', { title: 'restricted' })
- }
- const { from } = req.query
- logger.log({ from }, 'redirecting to login')
- if (from) {
- AuthenticationController.setRedirectInSession(req, from)
- }
- res.redirect('/login')
- },
- }
|