Cache / Permissions: Prevent server crash when command times out (#16927)

* Catch get permissions from cache when command times out

* Update api/src/utils/get-permissions.ts

Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com>

* Use get/set cache for permissions

Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com>
This commit is contained in:
José Varela
2023-01-06 18:20:14 +00:00
committed by GitHub
parent d928275447
commit c1887bee86

View File

@@ -2,7 +2,7 @@ import { Accountability, Permission, SchemaOverview } from '@directus/shared/typ
import { deepMap, parseFilter, parseJSON, parsePreset } from '@directus/shared/utils';
import { cloneDeep } from 'lodash';
import hash from 'object-hash';
import { getCache, getSystemCache, setSystemCache } from '../cache';
import { getCache, getSystemCache, setSystemCache, getCacheValue, setCacheValue } from '../cache';
import getDatabase from '../database';
import { appAccessMinimalPermissions } from '../database/system-data/app-access-permissions';
import env from '../env';
@@ -10,6 +10,7 @@ import { RolesService } from '../services/roles';
import { UsersService } from '../services/users';
import { mergePermissions } from '../utils/merge-permissions';
import { mergePermissionsForShare } from './merge-permissions-for-share';
import logger from '../logger';
export async function getPermissions(accountability: Accountability, schema: SchemaOverview) {
const database = getDatabase();
@@ -20,15 +21,22 @@ export async function getPermissions(accountability: Accountability, schema: Sch
const { user, role, app, admin, share_scope } = accountability;
const cacheKey = `permissions-${hash({ user, role, app, admin, share_scope })}`;
if (env.CACHE_PERMISSIONS !== false) {
const cachedPermissions = await getSystemCache(cacheKey);
if (cache && env.CACHE_PERMISSIONS !== false) {
let cachedPermissions;
try {
cachedPermissions = await getSystemCache(cacheKey);
} catch (err: any) {
logger.warn(err, `[cache] Couldn't read key ${cacheKey}. ${err.message}`);
}
if (cachedPermissions) {
if (!cachedPermissions.containDynamicData) {
return processPermissions(accountability, cachedPermissions.permissions, {});
}
const cachedFilterContext = await cache?.get(
const cachedFilterContext = await getCacheValue(
cache,
`filterContext-${hash({ user, role, permissions: cachedPermissions.permissions })}`
);
@@ -48,7 +56,7 @@ export async function getPermissions(accountability: Accountability, schema: Sch
: {};
if (containDynamicData && env.CACHE_ENABLED !== false) {
await cache?.set(`filterContext-${hash({ user, role, permissions })}`, filterContext);
await setCacheValue(cache, `filterContext-${hash({ user, role, permissions })}`, filterContext);
}
return processPermissions(accountability, permissions, filterContext);