Document gen fixed

This commit is contained in:
2025-10-12 17:52:17 +02:00
parent e0303ece74
commit 23f2011e33
16 changed files with 1116 additions and 88 deletions
+44 -10
View File
@@ -42,7 +42,7 @@ public function resolve(
$customTypes = [];
if (isset($template->meta['custom_default_types']) && is_array($template->meta['custom_default_types'])) {
foreach ($template->meta['custom_default_types'] as $k => $t) {
$t = in_array($t, ['string', 'number', 'date'], true) ? $t : 'string';
$t = in_array($t, ['string', 'number', 'date', 'text'], true) ? $t : 'string';
$customTypes[(string) $k] = $t;
}
}
@@ -57,6 +57,17 @@ public function resolve(
} else {
$templateEntities = array_keys($globalWhitelist);
}
// Normalize template tokens list (used as an allow-list if columns / global whitelist are not exhaustive)
$templateTokens = [];
$rawTemplateTokens = $template->tokens ?? null;
if (is_array($rawTemplateTokens)) {
$templateTokens = array_values(array_filter(array_map('strval', $rawTemplateTokens)));
} elseif (is_string($rawTemplateTokens)) {
$decoded = json_decode($rawTemplateTokens, true);
if (is_array($decoded)) {
$templateTokens = array_values(array_filter(array_map('strval', $decoded)));
}
}
foreach ($tokens as $token) {
[$entity,$attr] = explode('.', $token, 2);
if ($entity === 'generation') {
@@ -93,20 +104,43 @@ public function resolve(
continue;
}
if (! in_array($entity, $templateEntities, true)) {
if ($policy === 'fail') {
throw new \RuntimeException("Nedovoljen entiteta token: $entity");
}
$unresolved[] = $token;
// If the token is explicitly listed on the template's tokens, allow it
if (! $templateTokens || ! in_array($token, $templateTokens, true)) {
if ($policy === 'fail') {
throw new \RuntimeException("Nedovoljen entiteta token: $entity");
}
$unresolved[] = $token;
continue;
continue;
}
}
// Allowed attributes: merge template-declared columns with global whitelist (config + DB settings)
// Rationale: old templates may not list newly allowed attributes (like nested paths),
// so we honor both sources instead of preferring one exclusively.
$allowedFromTemplate = $template->columns[$entity] ?? [];
// Support nested dotted attributes (e.g. person.person_address.city). We allow if either the full
// dotted path is listed or if the base prefix is listed (e.g. person.person_address) and the resolver
// can handle it.
// Safely read template-declared columns
$columns = is_array($template->columns ?? null) ? $template->columns : [];
$allowedFromTemplate = $columns[$entity] ?? [];
$allowedFromGlobal = $globalWhitelist[$entity] ?? [];
$allowed = array_values(array_unique(array_merge($allowedFromTemplate, $allowedFromGlobal)));
if (! in_array($attr, $allowed, true)) {
$isAllowed = in_array($attr, $allowed, true);
if (! $isAllowed && str_contains($attr, '.')) {
// Check progressive prefixes: a.b.c -> a.b
$parts = explode('.', $attr);
while (count($parts) > 1 && ! $isAllowed) {
array_pop($parts);
$prefix = implode('.', $parts);
if (in_array($prefix, $allowed, true)) {
$isAllowed = true;
break;
}
}
}
// If still not allowed, permit tokens explicitly scanned/stored on the template
if (! $isAllowed && $templateTokens) {
$isAllowed = in_array($token, $templateTokens, true);
}
if (! $isAllowed) {
if ($policy === 'fail') {
throw new \RuntimeException("Nedovoljen stolpec token: $token");
}