mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-14 14:13:43 +01:00
Merge pull request #24357 from overleaf/em-reviewers-limit
Count reviewers towards the collaborator limit in the backend GitOrigin-RevId: 352fa37023ffbb032e23a474a81897ca871fee69
This commit is contained in:
@@ -14,7 +14,6 @@ import { hasAdminAccess } from '../Helpers/AdminAuthorizationHelper.js'
|
||||
import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.js'
|
||||
import ProjectAuditLogHandler from '../Project/ProjectAuditLogHandler.js'
|
||||
import LimitationsManager from '../Subscription/LimitationsManager.js'
|
||||
import PrivilegeLevels from '../Authorization/PrivilegeLevels.js'
|
||||
|
||||
const ObjectId = mongodb.ObjectId
|
||||
|
||||
@@ -80,17 +79,20 @@ async function setCollaboratorInfo(req, res, next) {
|
||||
const userId = req.params.user_id
|
||||
const { privilegeLevel } = req.body
|
||||
|
||||
if (privilegeLevel !== PrivilegeLevels.READ_ONLY) {
|
||||
const allowed =
|
||||
await LimitationsManager.promises.canAddXEditCollaborators(projectId, 1)
|
||||
if (!allowed) {
|
||||
return HttpErrorHandler.forbidden(
|
||||
req,
|
||||
res,
|
||||
'edit collaborator limit reached'
|
||||
)
|
||||
}
|
||||
const allowed =
|
||||
await LimitationsManager.promises.canChangeCollaboratorPrivilegeLevel(
|
||||
projectId,
|
||||
userId,
|
||||
privilegeLevel
|
||||
)
|
||||
if (!allowed) {
|
||||
return HttpErrorHandler.forbidden(
|
||||
req,
|
||||
res,
|
||||
'edit collaborator limit reached'
|
||||
)
|
||||
}
|
||||
|
||||
await CollaboratorsHandler.promises.setCollaboratorPrivilegeLevel(
|
||||
projectId,
|
||||
userId,
|
||||
|
||||
@@ -128,12 +128,13 @@ async function getMemberIdPrivilegeLevel(userId, projectId) {
|
||||
}
|
||||
|
||||
async function getInvitedEditCollaboratorCount(projectId) {
|
||||
// Only counts invited members with readAndWrite privilege
|
||||
// Counts invited members with editor or reviewer roles
|
||||
const members = await getMemberIdsWithPrivilegeLevels(projectId)
|
||||
return members.filter(
|
||||
m =>
|
||||
m.source === Sources.INVITE &&
|
||||
m.privilegeLevel === PrivilegeLevels.READ_AND_WRITE
|
||||
(m.privilegeLevel === PrivilegeLevels.READ_AND_WRITE ||
|
||||
m.privilegeLevel === PrivilegeLevels.REVIEW)
|
||||
).length
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// @ts-check
|
||||
|
||||
const logger = require('@overleaf/logger')
|
||||
const ProjectGetter = require('../Project/ProjectGetter')
|
||||
const UserGetter = require('../User/UserGetter')
|
||||
@@ -5,6 +7,7 @@ const SubscriptionLocator = require('./SubscriptionLocator')
|
||||
const Settings = require('@overleaf/settings')
|
||||
const CollaboratorsGetter = require('../Collaborators/CollaboratorsGetter')
|
||||
const CollaboratorsInvitesGetter = require('../Collaborators/CollaboratorsInviteGetter')
|
||||
const PrivilegeLevels = require('../Authorization/PrivilegeLevels')
|
||||
const {
|
||||
callbackify,
|
||||
callbackifyMultiResult,
|
||||
@@ -58,6 +61,54 @@ async function canAddXEditCollaborators(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a collaborator can be switched to the given privilege level
|
||||
*
|
||||
* @param {string} projectId
|
||||
* @param {string} userId
|
||||
* @param {'readOnly' | 'review' | 'readAndWrite'} privilegeLevel
|
||||
* @return {Promise<boolean>}
|
||||
*/
|
||||
async function canChangeCollaboratorPrivilegeLevel(
|
||||
projectId,
|
||||
userId,
|
||||
privilegeLevel
|
||||
) {
|
||||
if (privilegeLevel === PrivilegeLevels.READ_ONLY) {
|
||||
return true
|
||||
}
|
||||
|
||||
const currentPrivilegeLevel =
|
||||
await CollaboratorsGetter.promises.getMemberIdPrivilegeLevel(
|
||||
userId,
|
||||
projectId
|
||||
)
|
||||
if (
|
||||
[PrivilegeLevels.READ_AND_WRITE, PrivilegeLevels.REVIEW].includes(
|
||||
currentPrivilegeLevel
|
||||
)
|
||||
) {
|
||||
// Current collaborator already takes a slot, so changing the privilege
|
||||
// level won't increase the collaborator count
|
||||
return true
|
||||
}
|
||||
|
||||
const allowedNumber = await allowedNumberOfCollaboratorsInProject(projectId)
|
||||
if (allowedNumber < 0) {
|
||||
// -1 means unlimited
|
||||
return true
|
||||
}
|
||||
|
||||
const slotsTaken =
|
||||
await CollaboratorsGetter.promises.getInvitedEditCollaboratorCount(
|
||||
projectId
|
||||
)
|
||||
const inviteCount =
|
||||
await CollaboratorsInvitesGetter.promises.getEditInviteCount(projectId)
|
||||
|
||||
return slotsTaken + inviteCount < allowedNumber
|
||||
}
|
||||
|
||||
async function hasPaidSubscription(user) {
|
||||
const { hasSubscription, subscription } = await userHasSubscription(user)
|
||||
const { isMember } = await userIsMemberOfGroupSubscription(user)
|
||||
@@ -122,6 +173,9 @@ const LimitationsManager = {
|
||||
allowedNumberOfCollaboratorsForUser
|
||||
),
|
||||
canAddXEditCollaborators: callbackify(canAddXEditCollaborators),
|
||||
canChangeCollaboratorPrivilegeLevel: callbackify(
|
||||
canChangeCollaboratorPrivilegeLevel
|
||||
),
|
||||
hasPaidSubscription: callbackifyMultiResult(hasPaidSubscription, [
|
||||
'hasPaidSubscription',
|
||||
'subscription',
|
||||
@@ -150,6 +204,7 @@ const LimitationsManager = {
|
||||
allowedNumberOfCollaboratorsForUser,
|
||||
canAcceptEditCollaboratorInvite,
|
||||
canAddXEditCollaborators,
|
||||
canChangeCollaboratorPrivilegeLevel,
|
||||
hasPaidSubscription,
|
||||
userHasSubscriptionOrIsGroupMember,
|
||||
userHasSubscription,
|
||||
|
||||
Reference in New Issue
Block a user