Skip to content

Commit a6159d1

Browse files
committed
fixup! feat: add import function (#1425)
fix: add import validation
1 parent 38b9aca commit a6159d1

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

lib/Controller/ApiController.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,13 @@ public function getForms(string $type = 'owned'): DataResponse {
156156
* @throws OCSForbiddenException The user is not allowed to create forms
157157
* @throws OCSBadRequestException Cannot use both fromId and import parameters
158158
* @throws OCSBadRequestException Invalid form data: missing questions
159+
* @throws OCSBadRequestException Invalid form data: unknown properties
159160
* @throws OCSBadRequestException Invalid question data: missing id
161+
* @throws OCSBadRequestException Invalid question data: unknown properties
162+
* @throws OCSBadRequestException Invalid question data: invalid type
163+
* @throws OCSBadRequestException Invalid question data: datetime type no longer supported
164+
* @throws OCSBadRequestException Invalid question data: invalid extraSettings
165+
* @throws OCSBadRequestException Invalid option data: unknown properties
160166
*
161167
* 201: the created form
162168
*/
@@ -203,6 +209,19 @@ public function newForm(?int $fromId = null, ?bool $import = false, ?array $form
203209
$questions = $formData['questions'];
204210
$oldConfirmationEmailQuestionId = $formData['confirmationEmailQuestionId'] ?? null;
205211
unset($formData['questions']);
212+
213+
// Validate form data whitelist
214+
$allowedFormProperties = [
215+
'title', 'description', 'access', 'expires', 'isAnonymous',
216+
'submitMultiple', 'allowEditSubmissions', 'showExpiration',
217+
'submissionMessage', 'maxSubmissions', 'confirmationEmailEnabled',
218+
'confirmationEmailSubject', 'confirmationEmailBody', 'confirmationEmailQuestionId',
219+
'allowComments',
220+
];
221+
$invalidKeys = array_diff(array_keys($formData), $allowedFormProperties);
222+
if (!empty($invalidKeys)) {
223+
throw new OCSBadRequestException('Invalid form data: unknown properties: ' . implode(', ', $invalidKeys));
224+
}
206225
} else {
207226
$oldForm = $this->formsService->getFormIfAllowed($fromId, Constants::PERMISSION_EDIT);
208227

@@ -246,6 +265,32 @@ public function newForm(?int $fromId = null, ?bool $import = false, ?array $form
246265
if (!isset($oldQuestion['id'])) {
247266
throw new OCSBadRequestException('Invalid question data: missing id');
248267
}
268+
269+
// Validate question property whitelist
270+
$allowedQuestionProperties = ['id', 'order', 'type', 'isRequired', 'text', 'name', 'description', 'extraSettings', 'options'];
271+
$invalidQuestionKeys = array_diff(array_keys($oldQuestion), $allowedQuestionProperties);
272+
if (!empty($invalidQuestionKeys)) {
273+
throw new OCSBadRequestException('Invalid question data: unknown properties: ' . implode(', ', $invalidQuestionKeys));
274+
}
275+
276+
// Validate question type
277+
$type = $oldQuestion['type'] ?? null;
278+
if ($type === null || array_search($type, Constants::ANSWER_TYPES) === false) {
279+
throw new OCSBadRequestException('Invalid question data: invalid type');
280+
}
281+
282+
// Block datetime questions
283+
if ($type === 'datetime') {
284+
throw new OCSBadRequestException('Invalid question data: datetime type no longer supported');
285+
}
286+
287+
// Validate extraSettings
288+
if (!empty($oldQuestion['extraSettings'] ?? [])) {
289+
if (!$this->formsService->areExtraSettingsValid($oldQuestion['extraSettings'], $type)) {
290+
throw new OCSBadRequestException('Invalid question data: invalid extraSettings');
291+
}
292+
}
293+
249294
$questionData = $oldQuestion;
250295
$oldQuestionId = $oldQuestion['id'];
251296
$options = $oldQuestion['options'] ?? [];
@@ -271,6 +316,15 @@ public function newForm(?int $fromId = null, ?bool $import = false, ?array $form
271316
foreach ($options as $oldOption) {
272317
$optionData = $import ? $oldOption : $oldOption->read();
273318

319+
if ($import) {
320+
// Validate option property whitelist
321+
$allowedOptionProperties = ['text', 'order', 'optionType'];
322+
$invalidOptionKeys = array_diff(array_keys($optionData), $allowedOptionProperties);
323+
if (!empty($invalidOptionKeys)) {
324+
throw new OCSBadRequestException('Invalid option data: unknown properties: ' . implode(', ', $invalidOptionKeys));
325+
}
326+
}
327+
274328
unset($optionData['id']);
275329
$optionData['questionId'] = $newQuestion->getId();
276330
$newOption = Option::fromParams($optionData);

0 commit comments

Comments
 (0)