mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #13505 from overleaf/bg-group-policy-meta-tags
hide restricted elements for managed users on settings page GitOrigin-RevId: be8679957eb5185d8b91d29e5a787c837684c314
This commit is contained in:
parent
4f8852feaa
commit
bf92436e6f
10 changed files with 89 additions and 11 deletions
|
@ -1,5 +1,9 @@
|
|||
const { ForbiddenError } = require('../Errors/Errors')
|
||||
const { hasPermission, getUserCapabilities } = require('./PermissionsManager')
|
||||
const { ForbiddenError, UserNotFoundError } = require('../Errors/Errors')
|
||||
const {
|
||||
hasPermission,
|
||||
getUserCapabilities,
|
||||
getUserRestrictions,
|
||||
} = require('./PermissionsManager')
|
||||
const ManagedUsersHandler = require('../Subscription/ManagedUsersHandler')
|
||||
|
||||
/**
|
||||
|
@ -8,6 +12,16 @@ const ManagedUsersHandler = require('../Subscription/ManagedUsersHandler')
|
|||
*/
|
||||
function useCapabilities() {
|
||||
return async function (req, res, next) {
|
||||
// attach the user's capabilities to the request object
|
||||
req.capabilitySet = new Set()
|
||||
// provide a function to assert that a capability is present
|
||||
req.assertPermission = capability => {
|
||||
if (!req.capabilitySet.has(capability)) {
|
||||
throw new ForbiddenError(
|
||||
`user does not have permission for ${capability}`
|
||||
)
|
||||
}
|
||||
}
|
||||
if (!req.user) {
|
||||
return next()
|
||||
}
|
||||
|
@ -15,20 +29,25 @@ function useCapabilities() {
|
|||
// get the group policy applying to the user
|
||||
const groupPolicy =
|
||||
await ManagedUsersHandler.promises.getGroupPolicyForUser(req.user)
|
||||
const capabilitySet = getUserCapabilities(groupPolicy)
|
||||
req.assertPermission = capability => {
|
||||
if (!capabilitySet.has(capability)) {
|
||||
throw new ForbiddenError(
|
||||
`user does not have permission for ${capability}`
|
||||
)
|
||||
}
|
||||
// attach the new capabilities to the request object
|
||||
for (const cap of getUserCapabilities(groupPolicy)) {
|
||||
req.capabilitySet.add(cap)
|
||||
}
|
||||
// also attach the user's restrictions (the capabilities they don't have)
|
||||
req.userRestrictions = getUserRestrictions(groupPolicy)
|
||||
next()
|
||||
} catch (error) {
|
||||
next(error)
|
||||
if (error instanceof UserNotFoundError) {
|
||||
// the user is logged in but doesn't exist in the database
|
||||
// this can happen if the user has just deleted their account
|
||||
return next()
|
||||
} else {
|
||||
next(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that returns middleware to check if the user has permission to access a resource.
|
||||
* @param {[string]} requiredCapabilities - the capabilities required to access the resource.
|
||||
|
|
|
@ -238,6 +238,23 @@ function getUserCapabilities(groupPolicy) {
|
|||
return userCapabilities
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set of capabilities that a user does not have based on their group policy.
|
||||
*
|
||||
* @param {Object} groupPolicy - The group policy object to check.
|
||||
* @returns {Set} A set of capabilities that the user does not have, based on their group
|
||||
* policy.
|
||||
* @throws {Error} If the policy is unknown.
|
||||
*/
|
||||
function getUserRestrictions(groupPolicy) {
|
||||
const userCapabilities = getUserCapabilities(groupPolicy)
|
||||
const userRestrictions = getDefaultCapabilities()
|
||||
for (const capability of userCapabilities) {
|
||||
userRestrictions.delete(capability)
|
||||
}
|
||||
return userRestrictions
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a user has permission for a given capability based on their group
|
||||
* policy.
|
||||
|
@ -299,6 +316,7 @@ module.exports = {
|
|||
registerPolicy,
|
||||
hasPermission,
|
||||
getUserCapabilities,
|
||||
getUserRestrictions,
|
||||
getUserValidationStatus: callbackify(getUserValidationStatus),
|
||||
promises: { getUserValidationStatus },
|
||||
}
|
||||
|
|
|
@ -127,6 +127,7 @@ async function settingsPage(req, res) {
|
|||
personalAccessTokens,
|
||||
emailAddressLimit: Settings.emailAddressLimit,
|
||||
isManagedAccount: !!user.enrollment?.managedBy,
|
||||
userRestrictions: Array.from(req.userRestrictions || []),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -285,6 +285,7 @@ function initialize(webRouter, privateApiRouter, publicApiRouter) {
|
|||
webRouter.get(
|
||||
'/user/settings',
|
||||
AuthenticationController.requireLogin(),
|
||||
PermissionsController.useCapabilities(),
|
||||
UserPagesController.settingsPage
|
||||
)
|
||||
webRouter.post(
|
||||
|
|
|
@ -64,6 +64,9 @@ html(
|
|||
indexName : settings.templates.indexName
|
||||
})
|
||||
|
||||
each restriction in userRestrictions || []
|
||||
meta(name='ol-cannot-' + restriction data-type="boolean" content=true)
|
||||
|
||||
block head-scripts
|
||||
|
||||
body(ng-csp=(cspEnabled ? "no-unsafe-eval" : false) class=(showThinFooter ? 'thin-footer' : undefined))
|
||||
|
|
|
@ -171,6 +171,7 @@
|
|||
"confirm_primary_email_change": "",
|
||||
"conflicting_paths_found": "",
|
||||
"connected_users": "",
|
||||
"contact_group_admin": "",
|
||||
"contact_message_label": "",
|
||||
"contact_sales": "",
|
||||
"contact_support_to_change_group_subscription": "",
|
||||
|
|
|
@ -23,6 +23,11 @@ function EmailsSectionContent() {
|
|||
} = useUserEmailsContext()
|
||||
const userEmails = Object.values(userEmailsData.byId)
|
||||
|
||||
// Only show the "add email" button if the user has permission to add a secondary email
|
||||
const hideAddSecondaryEmail = getMeta(
|
||||
'ol-cannot-add-secondary-email'
|
||||
) as boolean
|
||||
|
||||
return (
|
||||
<>
|
||||
<h3>{t('emails_and_affiliations_title')}</h3>
|
||||
|
@ -57,7 +62,7 @@ function EmailsSectionContent() {
|
|||
</>
|
||||
)}
|
||||
{isInitializingSuccess && <LeaversSurveyAlert />}
|
||||
{isInitializingSuccess && <AddEmail />}
|
||||
{isInitializingSuccess && !hideAddSecondaryEmail && <AddEmail />}
|
||||
{isInitializingError && (
|
||||
<Alert bsStyle="danger" className="text-center">
|
||||
<Icon type="exclamation-triangle" fw />{' '}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { useState, useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import LeaveModal from './leave/modal'
|
||||
import getMeta from '../../../utils/meta'
|
||||
|
||||
function LeaveSection() {
|
||||
const { t } = useTranslation()
|
||||
|
@ -15,6 +16,15 @@ function LeaveSection() {
|
|||
setIsModalOpen(true)
|
||||
}, [])
|
||||
|
||||
// Prevent managed users deleting their own accounts
|
||||
if (getMeta('ol-cannot-delete-own-account')) {
|
||||
return (
|
||||
<>
|
||||
{t('need_to_leave')} {t('contact_group_admin')}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{t('need_to_leave')}{' '}
|
||||
|
|
|
@ -39,6 +39,25 @@ function LinkingSection() {
|
|||
|
||||
const hasIntegrationLinkingSection = allIntegrationLinkingWidgets.length
|
||||
const hasReferencesLinkingSection = referenceLinkingWidgets.length
|
||||
|
||||
// Filter out SSO providers that are not allowed to be linked by
|
||||
// managed users. Allow unlinking them if they are already linked.
|
||||
const hideGoogleSSO = getMeta('ol-cannot-link-google-sso')
|
||||
const hideOtherThirdPartySSO = getMeta('ol-cannot-link-other-third-party-sso')
|
||||
|
||||
for (const providerId in subscriptions) {
|
||||
const isLinked = subscriptions[providerId].linked
|
||||
if (providerId === 'google') {
|
||||
if (hideGoogleSSO && !isLinked) {
|
||||
delete subscriptions[providerId]
|
||||
}
|
||||
} else {
|
||||
if (hideOtherThirdPartySSO && !isLinked) {
|
||||
delete subscriptions[providerId]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const hasSSOLinkingSection = Object.keys(subscriptions).length > 0
|
||||
|
||||
if (
|
||||
|
|
|
@ -275,6 +275,7 @@
|
|||
"connected_users": "Connected Users",
|
||||
"connecting": "Connecting",
|
||||
"contact": "Contact",
|
||||
"contact_group_admin": "Please contact your group administrator.",
|
||||
"contact_message_label": "Message",
|
||||
"contact_sales": "Contact Sales",
|
||||
"contact_support_to_change_group_subscription": "Please <0>contact support</0> if you wish to change your group subscription.",
|
||||
|
|
Loading…
Reference in a new issue