From 9c2c2c1fa22aaa5c77aee1f81bcd3ff2a783ce99 Mon Sep 17 00:00:00 2001 From: Bernd Bestel Date: Thu, 27 Sep 2018 14:01:00 +0200 Subject: [PATCH] Prepare file upload API (references #58) --- controllers/FilesApiController.php | 38 +++++++++++++++++++ grocy.openapi.json | 60 ++++++++++++++++++++++++++++++ helpers/extensions.php | 10 +++++ routes.php | 3 ++ services/FilesService.php | 31 +++++++++++++++ 5 files changed, 142 insertions(+) create mode 100644 controllers/FilesApiController.php create mode 100644 services/FilesService.php diff --git a/controllers/FilesApiController.php b/controllers/FilesApiController.php new file mode 100644 index 00000000..91192e47 --- /dev/null +++ b/controllers/FilesApiController.php @@ -0,0 +1,38 @@ +FilesService = new FilesService(); + } + + protected $FilesService; + + public function Upload(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) + { + try + { + if (isset($request->getQueryParams()['file_name']) && !empty($request->getQueryParams()['file_name']) && IsValidFileName($request->getQueryParams()['file_name'])) + { + $fileName = $request->getQueryParams()['file_name']; + } + else + { + throw new \Exception('file_name query parameter missing or contains an invalid filename'); + } + + $data = $request->getBody()->getContents(); + file_put_contents($this->FilesService->GetFilePath($args['group'], $fileName), $data); + } + catch (\Exception $ex) + { + return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage()); + } + } +} diff --git a/grocy.openapi.json b/grocy.openapi.json index 5e356677..fcb0883f 100644 --- a/grocy.openapi.json +++ b/grocy.openapi.json @@ -390,6 +390,66 @@ } } }, + "/files/upload/{group}": { + "post": { + "description": "Uploads a single file to /data/storage/{group}/{file_name}", + "tags": [ + "Files" + ], + "parameters": [ + { + "in": "path", + "name": "group", + "required": true, + "description": "The file group", + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "file_name", + "required": true, + "description": "The file name (including extension)", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/octet-stream": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "responses": { + "200": { + "description": "A VoidApiActionResponse object", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VoidApiActionResponse" + } + } + } + }, + "400": { + "description": "A VoidApiActionResponse object", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorExampleVoidApiActionResponse" + } + } + } + } + } + } + }, "/users/get": { "get": { "description": "Returns all users", diff --git a/helpers/extensions.php b/helpers/extensions.php index 82a66ff2..416e2809 100644 --- a/helpers/extensions.php +++ b/helpers/extensions.php @@ -178,3 +178,13 @@ function Pluralize($number, $singularForm, $pluralForm) } return $text; } + +function IsValidFileName($fileName) +{ + if(preg_match('#^[a-z0-9]+\.[a-z]+?$#i', $fileName)) + { + return true; + } + + return false; +} diff --git a/routes.php b/routes.php index b32b22cd..57814751 100644 --- a/routes.php +++ b/routes.php @@ -82,6 +82,9 @@ $app->group('/api', function() // System $this->get('/system/get-db-changed-time', '\Grocy\Controllers\SystemApiController:GetDbChangedTime'); + // Files + $this->post('/files/upload/{group}', '\Grocy\Controllers\FilesApiController:Upload'); + // Users $this->get('/users/get', '\Grocy\Controllers\UsersApiController:GetUsers'); $this->post('/users/create', '\Grocy\Controllers\UsersApiController:CreateUser'); diff --git a/services/FilesService.php b/services/FilesService.php new file mode 100644 index 00000000..ea85f5e1 --- /dev/null +++ b/services/FilesService.php @@ -0,0 +1,31 @@ +StoragePath = GROCY_DATAPATH . '/storage'; + + if (!file_exists($this->StoragePath)) + { + mkdir($this->StoragePath); + } + } + + private $StoragePath; + + public function GetFilePath($group, $fileName) + { + $groupFolderPath = $this->StoragePath . '/' . $group; + if (!file_exists($groupFolderPath)) + { + mkdir($groupFolderPath); + } + + return $groupFolderPath . '/' . $fileName; + } +}