Merge pull request #10637 from overleaf/bg-delete-user-from-dropbox

delete user data from dropbox

GitOrigin-RevId: d586c73b4500f4fe718927f537ae770356eaefc1
This commit is contained in:
Brian Gough 2022-11-28 14:37:49 +00:00 committed by Copybot
parent 12885bc9ec
commit 4589a57774
5 changed files with 54 additions and 0 deletions

View file

@ -12,6 +12,7 @@ const SubscriptionLocator = require('../Subscription/SubscriptionLocator')
const UserMembershipsHandler = require('../UserMembership/UserMembershipsHandler')
const UserSessionsManager = require('./UserSessionsManager')
const InstitutionsAPI = require('../Institutions/InstitutionsAPI')
const Modules = require('../../infrastructure/Modules')
const Errors = require('../Errors/Errors')
module.exports = {
@ -42,6 +43,7 @@ async function deleteUser(userId, options = {}) {
await ensureCanDeleteUser(user)
await _cleanupUser(user)
await Modules.promises.hooks.fire('deleteUser', userId)
await _createDeletedUser(user, options)
await ProjectDeleter.promises.deleteUsersProjects(user._id)
await deleteMongoUser(user._id)
@ -63,6 +65,7 @@ async function deleteMongoUser(userId) {
}
async function expireDeletedUser(userId) {
await Modules.promises.hooks.fire('expireDeletedUser', userId)
const deletedUser = await DeletedUser.findOne({
'deleterData.deletedUserId': userId,
}).exec()

View file

@ -141,6 +141,11 @@ function attachHook(name, method) {
}
function fireHook(name, ...rest) {
// ensure that modules are loaded if we need to fire a hook
// this can happen if a script calls a method that fires a hook
if (!_modulesLoaded) {
loadModules()
}
const adjustedLength = Math.max(rest.length, 1)
const args = rest.slice(0, adjustedLength - 1)
const callback = rest[adjustedLength - 1]

View file

@ -13,6 +13,7 @@ const MockSpellingApi = require('./mocks/MockSpellingApi')
const MockV1Api = require('./mocks/MockV1Api')
const MockV1HistoryApi = require('./mocks/MockV1HistoryApi')
const MockHaveIBeenPwnedApi = require('./mocks/MockHaveIBeenPwnedApi')
const MockThirdPartyDataStoreApi = require('./mocks/MockThirdPartyDataStoreApi')
const mockOpts = {
debug: ['1', 'true', 'TRUE'].includes(process.env.DEBUG_MOCKS),
@ -32,4 +33,5 @@ if (Features.hasFeature('saas')) {
MockProjectHistoryApi.initialize(23054, mockOpts)
MockV1Api.initialize(25000, mockOpts)
MockV1HistoryApi.initialize(23100, mockOpts)
MockThirdPartyDataStoreApi.initialize(23002, mockOpts)
}

View file

@ -0,0 +1,23 @@
const AbstractMockApi = require('./AbstractMockApi')
class MockThirdPartyDataStoreApi extends AbstractMockApi {
reset() {}
deleteUser(req, res) {
res.sendStatus(200)
}
applyRoutes() {
this.app.delete('/user/:user_id', (req, res) => this.deleteUser(req, res))
}
}
module.exports = MockThirdPartyDataStoreApi
// type hint for the inherited `instance` method
/**
* @function instance
* @memberOf MockThirdPartyDataStoreApi
* @static
* @returns {MockThirdPartyDataStoreApi}
*/

View file

@ -88,6 +88,10 @@ describe('UserDeleter', function () {
deleteMany: sinon.stub().returns({ exec: sinon.stub().resolves() }),
}
this.Modules = {
promises: { hooks: { fire: sinon.stub().resolves() } },
}
this.UserDeleter = SandboxedModule.require(modulePath, {
requires: {
'../../models/User': { User },
@ -103,6 +107,7 @@ describe('UserDeleter', function () {
'../../models/UserAuditLogEntry': {
UserAuditLogEntry: this.UserAuditLogEntry,
},
'../../infrastructure/Modules': this.Modules,
},
})
})
@ -194,6 +199,14 @@ describe('UserDeleter', function () {
).to.have.been.calledWith(this.userId)
})
it('should fire the deleteUser hook for modules', async function () {
await this.UserDeleter.promises.deleteUser(this.userId)
expect(this.Modules.promises.hooks.fire).to.have.been.calledWith(
'deleteUser',
this.userId
)
})
it('should stop the user sessions', async function () {
await this.UserDeleter.promises.deleteUser(this.userId)
expect(
@ -488,6 +501,14 @@ describe('UserDeleter', function () {
this.mockedDeletedUser.verify()
})
it('should fire the expireDeletedUser hook for modules', async function () {
await this.UserDeleter.promises.expireDeletedUser('giraffe')
expect(this.Modules.promises.hooks.fire).to.have.been.calledWith(
'expireDeletedUser',
'giraffe'
)
})
describe('when called as a callback', function () {
it('should expire the user', function (done) {
this.UserDeleter.expireDeletedUser('giraffe', err => {