Skip to content

Commit

Permalink
fix: added sharing guard to workspace decorator to enable permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
apsantiso committed Jul 25, 2024
1 parent e8233a0 commit a421c41
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 8 deletions.
11 changes: 10 additions & 1 deletion src/modules/file/file.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
Post,
Put,
Query,
UseGuards,
} from '@nestjs/common';
import {
ApiBearerAuth,
Expand All @@ -31,6 +32,10 @@ import { UpdateFileMetaDto } from './dto/update-file-meta.dto';
import { ValidateUUIDPipe } from '../workspaces/pipes/validate-uuid.pipe';
import { WorkspacesInBehalfValidationFile } from '../workspaces/guards/workspaces-resources-in-behalf.decorator';
import { CreateFileDto } from './dto/create-file.dto';
import { RequiredSharingPermissions } from '../sharing/guards/sharing-permissions.decorator';
import { SharingActionName } from '../sharing/sharing.domain';
import { BehalfUserDecorator } from '../sharing/decorators/behalfUser.decorator';
import { SharingPermissionsGuard } from '../sharing/guards/sharing-permissions.guard';

const filesStatuses = ['ALL', 'EXISTS', 'TRASHED', 'DELETED'] as const;

Expand All @@ -44,11 +49,14 @@ export class FileController {
summary: 'Create File',
})
@ApiBearerAuth()
@RequiredSharingPermissions(SharingActionName.UploadFile)
@UseGuards(SharingPermissionsGuard)
async createFile(
@UserDecorator() user: User,
@Body() createFileDto: CreateFileDto,
@BehalfUserDecorator() behalfUser?: User,
) {
return this.fileUseCases.createFile(user, createFileDto);
return this.fileUseCases.createFile(behalfUser ?? user, createFileDto);
}

@Get('/count')
Expand Down Expand Up @@ -146,6 +154,7 @@ export class FileController {
required: true,
description: 'file uuid',
})
@RequiredSharingPermissions(SharingActionName.RenameItems)
@WorkspacesInBehalfValidationFile([
{ sourceKey: 'params', fieldName: 'uuid', newFieldName: 'itemId' },
])
Expand Down
2 changes: 2 additions & 0 deletions src/modules/file/file.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { ThumbnailModule } from '../thumbnail/thumbnail.module';
import { FileModel } from './file.model';
import { SharingModule } from '../sharing/sharing.module';
import { WorkspacesModule } from '../workspaces/workspaces.module';
import { UserModule } from '../user/user.module';

