mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
Add hasAdminCapabilities function to ExpressLocals
This will be available in pug to allow admin capabilities to be used. GitOrigin-RevId: 6bc4e38385b421aa44ee9385e28f3c59b09e3ade
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
const Settings = require('@overleaf/settings')
|
||||
const Modules = require('../../infrastructure/Modules')
|
||||
|
||||
module.exports = {
|
||||
hasAdminAccess,
|
||||
canRedirectToAdminDomain,
|
||||
getAdminCapabilities,
|
||||
}
|
||||
|
||||
function hasAdminAccess(user) {
|
||||
@@ -11,6 +13,18 @@ function hasAdminAccess(user) {
|
||||
return Boolean(user.isAdmin)
|
||||
}
|
||||
|
||||
async function getAdminCapabilities(user) {
|
||||
const rawAdminCapabilties = await Modules.promises.hooks.fire(
|
||||
'getAdminCapabilities',
|
||||
user
|
||||
)
|
||||
|
||||
return {
|
||||
adminCapabilities: [...new Set(rawAdminCapabilties.flat())],
|
||||
adminCapabilitiesAvailable: rawAdminCapabilties.length > 0,
|
||||
}
|
||||
}
|
||||
|
||||
function canRedirectToAdminDomain(user) {
|
||||
if (Settings.adminPrivilegeAvailable) return false
|
||||
if (!Settings.adminUrl) return false
|
||||
|
||||
@@ -14,12 +14,14 @@ const Modules = require('./Modules')
|
||||
const Errors = require('../Features/Errors/Errors')
|
||||
const {
|
||||
canRedirectToAdminDomain,
|
||||
getAdminCapabilities,
|
||||
hasAdminAccess,
|
||||
} = require('../Features/Helpers/AdminAuthorizationHelper')
|
||||
const {
|
||||
addOptionalCleanupHandlerAfterDrainingConnections,
|
||||
} = require('./GracefulShutdown')
|
||||
const { sanitizeSessionUserForFrontEnd } = require('./FrontEndUser')
|
||||
const { expressify } = require('@overleaf/promise-utils')
|
||||
|
||||
const IEEE_BRAND_ID = Settings.ieeeBrandId
|
||||
|
||||
@@ -312,6 +314,35 @@ module.exports = function (webRouter, privateApiRouter, publicApiRouter) {
|
||||
next()
|
||||
})
|
||||
|
||||
webRouter.use(
|
||||
expressify(async function (req, res, next) {
|
||||
const user = SessionManager.getSessionUser(req.session)
|
||||
try {
|
||||
const { adminCapabilities, adminCapabilitiesAvailable } =
|
||||
await getAdminCapabilities(user)
|
||||
res.locals.hasAdminCapability = capability => {
|
||||
if (!hasAdminAccess(user)) {
|
||||
return false
|
||||
}
|
||||
if (!adminCapabilitiesAvailable) {
|
||||
// If admin capabilities are not available, then all admins have all capabilities
|
||||
return true
|
||||
}
|
||||
return adminCapabilities.includes(capability)
|
||||
}
|
||||
} catch (error) {
|
||||
if (user) {
|
||||
// This is unexpected, it probably means that the session user does not exist.
|
||||
logger.warn({ error, req, user }, 'Failed to get admin capabilities')
|
||||
}
|
||||
// adminCapabilitiesAvailable should be true if we are here so deny to be safe
|
||||
res.locals.hasAdminCapability = () => false
|
||||
}
|
||||
|
||||
next()
|
||||
})
|
||||
)
|
||||
|
||||
webRouter.use(function (req, res, next) {
|
||||
// Clone the nav settings so they can be modified for each request
|
||||
res.locals.nav = {}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
const { expect } = require('chai')
|
||||
const SandboxedModule = require('sandboxed-module')
|
||||
const sinon = require('sinon')
|
||||
|
||||
const modulePath =
|
||||
'../../../../app/src/Features/Helpers/AdminAuthorizationHelper'
|
||||
|
||||
describe('AdminAuthorizationHelper', function () {
|
||||
beforeEach(function () {
|
||||
this.fireHook = sinon.stub().resolves([])
|
||||
this.AdminAuthorizationHelper = SandboxedModule.require(modulePath, {
|
||||
requires: {
|
||||
'@overleaf/settings': {
|
||||
adminPrivilegeAvailable: true,
|
||||
adminUrl: 'https://admin.overleaf.com',
|
||||
},
|
||||
'../../infrastructure/Modules': {
|
||||
promises: {
|
||||
hooks: {
|
||||
fire: this.fireHook,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
describe('getAdminCapabilities', function () {
|
||||
describe('when modules return capabilities', function () {
|
||||
let result
|
||||
const module1Capabilities = ['capability1', 'capability2']
|
||||
const module2Capabilities = ['capability2', 'capability3']
|
||||
|
||||
beforeEach(async function () {
|
||||
this.fireHook.resolves([module1Capabilities, module2Capabilities])
|
||||
result = await this.AdminAuthorizationHelper.getAdminCapabilities({})
|
||||
})
|
||||
it('returns true for adminCapabilitiesAvailable', async function () {
|
||||
expect(result.adminCapabilitiesAvailable).to.be.true
|
||||
})
|
||||
it('returns a flattened array of the returned capabilities', function () {
|
||||
expect(result.adminCapabilities)
|
||||
.to.be.an('array')
|
||||
.that.includes(...module1Capabilities, ...module2Capabilities)
|
||||
})
|
||||
})
|
||||
describe('when no module returns capabilities', function () {
|
||||
let result
|
||||
beforeEach(async function () {
|
||||
result = await this.AdminAuthorizationHelper.getAdminCapabilities({})
|
||||
})
|
||||
|
||||
it('returns false for adminCapabilitiesAvailable', function () {
|
||||
expect(result.adminCapabilitiesAvailable).to.be.false
|
||||
})
|
||||
it('returns an empty adminCapabilities array', function () {
|
||||
expect(result.adminCapabilities).to.be.an('array').that.is.empty
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user