[web] Add requireAdminRoles param to hasAdminCapability (#28006)

* Add `requireAdminRoles` param to `hasAdminCapability`

https://github.com/overleaf/internal/pull/27965#discussion_r2284808889

Co-authored-by: Andrew Rumble <andrew.rumble@overleaf.com>

* Update test

---------

Co-authored-by: Andrew Rumble <andrew.rumble@overleaf.com>
GitOrigin-RevId: 83f8af84debc70c7a2e294638747369c786be22f
This commit is contained in:
Antoine Clausse
2025-08-19 14:13:12 +02:00
committed by Copybot
parent 4edaafe98e
commit 2c44d65785
6 changed files with 66 additions and 14 deletions
@@ -19,8 +19,11 @@ function hasAdminAccess(user) {
return Boolean(user.isAdmin)
}
function hasAdminCapability(capability) {
function hasAdminCapability(capability, requireAdminRoles = true) {
return req => {
if (requireAdminRoles && !Settings.adminRolesEnabled) {
return false
}
if (!hasAdminAccess(SessionManager.getSessionUser(req.session))) {
return false
}
@@ -69,8 +72,8 @@ async function useAdminCapabilities(req, res, next) {
}
function useHasAdminCapability(req, res, next) {
res.locals.hasAdminCapability = capability =>
hasAdminCapability(capability)(req)
res.locals.hasAdminCapability = (capability, requireAdminRoles = true) =>
hasAdminCapability(capability, requireAdminRoles)(req)
next()
}
@@ -20,7 +20,8 @@ const UserMembershipAuthorization = {
return hasAdminCapability(
req.entity.managedUsersEnabled
? 'modify-managed-group-member'
: 'modify-group-member'
: 'modify-group-member',
true
)(req, res)
},
+2 -2
View File
@@ -17,8 +17,8 @@ block append meta
- const sessionUser = getSessionUser()
- const staffAccess = sessionUser?.staffAccess
- const canDisplaySplitTestMenu = hasFeature('saas') && ((canDisplayAdminMenu && hasAdminCapability('view-split-test')) || staffAccess?.splitTestMetrics || staffAccess?.splitTestManagement)
- const canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu && hasAdminCapability('manage-survey')
- const canDisplayScriptLogMenu = hasFeature('saas') && hasAdminCapability('view-script-log') && canDisplayAdminMenu
- const canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu && hasAdminCapability('manage-survey', false)
- const canDisplayScriptLogMenu = hasFeature('saas') && hasAdminCapability('view-script-log', false) && canDisplayAdminMenu
- const enableUpgradeButton = projectDashboardReact && usersBestSubscription && (usersBestSubscription.type === 'free' || usersBestSubscription.type === 'standalone-ai-add-on')
- const showSignUpLink = hasFeature('registration-page')
@@ -34,8 +34,8 @@ nav.navbar.navbar-default.navbar-main.navbar-expand-lg(
- var canDisplayAdminMenu = hasAdminAccess()
- var canDisplayAdminRedirect = canRedirectToAdminDomain()
- var canDisplaySplitTestMenu = hasFeature('saas') && ((canDisplayAdminMenu && hasAdminCapability('view-split-test')) || (getSessionUser() && getSessionUser().staffAccess && (getSessionUser().staffAccess.splitTestMetrics || getSessionUser().staffAccess.splitTestManagement)))
- var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu && hasAdminCapability('manage-survey')
- var canDisplayScriptLogMenu = hasFeature('saas') && hasAdminCapability('view-script-log') && canDisplayAdminMenu
- var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu && hasAdminCapability('manage-survey', false)
- var canDisplayScriptLogMenu = hasFeature('saas') && hasAdminCapability('view-script-log', false) && canDisplayAdminMenu
if typeof suppressNavbarRight === 'undefined'
button#navbar-toggle-btn.navbar-toggler.collapsed(
@@ -40,8 +40,8 @@ nav.navbar.navbar-default.navbar-main.website-redesign-navbar(
- var canDisplayAdminMenu = hasAdminAccess()
- var canDisplayAdminRedirect = canRedirectToAdminDomain()
- var canDisplaySplitTestMenu = hasFeature('saas') && ((canDisplayAdminMenu && hasAdminCapability('view-split-test')) || (getSessionUser() && getSessionUser().staffAccess && (getSessionUser().staffAccess.splitTestMetrics || getSessionUser().staffAccess.splitTestManagement)))
- var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu && hasAdminCapability('manage-survey')
- var canDisplayScriptLogMenu = hasFeature('saas') && hasAdminCapability('view-script-log') && canDisplayAdminMenu
- var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu && hasAdminCapability('manage-survey', false)
- var canDisplayScriptLogMenu = hasFeature('saas') && hasAdminCapability('view-script-log', false) && canDisplayAdminMenu
if typeof suppressNavbarRight == 'undefined'
#navbar-main-collapse.navbar-collapse.collapse
@@ -10,12 +10,14 @@ const modulePath =
describe('AdminAuthorizationHelper', function () {
beforeEach(function () {
this.fireHook = sinon.stub().resolves([])
this.settings = {
adminPrivilegeAvailable: true,
adminUrl: 'https://admin.overleaf.com',
adminRolesEnabled: true,
}
this.AdminAuthorizationHelper = SandboxedModule.require(modulePath, {
requires: {
'@overleaf/settings': {
adminPrivilegeAvailable: true,
adminUrl: 'https://admin.overleaf.com',
},
'@overleaf/settings': this.settings,
'../../infrastructure/Modules': {
promises: {
hooks: {
@@ -395,6 +397,24 @@ describe('AdminAuthorizationHelper', function () {
this.AdminAuthorizationHelper.hasAdminCapability('capability')(req)
).to.be.true
})
it('ignores the "requireAdminRoles" argument', function () {
const req = {
session: { user: { isAdmin: true } },
adminCapabilitiesAvailable: false,
}
expect(
this.AdminAuthorizationHelper.hasAdminCapability(
'capability',
true
)(req)
).to.be.true
expect(
this.AdminAuthorizationHelper.hasAdminCapability(
'capability',
false
)(req)
).to.be.true
})
})
describe('when adminCapabilitiesAvailable is true', function () {
describe('when user has the requested capability', function () {
@@ -427,5 +447,33 @@ describe('AdminAuthorizationHelper', function () {
})
})
})
describe('when admin roles are not enabled', function () {
beforeEach(function () {
this.settings.adminRolesEnabled = false
})
it('returns false even for admins', function () {
const req = { session: { user: { isAdmin: true } } }
expect(
this.AdminAuthorizationHelper.hasAdminCapability('capability')(req)
).to.be.false
expect(
this.AdminAuthorizationHelper.hasAdminCapability(
'capability',
true
)(req)
).to.be.false
})
it('returns true when requireAdminRoles=false', function () {
const req = { session: { user: { isAdmin: true } } }
expect(
this.AdminAuthorizationHelper.hasAdminCapability(
'capability',
false
)(req)
).to.be.true
})
})
})
})