backend/lib/seed/engine/EngineAccessService.ts
2025-05-14 21:45:16 +02:00

162 lines
5.1 KiB
TypeScript

import { AccountTypeEnum } from '@src/accounts/account.components';
import AccountModel from '@src/accounts/account.model';
import { newError } from '@seed/helpers/Error';
import _ from 'lodash';
export class EngineAccessService {
static addPermissions<U, T>(ressource: any, type: ('r' | 'w' | 'd')[], ids: (string | string)[]): void {
for (let index = 0; index < type.length; index++) {
const t = type[index];
ressource.permissions[t] = ressource.permissions[t].concat(ids);
}
}
static addPermissionToQuery(account: AccountModel | null, query: 'get' | 'update' | 'delete', params: any): any {
let types: any[] = ['public'];
if (account && account.types) {
/*
* Verify if admin, no need to add the query filters
*/
if (account.types.includes(AccountTypeEnum.admin)) return params;
/*
* Verify if organisation type of access
*/
// if (account.organisationIds) {
// params.organisationId = { $in: account.organisationIds };
// }
/*
* Add the account id and type
*/
types.push(account._id);
types = types.concat(account.types);
}
if (!params.$and) params.$and = [];
switch (query) {
default:
case 'get':
params.$and.push({ 'permissions.r': { $in: types } });
break;
case 'update':
params.$and.push({ 'permissions.w': { $in: types } });
break;
case 'delete':
params.$and.push({ 'permissions.d': { $in: types } });
break;
}
return params;
}
static checkPermissions<U, T>(ressource: any, account: AccountModel | null, type: 'c' | 'r' | 'w' | 'd'): boolean {
// Adding the public by default
let perm: any[] = [AccountTypeEnum.public];
if (account && account.types) {
/*
* Verify if admin
*/
if (account.types.includes(AccountTypeEnum.admin)) return true;
/*
* Verify if organisation type of access
*/
if (
ressource.organisationId &&
account.organisationIds &&
!account.organisationIds.includes(ressource.organisationId) &&
!ressource.permissions.r.includes(AccountTypeEnum.public)
)
throw newError(2100, {
allowed: ressource.organisationId,
you: account.organisationIds,
});
/*
* Add the account id and type
*/
perm.push(account._id);
perm = perm.concat(account.types);
}
/*
* Verify on the ressource level
*/
const permissions = ressource.permissions[type];
// if there is no permission on the ressource, return true
if (!permissions) return true;
let hasPerm = false;
// Verifying if it matches
for (let index = 0; index < perm.length; index++) {
const element = perm[index];
if (permissions.includes(element)) {
hasPerm = true;
break;
}
}
if (!hasPerm)
throw newError(2000, {
allowed: permissions,
you: { _id: account?._id, types: account?.types },
});
return true;
}
static checkOrganisationPermissions<U, T>(ressource: any, organisationId: string): boolean {
if (organisationId == ressource.organisationId || organisationId == ressource._id) return true;
throw newError(2100, { allowedOrgId: ressource.organisationId, youOrgId: organisationId });
}
static addOrganisationToQuery(account: AccountModel | null, query: 'get' | 'update' | 'delete', params: any): any {
let types: any[] = ['public'];
if (account && account.types) {
/*
* Verify if admin, no need to add the query filters
*/
if (account.types.includes(AccountTypeEnum.admin)) return params;
/*
* Verify if organisation type of access
*/
if (account.organisationIds) {
params.organisationId = { $in: account.organisationIds };
}
/*
* Add the account id and type
*/
types.push(account._id);
types = types.concat(account.types);
}
switch (query) {
default:
case 'get':
params = { ...params, $or: [{ 'permissions.r': { $in: _.uniq(types) } }] };
break;
case 'update':
params = { ...params, $or: [{ 'permissions.w': { $in: _.uniq(types) } }] };
break;
case 'delete':
params = { ...params, $or: [{ 'permissions.d': { $in: _.uniq(types) } }] };
break;
}
return params;
}
}