mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #2162 from overleaf/ta-decaf-cleanup-authorization
Decafeinate Authorization Feature GitOrigin-RevId: 5f139c24eac38ef0818a0eec9d308aacca0fde56
This commit is contained in:
parent
c1c1b85a40
commit
af7eea35a1
5 changed files with 261 additions and 358 deletions
|
@ -1,16 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
handle-callback-err,
|
||||
max-len,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
let AuthorizationManager
|
||||
const CollaboratorsHandler = require('../Collaborators/CollaboratorsHandler')
|
||||
const ProjectGetter = require('../Project/ProjectGetter')
|
||||
|
@ -22,29 +9,25 @@ const { ObjectId } = require('mongojs')
|
|||
const TokenAccessHandler = require('../TokenAccess/TokenAccessHandler')
|
||||
|
||||
module.exports = AuthorizationManager = {
|
||||
getPublicAccessLevel(project_id, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(err, level) {}
|
||||
}
|
||||
if (!ObjectId.isValid(project_id)) {
|
||||
getPublicAccessLevel(projectId, callback) {
|
||||
if (!ObjectId.isValid(projectId)) {
|
||||
return callback(new Error('invalid project id'))
|
||||
}
|
||||
// Note, the Project property in the DB is `publicAccesLevel`, without the second `s`
|
||||
return ProjectGetter.getProject(
|
||||
project_id,
|
||||
{ publicAccesLevel: 1 },
|
||||
function(error, project) {
|
||||
if (error != null) {
|
||||
return callback(error)
|
||||
}
|
||||
if (project == null) {
|
||||
return callback(
|
||||
new Errors.NotFoundError(`no project found with id ${project_id}`)
|
||||
)
|
||||
}
|
||||
return callback(null, project.publicAccesLevel)
|
||||
ProjectGetter.getProject(projectId, { publicAccesLevel: 1 }, function(
|
||||
error,
|
||||
project
|
||||
) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
)
|
||||
if (!project) {
|
||||
return callback(
|
||||
new Errors.NotFoundError(`no project found with id ${projectId}`)
|
||||
)
|
||||
}
|
||||
callback(null, project.publicAccesLevel)
|
||||
})
|
||||
},
|
||||
|
||||
// Get the privilege level that the user has for the project
|
||||
|
@ -53,142 +36,131 @@ module.exports = AuthorizationManager = {
|
|||
// access. false if the user does not have access
|
||||
// * becausePublic: true if the access level is only because the project is public.
|
||||
// * becauseSiteAdmin: true if access level is only because user is admin
|
||||
getPrivilegeLevelForProject(user_id, project_id, token, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(
|
||||
error,
|
||||
privilegeLevel,
|
||||
becausePublic,
|
||||
becauseSiteAdmin
|
||||
) {}
|
||||
}
|
||||
if (user_id == null) {
|
||||
// User is Anonymous, Try Token-based access
|
||||
return AuthorizationManager.getPublicAccessLevel(project_id, function(
|
||||
err,
|
||||
publicAccessLevel
|
||||
) {
|
||||
if (err != null) {
|
||||
return callback(err)
|
||||
}
|
||||
if (publicAccessLevel === PublicAccessLevels.TOKEN_BASED) {
|
||||
// Anonymous users can have read-only access to token-based projects,
|
||||
// while read-write access must be logged in,
|
||||
// unless the `enableAnonymousReadAndWriteSharing` setting is enabled
|
||||
return TokenAccessHandler.isValidToken(project_id, token, function(
|
||||
err,
|
||||
isValidReadAndWrite,
|
||||
isValidReadOnly
|
||||
) {
|
||||
if (err != null) {
|
||||
return callback(err)
|
||||
}
|
||||
if (isValidReadOnly) {
|
||||
// Grant anonymous user read-only access
|
||||
return callback(null, PrivilegeLevels.READ_ONLY, false, false)
|
||||
} else if (
|
||||
isValidReadAndWrite &&
|
||||
TokenAccessHandler.ANONYMOUS_READ_AND_WRITE_ENABLED
|
||||
) {
|
||||
// Grant anonymous user read-and-write access
|
||||
return callback(
|
||||
null,
|
||||
PrivilegeLevels.READ_AND_WRITE,
|
||||
false,
|
||||
false
|
||||
)
|
||||
} else {
|
||||
// Deny anonymous access
|
||||
return callback(null, PrivilegeLevels.NONE, false, false)
|
||||
}
|
||||
})
|
||||
} else if (publicAccessLevel === PublicAccessLevels.READ_ONLY) {
|
||||
// Legacy public read-only access for anonymous user
|
||||
return callback(null, PrivilegeLevels.READ_ONLY, true, false)
|
||||
} else if (publicAccessLevel === PublicAccessLevels.READ_AND_WRITE) {
|
||||
// Legacy public read-write access for anonymous user
|
||||
return callback(null, PrivilegeLevels.READ_AND_WRITE, true, false)
|
||||
} else {
|
||||
// Deny anonymous user access
|
||||
return callback(null, PrivilegeLevels.NONE, false, false)
|
||||
}
|
||||
})
|
||||
getPrivilegeLevelForProject(userId, projectId, token, callback) {
|
||||
if (userId) {
|
||||
AuthorizationManager.getPrivilegeLevelForProjectWithUser(
|
||||
userId,
|
||||
projectId,
|
||||
token,
|
||||
callback
|
||||
)
|
||||
} else {
|
||||
// User is present, get their privilege level from database
|
||||
return CollaboratorsHandler.getMemberIdPrivilegeLevel(
|
||||
user_id,
|
||||
project_id,
|
||||
function(error, privilegeLevel) {
|
||||
if (error != null) {
|
||||
return callback(error)
|
||||
}
|
||||
if (
|
||||
privilegeLevel != null &&
|
||||
privilegeLevel !== PrivilegeLevels.NONE
|
||||
) {
|
||||
// The user has direct access
|
||||
return callback(null, privilegeLevel, false, false)
|
||||
} else {
|
||||
return AuthorizationManager.isUserSiteAdmin(user_id, function(
|
||||
error,
|
||||
isAdmin
|
||||
) {
|
||||
if (error != null) {
|
||||
return callback(error)
|
||||
}
|
||||
if (isAdmin) {
|
||||
return callback(null, PrivilegeLevels.OWNER, false, true)
|
||||
} else {
|
||||
// Legacy public-access system
|
||||
// User is present (not anonymous), but does not have direct access
|
||||
return AuthorizationManager.getPublicAccessLevel(
|
||||
project_id,
|
||||
function(err, publicAccessLevel) {
|
||||
if (err != null) {
|
||||
return callback(err)
|
||||
}
|
||||
if (publicAccessLevel === PublicAccessLevels.READ_ONLY) {
|
||||
return callback(
|
||||
null,
|
||||
PrivilegeLevels.READ_ONLY,
|
||||
true,
|
||||
false
|
||||
)
|
||||
} else if (
|
||||
publicAccessLevel === PublicAccessLevels.READ_AND_WRITE
|
||||
) {
|
||||
return callback(
|
||||
null,
|
||||
PrivilegeLevels.READ_AND_WRITE,
|
||||
true,
|
||||
false
|
||||
)
|
||||
} else {
|
||||
return callback(null, PrivilegeLevels.NONE, false, false)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
AuthorizationManager.getPrivilegeLevelForProjectWithoutUser(
|
||||
projectId,
|
||||
token,
|
||||
callback
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
canUserReadProject(user_id, project_id, token, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(error, canRead) {}
|
||||
}
|
||||
return AuthorizationManager.getPrivilegeLevelForProject(
|
||||
user_id,
|
||||
project_id,
|
||||
token,
|
||||
function(error, privilegeLevel) {
|
||||
if (error != null) {
|
||||
// User is present, get their privilege level from database
|
||||
getPrivilegeLevelForProjectWithUser(userId, projectId, token, callback) {
|
||||
CollaboratorsHandler.getMemberIdPrivilegeLevel(userId, projectId, function(
|
||||
error,
|
||||
privilegeLevel
|
||||
) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
if (privilegeLevel && privilegeLevel !== PrivilegeLevels.NONE) {
|
||||
// The user has direct access
|
||||
return callback(null, privilegeLevel, false, false)
|
||||
}
|
||||
AuthorizationManager.isUserSiteAdmin(userId, function(error, isAdmin) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
return callback(
|
||||
if (isAdmin) {
|
||||
return callback(null, PrivilegeLevels.OWNER, false, true)
|
||||
}
|
||||
// Legacy public-access system
|
||||
// User is present (not anonymous), but does not have direct access
|
||||
AuthorizationManager.getPublicAccessLevel(projectId, function(
|
||||
err,
|
||||
publicAccessLevel
|
||||
) {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
if (publicAccessLevel === PublicAccessLevels.READ_ONLY) {
|
||||
return callback(null, PrivilegeLevels.READ_ONLY, true, false)
|
||||
}
|
||||
if (publicAccessLevel === PublicAccessLevels.READ_AND_WRITE) {
|
||||
return callback(null, PrivilegeLevels.READ_AND_WRITE, true, false)
|
||||
}
|
||||
callback(null, PrivilegeLevels.NONE, false, false)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// User is Anonymous, Try Token-based access
|
||||
getPrivilegeLevelForProjectWithoutUser(projectId, token, callback) {
|
||||
AuthorizationManager.getPublicAccessLevel(projectId, function(
|
||||
err,
|
||||
publicAccessLevel
|
||||
) {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
if (publicAccessLevel === PublicAccessLevels.READ_ONLY) {
|
||||
// Legacy public read-only access for anonymous user
|
||||
return callback(null, PrivilegeLevels.READ_ONLY, true, false)
|
||||
}
|
||||
if (publicAccessLevel === PublicAccessLevels.READ_AND_WRITE) {
|
||||
// Legacy public read-write access for anonymous user
|
||||
return callback(null, PrivilegeLevels.READ_AND_WRITE, true, false)
|
||||
}
|
||||
if (publicAccessLevel === PublicAccessLevels.TOKEN_BASED) {
|
||||
return AuthorizationManager.getPrivilegeLevelForProjectWithToken(
|
||||
projectId,
|
||||
token,
|
||||
callback
|
||||
)
|
||||
}
|
||||
// Deny anonymous user access
|
||||
callback(null, PrivilegeLevels.NONE, false, false)
|
||||
})
|
||||
},
|
||||
|
||||
getPrivilegeLevelForProjectWithToken(projectId, token, callback) {
|
||||
// Anonymous users can have read-only access to token-based projects,
|
||||
// while read-write access must be logged in,
|
||||
// unless the `enableAnonymousReadAndWriteSharing` setting is enabled
|
||||
TokenAccessHandler.isValidToken(projectId, token, function(
|
||||
err,
|
||||
isValidReadAndWrite,
|
||||
isValidReadOnly
|
||||
) {
|
||||
if (err) {
|
||||
return callback(err)
|
||||
}
|
||||
if (isValidReadOnly) {
|
||||
// Grant anonymous user read-only access
|
||||
return callback(null, PrivilegeLevels.READ_ONLY, false, false)
|
||||
}
|
||||
if (
|
||||
isValidReadAndWrite &&
|
||||
TokenAccessHandler.ANONYMOUS_READ_AND_WRITE_ENABLED
|
||||
) {
|
||||
// Grant anonymous user read-and-write access
|
||||
return callback(null, PrivilegeLevels.READ_AND_WRITE, false, false)
|
||||
}
|
||||
// Deny anonymous access
|
||||
callback(null, PrivilegeLevels.NONE, false, false)
|
||||
})
|
||||
},
|
||||
|
||||
canUserReadProject(userId, projectId, token, callback) {
|
||||
AuthorizationManager.getPrivilegeLevelForProject(
|
||||
userId,
|
||||
projectId,
|
||||
token,
|
||||
function(error, privilegeLevel) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
callback(
|
||||
null,
|
||||
[
|
||||
PrivilegeLevels.OWNER,
|
||||
|
@ -200,19 +172,16 @@ module.exports = AuthorizationManager = {
|
|||
)
|
||||
},
|
||||
|
||||
canUserWriteProjectContent(user_id, project_id, token, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(error, canWriteContent) {}
|
||||
}
|
||||
return AuthorizationManager.getPrivilegeLevelForProject(
|
||||
user_id,
|
||||
project_id,
|
||||
canUserWriteProjectContent(userId, projectId, token, callback) {
|
||||
AuthorizationManager.getPrivilegeLevelForProject(
|
||||
userId,
|
||||
projectId,
|
||||
token,
|
||||
function(error, privilegeLevel) {
|
||||
if (error != null) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
return callback(
|
||||
callback(
|
||||
null,
|
||||
[PrivilegeLevels.OWNER, PrivilegeLevels.READ_AND_WRITE].includes(
|
||||
privilegeLevel
|
||||
|
@ -222,45 +191,39 @@ module.exports = AuthorizationManager = {
|
|||
)
|
||||
},
|
||||
|
||||
canUserWriteProjectSettings(user_id, project_id, token, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(error, canWriteSettings) {}
|
||||
}
|
||||
return AuthorizationManager.getPrivilegeLevelForProject(
|
||||
user_id,
|
||||
project_id,
|
||||
canUserWriteProjectSettings(userId, projectId, token, callback) {
|
||||
AuthorizationManager.getPrivilegeLevelForProject(
|
||||
userId,
|
||||
projectId,
|
||||
token,
|
||||
function(error, privilegeLevel, becausePublic) {
|
||||
if (error != null) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
if (privilegeLevel === PrivilegeLevels.OWNER) {
|
||||
return callback(null, true)
|
||||
} else if (
|
||||
}
|
||||
if (
|
||||
privilegeLevel === PrivilegeLevels.READ_AND_WRITE &&
|
||||
!becausePublic
|
||||
) {
|
||||
return callback(null, true)
|
||||
} else {
|
||||
return callback(null, false)
|
||||
}
|
||||
callback(null, false)
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
canUserAdminProject(user_id, project_id, token, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(error, canAdmin, becauseSiteAdmin) {}
|
||||
}
|
||||
return AuthorizationManager.getPrivilegeLevelForProject(
|
||||
user_id,
|
||||
project_id,
|
||||
canUserAdminProject(userId, projectId, token, callback) {
|
||||
AuthorizationManager.getPrivilegeLevelForProject(
|
||||
userId,
|
||||
projectId,
|
||||
token,
|
||||
function(error, privilegeLevel, becausePublic, becauseSiteAdmin) {
|
||||
if (error != null) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
return callback(
|
||||
callback(
|
||||
null,
|
||||
privilegeLevel === PrivilegeLevels.OWNER,
|
||||
becauseSiteAdmin
|
||||
|
@ -269,21 +232,15 @@ module.exports = AuthorizationManager = {
|
|||
)
|
||||
},
|
||||
|
||||
isUserSiteAdmin(user_id, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(error, isAdmin) {}
|
||||
}
|
||||
if (user_id == null) {
|
||||
isUserSiteAdmin(userId, callback) {
|
||||
if (!userId) {
|
||||
return callback(null, false)
|
||||
}
|
||||
return User.findOne({ _id: user_id }, { isAdmin: 1 }, function(
|
||||
error,
|
||||
user
|
||||
) {
|
||||
if (error != null) {
|
||||
User.findOne({ _id: userId }, { isAdmin: 1 }, function(error, user) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
return callback(null, (user != null ? user.isAdmin : undefined) === true)
|
||||
callback(null, (user && user.isAdmin) === true)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,3 @@
|
|||
/* eslint-disable
|
||||
camelcase,
|
||||
handle-callback-err,
|
||||
max-len,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS103: Rewrite code to no longer use __guard__
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
let AuthorizationMiddleware
|
||||
const AuthorizationManager = require('./AuthorizationManager')
|
||||
const async = require('async')
|
||||
|
@ -23,276 +9,242 @@ const TokenAccessHandler = require('../TokenAccess/TokenAccessHandler')
|
|||
|
||||
module.exports = AuthorizationMiddleware = {
|
||||
ensureUserCanReadMultipleProjects(req, res, next) {
|
||||
const project_ids = (req.query.project_ids || '').split(',')
|
||||
return AuthorizationMiddleware._getUserId(req, function(error, user_id) {
|
||||
if (error != null) {
|
||||
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
|
||||
return async.rejectSeries(
|
||||
project_ids,
|
||||
function(project_id, cb) {
|
||||
const token = TokenAccessHandler.getRequestToken(req, project_id)
|
||||
return AuthorizationManager.canUserReadProject(
|
||||
user_id,
|
||||
project_id,
|
||||
async.rejectSeries(
|
||||
projectIds,
|
||||
function(projectId, cb) {
|
||||
const token = TokenAccessHandler.getRequestToken(req, projectId)
|
||||
AuthorizationManager.canUserReadProject(
|
||||
userId,
|
||||
projectId,
|
||||
token,
|
||||
function(error, canRead) {
|
||||
if (error != null) {
|
||||
if (error) {
|
||||
return next(error)
|
||||
}
|
||||
return cb(canRead)
|
||||
cb(canRead)
|
||||
}
|
||||
)
|
||||
},
|
||||
function(unauthorized_project_ids) {
|
||||
if (unauthorized_project_ids.length > 0) {
|
||||
function(unauthorizedProjectIds) {
|
||||
if (unauthorizedProjectIds.length > 0) {
|
||||
return AuthorizationMiddleware.redirectToRestricted(req, res, next)
|
||||
} else {
|
||||
return next()
|
||||
}
|
||||
next()
|
||||
}
|
||||
)
|
||||
})
|
||||
},
|
||||
|
||||
ensureUserCanReadProject(req, res, next) {
|
||||
return AuthorizationMiddleware._getUserAndProjectId(req, function(
|
||||
AuthorizationMiddleware._getUserAndProjectId(req, function(
|
||||
error,
|
||||
user_id,
|
||||
project_id
|
||||
userId,
|
||||
projectId
|
||||
) {
|
||||
if (error != null) {
|
||||
if (error) {
|
||||
return next(error)
|
||||
}
|
||||
const token = TokenAccessHandler.getRequestToken(req, project_id)
|
||||
return AuthorizationManager.canUserReadProject(
|
||||
user_id,
|
||||
project_id,
|
||||
const token = TokenAccessHandler.getRequestToken(req, projectId)
|
||||
AuthorizationManager.canUserReadProject(
|
||||
userId,
|
||||
projectId,
|
||||
token,
|
||||
function(error, canRead) {
|
||||
if (error != null) {
|
||||
if (error) {
|
||||
return next(error)
|
||||
}
|
||||
if (canRead) {
|
||||
logger.log(
|
||||
{ user_id, project_id },
|
||||
{ userId, projectId },
|
||||
'allowing user read access to project'
|
||||
)
|
||||
return next()
|
||||
} else {
|
||||
logger.log(
|
||||
{ user_id, project_id },
|
||||
'denying user read access to project'
|
||||
)
|
||||
if (
|
||||
__guard__(
|
||||
req.headers != null ? req.headers['accept'] : undefined,
|
||||
x => x.match(/^application\/json.*$/)
|
||||
)
|
||||
) {
|
||||
return res.sendStatus(403)
|
||||
} else {
|
||||
return AuthorizationMiddleware.redirectToRestricted(
|
||||
req,
|
||||
res,
|
||||
next
|
||||
)
|
||||
}
|
||||
}
|
||||
logger.log(
|
||||
{ userId, projectId },
|
||||
'denying user read access to project'
|
||||
)
|
||||
const acceptHeader = req.headers && req.headers['accept']
|
||||
if (acceptHeader && acceptHeader.match(/^application\/json.*$/)) {
|
||||
return res.sendStatus(403)
|
||||
}
|
||||
AuthorizationMiddleware.redirectToRestricted(req, res, next)
|
||||
}
|
||||
)
|
||||
})
|
||||
},
|
||||
|
||||
ensureUserCanWriteProjectSettings(req, res, next) {
|
||||
return AuthorizationMiddleware._getUserAndProjectId(req, function(
|
||||
AuthorizationMiddleware._getUserAndProjectId(req, function(
|
||||
error,
|
||||
user_id,
|
||||
project_id
|
||||
userId,
|
||||
projectId
|
||||
) {
|
||||
if (error != null) {
|
||||
if (error) {
|
||||
return next(error)
|
||||
}
|
||||
const token = TokenAccessHandler.getRequestToken(req, project_id)
|
||||
return AuthorizationManager.canUserWriteProjectSettings(
|
||||
user_id,
|
||||
project_id,
|
||||
const token = TokenAccessHandler.getRequestToken(req, projectId)
|
||||
AuthorizationManager.canUserWriteProjectSettings(
|
||||
userId,
|
||||
projectId,
|
||||
token,
|
||||
function(error, canWrite) {
|
||||
if (error != null) {
|
||||
if (error) {
|
||||
return next(error)
|
||||
}
|
||||
if (canWrite) {
|
||||
logger.log(
|
||||
{ user_id, project_id },
|
||||
{ userId, projectId },
|
||||
'allowing user write access to project settings'
|
||||
)
|
||||
return next()
|
||||
} else {
|
||||
logger.log(
|
||||
{ user_id, project_id },
|
||||
'denying user write access to project settings'
|
||||
)
|
||||
return AuthorizationMiddleware.redirectToRestricted(req, res, next)
|
||||
}
|
||||
logger.log(
|
||||
{ userId, projectId },
|
||||
'denying user write access to project settings'
|
||||
)
|
||||
AuthorizationMiddleware.redirectToRestricted(req, res, next)
|
||||
}
|
||||
)
|
||||
})
|
||||
},
|
||||
|
||||
ensureUserCanWriteProjectContent(req, res, next) {
|
||||
return AuthorizationMiddleware._getUserAndProjectId(req, function(
|
||||
AuthorizationMiddleware._getUserAndProjectId(req, function(
|
||||
error,
|
||||
user_id,
|
||||
project_id
|
||||
userId,
|
||||
projectId
|
||||
) {
|
||||
if (error != null) {
|
||||
if (error) {
|
||||
return next(error)
|
||||
}
|
||||
const token = TokenAccessHandler.getRequestToken(req, project_id)
|
||||
return AuthorizationManager.canUserWriteProjectContent(
|
||||
user_id,
|
||||
project_id,
|
||||
const token = TokenAccessHandler.getRequestToken(req, projectId)
|
||||
AuthorizationManager.canUserWriteProjectContent(
|
||||
userId,
|
||||
projectId,
|
||||
token,
|
||||
function(error, canWrite) {
|
||||
if (error != null) {
|
||||
if (error) {
|
||||
return next(error)
|
||||
}
|
||||
if (canWrite) {
|
||||
logger.log(
|
||||
{ user_id, project_id },
|
||||
{ userId, projectId },
|
||||
'allowing user write access to project content'
|
||||
)
|
||||
return next()
|
||||
} else {
|
||||
logger.log(
|
||||
{ user_id, project_id },
|
||||
'denying user write access to project settings'
|
||||
)
|
||||
return AuthorizationMiddleware.redirectToRestricted(req, res, next)
|
||||
}
|
||||
logger.log(
|
||||
{ userId, projectId },
|
||||
'denying user write access to project settings'
|
||||
)
|
||||
AuthorizationMiddleware.redirectToRestricted(req, res, next)
|
||||
}
|
||||
)
|
||||
})
|
||||
},
|
||||
|
||||
ensureUserCanAdminProject(req, res, next) {
|
||||
return AuthorizationMiddleware._getUserAndProjectId(req, function(
|
||||
AuthorizationMiddleware._getUserAndProjectId(req, function(
|
||||
error,
|
||||
user_id,
|
||||
project_id
|
||||
userId,
|
||||
projectId
|
||||
) {
|
||||
if (error != null) {
|
||||
if (error) {
|
||||
return next(error)
|
||||
}
|
||||
const token = TokenAccessHandler.getRequestToken(req, project_id)
|
||||
return AuthorizationManager.canUserAdminProject(
|
||||
user_id,
|
||||
project_id,
|
||||
const token = TokenAccessHandler.getRequestToken(req, projectId)
|
||||
AuthorizationManager.canUserAdminProject(
|
||||
userId,
|
||||
projectId,
|
||||
token,
|
||||
function(error, canAdmin) {
|
||||
if (error != null) {
|
||||
if (error) {
|
||||
return next(error)
|
||||
}
|
||||
if (canAdmin) {
|
||||
logger.log(
|
||||
{ user_id, project_id },
|
||||
{ userId, projectId },
|
||||
'allowing user admin access to project'
|
||||
)
|
||||
return next()
|
||||
} else {
|
||||
logger.log(
|
||||
{ user_id, project_id },
|
||||
'denying user admin access to project'
|
||||
)
|
||||
return AuthorizationMiddleware.redirectToRestricted(req, res, next)
|
||||
}
|
||||
logger.log(
|
||||
{ userId, projectId },
|
||||
'denying user admin access to project'
|
||||
)
|
||||
AuthorizationMiddleware.redirectToRestricted(req, res, next)
|
||||
}
|
||||
)
|
||||
})
|
||||
},
|
||||
|
||||
ensureUserIsSiteAdmin(req, res, next) {
|
||||
return AuthorizationMiddleware._getUserId(req, function(error, user_id) {
|
||||
if (error != null) {
|
||||
AuthorizationMiddleware._getUserId(req, function(error, userId) {
|
||||
if (error) {
|
||||
return next(error)
|
||||
}
|
||||
return AuthorizationManager.isUserSiteAdmin(user_id, function(
|
||||
error,
|
||||
isAdmin
|
||||
) {
|
||||
if (error != null) {
|
||||
AuthorizationManager.isUserSiteAdmin(userId, function(error, isAdmin) {
|
||||
if (error) {
|
||||
return next(error)
|
||||
}
|
||||
if (isAdmin) {
|
||||
logger.log({ user_id }, 'allowing user admin access to site')
|
||||
logger.log({ userId }, 'allowing user admin access to site')
|
||||
return next()
|
||||
} else {
|
||||
logger.log({ user_id }, 'denying user admin access to site')
|
||||
return AuthorizationMiddleware.redirectToRestricted(req, res, next)
|
||||
}
|
||||
logger.log({ userId }, 'denying user admin access to site')
|
||||
AuthorizationMiddleware.redirectToRestricted(req, res, next)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
_getUserAndProjectId(req, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(error, user_id, project_id) {}
|
||||
}
|
||||
const project_id =
|
||||
(req.params != null ? req.params.project_id : undefined) ||
|
||||
(req.params != null ? req.params.Project_id : undefined)
|
||||
if (project_id == null) {
|
||||
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(project_id)) {
|
||||
if (!ObjectId.isValid(projectId)) {
|
||||
return callback(
|
||||
new Errors.NotFoundError(`invalid project_id: ${project_id}`)
|
||||
new Errors.NotFoundError(`invalid projectId: ${projectId}`)
|
||||
)
|
||||
}
|
||||
return AuthorizationMiddleware._getUserId(req, function(error, user_id) {
|
||||
if (error != null) {
|
||||
AuthorizationMiddleware._getUserId(req, function(error, userId) {
|
||||
if (error) {
|
||||
return callback(error)
|
||||
}
|
||||
return callback(null, user_id, project_id)
|
||||
callback(null, userId, projectId)
|
||||
})
|
||||
},
|
||||
|
||||
_getUserId(req, callback) {
|
||||
if (callback == null) {
|
||||
callback = function(error, user_id) {}
|
||||
}
|
||||
const user_id =
|
||||
const userId =
|
||||
AuthenticationController.getLoggedInUserId(req) ||
|
||||
__guard__(req != null ? req.oauth_user : undefined, x => x._id) ||
|
||||
(req.oauth_user && req.oauth_user._id) ||
|
||||
null
|
||||
return callback(null, user_id)
|
||||
callback(null, userId)
|
||||
},
|
||||
|
||||
redirectToRestricted(req, res, next) {
|
||||
// TODO: move this to throwing ForbiddenError
|
||||
return res.redirect(`/restricted?from=${encodeURIComponent(req.url)}`)
|
||||
res.redirect(`/restricted?from=${encodeURIComponent(req.url)}`)
|
||||
},
|
||||
|
||||
restricted(req, res, next) {
|
||||
if (AuthenticationController.isUserLoggedIn(req)) {
|
||||
return res.render('user/restricted', { title: 'restricted' })
|
||||
} else {
|
||||
const { from } = req.query
|
||||
logger.log({ from }, 'redirecting to login')
|
||||
const redirect_to = '/login'
|
||||
if (from != null) {
|
||||
AuthenticationController.setRedirectInSession(req, from)
|
||||
}
|
||||
return res.redirect(redirect_to)
|
||||
}
|
||||
const { from } = req.query
|
||||
logger.log({ from }, 'redirecting to login')
|
||||
if (from) {
|
||||
AuthenticationController.setRedirectInSession(req, from)
|
||||
}
|
||||
res.redirect('/login')
|
||||
}
|
||||
}
|
||||
|
||||
function __guard__(value, transform) {
|
||||
return typeof value !== 'undefined' && value !== null
|
||||
? transform(value)
|
||||
: undefined
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Sanity-check the conversion and remove this comment.
|
||||
module.exports = {
|
||||
NONE: false,
|
||||
READ_ONLY: 'readOnly',
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Sanity-check the conversion and remove this comment.
|
||||
module.exports = {
|
||||
READ_ONLY: 'readOnly', // LEGACY
|
||||
READ_AND_WRITE: 'readAndWrite', // LEGACY
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Sanity-check the conversion and remove this comment.
|
||||
module.exports = {
|
||||
INVITE: 'invite',
|
||||
TOKEN: 'token',
|
||||
|
|
Loading…
Reference in a new issue