[permissions] Add SettingsPermissionGuard on data model and roles features (#10063)

Adding SettingsPermissionsGuard to execute permission check. 

The guard is added directly in resolver, either at resolver level (ex:
roles) or resolver-endpoint level (ex: metadata). this can be challenged
!
This commit is contained in:
Marie
2025-02-07 16:48:04 +01:00
committed by GitHub
parent 859e7c94f9
commit a24e411384
11 changed files with 144 additions and 64 deletions

View File

@ -3,10 +3,6 @@ import { Injectable } from '@nestjs/common';
import { SettingsFeatures } from 'twenty-shared';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import {
PermissionsException,
PermissionsExceptionCode,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
@Injectable()
@ -40,25 +36,22 @@ export class PermissionsService {
);
}
public async validateUserHasWorkspaceSettingPermissionOrThrow({
public async userHasWorkspaceSettingPermission({
userWorkspaceId,
setting,
_setting,
}: {
userWorkspaceId: string;
setting: SettingsFeatures;
}): Promise<void> {
_setting: SettingsFeatures;
}): Promise<boolean> {
const [roleOfUserWorkspace] = await this.userRoleService
.getRolesByUserWorkspaces([userWorkspaceId])
.then((roles) => roles?.get(userWorkspaceId) ?? []);
if (roleOfUserWorkspace?.canUpdateAllSettings === true) {
return;
return true;
}
throw new PermissionsException(
`User does not have permission to access this setting: ${setting}`,
PermissionsExceptionCode.PERMISSION_DENIED,
);
return false;
}
public async isPermissionsEnabled(): Promise<boolean> {

View File

@ -1,3 +1,5 @@
import { Catch, ExceptionFilter } from '@nestjs/common';
import {
ForbiddenError,
InternalServerError,
@ -7,16 +9,15 @@ import {
PermissionsExceptionCode,
} from 'src/engine/metadata-modules/permissions/permissions.exception';
export const permissionsGraphqlApiExceptionHandler = (error: Error) => {
if (error instanceof PermissionsException) {
switch (error.code) {
@Catch(PermissionsException)
export class PermissionsGraphqlApiExceptionFilter implements ExceptionFilter {
catch(exception: PermissionsException) {
switch (exception.code) {
case PermissionsExceptionCode.PERMISSION_DENIED:
case PermissionsExceptionCode.CANNOT_UNASSIGN_LAST_ADMIN:
throw new ForbiddenError(error.message);
throw new ForbiddenError(exception.message);
default:
throw new InternalServerError(error.message);
throw new InternalServerError(exception.message);
}
}
throw error;
};
}