Fix type casting in authorization service

Fixes #776
This commit is contained in:
rijkvanzanten
2020-10-26 11:30:21 +01:00
parent f05e928ada
commit dae2ca530f
2 changed files with 22 additions and 6 deletions

View File

@@ -17,22 +17,25 @@ import { ForbiddenException, FailedValidationException } from '../exceptions';
import { uniq, merge, flatten } from 'lodash';
import generateJoi from '../utils/generate-joi';
import { ItemsService } from './items';
import { PayloadService } from './payload';
import { parseFilter } from '../utils/parse-filter';
import { toArray } from '../utils/to-array';
export class AuthorizationService {
knex: Knex;
accountability: Accountability | null;
payloadService: PayloadService;
constructor(options?: AbstractServiceOptions) {
this.knex = options?.knex || database;
this.accountability = options?.accountability || null;
this.payloadService = new PayloadService('directus_permissions', { knex: this.knex });
}
async processAST(ast: AST, action: PermissionsAction = 'read'): Promise<AST> {
const collectionsRequested = getCollectionsFromAST(ast);
const permissionsForCollections = await this.knex
let permissionsForCollections = await this.knex
.select<Permission[]>('*')
.from('directus_permissions')
.where({ action, role: this.accountability?.role })
@@ -41,6 +44,11 @@ export class AuthorizationService {
collectionsRequested.map(({ collection }) => collection)
);
permissionsForCollections = (await this.payloadService.processValues(
'read',
permissionsForCollections
)) as Permission[];
// If the permissions don't match the collections, you don't have permission to read all of them
const uniqueCollectionsRequestedCount = uniq(
collectionsRequested.map(({ collection }) => collection)
@@ -111,7 +119,7 @@ export class AuthorizationService {
(permission) => permission.collection === collection
)!;
const allowedFields = permissions.fields?.split(',') || [];
const allowedFields = permissions.fields || [];
for (const childNode of ast.children) {
if (childNode.type !== 'field') {
@@ -213,21 +221,26 @@ export class AuthorizationService {
permissions: {},
validation: {},
limit: null,
fields: '*',
fields: ['*'],
presets: {},
};
} else {
permission = await this.knex
.select<Permission>('*')
.select('*')
.from('directus_permissions')
.where({ action, collection, role: this.accountability?.role || null })
.first();
permission = (await this.payloadService.processValues(
'read',
permission as Item
)) as Permission;
// Check if you have permission to access the fields you're trying to acces
if (!permission) throw new ForbiddenException();
const allowedFields = permission.fields?.split(',') || [];
const allowedFields = permission.fields || [];
if (allowedFields.includes('*') === false) {
for (const payload of payloads) {
@@ -260,13 +273,16 @@ export class AuthorizationService {
.from('directus_fields')
.where({ collection, field: column.name })
.first();
const specials = (field?.special || '').split(',');
const hasGenerateSpecial = [
'uuid',
'date-created',
'role-created',
'user-created',
].some((name) => specials.includes(name));
const isRequired =
column.is_nullable === false &&
column.has_auto_increment === false &&

View File

@@ -9,5 +9,5 @@ export type Permission = {
validation: Record<string, any>;
limit: number | null;
presets: Record<string, any> | null;
fields: string | null;
fields: string[] | null;
};