@Module({
imports: [
Expand All @@ -24,6 +25,7 @@ import { WorkspacesModule } from '../workspaces/workspaces.module';
forwardRef(() => WorkspacesModule),
BridgeModule,
CryptoModule,
UserModule,
],
controllers: [FileController],
providers: [SequelizeFileRepository, FileUseCases],
Expand Down
7 changes: 6 additions & 1 deletion src/modules/folder/folder.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ import { CreateFolderDto } from './dto/create-folder.dto';
import { CheckFoldersExistenceDto } from './dto/folder-existence-in-folder.dto';
import { InvalidParentFolderException } from './exception/invalid-parent-folder';
import { CheckFileExistenceInFolderDto } from './dto/files-existence-in-folder.dto';
import { RequiredSharingPermissions } from '../sharing/guards/sharing-permissions.decorator';
import { SharingActionName } from '../sharing/sharing.domain';
import { BehalfUserDecorator } from '../sharing/decorators/behalfUser.decorator';

const foldersStatuses = ['ALL', 'EXISTS', 'TRASHED', 'DELETED'] as const;

Expand Down Expand Up @@ -689,14 +692,16 @@ export class FolderController {
@WorkspacesInBehalfValidationFolder([
{ sourceKey: 'params', fieldName: 'uuid', newFieldName: 'itemId' },
])
@RequiredSharingPermissions(SharingActionName.RenameItems)
async updateFolderMetadata(
@Param('uuid', ValidateUUIDPipe)
folderUuid: Folder['uuid'],
@UserDecorator() user: User,
@Body() updateFolderMetaDto: UpdateFolderMetaDto,
@BehalfUserDecorator() behalfUser?: User,
) {
return this.folderUseCases.updateFolderMetaData(
user,
behalfUser ?? user,
folderUuid,
updateFolderMetaDto,
);
Expand Down
2 changes: 1 addition & 1 deletion src/modules/sharing/decorators/behalfUser.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ export const BehalfUserDecorator = createParamDecorator(
async (_, ctx: ExecutionContext) => {
const req = ctx.switchToHttp().getRequest();

return req.behalfUser;
return req?.behalfUser;
},
);
12 changes: 9 additions & 3 deletions src/modules/sharing/guards/sharing-permissions.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export class SharingPermissionsGuard implements CanActivate {
PermissionsMetadataName,
context.getHandler(),
);
const { action } = permissionsOptions;

const request = context.switchToHttp().getRequest();
const requester = request?.user as User;
Expand All @@ -49,10 +48,16 @@ export class SharingPermissionsGuard implements CanActivate {

const resourcesToken = request.headers['internxt-resources-token'];

if (!resourcesToken || typeof resourcesToken !== 'string') {
if (
!resourcesToken ||
typeof resourcesToken !== 'string' ||
!permissionsOptions
) {
return true;
}

const { action } = permissionsOptions;

const decoded = verifyWithDefaultSecret(resourcesToken) as
| {
owner?: {
Expand Down Expand Up @@ -100,7 +105,8 @@ export class SharingPermissionsGuard implements CanActivate {
throw new NotFoundException('Resource owner not found');
}

request.behalfUser = resourceOwner;
request.user = resourceOwner;
request.isSharedItem = true;

return true;
}
Expand Down
2 changes: 2 additions & 0 deletions src/modules/trash/trash.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import { ShareModule } from '../share/share.module';
import { ShareModel } from '../share/share.repository';
import { FileModel } from '../file/file.model';
import { WorkspacesModule } from '../workspaces/workspaces.module';
import { SharingModule } from '../sharing/sharing.module';

@Module({
imports: [
SequelizeModule.forFeature([FileModel, ShareModel]),
forwardRef(() => FileModule),
forwardRef(() => ShareModule),
forwardRef(() => WorkspacesModule),
forwardRef(() => SharingModule),
FolderModule,
NotificationModule,
UserModule,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { applyDecorators, UseGuards, SetMetadata } from '@nestjs/common';
import { WorkspacesResourcesItemsInBehalfGuard } from './workspaces-resources-in-items-in-behalf.guard';
import { WorkspaceItemType } from '../attributes/workspace-items-users.attributes';
import { SharingPermissionsGuard } from '../../sharing/guards/sharing-permissions.guard';

export interface DataSource {
sourceKey?: 'body' | 'query' | 'params' | 'headers';
Expand Down Expand Up @@ -39,7 +40,8 @@ const createValidationDecorator = (
return applyDecorators(
SetMetadata(WORKSPACE_IN_BEHALF_SOURCES_META_KEY, dataSourcesWithOptions),
SetMetadata(WORKSPACE_IN_BEHALF_ACTION_META_KEY, options?.action),
UseGuards(WorkspacesResourcesItemsInBehalfGuard),
// TODO: rename this guard or remove sharings from here
UseGuards(SharingPermissionsGuard, WorkspacesResourcesItemsInBehalfGuard),
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ export class WorkspacesResourcesItemsInBehalfGuard implements CanActivate {

const actionHandler = this.getActionHandler(action);

const canUserPerformAction = await actionHandler(requester, extractedData);
const isSharedItem = request.isSharedItem;
const canUserPerformAction = !isSharedItem
? await actionHandler(requester, extractedData)
: true;

if (!canUserPerformAction) {
throw new ForbiddenException(
Expand Down

0 comments on commit a421c41

Please sign in to comment.