From 3b60d050741d0eedf4f738023eb1b921b2b41422 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Tue, 27 Jun 2023 11:01:59 +0100 Subject: [PATCH] Merge pull request #13536 from overleaf/bg-implement-managed-users-policy add missing review comment changes from backend support for managed users GitOrigin-RevId: 31eab361844da3bb2c46d745127a6aa413c3e242 --- .../Subscription/ManagedUsersHandler.js | 42 ++++++++++++++++++- .../acceptance/src/helpers/Subscription.js | 9 ++++ .../web/test/acceptance/src/helpers/User.js | 8 ---- 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/services/web/app/src/Features/Subscription/ManagedUsersHandler.js b/services/web/app/src/Features/Subscription/ManagedUsersHandler.js index 6d5b3e073c..1380397b7b 100644 --- a/services/web/app/src/Features/Subscription/ManagedUsersHandler.js +++ b/services/web/app/src/Features/Subscription/ManagedUsersHandler.js @@ -1,7 +1,9 @@ const { callbackify } = require('util') const { Subscription } = require('../../models/Subscription') const { GroupPolicy } = require('../../models/GroupPolicy') +const { User } = require('../../models/User') const ManagedUsersPolicy = require('./ManagedUsersPolicy') +const OError = require('@overleaf/o-error') /** * This module contains functions for handling managed users in a @@ -42,21 +44,59 @@ async function getGroupPolicyForUser(user) { if (user.enrollment?.managedBy == null) { return } + // retrieve the subscription and the group policy (without the _id field) const subscription = await Subscription.findById(user.enrollment.managedBy) .populate('groupPolicy', '-_id') .exec() - // return the group policy as a plain object without the _id and __v field + // return the group policy as a plain object (without the __v field) const groupPolicy = subscription?.groupPolicy.toObject({ versionKey: false, }) return groupPolicy } +async function enrollInSubscription(userId, subscription) { + // check whether the user is already enrolled in a subscription + const user = await User.findOne({ + _id: userId, + 'enrollment.managedBy': { $exists: true }, + }).exec() + if (user != null) { + throw new OError('User is already enrolled in a subscription', { + userId, + subscriptionId: subscription._id, + }) + } + // update the user to be enrolled in the subscription + const updatedUser = await User.findOneAndUpdate( + { _id: userId, 'enrollment.managedBy': { $exists: false } }, + { + enrollment: { + managedBy: subscription._id, + enrolledAt: new Date(), + }, + }, + { new: true } + ).exec() + // check whether the enrollment succeeded + if ( + !updatedUser || + !subscription.equals(updatedUser?.enrollment?.managedBy) + ) { + throw new OError('Failed to enroll user in subscription', { + userId, + subscriptionId: subscription._id, + }) + } +} + module.exports = { promises: { enableManagedUsers, getGroupPolicyForUser, + enrollInSubscription, }, enableManagedUsers: callbackify(enableManagedUsers), getGroupPolicyForUser: callbackify(getGroupPolicyForUser), + enrollInSubscription: callbackify(enrollInSubscription), } diff --git a/services/web/test/acceptance/src/helpers/Subscription.js b/services/web/test/acceptance/src/helpers/Subscription.js index 290356b307..2da569e7fc 100644 --- a/services/web/test/acceptance/src/helpers/Subscription.js +++ b/services/web/test/acceptance/src/helpers/Subscription.js @@ -68,6 +68,15 @@ class Subscription { ManagedUsersHandler.getGroupPolicyForUser(user, callback) } + enrollManagedUser(user, callback) { + SubscriptionModel.findById(this._id).exec((error, subscription) => { + if (error) { + return callback(error) + } + ManagedUsersHandler.enrollInSubscription(user._id, subscription, callback) + }) + } + expectDeleted(deleterData, callback) { DeletedSubscriptionModel.find( { 'subscription._id': this._id }, diff --git a/services/web/test/acceptance/src/helpers/User.js b/services/web/test/acceptance/src/helpers/User.js index 3b5db84efa..0409669727 100644 --- a/services/web/test/acceptance/src/helpers/User.js +++ b/services/web/test/acceptance/src/helpers/User.js @@ -205,14 +205,6 @@ class User { ) } - enrollInSubscription(subscription, callback) { - UserModel.updateOne( - { _id: this.id }, - { 'enrollment.managedBy': subscription._id }, - callback - ) - } - logout(callback) { this.getCsrfToken(error => { if (error != null) {