Added new API calls for project attachements

This commit is contained in:
Frederic Guillot 2016-06-26 15:17:38 -04:00
parent 3d34681610
commit f621129836
No known key found for this signature in database
GPG Key ID: 92D77191BA7FBC99
12 changed files with 370 additions and 11 deletions

View File

@ -5,7 +5,7 @@ New features:
* Added application and project roles validation for API procedure calls
* Added new API call: "getProjectByIdentifier"
* Added new API calls for external task links
* Added new API calls for external task links, project attachments
Improvements:

View File

@ -0,0 +1,68 @@
<?php
namespace Kanboard\Api\Procedure;
use Kanboard\Api\Authorization\ProjectAuthorization;
use Kanboard\Core\ObjectStorage\ObjectStorageException;
/**
* Project File API controller
*
* @package Kanboard\Api\Procedure
* @author Frederic Guillot
*/
class ProjectFileProcedure extends BaseProcedure
{
public function getProjectFile($project_id, $file_id)
{
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getProjectFile', $project_id);
return $this->projectFileModel->getById($file_id);
}
public function getAllProjectFiles($project_id)
{
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'getAllProjectFiles', $project_id);
return $this->projectFileModel->getAll($project_id);
}
public function downloadProjectFile($project_id, $file_id)
{
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'downloadProjectFile', $project_id);
try {
$file = $this->projectFileModel->getById($file_id);
if (! empty($file)) {
return base64_encode($this->objectStorage->get($file['path']));
}
} catch (ObjectStorageException $e) {
$this->logger->error($e->getMessage());
}
return '';
}
public function createProjectFile($project_id, $filename, $blob)
{
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'createProjectFile', $project_id);
try {
return $this->projectFileModel->uploadContent($project_id, $filename, $blob);
} catch (ObjectStorageException $e) {
$this->logger->error(__METHOD__.': '.$e->getMessage());
return false;
}
}
public function removeProjectFile($project_id, $file_id)
{
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeProjectFile', $project_id);
return $this->projectFileModel->remove($file_id);
}
public function removeAllProjectFiles($project_id)
{
ProjectAuthorization::getInstance($this->container)->check($this->getClassName(), 'removeAllProjectFiles', $project_id);
return $this->projectFileModel->removeAll($project_id);
}
}

View File

@ -5,7 +5,7 @@ namespace Kanboard\Api\Procedure;
use Kanboard\Api\Authorization\SubtaskAuthorization;
/**
* Subtask Time Tracking API controller
* Subtask Time Tracking API controller
*
* @package Kanboard\Api\Procedure
* @author Frederic Guillot
@ -25,13 +25,13 @@ class SubtaskTimeTrackingProcedure extends BaseProcedure
return $this->subtaskTimeTrackingModel->logStartTime($subtask_id, $user_id);
}
public function logSubtaskEndTime($subtask_id,$user_id)
public function logSubtaskEndTime($subtask_id, $user_id)
{
SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'logSubtaskEndTime', $subtask_id);
return $this->subtaskTimeTrackingModel->logEndTime($subtask_id, $user_id);
}
public function getSubtaskTimeSpent($subtask_id,$user_id)
public function getSubtaskTimeSpent($subtask_id, $user_id)
{
SubtaskAuthorization::getInstance($this->container)->check($this->getClassName(), 'getSubtaskTimeSpent', $subtask_id);
return $this->subtaskTimeTrackingModel->getTimeSpent($subtask_id, $user_id);

View File

@ -30,7 +30,7 @@ class TaskFileProcedure extends BaseProcedure
public function downloadTaskFile($file_id)
{
TaskFileAuthorization::getInstance($this->container)->check($this->getClassName(), 'downloadTaskFile', $file_id);
try {
$file = $this->taskFileModel->getById($file_id);
@ -51,7 +51,7 @@ class TaskFileProcedure extends BaseProcedure
try {
return $this->taskFileModel->uploadContent($task_id, $filename, $blob);
} catch (ObjectStorageException $e) {
$this->logger->error($e->getMessage());
$this->logger->error(__METHOD__.': '.$e->getMessage());
return false;
}
}

View File

@ -9,6 +9,7 @@ use Kanboard\Api\Procedure\BoardProcedure;
use Kanboard\Api\Procedure\CategoryProcedure;
use Kanboard\Api\Procedure\ColumnProcedure;
use Kanboard\Api\Procedure\CommentProcedure;
use Kanboard\Api\Procedure\ProjectFileProcedure;
use Kanboard\Api\Procedure\TaskExternalLinkProcedure;
use Kanboard\Api\Procedure\TaskFileProcedure;
use Kanboard\Api\Procedure\GroupProcedure;
@ -58,6 +59,7 @@ class ApiProvider implements ServiceProviderInterface
->withObject(new CategoryProcedure($container))
->withObject(new CommentProcedure($container))
->withObject(new TaskFileProcedure($container))
->withObject(new ProjectFileProcedure($container))
->withObject(new LinkProcedure($container))
->withObject(new ProjectProcedure($container))
->withObject(new ProjectPermissionProcedure($container))

View File

@ -202,6 +202,7 @@ class AuthenticationProvider implements ServiceProviderInterface
$acl->add('SubtaskProcedure', '*', Role::PROJECT_MEMBER);
$acl->add('SubtaskTimeTrackingProcedure', '*', Role::PROJECT_MEMBER);
$acl->add('SwimlaneProcedure', '*', Role::PROJECT_MANAGER);
$acl->add('ProjectFileProcedure', '*', Role::PROJECT_MEMBER);
$acl->add('TaskFileProcedure', '*', Role::PROJECT_MEMBER);
$acl->add('TaskLinkProcedure', '*', Role::PROJECT_MEMBER);
$acl->add('TaskExternalLinkProcedure', array('createExternalTaskLink', 'updateExternalTaskLink', 'removeExternalTaskLink'), Role::PROJECT_MEMBER);

View File

@ -58,7 +58,8 @@ Usage
- [Automatic Actions](api-action-procedures.markdown)
- [Tasks](api-task-procedures.markdown)
- [Subtasks](api-subtask-procedures.markdown)
- [Files](api-file-procedures.markdown)
- [Task Files](api-task-file-procedures.markdown)
- [Project Files](api-project-file-procedures.markdown)
- [Links](api-link-procedures.markdown)
- [Internal Task Links](api-internal-task-link-procedures.markdown)
- [External Task Links](api-external-task-link-procedures.markdown)

View File

@ -0,0 +1,221 @@
Project File API Procedures
===========================
## createProjectFile
- Purpose: **Create and upload a new project attachment**
- Parameters:
- **project_id** (integer, required)
- **filename** (integer, required)
- **blob** File content encoded in base64 (string, required)
- Result on success: **file_id**
- Result on failure: **false**
- Note: **The maximum file size depends of your PHP configuration, this method should not be used to upload large files**
Request example:
```json
{
"jsonrpc": "2.0",
"method": "createProjectFile",
"id": 94500810,
"params": [
1,
"My file",
"cGxhaW4gdGV4dCBmaWxl"
]
}
```
Response example:
```json
{
"jsonrpc": "2.0",
"id": 94500810,
"result": 1
}
```
## getAllProjectFiles
- Purpose: **Get all files attached to a project**
- Parameters:
- **project_id** (integer, required)
- Result on success: **list of files**
- Result on failure: **false**
Request example:
```json
{
"jsonrpc": "2.0",
"method": "getAllProjectFiles",
"id": 1880662820,
"params": {
"project_id": 1
}
}
```
Response example:
```json
{
"jsonrpc": "2.0",
"id": 1880662820,
"result": [
{
"id": "1",
"name": "My file",
"path": "1\/1\/0db4d0a897a4c852f6e12f0239d4805f7b4ab596",
"is_image": "0",
"project_id": "1",
"date": "1432509941",
"user_id": "0",
"size": "15",
"username": null,
"user_name": null
}
]
}
```
## getProjectFile
- Purpose: **Get file information**
- Parameters:
- **project_id** (integer, required)
- **file_id** (integer, required)
- Result on success: **file properties**
- Result on failure: **false**
Request example:
```json
{
"jsonrpc": "2.0",
"method": "getProjectFile",
"id": 318676852,
"params": [
"42",
"1"
]
}
```
Response example:
```json
{
"jsonrpc": "2.0",
"id": 318676852,
"result": {
"id": "1",
"name": "My file",
"path": "1\/1\/0db4d0a897a4c852f6e12f0239d4805f7b4ab596",
"is_image": "0",
"project_id": "1",
"date": "1432509941",
"user_id": "0",
"size": "15"
}
}
```
## downloadProjectFile
- Purpose: **Download project file contents (encoded in base64)**
- Parameters:
- **project_id** (integer, required)
- **file_id** (integer, required)
- Result on success: **base64 encoded string**
- Result on failure: **empty string**
Request example:
```json
{
"jsonrpc": "2.0",
"method": "downloadProjectFile",
"id": 235943344,
"params": [
"1",
"1"
]
}
```
Response example:
```json
{
"jsonrpc": "2.0",
"id": 235943344,
"result": "cGxhaW4gdGV4dCBmaWxl"
}
```
## removeProjectFile
- Purpose: **Remove a file associated to a project**
- Parameters:
- **project_id** (integer, required)
- **file_id** (integer, required)
- Result on success: **true**
- Result on failure: **false**
Request example:
```json
{
"jsonrpc": "2.0",
"method": "removeProjectFile",
"id": 447036524,
"params": [
"1",
"1"
]
}
```
Response example:
```json
{
"jsonrpc": "2.0",
"id": 447036524,
"result": true
}
```
## removeAllProjectFiles
- Purpose: **Remove all files associated to a project**
- Parameters:
- **project_id** (integer, required)
- Result on success: **true**
- Result on failure: **false**
Request example:
```json
{
"jsonrpc": "2.0",
"method": "removeAllProjectFiles",
"id": 593312993,
"params": {
"project_id": 1
}
}
```
Response example:
```json
{
"jsonrpc": "2.0",
"id": 593312993,
"result": true
}
```

View File

@ -1,5 +1,5 @@
API File Procedures
===================
Task File API Procedures
========================
## createTaskFile

View File

@ -23,7 +23,7 @@ case "$1" in
/var/www/html/vendor/phpunit/phpunit/phpunit -c /var/www/html/tests/integration.sqlite.xml
;;
"integration-test-postgres")
wait_schema_creation 5
wait_schema_creation 10
/var/www/html/vendor/phpunit/phpunit/phpunit -c /var/www/html/tests/integration.postgres.xml
;;
"integration-test-mysql")

View File

@ -0,0 +1,66 @@
<?php
require_once __DIR__.'/BaseProcedureTest.php';
class ProjectFileProcedureTest extends BaseProcedureTest
{
protected $projectName = 'My project to test project files';
protected $fileId;
public function testAll()
{
$this->assertCreateTeamProject();
$this->assertCreateProjectFile();
$this->assertGetProjectFile();
$this->assertDownloadProjectFile();
$this->assertGetAllFiles();
$this->assertRemoveProjectFile();
$this->assertRemoveAllProjectFiles();
}
public function assertCreateProjectFile()
{
$this->fileId = $this->app->createProjectFile($this->projectId, 'My file.txt', base64_encode('plain text file'));
$this->assertNotFalse($this->fileId);
}
public function assertGetProjectFile()
{
$file = $this->app->getProjectFile($this->projectId, $this->fileId);
$this->assertNotEmpty($file);
$this->assertEquals('My file.txt', $file['name']);
}
public function assertDownloadProjectFile()
{
$content = $this->app->downloadProjectFile($this->projectId, $this->fileId);
$this->assertNotEmpty($content);
$this->assertEquals('plain text file', base64_decode($content));
}
public function assertGetAllFiles()
{
$files = $this->app->getAllProjectFiles($this->projectId);
$this->assertCount(1, $files);
$this->assertEquals('My file.txt', $files[0]['name']);
}
public function assertRemoveProjectFile()
{
$this->assertTrue($this->app->removeProjectFile($this->projectId, $this->fileId));
$files = $this->app->getAllProjectFiles($this->projectId);
$this->assertEmpty($files);
}
public function assertRemoveAllProjectFiles()
{
$this->assertCreateProjectFile();
$this->assertCreateProjectFile();
$this->assertTrue($this->app->removeAllProjectFiles($this->projectId));
$files = $this->app->getAllProjectFiles($this->projectId);
$this->assertEmpty($files);
}
}

View File

@ -21,7 +21,7 @@ class TaskFileProcedureTest extends BaseProcedureTest
public function assertCreateTaskFile()
{
$this->fileId = $this->app->createTaskFile(1, $this->taskId, 'My file', base64_encode('plain text file'));
$this->fileId = $this->app->createTaskFile($this->projectId, $this->taskId, 'My file', base64_encode('plain text file'));
$this->assertNotFalse($this->fileId);
}