Skip to content

Commit 27de25d

Browse files
authored
Merge pull request #209 from import-ai/refactor/namespaces
refactor(namespaces): add getAllSubResourcesByUser
2 parents cc300b7 + 4d95ee3 commit 27de25d

File tree

4 files changed

+85
-71
lines changed

4 files changed

+85
-71
lines changed

src/namespace-resources/namespace-resources.service.ts

Lines changed: 64 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ import { MinioService } from 'omniboxd/minio/minio.service';
2727
import { WizardTaskService } from 'omniboxd/tasks/wizard-task.service';
2828
import { PermissionsService } from 'omniboxd/permissions/permissions.service';
2929
import { PrivateSearchResourceDto } from 'omniboxd/wizard/dto/agent-request.dto';
30-
import { ResourcePermission } from 'omniboxd/permissions/resource-permission.enum';
30+
import {
31+
comparePermission,
32+
ResourcePermission,
33+
} from 'omniboxd/permissions/resource-permission.enum';
3134
import { Response } from 'express';
3235
import { ResourceDto, SpaceType } from './dto/resource.dto';
3336
import { Namespace } from 'omniboxd/namespaces/entities/namespace.entity';
@@ -401,40 +404,49 @@ export class NamespaceResourcesService {
401404
namespaceId,
402405
resourceId,
403406
);
404-
return await this.getSubResourcesByParents(namespaceId, parents, userId);
407+
const subResources = await this.resourcesService.getSubResources(
408+
namespaceId,
409+
[resourceId],
410+
);
411+
const permissionMap = await this.permissionsService.getCurrentPermissions(
412+
userId,
413+
namespaceId,
414+
[...parents, ...subResources],
415+
);
416+
return subResources.filter((res) => {
417+
const permission = permissionMap.get(res.id);
418+
return (
419+
permission &&
420+
comparePermission(permission, ResourcePermission.CAN_VIEW) >= 0
421+
);
422+
});
405423
}
406424

