mirror of
https://github.com/overleaf/overleaf.git
synced 2024-12-28 20:42:37 +00:00
Merge pull request #14106 from overleaf/ab-ab-group-settings-admin-only
[web] Restrict group settings page and managed users activation to group admin GitOrigin-RevId: 97235d3e78d97d9c367ce7de70072607f15d98f0
This commit is contained in:
parent
d981ac2279
commit
d2d2386441
4 changed files with 46 additions and 62 deletions
|
@ -138,8 +138,8 @@ async function plansPage(req, res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("express").Request} req
|
* @param {import('express').Request} req
|
||||||
* @param {import("express").Response} res
|
* @param {import('express').Response} res
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async function paymentPage(req, res) {
|
async function paymentPage(req, res) {
|
||||||
|
@ -208,8 +208,8 @@ function formatGroupPlansDataForDash() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("express").Request} req
|
* @param {import('express').Request} req
|
||||||
* @param {import("express").Response} res
|
* @param {import('express').Response} res
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async function userSubscriptionPage(req, res) {
|
async function userSubscriptionPage(req, res) {
|
||||||
|
@ -246,9 +246,13 @@ async function userSubscriptionPage(req, res) {
|
||||||
|
|
||||||
const groupPlansDataForDash = formatGroupPlansDataForDash()
|
const groupPlansDataForDash = formatGroupPlansDataForDash()
|
||||||
|
|
||||||
|
// display the Group Settings button only to admins of group subscriptions with the Managed Users feature available
|
||||||
const groupSettingsEnabledFor = (managedGroupSubscriptions || [])
|
const groupSettingsEnabledFor = (managedGroupSubscriptions || [])
|
||||||
.filter(subscription =>
|
.filter(
|
||||||
ManagedUsersManager.hasManagedUsersFeature(subscription)
|
subscription =>
|
||||||
|
ManagedUsersManager.hasManagedUsersFeature(subscription) &&
|
||||||
|
(subscription.admin_id._id || subscription.admin_id).toString() ===
|
||||||
|
user._id.toString()
|
||||||
)
|
)
|
||||||
.map(subscription => subscription._id.toString())
|
.map(subscription => subscription._id.toString())
|
||||||
|
|
||||||
|
@ -399,8 +403,8 @@ async function createSubscription(req, res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("express").Request} req
|
* @param {import('express').Request} req
|
||||||
* @param {import("express").Response} res
|
* @param {import('express').Response} res
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async function successfulSubscription(req, res) {
|
async function successfulSubscription(req, res) {
|
||||||
|
@ -440,9 +444,9 @@ function cancelSubscription(req, res, next) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("express").Request} req
|
* @param {import('express').Request} req
|
||||||
* @param {import("express").Response} res
|
* @param {import('express').Response} res
|
||||||
* @param {import("express").NextFunction} next
|
* @param {import('express').NextFunction} next
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
function canceledSubscription(req, res, next) {
|
function canceledSubscription(req, res, next) {
|
||||||
|
|
|
@ -17,19 +17,12 @@ const UserMembershipAuthorization = {
|
||||||
if (!req.entity) {
|
if (!req.entity) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return req.entity[req.entityConfig.fields.access].some(accessUserId =>
|
const fieldAccess = req.entity[req.entityConfig.fields.access]
|
||||||
accessUserId.equals(req.user._id)
|
const fieldAccessArray = Array.isArray(fieldAccess)
|
||||||
)
|
? fieldAccess
|
||||||
}
|
: [fieldAccess.toString()]
|
||||||
},
|
return fieldAccessArray.some(
|
||||||
|
accessUserId => accessUserId.toString() === req.user._id.toString()
|
||||||
isEntityMember() {
|
|
||||||
return req => {
|
|
||||||
if (!req.entity) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return req.entity[req.entityConfig.fields.membership].some(accessUserId =>
|
|
||||||
accessUserId.equals(req.user._id)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,19 +14,6 @@ module.exports = {
|
||||||
baseQuery: {
|
baseQuery: {
|
||||||
groupPlan: true,
|
groupPlan: true,
|
||||||
},
|
},
|
||||||
translations: {
|
|
||||||
title: 'group_subscription',
|
|
||||||
subtitle: 'members_management',
|
|
||||||
remove: 'remove_from_group',
|
|
||||||
},
|
|
||||||
pathsFor(id) {
|
|
||||||
return {
|
|
||||||
addMember: `/manage/groups/${id}/invites`,
|
|
||||||
removeMember: `/manage/groups/${id}/user`,
|
|
||||||
removeInvite: `/manage/groups/${id}/invites`,
|
|
||||||
exportMembers: `/manage/groups/${id}/members/export`,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
team: {
|
team: {
|
||||||
|
@ -54,16 +41,20 @@ module.exports = {
|
||||||
baseQuery: {
|
baseQuery: {
|
||||||
groupPlan: true,
|
groupPlan: true,
|
||||||
},
|
},
|
||||||
translations: {
|
},
|
||||||
title: 'group_subscription',
|
|
||||||
subtitle: 'managers_management',
|
groupAdmin: {
|
||||||
remove: 'remove_manager',
|
modelName: 'Subscription',
|
||||||
|
fields: {
|
||||||
|
primaryKey: '_id',
|
||||||
|
read: ['admin_id'],
|
||||||
|
write: 'admin_id',
|
||||||
|
access: 'admin_id',
|
||||||
|
membership: 'admin_id',
|
||||||
|
name: 'teamName',
|
||||||
},
|
},
|
||||||
pathsFor(id) {
|
baseQuery: {
|
||||||
return {
|
groupPlan: true,
|
||||||
addMember: `/manage/groups/${id}/managers`,
|
|
||||||
removeMember: `/manage/groups/${id}/managers`,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -77,16 +68,9 @@ module.exports = {
|
||||||
membership: 'member_ids',
|
membership: 'member_ids',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
},
|
},
|
||||||
translations: {
|
|
||||||
title: 'institution_account',
|
|
||||||
subtitle: 'managers_management',
|
|
||||||
remove: 'remove_manager',
|
|
||||||
},
|
|
||||||
pathsFor(id) {
|
pathsFor(id) {
|
||||||
return {
|
return {
|
||||||
index: `/manage/institutions/${id}/managers`,
|
index: `/manage/institutions/${id}/managers`,
|
||||||
addMember: `/manage/institutions/${id}/managers`,
|
|
||||||
removeMember: `/manage/institutions/${id}/managers`,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -101,16 +85,9 @@ module.exports = {
|
||||||
membership: 'member_ids',
|
membership: 'member_ids',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
},
|
},
|
||||||
translations: {
|
|
||||||
title: 'publisher_account',
|
|
||||||
subtitle: 'managers_management',
|
|
||||||
remove: 'remove_manager',
|
|
||||||
},
|
|
||||||
pathsFor(id) {
|
pathsFor(id) {
|
||||||
return {
|
return {
|
||||||
index: `/manage/publishers/${id}/managers`,
|
index: `/manage/publishers/${id}/managers`,
|
||||||
addMember: `/manage/publishers/${id}/managers`,
|
|
||||||
removeMember: `/manage/publishers/${id}/managers`,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -64,6 +64,17 @@ const UserMembershipMiddleware = {
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
requireGroupAdminAccess: [
|
||||||
|
AuthenticationController.requireLogin(),
|
||||||
|
fetchEntityConfig('groupAdmin'),
|
||||||
|
fetchEntity(),
|
||||||
|
requireEntity(),
|
||||||
|
allowAccessIfAny([
|
||||||
|
UserMembershipAuthorization.hasEntityAccess(),
|
||||||
|
UserMembershipAuthorization.hasStaffAccess('groupManagement'),
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
|
||||||
requireInstitutionMetricsAccess: [
|
requireInstitutionMetricsAccess: [
|
||||||
AuthenticationController.requireLogin(),
|
AuthenticationController.requireLogin(),
|
||||||
fetchEntityConfig('institution'),
|
fetchEntityConfig('institution'),
|
||||||
|
@ -222,12 +233,11 @@ function fetchEntityConfig(entityName) {
|
||||||
// fetch the entity with id and config, and set it in the request
|
// fetch the entity with id and config, and set it in the request
|
||||||
function fetchEntity() {
|
function fetchEntity() {
|
||||||
return expressify(async (req, res, next) => {
|
return expressify(async (req, res, next) => {
|
||||||
const entity =
|
req.entity =
|
||||||
await UserMembershipHandler.promises.getEntityWithoutAuthorizationCheck(
|
await UserMembershipHandler.promises.getEntityWithoutAuthorizationCheck(
|
||||||
req.params.id,
|
req.params.id,
|
||||||
req.entityConfig
|
req.entityConfig
|
||||||
)
|
)
|
||||||
req.entity = entity
|
|
||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue