backend: enhance bulk room and recording deletion logic to check for permissions on each item to delete
This commit is contained in:
parent
5fe71482f7
commit
f2a84717e5
@ -4,6 +4,7 @@ import { EgressStatus, EncodedFileOutput, EncodedFileType, RoomCompositeOptions
|
||||
import ms from 'ms';
|
||||
import { Readable } from 'stream';
|
||||
import { uid } from 'uid';
|
||||
import { container } from '../config/dependency-injector.config.js';
|
||||
import { INTERNAL_CONFIG } from '../config/internal-config.js';
|
||||
import { MEET_ENV } from '../environment.js';
|
||||
import { RecordingHelper } from '../helpers/recording.helper.js';
|
||||
@ -32,6 +33,7 @@ import { LiveKitService } from './livekit.service.js';
|
||||
import { LoggerService } from './logger.service.js';
|
||||
import { MutexService, RedisLock } from './mutex.service.js';
|
||||
import { RequestSessionService } from './request-session.service.js';
|
||||
import { RoomService } from './room.service.js';
|
||||
import { BlobStorageService } from './storage/blob-storage.service.js';
|
||||
|
||||
@injectable()
|
||||
@ -282,15 +284,17 @@ export class RecordingService {
|
||||
recordingIds: string[],
|
||||
roomId?: string
|
||||
): Promise<{ deleted: string[]; failed: { recordingId: string; error: string }[] }> {
|
||||
const roomService = container.get(RoomService);
|
||||
|
||||
const validRecordingIds: Set<string> = new Set<string>();
|
||||
const deletedRecordings: Set<string> = new Set<string>();
|
||||
const failedRecordings: Set<{ recordingId: string; error: string }> = new Set();
|
||||
|
||||
for (const recordingId of recordingIds) {
|
||||
const { roomId: recRoomId } = RecordingHelper.extractInfoFromRecordingId(recordingId);
|
||||
|
||||
// If a roomId is provided, only process recordings from that room
|
||||
if (roomId) {
|
||||
const { roomId: recRoomId } = RecordingHelper.extractInfoFromRecordingId(recordingId);
|
||||
|
||||
if (recRoomId !== roomId) {
|
||||
this.logger.warn(`Skipping recording '${recordingId}' as it does not belong to room '${roomId}'`);
|
||||
failedRecordings.add({
|
||||
@ -299,6 +303,18 @@ export class RecordingService {
|
||||
});
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// Check room member permissions for each recording if no roomId filter is applied
|
||||
const permissions = await roomService.getAuthenticatedRoomMemberPermissions(recRoomId);
|
||||
|
||||
if (!permissions.canDeleteRecordings) {
|
||||
this.logger.warn(`Insufficient permissions to delete recording '${recordingId}'`);
|
||||
failedRecordings.add({
|
||||
recordingId,
|
||||
error: `Insufficient permissions to delete recording '${recordingId}'`
|
||||
});
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@ -27,6 +27,7 @@ import { MEET_ENV } from '../environment.js';
|
||||
import { MeetRoomHelper } from '../helpers/room.helper.js';
|
||||
import {
|
||||
errorDeletingRoom,
|
||||
errorInsufficientPermissions,
|
||||
errorRoomActiveMeeting,
|
||||
errorRoomNotFound,
|
||||
internalError,
|
||||
@ -328,7 +329,7 @@ export class RoomService {
|
||||
|
||||
/**
|
||||
* Retrieves a list of rooms based on the provided filtering, pagination, and sorting options.
|
||||
*
|
||||
*
|
||||
* If the request is made by an authenticated user, access is determined by the user's role:
|
||||
* - ADMIN: Can see all rooms
|
||||
* - USER: Can see rooms they own or are members of
|
||||
@ -716,6 +717,17 @@ export class RoomService {
|
||||
const roomId = typeof room === 'string' ? room : room.roomId;
|
||||
|
||||
try {
|
||||
const user = this.requestSessionService.getAuthenticatedUser();
|
||||
|
||||
// Check permissions if user is authenticated and not an admin
|
||||
if (user && user.role !== MeetUserRole.ADMIN) {
|
||||
const isOwner = await this.isRoomOwner(roomId, user.userId);
|
||||
|
||||
if (!isOwner) {
|
||||
throw errorInsufficientPermissions();
|
||||
}
|
||||
}
|
||||
|
||||
let result;
|
||||
|
||||
if (typeof room === 'string') {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user