Files
directus/api/src/utils/get-permissions.ts
Jay Cammarano 25375cc481 Add notifications system and support user mentions in comments (#9861)
* v-menu de/activated onKeyDown. No List yet.

* v-list

* add user suggestion

* uuids replaced

* user-popover working

* avatars flex row with usernames in suggestions

* added space to end of uuid insert

* autofocus + move caret to end of last insert

* removed unnecessary setTimeout()

* fixed filter 500 with ids

* better fix

* New translations en-US.yaml (French) (#9907)

* New translations en-US.yaml (French) (#9912)

* New translations en-US.yaml (French) (#9916)

* New translations en-US.yaml (Russian) (#9918)

* New translations en-US.yaml (Swedish) (#9920)

* Email updates (#9921)

* add from name for emails

* updatd email template style

* reset password email copy

* updated logo to newest version

* update invite email copy

* decouple field template logic

* push up styling

* Start on new v-template-input

* Add notifications API endpoints

Squashed commit of the following:

commit 9d86721ef795d03bc55693c0f99bde8e269d60e9
Merge: b4458c19f 34131d06e
Author: rijkvanzanten <rijkvanzanten@me.com>
Date:   Mon Nov 22 09:27:43 2021 -0500

    Merge branch 'mentions' into mentions-api

commit b4458c19f7c54f18fa415fc04c63642c2f5a17b0
Author: rijkvanzanten <rijkvanzanten@me.com>
Date:   Thu Nov 18 18:34:04 2021 -0500

    Remove unused import

commit e6a9d36bbfdf95cb18d29336da61ecb14b677934
Author: rijkvanzanten <rijkvanzanten@me.com>
Date:   Thu Nov 18 18:28:31 2021 -0500

    Extract user mentions from comments

commit b3e571a2daa287e1740a050096913662a57e9861
Merge: c93b833d2 af2a6dd7f
Author: rijkvanzanten <rijkvanzanten@me.com>
Date:   Thu Nov 18 17:39:52 2021 -0500

    Merge branch 'mentions' into mentions-api

commit c93b833d2b848e306c434b370d4e4e11967e85d0
Author: rijkvanzanten <rijkvanzanten@me.com>
Date:   Thu Nov 18 17:35:45 2021 -0500

    Send emails w/ parsed MD

commit 64bbd6596f20a07028d2387d60e33dfe4f91c032
Author: rijkvanzanten <rijkvanzanten@me.com>
Date:   Thu Nov 18 16:18:16 2021 -0500

    Add notifications endpoint + permissions

commit fba55c02dc9c303a38b1b958350684cccd3dd82c
Author: rijkvanzanten <rijkvanzanten@me.com>
Date:   Thu Nov 18 15:33:28 2021 -0500

    Add system data for notifications

* push

* Make v-template-input work

* Add the two-way binding

* submit button posting, not clearing text area

* comment text area clearing on submit

* Replace insertion correctly

* Added scope support to LDAP group and user search (#9529)

* Added scope support LDAP group and user search

* Fixed linter screwing up my markdown

* Update docs/configuration/config-options.md

* Always return correct DN for user with sub scope

* Fix indeterminate meta and schema property in advanded field creation (#9924)

* Fix impossibility to save M2M (alterations not triggered) (#9992)

* Fix alterations refactor

* fix roles aggregate query (#9994)

* Update iis.md (#9998)

added the IIS URL Rewrite module as a requirement

* New translations en-US.yaml (English, United Kingdom) (#10001)

* Fix LDAP race condition (#9993)

* Fix input ui

* Revert changes to v-field-template

* Update mentions permissions

* Fix linter warnings

* Optimize sending flow

* Revert "Rename activity->notifications module (#9446)"

This reverts commit 428e5d4ea9.

* Add notifications drawer

* Update migrations

* Improve constraints

* Add email notifications toggle on users

* Add docs, fix graphql support

* Move caret-pos to devdeps

* Remove unused new triggerKeyPressed system

* Remove unused use-caret composable

Co-authored-by: Nitwel <nitwel@arcor.de>
Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>
Co-authored-by: Ben Haynes <ben@rngr.org>
Co-authored-by: Aiden Foxx <aiden.foxx@sbab.se>
Co-authored-by: Oreille <33065839+Oreilles@users.noreply.github.com>
Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com>
Co-authored-by: Paul Boudewijn <paul@helderinternet.nl>
2021-11-24 16:11:26 -05:00

127 lines
4.1 KiB
TypeScript

import { Permission, Accountability } from '@directus/shared/types';
import { deepMap, parseFilter } from '@directus/shared/utils';
import { cloneDeep } from 'lodash';
import getDatabase from '../database';
import { appAccessMinimalPermissions } from '../database/system-data/app-access-permissions';
import { mergePermissions } from '../utils/merge-permissions';
import { UsersService } from '../services/users';
import { RolesService } from '../services/roles';
import { getCache } from '../cache';
import hash from 'object-hash';
import env from '../env';
import { SchemaOverview } from '../types';
export async function getPermissions(accountability: Accountability, schema: SchemaOverview) {
const database = getDatabase();
const { systemCache } = getCache();
let permissions: Permission[] = [];
const { user, role, app, admin } = accountability;
const cacheKey = `permissions-${hash({ user, role, app, admin })}`;
if (env.CACHE_PERMISSIONS !== false) {
const cachedPermissions = await systemCache.get(cacheKey);
if (cachedPermissions) {
return cachedPermissions;
}
}
if (accountability.admin !== true) {
const permissionsForRole = await database
.select('*')
.from('directus_permissions')
.where({ role: accountability.role });
const requiredPermissionData = {
$CURRENT_USER: [] as string[],
$CURRENT_ROLE: [] as string[],
};
permissions = permissionsForRole.map((permissionRaw) => {
const permission = cloneDeep(permissionRaw);
if (permission.permissions && typeof permission.permissions === 'string') {
permission.permissions = JSON.parse(permission.permissions);
} else if (permission.permissions === null) {
permission.permissions = {};
}
if (permission.validation && typeof permission.validation === 'string') {
permission.validation = JSON.parse(permission.validation);
} else if (permission.validation === null) {
permission.validation = {};
}
if (permission.presets && typeof permission.presets === 'string') {
permission.presets = JSON.parse(permission.presets);
} else if (permission.presets === null) {
permission.presets = {};
}
if (permission.fields && typeof permission.fields === 'string') {
permission.fields = permission.fields.split(',');
} else if (permission.fields === null) {
permission.fields = [];
}
const extractPermissionData = (val: any) => {
if (typeof val === 'string' && val.startsWith('$CURRENT_USER.')) {
requiredPermissionData.$CURRENT_USER.push(val.replace('$CURRENT_USER.', ''));
}
if (typeof val === 'string' && val.startsWith('$CURRENT_ROLE.')) {
requiredPermissionData.$CURRENT_ROLE.push(val.replace('$CURRENT_ROLE.', ''));
}
return val;
};
deepMap(permission.permissions, extractPermissionData);
deepMap(permission.validation, extractPermissionData);
deepMap(permission.presets, extractPermissionData);
return permission;
});
if (accountability.app === true) {
permissions = mergePermissions(
permissions,
appAccessMinimalPermissions.map((perm) => ({ ...perm, role: accountability!.role }))
);
}
const usersService = new UsersService({ schema });
const rolesService = new RolesService({ schema });
const filterContext: Record<string, any> = {};
if (accountability.user && requiredPermissionData.$CURRENT_USER.length > 0) {
filterContext.$CURRENT_USER = await usersService.readOne(accountability.user, {
fields: requiredPermissionData.$CURRENT_USER,
});
}
if (accountability.role && requiredPermissionData.$CURRENT_ROLE.length > 0) {
filterContext.$CURRENT_ROLE = await rolesService.readOne(accountability.role, {
fields: requiredPermissionData.$CURRENT_ROLE,
});
}
permissions = permissions.map((permission) => {
permission.permissions = parseFilter(permission.permissions, accountability!, filterContext);
permission.validation = parseFilter(permission.validation, accountability!, filterContext);
permission.presets = parseFilter(permission.presets, accountability!, filterContext);
return permission;
});
if (env.CACHE_PERMISSIONS !== false) {
await systemCache.set(cacheKey, permissions);
}
}
return permissions;
}