Skip to content
Snippets Groups Projects
Commit af32390d authored by Jan-Hendrik Willms's avatar Jan-Hendrik Willms
Browse files

show specific fields on error, fixes #2816

Closes #2816

Merge request studip/studip!1898
parent 06e57c15
No related branches found
No related tags found
No related merge requests found
...@@ -71,61 +71,67 @@ class QueryChecker ...@@ -71,61 +71,67 @@ class QueryChecker
protected function checkIncludePaths(ErrorCollection $errors, QueryParserInterface $queryParser): void protected function checkIncludePaths(ErrorCollection $errors, QueryParserInterface $queryParser): void
{ {
$withinAllowed = $this->valuesWithinAllowed( $invalidValues = $this->getInvalidValues(
iterator_to_array($queryParser->getIncludePaths()), $queryParser->getIncludePaths(),
$this->includePaths $this->includePaths
); );
if (!$withinAllowed) { foreach ($invalidValues as $value) {
$errors->addQueryParameterError( $errors->addQueryParameterError(
QueryParser::PARAM_INCLUDE, QueryParser::PARAM_INCLUDE,
'Include paths should contain only allowed ones.' sprintf('Include path %s is not allowed.', $value)
); );
} }
} }
protected function checkFieldSets(ErrorCollection $errors, QueryParserInterface $queryParser): void protected function checkFieldSets(ErrorCollection $errors, QueryParserInterface $queryParser): void
{ {
$withinAllowed = $this->isFieldsAllowed(iterator_to_array($queryParser->getFields())); $invalidFields = $this->getInvalidFields($queryParser->getFields());
if (!$withinAllowed) { foreach ($invalidFields as $field) {
$errors->addQueryParameterError(QueryParser::PARAM_FIELDS, 'Field sets should contain only allowed ones.'); $errors->addQueryParameterError(
QueryParser::PARAM_FIELDS,
sprintf('Field set %s is not allowed.', $field)
);
} }
} }
protected function checkFiltering(ErrorCollection $errors, QueryParserInterface $queryParser): void protected function checkFiltering(ErrorCollection $errors, QueryParserInterface $queryParser): void
{ {
$withinAllowed = $this->keysWithinAllowed( $invalidKeys = $this->getInvalidKeys(
iterator_to_array($queryParser->getFilters()), $queryParser->getFilters(),
$this->filteringParameters $this->filteringParameters
); );
if (!$withinAllowed) { foreach ($invalidKeys as $key) {
$errors->addQueryParameterError(QueryParser::PARAM_FILTER, 'Filter should contain only allowed values.'); $errors->addQueryParameterError(
QueryParser::PARAM_FILTER,
sprintf('Filter parameter %s is not allowed.', $key)
);
} }
} }
protected function checkSorting(ErrorCollection $errors, QueryParserInterface $queryParser): void protected function checkSorting(ErrorCollection $errors, QueryParserInterface $queryParser): void
{ {
$withinAllowed = $this->keysWithinAllowed( $invalidKeys = $this->getInvalidKeys(
iterator_to_array($queryParser->getSorts()), $queryParser->getSorts(),
$this->sortParameters $this->sortParameters
); );
if (!$withinAllowed) { foreach ($invalidKeys as $key) {
$errors->addQueryParameterError( $errors->addQueryParameterError(
QueryParser::PARAM_SORT, QueryParser::PARAM_SORT,
'Sort parameter should contain only allowed values.' sprintf('Sort parameter %s is not allowed.', $key)
); );
} }
} }
protected function checkPaging(ErrorCollection $errors, QueryParserInterface $queryParser): void protected function checkPaging(ErrorCollection $errors, QueryParserInterface $queryParser): void
{ {
$withinAllowed = $this->keysWithinAllowed( $invalidKeys = $this->getInvalidKeys(
iterator_to_array($queryParser->getPagination()), $queryParser->getPagination(),
$this->pagingParameters $this->pagingParameters
); );
if (!$withinAllowed) { foreach ($invalidKeys as $key) {
$errors->addQueryParameterError( $errors->addQueryParameterError(
QueryParser::PARAM_PAGE, QueryParser::PARAM_PAGE,
'Page parameter should contain only allowed values.' sprintf('Page parameter %s is not allowed.', $key)
); );
} }
} }
...@@ -139,48 +145,61 @@ class QueryChecker ...@@ -139,48 +145,61 @@ class QueryChecker
} }
} }
private function keysWithinAllowed(array $toCheck = null, array $allowed = null): bool private function getInvalidKeys(iterable $toCheck = null, iterable $allowed = null): array
{ {
return null === $toCheck || null === $allowed || empty(array_diff_key($toCheck, $allowed)); if (null === $toCheck || null === $allowed) {
return [];
}
return array_keys(array_diff_key(
$this->ensureArray($toCheck),
$this->ensureArray($allowed)
));
} }
private function valuesWithinAllowed(array $toCheck = null, array $allowed = null): bool private function getInvalidValues(iterable $toCheck = null, iterable $allowed = null): array
{ {
return null === $toCheck || null === $allowed || empty(array_diff($toCheck, $allowed)); if (null === $toCheck || null === $allowed) {
return [];
}
return array_diff(
$this->ensureArray($toCheck),
$this->ensureArray($allowed)
);
} }
/** private function ensureArray(iterable $input): array
* @return array|null {
*/ return is_array($input) ? $input : iterator_to_array($input);
private function flip(array $array = null) }
private function flip(array $array = null): ?array
{ {
return $array === null ? null : array_flip($array); return $array === null ? null : array_flip($array);
} }
/** /**
* Check input fields against allowed. * Check input fields against allowed.
*
* @param array|null $fields
*/ */
private function isFieldsAllowed(array $fields = null): bool private function getInvalidFields(iterable $fields = null): iterable
{ {
if ($this->fieldSetTypes === null || $fields === null) { if ($this->fieldSetTypes !== null && $fields !== null) {
return true; foreach ($fields as $type => $requestedFields) {
} if (
!array_key_exists($type, $this->fieldSetTypes)
foreach ($fields as $type => $requestedFields) { || (
if (array_key_exists($type, $this->fieldSetTypes) === false) { // if not all fields are allowed and requested more fields than allowed
return false; isset($this->fieldSetTypes[$type])
} && !empty(array_diff(
$this->ensureArray($requestedFields),
$allowedFields = $this->fieldSetTypes[$type]; $this->fieldSetTypes[$type]
))
// if not all fields are allowed and requested more fields than allowed )
if ($allowedFields !== null && empty(array_diff($requestedFields, $allowedFields)) === false) { ) {
return false; yield $type;
}
} }
} }
return true;
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment