diff --git a/app/V1Module/presenters/UploadedFilesPresenter.php b/app/V1Module/presenters/UploadedFilesPresenter.php index f2bef12e5..aa5c978b9 100644 --- a/app/V1Module/presenters/UploadedFilesPresenter.php +++ b/app/V1Module/presenters/UploadedFilesPresenter.php @@ -2,9 +2,11 @@ namespace App\V1Module\Presenters; +use App\Helpers\MetaFormats\Attributes\File; use App\Helpers\MetaFormats\Attributes\Post; use App\Helpers\MetaFormats\Attributes\Query; use App\Helpers\MetaFormats\Attributes\Path; +use App\Helpers\MetaFormats\FileRequestType; use App\Helpers\MetaFormats\Validators\VInt; use App\Helpers\MetaFormats\Validators\VString; use App\Helpers\MetaFormats\Validators\VUuid; @@ -321,6 +323,7 @@ public function checkUpload() * @throws CannotReceiveUploadedFileException * @throws InternalServerException */ + #[File(FileRequestType::FormData, "The whole file to be uploaded")] public function actionUpload() { $user = $this->getCurrentUser(); @@ -440,6 +443,7 @@ public function checkAppendPartial(string $id) */ #[Query("offset", new VInt(), "Offset of the chunk for verification", required: true)] #[Path("id", new VUuid(), "Identifier of the partial file", required: true)] + #[File(FileRequestType::OctetStream, "A chunk of the uploaded file", required: false)] public function actionAppendPartial(string $id, int $offset) { $partialFile = $this->uploadedPartialFiles->findOrThrow($id); diff --git a/app/V1Module/presenters/base/BasePresenter.php b/app/V1Module/presenters/base/BasePresenter.php index 59242990f..04dfe8e87 100644 --- a/app/V1Module/presenters/base/BasePresenter.php +++ b/app/V1Module/presenters/base/BasePresenter.php @@ -26,6 +26,7 @@ use App\Responses\StorageFileResponse; use App\Responses\ZipFilesResponse; use Nette\Application\Application; +use Nette\Http\FileUpload; use Nette\Http\IResponse; use Tracy\ILogger; use ReflectionClass; @@ -213,7 +214,14 @@ private function processParams(ReflectionMethod $reflection) } // handle loose parameters - $paramData = MetaFormatHelper::extractRequestParamData($reflection); + + // cache the data from the loose attributes to improve performance + $actionPath = get_class($this) . $reflection->name; + if (!FormatCache::looseParametersCached($actionPath)) { + $newParamData = MetaFormatHelper::extractRequestParamData($reflection); + FormatCache::cacheLooseParameters($actionPath, $newParamData); + } + $paramData = FormatCache::getLooseParameters($actionPath); $this->processParamsLoose($paramData); } @@ -279,7 +287,7 @@ private function processParamsFormat(string $format, ?array $valueDictionary): M } // this throws if the value is invalid - $formatInstance->checkedAssign($fieldName, $value); + $formatInstance->checkedAssignWithSchema($requestParamData, $fieldName, $value); } // validate structural constraints @@ -305,6 +313,8 @@ private function getValueFromParamData(RequestParamData $paramData): mixed return $this->getQueryField($paramData->name, required: $paramData->required); case Type::Path: return $this->getPathField($paramData->name); + case Type::File: + return $this->getFileField(required: $paramData->required); default: throw new InternalServerException("Unknown parameter type: {$paramData->type->name}"); } @@ -338,6 +348,30 @@ private function getPostField($param, $required = true) } } + /** + * @param bool $required Whether the file field is required. + * @throws BadRequestException Thrown when the number of files is not 1 (and the field is required). + * @return FileUpload|null Returns a FileUpload object or null if the file was optional and not sent. + */ + private function getFileField(bool $required = true): FileUpload | null + { + $req = $this->getRequest(); + $files = $req->getFiles(); + + if (count($files) === 0) { + if ($required) { + throw new BadRequestException("No file was uploaded"); + } else { + return null; + } + } elseif (count($files) > 1) { + throw new BadRequestException("Too many files were uploaded"); + } + + $file = array_pop($files); + return $file; + } + private function getQueryField($param, $required = true) { $value = $this->getRequest()->getParameter($param); diff --git a/app/helpers/MetaFormats/Attributes/FFile.php b/app/helpers/MetaFormats/Attributes/FFile.php new file mode 100644 index 000000000..2714a7961 --- /dev/null +++ b/app/helpers/MetaFormats/Attributes/FFile.php @@ -0,0 +1,28 @@ + => [ => RequestParamData, ...], ...] * mapping formats to their fields and field metadata. diff --git a/app/helpers/MetaFormats/MetaFormat.php b/app/helpers/MetaFormats/MetaFormat.php index 8138eff92..e6f724615 100644 --- a/app/helpers/MetaFormats/MetaFormat.php +++ b/app/helpers/MetaFormats/MetaFormat.php @@ -41,6 +41,21 @@ public function checkedAssign(string $fieldName, mixed $value) $this->$fieldName = $value; } + /** + * Tries to assign a value to a field. If the value does not conform to the provided schema, an exception is thrown. + * The exception details why the value does not conform to the format. + * More performant version of checkedAssign. + * @param RequestParamData $requestParamData The schema of the request parameter. + * @param string $fieldName The name of the field. + * @param mixed $value The value to be assigned. + * @throws InvalidApiArgumentException Thrown when the value is not assignable. + */ + public function checkedAssignWithSchema(RequestParamData $requestParamData, string $fieldName, mixed $value) + { + $requestParamData->conformsToDefinition($value); + $this->$fieldName = $value; + } + /** * Validates the given format. * @throws InvalidApiArgumentException Thrown when a value is not assignable. diff --git a/app/helpers/MetaFormats/MetaFormatHelper.php b/app/helpers/MetaFormats/MetaFormatHelper.php index 5c7ec8872..e25363eb0 100644 --- a/app/helpers/MetaFormats/MetaFormatHelper.php +++ b/app/helpers/MetaFormats/MetaFormatHelper.php @@ -3,6 +3,8 @@ namespace App\Helpers\MetaFormats; use App\Exceptions\InternalServerException; +use App\Helpers\MetaFormats\Attributes\FFile; +use App\Helpers\MetaFormats\Attributes\File; use App\Helpers\MetaFormats\Attributes\Format; use App\Helpers\MetaFormats\Attributes\FormatParameterAttribute; use App\Helpers\MetaFormats\Attributes\FPath; @@ -50,8 +52,9 @@ public static function getEndpointAttributes(ReflectionMethod $reflectionMethod) $path = $reflectionMethod->getAttributes(name: Path::class); $query = $reflectionMethod->getAttributes(name: Query::class); $post = $reflectionMethod->getAttributes(name: Post::class); + $file = $reflectionMethod->getAttributes(name: File::class); $param = $reflectionMethod->getAttributes(name: Param::class); - return array_merge($path, $query, $post, $param); + return array_merge($path, $query, $post, $file, $param); } /** @@ -91,7 +94,14 @@ public static function extractFormatParameterData(ReflectionProperty $reflection $pathAttributes = $reflectionObject->getAttributes(FPath::class); $queryAttributes = $reflectionObject->getAttributes(FQuery::class); $postAttributes = $reflectionObject->getAttributes(FPost::class); - $requestAttributes = array_merge($longAttributes, $pathAttributes, $queryAttributes, $postAttributes); + $fileAttributes = $reflectionObject->getAttributes(FFile::class); + $requestAttributes = array_merge( + $longAttributes, + $pathAttributes, + $queryAttributes, + $postAttributes, + $fileAttributes + ); // there should be only one attribute if (count($requestAttributes) == 0) { diff --git a/app/helpers/MetaFormats/RequestParamData.php b/app/helpers/MetaFormats/RequestParamData.php index 203d135ef..c5b87ac79 100644 --- a/app/helpers/MetaFormats/RequestParamData.php +++ b/app/helpers/MetaFormats/RequestParamData.php @@ -6,6 +6,7 @@ use App\Exceptions\InvalidApiArgumentException; use App\Helpers\MetaFormats\Validators\BaseValidator; use App\Helpers\MetaFormats\Validators\VArray; +use App\Helpers\MetaFormats\Validators\VFile; use App\Helpers\MetaFormats\Validators\VObject; use App\Helpers\Swagger\AnnotationParameterData; @@ -143,6 +144,12 @@ public function toAnnotationParameterData() }, $nestedRequestParmData); } + // get file request type if file + $fileRequestType = null; + if ($this->validators[0] instanceof VFile) { + $fileRequestType = $this->validators[0]->fileRequestType; + } + return new AnnotationParameterData( $swaggerType, $this->name, @@ -155,6 +162,7 @@ public function toAnnotationParameterData() $arrayDepth, $nestedObjectParameterData, $constraints, + $fileRequestType, ); } } diff --git a/app/helpers/MetaFormats/Type.php b/app/helpers/MetaFormats/Type.php index 32b5f06b9..a963c04fe 100644 --- a/app/helpers/MetaFormats/Type.php +++ b/app/helpers/MetaFormats/Type.php @@ -11,5 +11,6 @@ enum Type case Post; case Query; case Path; + case File; } // @codingStandardsIgnoreEnd diff --git a/app/helpers/MetaFormats/Validators/VFile.php b/app/helpers/MetaFormats/Validators/VFile.php new file mode 100644 index 000000000..051a448d4 --- /dev/null +++ b/app/helpers/MetaFormats/Validators/VFile.php @@ -0,0 +1,25 @@ +fileRequestType = $fileRequestType; + } + + public function validate(mixed $value): bool + { + return true; + } +} diff --git a/app/helpers/Swagger/AnnotationData.php b/app/helpers/Swagger/AnnotationData.php index 57d127e9f..b0d0a2ce5 100644 --- a/app/helpers/Swagger/AnnotationData.php +++ b/app/helpers/Swagger/AnnotationData.php @@ -2,7 +2,9 @@ namespace App\Helpers\Swagger; +use App\Exceptions\InternalServerException; use App\Helpers\MetaFormats\AnnotationConversion\Utils; +use App\Helpers\MetaFormats\FileRequestType; /** * A data structure for endpoint signatures that can produce annotations parsable by a swagger generator. @@ -25,6 +27,10 @@ class AnnotationData * @var AnnotationParameterData[] */ public array $bodyParams; + /** + * @var AnnotationParameterData[] + */ + public array $fileParams; public ?string $endpointDescription; public function __construct( @@ -34,6 +40,7 @@ public function __construct( array $pathParams, array $queryParams, array $bodyParams, + array $fileParams, ?string $endpointDescription = null, ) { $this->className = $className; @@ -42,12 +49,13 @@ public function __construct( $this->pathParams = $pathParams; $this->queryParams = $queryParams; $this->bodyParams = $bodyParams; + $this->fileParams = $fileParams; $this->endpointDescription = $endpointDescription; } public function getAllParams(): array { - return array_merge($this->pathParams, $this->queryParams, $this->bodyParams); + return array_merge($this->pathParams, $this->queryParams, $this->bodyParams, $this->fileParams); } /** @@ -63,24 +71,93 @@ private function getHttpMethodAnnotation(): string } /** - * Creates a JSON request body annotation string parsable by the swagger generator. - * Example: if the request body contains only the 'url' property, this method will produce: - * '@OA\RequestBody(@OA\MediaType(mediaType="application/json",@OA\Schema(@OA\Property(property="url",type="string"))))' - * @return string|null Returns the annotation string or null, if there are no body parameters. + * Creates a requestBody annotation string parsable by the swagger generator. + * Processes JSON request body and files (form-data, octet-stream). + * @return string|null Returns the annotation string or null, if there is no body. */ private function getBodyAnnotation(): string | null { - if (count($this->bodyParams) === 0) { + $head = '@OA\RequestBody'; + $body = new ParenthesesBuilder(); + + // add the json schema + $jsonSchema = $this->serializeBodyParams( + "application/json", + $this->bodyParams + ); + if ($jsonSchema !== null) { + $body->addValue($jsonSchema); + } + + // add the file schema + $fileSchema = $this->getFileAnnotation(); + if ($fileSchema !== null) { + $body->addValue($fileSchema); + } + + if ($jsonSchema === null && $fileSchema === null) { return null; } - // only json is supported due to the media type - $head = '@OA\RequestBody(@OA\MediaType(mediaType="application/json",@OA\Schema'; + return $head . $body->toString(); + } + + private function getFileAnnotation(): string | null + { + if (count($this->fileParams) === 0) { + return null; + } + + // filter file params based on type + $formParams = []; + $octetParams = []; + foreach ($this->fileParams as $fileParam) { + if ($fileParam->fileRequestType === FileRequestType::FormData) { + $formParams[] = $fileParam; + } elseif ($fileParam->fileRequestType === FileRequestType::OctetStream) { + $octetParams[] = $fileParam; + } elseif ($fileParam->fileRequestType === null) { + throw new InternalServerException("The FileRequestType is null"); + } else { + throw new InternalServerException("Unknown FileRequestType: " . $fileParam->fileRequestType->name); + } + } + + if (count($formParams) > 0 && count($octetParams) > 0) { + throw new InternalServerException("File requests cannot upload files as both form-data and octet-stream."); + } + if (count($octetParams) > 1) { + throw new InternalServerException("There can only be one octet-stream per request."); + } + + // generate a form-data or octet-stream annotation + if (count($formParams) > 0) { + return $this->serializeBodyParams("multipart/form-data", $formParams); + } else { + return $this->getOctetStreamAnnotation($octetParams[0]); + } + } + + /** + * Creates a content annotation string parsable by the swagger generator. + * Example: if a JSON request body contains only the 'url' property, this method will produce: + * '@OA\MediaType(mediaType="application/json",@OA\Schema(@OA\Property(property="url",type="string")))' + * @param string $mediaType The media type of the parameters ("application/json", "multipart/form-data"). + * @param array $bodyParams AnnotationParameterData array used to generate the annotation. + * @return string|null Returns the annotation string or null, if there are no body parameters. + */ + private function serializeBodyParams(string $mediaType, array $bodyParams): string | null + { + if (count($bodyParams) === 0) { + return null; + } + + $head = '@OA\MediaType(mediaType="' . $mediaType . '",@OA\Schema'; $body = new ParenthesesBuilder(); // list of all required properties $required = []; - foreach ($this->bodyParams as $bodyParam) { + foreach ($bodyParams as $bodyParam) { $body->addValue($bodyParam->toPropertyAnnotation()); if ($bodyParam->required) { // add quotes around the names (required by the swagger generator) @@ -95,7 +172,17 @@ private function getBodyAnnotation(): string | null $body->addValue("required=" . $requiredString); } - return $head . $body->toString() . "))"; + return $head . $body->toString() . ")"; + } + + private function getOctetStreamAnnotation(AnnotationParameterData $octetParam): string + { + $head = '@OA\MediaType(mediaType="application/octet-stream",@OA\Schema'; + $body = new ParenthesesBuilder(); + + $body->addKeyValue("type", $octetParam->swaggerType); + $body->addKeyValue("format", "binary"); + return $head . $body->toString() . ")"; } /** @@ -137,9 +224,9 @@ public function toSwaggerAnnotations(string $route) $body->addValue($queryParam->toParameterAnnotation()); } - $jsonProperties = $this->getBodyAnnotation(); - if ($jsonProperties !== null) { - $body->addValue($jsonProperties); + $bodyProperties = $this->getBodyAnnotation(); + if ($bodyProperties !== null) { + $body->addValue($bodyProperties); } ///TODO: A placeholder for the response type. This has to be replaced with the autogenerated meta-view diff --git a/app/helpers/Swagger/AnnotationHelper.php b/app/helpers/Swagger/AnnotationHelper.php index c28a12e09..6eddf5f7f 100644 --- a/app/helpers/Swagger/AnnotationHelper.php +++ b/app/helpers/Swagger/AnnotationHelper.php @@ -294,6 +294,7 @@ private static function annotationParameterDataToAnnotationData( $pathParams = []; $queryParams = []; $bodyParams = []; + $fileParams = []; foreach ($params as $param) { if ($param->location === 'path') { @@ -302,6 +303,8 @@ private static function annotationParameterDataToAnnotationData( $queryParams[] = $param; } elseif ($param->location === 'post') { $bodyParams[] = $param; + } elseif ($param->location === 'file') { + $fileParams[] = $param; } else { throw new Exception("Error in extractAnnotationData: Unknown param location: {$param->location}"); } @@ -314,6 +317,7 @@ private static function annotationParameterDataToAnnotationData( $pathParams, $queryParams, $bodyParams, + $fileParams, $description ); } @@ -364,13 +368,13 @@ public static function extractAttributeData(string $className, string $methodNam $httpMethod = self::extractAnnotationHttpMethod($methodAnnotations); $reflectionMethod = self::getMethod($className, $methodName); + // extract loose attributes + $attributeData = MetaFormatHelper::extractRequestParamData($reflectionMethod); + + // if the endpoint is linked to a format, add the format class attributes $format = MetaFormatHelper::extractFormatFromAttribute($reflectionMethod); - // if the endpoint is linked to a format, use the format class if ($format !== null) { - $attributeData = FormatCache::getFieldDefinitions($format); - // otherwise use loose param attributes - } else { - $attributeData = MetaFormatHelper::extractRequestParamData($reflectionMethod); + $attributeData = array_merge($attributeData, FormatCache::getFieldDefinitions($format)); } $params = array_map(function ($data) { diff --git a/app/helpers/Swagger/AnnotationParameterData.php b/app/helpers/Swagger/AnnotationParameterData.php index 6ee06bd27..8d22599a1 100644 --- a/app/helpers/Swagger/AnnotationParameterData.php +++ b/app/helpers/Swagger/AnnotationParameterData.php @@ -3,6 +3,8 @@ namespace App\Helpers\Swagger; use App\Exceptions\InternalServerException; +use App\Helpers\MetaFormats\FileRequestType; +use App\Helpers\MetaFormats\Type; /** * Contains data of a single annotation parameter. @@ -21,6 +23,7 @@ class AnnotationParameterData public ?int $arrayDepth; public ?array $nestedObjectParameterData; public ?ParameterConstraints $constraints; + public ?FileRequestType $fileRequestType; public function __construct( string $swaggerType, @@ -34,6 +37,7 @@ public function __construct( ?int $arrayDepth = null, ?array $nestedObjectParameterData = null, ?ParameterConstraints $constraints = null, + ?FileRequestType $fileRequestType = null, ) { $this->swaggerType = $swaggerType; $this->name = $name; @@ -46,6 +50,7 @@ public function __construct( $this->arrayDepth = $arrayDepth; $this->nestedObjectParameterData = $nestedObjectParameterData; $this->constraints = $constraints; + $this->fileRequestType = $fileRequestType; } private function addArrayItemsIfArray(ParenthesesBuilder $container) @@ -105,6 +110,15 @@ private function addObjectParamsIfObject(ParenthesesBuilder $container) } } + private function addFileParamsIfFile(ParenthesesBuilder $container) + { + if ($this->location !== strtolower(Type::File->name)) { + return; + } + + $container->addKeyValue("format", "binary"); + } + /** * Generates swagger schema annotations based on the data type. * @return string Returns the annotation. @@ -116,6 +130,11 @@ private function generateSchemaAnnotation(): string $body->addKeyValue("type", $this->swaggerType); $body->addKeyValue("nullable", $this->nullable); + + if ($this->swaggerType !== "array") { + $this->constraints?->addConstraints($body); + } + $this->addArrayItemsIfArray($body); return $head . $body->toString(); @@ -170,6 +189,9 @@ public function toPropertyAnnotation(): string // handle objects $this->addObjectParamsIfObject($body); + // handle files + $this->addFileParamsIfFile($body); + // add example value if ($this->swaggerType !== "array" && $this->swaggerType !== "object") { if ($this->example != null) { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 226e9fd7e..1f3fe7a2b 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -232,6 +232,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -248,6 +249,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -512,6 +514,8 @@ paths: required: false schema: type: string + maxLength: 32 + minLength: 1 nullable: false - name: force @@ -537,6 +541,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -553,6 +558,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -626,6 +632,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -643,6 +650,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -673,6 +681,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -702,6 +711,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: archived @@ -727,6 +737,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -757,6 +768,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: groupId @@ -781,6 +793,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: groupId @@ -806,6 +819,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: name @@ -814,6 +828,8 @@ paths: required: true schema: type: string + maxLength: 32 + minLength: 1 nullable: false responses: '200': @@ -830,6 +846,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: name @@ -855,6 +872,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -885,6 +903,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -916,6 +935,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -946,6 +966,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -976,6 +997,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -992,6 +1014,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -1021,6 +1044,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: fileId @@ -1046,6 +1070,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1063,6 +1088,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1079,6 +1105,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -1108,6 +1135,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: fileId @@ -1133,6 +1161,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1150,6 +1179,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1166,6 +1196,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -1196,6 +1227,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1212,6 +1244,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -1242,6 +1275,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1258,6 +1292,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -1288,6 +1323,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -1324,6 +1360,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: runtimeEnvironmentId @@ -1356,6 +1393,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: runtimeEnvironmentId @@ -1401,6 +1439,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: runtimeEnvironmentId @@ -1434,6 +1473,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1450,6 +1490,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -1480,6 +1521,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1496,6 +1538,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -1556,6 +1599,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1572,6 +1616,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -1720,6 +1765,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1737,6 +1783,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1754,6 +1801,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1771,6 +1819,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1788,6 +1837,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: userId @@ -1813,6 +1863,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: userId @@ -1838,6 +1889,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -1868,6 +1920,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1885,6 +1938,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: userId @@ -1910,6 +1964,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -1959,6 +2014,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1975,6 +2031,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -1992,6 +2049,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: userId @@ -2030,6 +2088,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -2206,6 +2265,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -2222,6 +2282,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -2282,6 +2343,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -2299,6 +2361,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -2316,6 +2379,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -2346,6 +2410,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -2376,6 +2441,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -2415,6 +2481,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -2432,6 +2499,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: examId @@ -2457,6 +2525,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: newParentId @@ -2482,6 +2551,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -2499,6 +2569,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: userId @@ -2523,6 +2594,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: userId @@ -2547,6 +2619,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: userId @@ -2572,6 +2645,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: userId @@ -2597,6 +2671,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: userId @@ -2621,6 +2696,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: userId @@ -2646,6 +2722,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -2663,6 +2740,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: userId @@ -2701,6 +2779,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: userId @@ -2726,6 +2805,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -2743,6 +2823,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -2811,6 +2892,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -2827,6 +2909,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -2859,6 +2942,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -2876,6 +2960,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -2957,6 +3042,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -3013,6 +3099,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -3029,6 +3116,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -3056,6 +3144,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -3073,6 +3162,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -3089,6 +3179,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -3364,6 +3455,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -3409,6 +3501,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -3540,6 +3633,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -3556,6 +3650,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -3586,6 +3681,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -3603,6 +3699,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -3637,6 +3734,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -3654,6 +3752,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: flag @@ -3692,6 +3791,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -3720,6 +3820,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -3737,6 +3838,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -3821,6 +3923,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -3837,6 +3940,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -3866,6 +3970,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -3883,6 +3988,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -3938,6 +4044,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: commentId @@ -3987,6 +4094,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: commentId @@ -4012,6 +4120,7 @@ paths: required: false schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: groupId @@ -4020,6 +4129,7 @@ paths: required: false schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: userId @@ -4028,6 +4138,7 @@ paths: required: false schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4061,6 +4172,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4078,6 +4190,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -4143,6 +4256,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: offset @@ -4152,6 +4266,12 @@ paths: schema: type: integer nullable: false + requestBody: + content: + application/octet-stream: + schema: + type: string + format: binary responses: '200': description: 'The data' @@ -4167,6 +4287,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4183,6 +4304,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4192,6 +4314,19 @@ paths: summary: 'Upload a file' description: 'Upload a file' operationId: uploadedFilesPresenterActionUpload + requestBody: + content: + multipart/form-data: + schema: + required: + - file + properties: + file: + description: 'The whole file to be uploaded' + type: string + format: binary + nullable: false + type: object responses: '200': description: 'The data' @@ -4208,6 +4343,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4225,6 +4361,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4242,6 +4379,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: entry @@ -4250,6 +4388,7 @@ paths: required: false schema: type: string + minLength: 1 nullable: false - name: similarSolutionId @@ -4258,6 +4397,7 @@ paths: required: false schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4275,6 +4415,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: entry @@ -4283,6 +4424,7 @@ paths: required: false schema: type: string + minLength: 1 nullable: false - name: similarSolutionId @@ -4291,6 +4433,7 @@ paths: required: false schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4308,6 +4451,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4634,6 +4778,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4650,6 +4795,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -4721,6 +4867,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4738,6 +4885,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4755,6 +4903,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4772,6 +4921,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4789,6 +4939,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4806,6 +4957,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -4889,6 +5041,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -4924,6 +5077,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -4941,6 +5095,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -4972,6 +5127,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: service @@ -5011,6 +5167,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: service @@ -5036,6 +5193,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -5052,6 +5210,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -5069,6 +5228,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -5086,6 +5246,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -5275,6 +5436,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -5303,6 +5465,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -5319,6 +5482,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -5374,6 +5538,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -5391,6 +5556,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -5408,6 +5574,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -5438,6 +5605,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -5454,6 +5622,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -5483,6 +5652,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: fileId @@ -5508,6 +5678,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -5933,6 +6104,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -5949,6 +6121,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -6012,6 +6185,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -6049,6 +6223,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -6079,6 +6254,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -6261,6 +6437,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -6321,6 +6498,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -6355,6 +6533,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -6397,6 +6576,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -6422,6 +6602,8 @@ paths: required: false schema: type: string + maxLength: 255 + minLength: 1 nullable: false - name: solutionId @@ -6430,6 +6612,7 @@ paths: required: false schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -6475,6 +6658,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false responses: '200': @@ -6491,6 +6675,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false requestBody: content: @@ -6524,6 +6709,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: solutionId @@ -6548,6 +6734,7 @@ paths: required: true schema: type: string + pattern: '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' nullable: false - name: solutionId @@ -6628,6 +6815,8 @@ paths: required: false schema: type: string + maxLength: 2 + minLength: 2 nullable: false - name: return