407-
async getSubResourcesByParents(
408-
namespaceId: string,
409-
parents: ResourceMetaDto[],
425+
async getAllSubResourcesByUser(
410426
userId: string,
427+
namespaceId: string,
428+
resourceId: string,
411429
): Promise<ResourceMetaDto[]> {
412-
if (!parents) {
413-
return [];
414-
}
415-
const permission = await this.permissionsService.getCurrentPermission(
430+
const parents = await this.resourcesService.getParentResourcesOrFail(
416431
namespaceId,
417-
parents,
432+
resourceId,
433+
);
434+
const allSubResources = await this.resourcesService.getAllSubResources(
435+
namespaceId,
436+
[resourceId],
437+
);
438+
const permissionMap = await this.permissionsService.getCurrentPermissions(
418439
userId,
440+
namespaceId,
441+
[...parents, ...allSubResources],
419442
);
420-
if (permission === ResourcePermission.NO_ACCESS) {
421-
return [];
422-
}
423-
const children = await this.resourcesService.getSubResources(namespaceId, [
424-
parents[0].id,
425-
]);
426-
const filteredChildren: ResourceMetaDto[] = [];
427-
for (const child of children) {
428-
const permission = await this.permissionsService.getCurrentPermission(
429-
namespaceId,
430-
[child, ...parents],
431-
userId,
443+
return allSubResources.filter((res) => {
444+
const permission = permissionMap.get(res.id);
445+
return (
446+
permission &&
447+
comparePermission(permission, ResourcePermission.CAN_VIEW) >= 0
432448
);
433-
if (permission !== ResourcePermission.NO_ACCESS) {
434-
filteredChildren.push(child);
435-
}
436-
}
437-
return filteredChildren;
449+
});
438450
}
439451

440452
async listChildren(
@@ -446,42 +458,45 @@ export class NamespaceResourcesService {
446458
namespaceId,
447459
resourceId,
448460
);
449-
const children = await this.resourcesService.getSubResources(namespaceId, [
461+
let children = await this.resourcesService.getSubResources(namespaceId, [
450462
resourceId,
451463
]);
452-
const subChildren = await this.resourcesService.getSubResources(
464+
let subChildren = await this.resourcesService.getSubResources(
453465
namespaceId,
454466
children.map((child) => child.id),
455467
);
456-
const resources = [...parents, ...children, ...subChildren];
457468
const permissionMap = await this.permissionsService.getCurrentPermissions(
458469
userId,
459470
namespaceId,
460-
resources,
471+
[...parents, ...children, ...subChildren],
461472
);
462473

474+
children = children.filter((res) => {
475+
const permission = permissionMap.get(res.id);
476+
return (
477+
permission &&
478+
comparePermission(permission, ResourcePermission.CAN_VIEW) >= 0
479+
);
480+
});
481+
482+
subChildren = subChildren.filter((res) => {
483+
const permission = permissionMap.get(res.id);
484+
return (
485+
permission &&
486+
comparePermission(permission, ResourcePermission.CAN_VIEW) >= 0
487+
);
488+
});
489+
463490
const hasChildrenMap = new Map<string, boolean>();
464-
for (const subChild of subChildren) {
465-
if (!subChild.parentId) {
466-
continue;
467-
}
468-
const permission = permissionMap.get(subChild.id);
469-
if (!permission || permission === ResourcePermission.NO_ACCESS) {
470-
continue;
491+
for (const resource of subChildren) {
492+
if (resource.parentId) {
493+
hasChildrenMap.set(resource.parentId, true);
471494
}
472-
hasChildrenMap.set(subChild.parentId, true);
473495
}
474496

475-
const childrenDtos: ChildrenMetaDto[] = [];
476-
for (const child of children) {
477-
const permission = permissionMap.get(child.id);
478-
if (!permission || permission === ResourcePermission.NO_ACCESS) {
479-
continue;
480-
}
481-
const hasChildren = hasChildrenMap.get(child.id) || false;
482-
childrenDtos.push(new ChildrenMetaDto(child, hasChildren));
483-
}
484-
return childrenDtos;
497+
return children.map(
498+
(res) => new ChildrenMetaDto(res, !!hasChildrenMap.get(res.id)),
499+
);
485500
}
486501

487502
async getSpaceType(

src/resources/resources.service.ts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ export class ResourcesService {
8282
return resource;
8383
}
8484

85+
/**
86+
* Return the parents of a resource, including the resource itself.
87+
*/
8588
async getParentResources(
8689
namespaceId: string,
8790
resourceId: string | null,
@@ -134,17 +137,22 @@ export class ResourcesService {
134137

135138
async getAllSubResources(
136139
namespaceId: string,
137-
resourceId: string,
140+
parentIds: string[],
138141
): Promise<ResourceMetaDto[]> {
139-
const children = await this.getSubResources(namespaceId, [resourceId]);
140-
const allResources: ResourceMetaDto[] = [...children];
141-
142-
for (const child of children) {
143-
const subResources = await this.getAllSubResources(namespaceId, child.id);
144-
allResources.push(...subResources);
142+
const resourcesMap: Map<string, ResourceMetaDto> = new Map();
143+
while (parentIds.length > 0) {
144+
const resources = await this.getSubResources(namespaceId, parentIds);
145+
for (const resource of resources) {
146+
if (resourcesMap.has(resource.id)) {
147+
throw new UnprocessableEntityException(
148+
'Cycle detected in the resource tree',
149+
);
150+
}
151+
resourcesMap.set(resource.id, resource);
152+
}
153+
parentIds = resources.map((r) => r.id);
145154
}
146-
147-
return allResources;
155+
return [...resourcesMap.values()];
148156
}
149157

150158
async getAllResources(namespaceId: string): Promise<ResourceMetaDto[]> {
@@ -239,15 +247,7 @@ export class ResourcesService {
239247
}
240248

241249
if (props.parentId) {
242-
// Check if the parent belongs to the same namespace
243-
await this.getResourceMetaOrFail(
244-
namespaceId,
245-
props.parentId,
246-
entityManager,
247-
);
248-
249-
// Check if there are any cycles
250-
const parents = await this.getParentResources(
250+
const parents = await this.getParentResourcesOrFail(
251251
namespaceId,
252252
props.parentId,
253253
entityManager,

src/shared-resources/shared-resources.service.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,9 @@ export class SharedResourcesService {
7878
}
7979

8080
const subResources = share.allResources
81-
? await this.resourcesService.getAllSubResources(
82-
share.namespaceId,
81+
? await this.resourcesService.getAllSubResources(share.namespaceId, [
8382
rootResource.id,
84-
)
83+
])
8584
: [];
8685

8786
const allResources = [

src/wizard/stream.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ export class StreamService {
239239
for (const resource of resources) {
240240
if (resource.type === 'folder') {
241241
const resources =
242-
await this.namespaceResourcesService.getSubResourcesByUser(
242+
await this.namespaceResourcesService.getAllSubResourcesByUser(
243243
userId,
244244
namespaceId,
245245
resource.id,

0 commit comments

Comments
 (0)