Repository: directus/directus
File: api/src/permissions/modules/process-ast/lib/inject-cases.ts (TypeScript)

Code before:
) {
	// Use uniq here, since there might be multiple duplications due to aliases or functions
	const requestedKeys = uniq(children.map(getUnaliasedFieldKey));
	const { cases, caseMap, allowedFields } = getCases(collection, permissions, requestedKeys);

	// TODO this can be optimized if there is only one rule to skip the whole case/where system,
	//  since fields that are not allowed at all are already filtered out

	// TODO this can be optimized if all cases are the same for all requested keys, as those should be
	//

	for (const child of children) {
		const fieldKey = getUnaliasedFieldKey(child);

		const globalWhenCase = caseMap['*'];
		const fieldWhenCase = caseMap[fieldKey];

		// Validation should catch any fields that are attempted to be read that don't have any access control configured.
		// When there are no access rules for this field, and no rules for "all" fields `*`, we missed something in the validation
		// and should abort.
		if (!globalWhenCase && !fieldWhenCase) {
			throw new Error(`Cannot extract access permissions for field "${fieldKey}" in collection "${collection}"`);
		}

		// If there's one or more permissions that allow full access to this field, we can safe some
		// query perf overhead by ignoring the whole case/when system
		if (!allowedFields.has('*') && !allowedFields.has(fieldKey)) {
			// Global and field can't both be undefined as per the error check prior
			child.whenCase = [...(globalWhenCase ?? []), ...(fieldWhenCase ?? [])];
		}

		if (child.type === 'm2o') {
			child.cases = processChildren(child.relation.related_collection!, child.children, permissions);
		}

		if (child.type === 'o2m') {
			child.cases = processChildren(child.relation.collection, child.children, permissions);
		}

		if (child.type === 'a2o') {
			for (const collection of child.names) {
				child.cases[collection] = processChildren(collection, child.children[collection] ?? [], permissions);
			}
		}

		if (child.type === 'functionField') {
			const { cases } = getCases(child.relatedCollection, permissions, []);
			child.cases = cases;
		}
	}


Review comment (suggestion):
I'd probably slightly adjust this comment, for example as follows, as the conditions have now been reversed
```suggestion
		// The case/when system only needs to take place if no full access is given on this field,
		// otherwise we can skip and thus safe some query perf overhead
```

Code after:
) {
	// Use uniq here, since there might be multiple duplications due to aliases or functions
	const requestedKeys = uniq(children.map(getUnaliasedFieldKey));
	const { cases, caseMap, allowedFields } = getCases(collection, permissions, requestedKeys);

	// TODO this can be optimized if there is only one rule to skip the whole case/where system,
	//  since fields that are not allowed at all are already filtered out

	// TODO this can be optimized if all cases are the same for all requested keys, as those should be
	//

	for (const child of children) {
		const fieldKey = getUnaliasedFieldKey(child);

		const globalWhenCase = caseMap['*'];
		const fieldWhenCase = caseMap[fieldKey];

		// Validation should catch any fields that are attempted to be read that don't have any access control configured.
		// When there are no access rules for this field, and no rules for "all" fields `*`, we missed something in the validation
		// and should abort.
		if (!globalWhenCase && !fieldWhenCase) {
			throw new Error(`Cannot extract access permissions for field "${fieldKey}" in collection "${collection}"`);
		}

		// The case/when system only needs to take place if no full access is given on this field,
		// otherwise we can skip and thus safe some query perf overhead
		if (!allowedFields.has('*') && !allowedFields.has(fieldKey)) {
			// Global and field can't both be undefined as per the error check prior
			child.whenCase = [...(globalWhenCase ?? []), ...(fieldWhenCase ?? [])];
		}

		if (child.type === 'm2o') {
			child.cases = processChildren(child.relation.related_collection!, child.children, permissions);
		}

		if (child.type === 'o2m') {
			child.cases = processChildren(child.relation.collection, child.children, permissions);
		}

		if (child.type === 'a2o') {
			for (const collection of child.names) {
				child.cases[collection] = processChildren(collection, child.children[collection] ?? [], permissions);
			}
		}

		if (child.type === 'functionField') {
			const { cases } = getCases(child.relatedCollection, permissions, []);
			child.cases = cases;
		}
	}