mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-06-01 05:11:34 +02:00
* [web] `transfer-ownership` group audit log Includes `transfer-ownership` in the list of project audit logs visible to managed group admins, and adds logic to add multiple log entries when more than one managed group is involved. GitOrigin-RevId: 780b90a74a960047e97ebba83e5502a237b83b41
196 lines
6.3 KiB
JavaScript
196 lines
6.3 KiB
JavaScript
import { vi, expect } from 'vitest'
|
|
import mongodb from 'mongodb-legacy'
|
|
import sinon from 'sinon'
|
|
const modulePath =
|
|
'../../../../app/src/Features/Project/ProjectAuditLogHandler.mjs'
|
|
|
|
const { ObjectId } = mongodb
|
|
|
|
const projectId = new ObjectId()
|
|
const userId = new ObjectId()
|
|
const subscriptionId = new ObjectId()
|
|
const previousOwnerId = new ObjectId()
|
|
const newOwnerId = new ObjectId()
|
|
const subscriptionId2 = new ObjectId()
|
|
|
|
describe('ProjectAuditLogHandler', function (ctx) {
|
|
beforeEach(async function (ctx) {
|
|
ctx.createEntryMock = sinon.stub().resolves()
|
|
vi.doMock('../../../../app/src/models/ProjectAuditLogEntry', () => ({
|
|
ProjectAuditLogEntry: {
|
|
create: ctx.createEntryMock,
|
|
},
|
|
}))
|
|
|
|
ctx.getUniqueManagedSubscriptionMemberOfMock = sinon.stub().resolves()
|
|
vi.doMock(
|
|
'../../../../app/src/Features/Subscription/SubscriptionLocator.mjs',
|
|
() => ({
|
|
default: {
|
|
promises: {
|
|
getUniqueManagedSubscriptionMemberOf:
|
|
ctx.getUniqueManagedSubscriptionMemberOfMock,
|
|
},
|
|
},
|
|
})
|
|
)
|
|
|
|
ctx.ProjectAuditLogHandler = (await import(modulePath)).default
|
|
})
|
|
|
|
describe('addEntry', function () {
|
|
it('creates an entry in the database', async function (ctx) {
|
|
await ctx.ProjectAuditLogHandler.promises.addEntry(
|
|
projectId,
|
|
'project-op',
|
|
userId,
|
|
'0:0:0:0'
|
|
)
|
|
expect(ctx.createEntryMock).to.have.been.calledOnceWith({
|
|
operation: 'project-op',
|
|
projectId,
|
|
initiatorId: userId,
|
|
ipAddress: '0:0:0:0',
|
|
info: {},
|
|
})
|
|
})
|
|
|
|
it('does not include managedSubscriptionId when the user is not managed ', async function (ctx) {
|
|
await ctx.ProjectAuditLogHandler.promises.addEntry(
|
|
projectId,
|
|
'accept-invite', // this event logs managedSubscriptionId when available
|
|
userId,
|
|
'0:0:0:0'
|
|
)
|
|
expect(ctx.createEntryMock).not.to.have.been.calledWithMatch({
|
|
managedSubscriptionId: subscriptionId,
|
|
})
|
|
})
|
|
|
|
it('includes managedSubscriptionId when the user is managed ', async function (ctx) {
|
|
ctx.getUniqueManagedSubscriptionMemberOfMock.resolves({
|
|
_id: subscriptionId,
|
|
})
|
|
await ctx.ProjectAuditLogHandler.promises.addEntry(
|
|
projectId,
|
|
'accept-invite', // this event logs managedSubscriptionId when available
|
|
userId,
|
|
'0:0:0:0'
|
|
)
|
|
expect(ctx.createEntryMock).to.have.been.calledWithMatch({
|
|
managedSubscriptionId: subscriptionId.toString(),
|
|
})
|
|
})
|
|
|
|
it('does not include managedSubscriptionId when the user is managed, but the event is not of managed group interest', async function (ctx) {
|
|
ctx.getUniqueManagedSubscriptionMemberOfMock.resolves({
|
|
_id: subscriptionId,
|
|
})
|
|
await ctx.ProjectAuditLogHandler.promises.addEntry(
|
|
projectId,
|
|
'any-event',
|
|
userId,
|
|
'0:0:0:0'
|
|
)
|
|
expect(ctx.createEntryMock).not.to.have.been.calledWithMatch({
|
|
managedSubscriptionId: subscriptionId,
|
|
})
|
|
})
|
|
|
|
it('adds multiple entries when the log involves multiple group subscriptions', async function (ctx) {
|
|
ctx.getUniqueManagedSubscriptionMemberOfMock.onFirstCall().resolves({
|
|
_id: subscriptionId,
|
|
})
|
|
ctx.getUniqueManagedSubscriptionMemberOfMock.onSecondCall().resolves({
|
|
_id: subscriptionId2,
|
|
})
|
|
await ctx.ProjectAuditLogHandler.promises.addEntry(
|
|
projectId,
|
|
'transfer-ownership',
|
|
userId,
|
|
'0:0:0:0',
|
|
{ previousOwnerId, newOwnerId }
|
|
)
|
|
expect(ctx.createEntryMock).to.have.been.calledTwice
|
|
expect(ctx.createEntryMock).to.have.been.calledWithMatch({
|
|
managedSubscriptionId: subscriptionId.toString(),
|
|
})
|
|
expect(ctx.createEntryMock).to.have.been.calledWithMatch({
|
|
managedSubscriptionId: subscriptionId2.toString(),
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('addEntryIfManaged', function () {
|
|
describe('when the user is managed', function () {
|
|
beforeEach(function (ctx) {
|
|
ctx.getUniqueManagedSubscriptionMemberOfMock.resolves({
|
|
_id: subscriptionId,
|
|
})
|
|
})
|
|
|
|
it('adds an entry in the DB if the event is of interest of managed groups ', async function (ctx) {
|
|
await ctx.ProjectAuditLogHandler.promises.addEntryIfManaged(
|
|
projectId,
|
|
'accept-invite', // this event logs managedSubscriptionId when available
|
|
userId,
|
|
'0:0:0:0'
|
|
)
|
|
expect(ctx.createEntryMock).to.have.been.calledOnceWith({
|
|
operation: 'accept-invite',
|
|
projectId,
|
|
initiatorId: userId,
|
|
ipAddress: '0:0:0:0',
|
|
info: {},
|
|
managedSubscriptionId: subscriptionId.toString(),
|
|
})
|
|
})
|
|
|
|
it('does not add an entry in the DB when the event is not of interest of managed groups ', async function (ctx) {
|
|
await ctx.ProjectAuditLogHandler.promises.addEntryIfManaged(
|
|
projectId,
|
|
'foo',
|
|
userId,
|
|
'0:0:0:0'
|
|
)
|
|
expect(ctx.createEntryMock).not.to.have.been.called
|
|
})
|
|
})
|
|
|
|
describe('when the user is not managed', function () {
|
|
it('does not add an entry in the DB ', async function (ctx) {
|
|
await ctx.ProjectAuditLogHandler.promises.addEntryIfManaged(
|
|
projectId,
|
|
'accept-invite', // this event logs managedSubscriptionId when available
|
|
userId,
|
|
'0:0:0:0'
|
|
)
|
|
expect(ctx.createEntryMock).not.to.have.been.called
|
|
})
|
|
})
|
|
|
|
it('adds multiple entries when the log involves multiple group subscriptions', async function (ctx) {
|
|
ctx.getUniqueManagedSubscriptionMemberOfMock.onFirstCall().resolves({
|
|
_id: subscriptionId,
|
|
})
|
|
ctx.getUniqueManagedSubscriptionMemberOfMock.onSecondCall().resolves({
|
|
_id: subscriptionId2,
|
|
})
|
|
await ctx.ProjectAuditLogHandler.promises.addEntryIfManaged(
|
|
projectId,
|
|
'transfer-ownership',
|
|
userId,
|
|
'0:0:0:0',
|
|
{ previousOwnerId, newOwnerId }
|
|
)
|
|
expect(ctx.createEntryMock).to.have.been.calledTwice
|
|
expect(ctx.createEntryMock).to.have.been.calledWithMatch({
|
|
managedSubscriptionId: subscriptionId.toString(),
|
|
})
|
|
expect(ctx.createEntryMock).to.have.been.calledWithMatch({
|
|
managedSubscriptionId: subscriptionId2.toString(),
|
|
})
|
|
})
|
|
})
|
|
})
|