Attachment endpoints and minor cleanup

This commit is contained in:
Matthew Ross 2020-05-11 19:07:30 -04:00
parent 1b3cf2665f
commit f28ab24634
4 changed files with 106 additions and 43 deletions

View File

@ -15,7 +15,7 @@ class Activity extends BaseController {
// TODO: More activity types
if ($args['type'] === 'task') {
if (!$this->checkBoardAccess($this->getBoardId((int)$args['id']),
$request)) {
$request)) {
return $this->jsonResponse($response, 403);
}
@ -36,42 +36,22 @@ class Activity extends BaseController {
}
private function sortLogs($a, $b) {
if ($a->timestamp === $b->timestamp) {
return 0; // @codeCoverageIgnore
}
return $a->timestamp > $b->timestamp ? -1 : 1;
return $b->timestamp - $a->timestamp;
}
private function getTaskActivity($taskId) {
$task = R::load('task', $taskId);
$logs = [];
$commentIds = [];
$attachmentIds = [];
foreach ($task->ownComment as $comment) {
$commentIds[] = (int)$comment->id;
}
foreach ($task->ownAttachment as $attachment) {
$attachmentIds[] = (int)$attachment->id;
}
$taskActivity = R::find('activity',
'item_type="task" AND item_id=?',
$taskActivity = R::find('activity', 'item_type="task" AND item_id=?',
[$taskId]);
$this->addLogItems($logs, $taskActivity);
$commentActivity =
R::find('activity', 'item_type="comment" AND '.
'item_id IN(' . R::genSlots($commentIds) . ')',
$commentIds);
$commentActivity = R::find('activity', 'item_type="comment" AND item_id=?',
[$taskId]);
$this->addLogItems($logs, $commentActivity);
$attachmentActivity =
R::find('activity', 'item_type="attachment" AND '.
'item_id IN(' . R::genSlots($attachmentIds) . ')',
$attachmentIds);
$attachmentActivity = R::find('activity', 'item_type="attachment" AND ' .
'item_id=?', [$taskId]);
$this->addLogItems($logs, $attachmentActivity);
usort($logs, array("Activity", "sortLogs"));

View File

@ -31,6 +31,35 @@ class Attachments extends BaseController {
return $this->jsonResponse($response);
}
public function getAttachmentByHash($request, $response, $args) {
$status = $this->secureRoute($request, $response, SecurityLevel::USER);
if ($status !== 200) {
return $this->jsonResponse($response, $status);
}
$attachment = R::findOne('attachment',' diskfilename = ? ',
[$args['hash']]);
if (is_null($attachment)) {
$this->logger->error('Attempt to load attachment ' .
$args['hash'] . ' failed.');
$this->apiJson->addAlert('error', 'No attachment found for hash ' .
$args['hash'] . '.');
return $this->jsonResponse($response);
}
if (!$this->checkBoardAccess($this->getBoardId($attachment->task_id),
$request)) {
return $this->jsonResponse($response, 403);
}
$this->apiJson->setSuccess();
$this->apiJson->addData($attachment);
return $this->jsonResponse($response);
}
public function addAttachment($request, $response) {
$status = $this->secureRoute($request, $response, SecurityLevel::USER);
if ($status !== 200) {
@ -65,18 +94,67 @@ class Attachments extends BaseController {
$body = json_decode($body);
$attachment->diskfilename = sha1($body->filename);
file_put_contents('uploads/' . $attachment->diskfilename, $body->data);
R::store($attachment);
$this->apiJson->setSuccess();
$this->apiJson->addAlert('success', 'Attachment added.');
$this->apiJson->addData($attachment);
return $this->jsonResponse($response);
}
public function uploadFile($request, $response, $args) {
$status = $this->secureRoute($request, $response, SecurityLevel::USER);
if ($status !== 200) {
return $this->jsonResponse($response, $status);
}
$attachment = R::findOne('attachment',' diskfilename = ? ', [$args['hash']]);
if (is_null($attachment)) {
$this->logger->error('Upload Attachment: ', [$attachment]);
$this->apiJson->addAlert('error', 'Error uploading attachment. ' .
'Please try again.');
return $this->jsonResponse($response);
}
$task = R::load('task', $attachment->task_id);
if (!$this->checkBoardAccess($this->getBoardId($task->id), $request)) {
return $this->jsonResponse($response, 403);
}
$move = move_uploaded_file($_FILES['file']['tmp_name'],
'uploads/' . $attachment->diskfilename);
$err = $_FILES['file']['error'];
if ($err > 0 && !$move) {
$phpFileUploadErrors = array(
0 => 'There is no error, the file uploaded with success',
1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini',
2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
3 => 'The uploaded file was only partially uploaded',
4 => 'No file was uploaded',
6 => 'Missing a temporary folder',
7 => 'Failed to write file to disk.',
8 => 'A PHP extension stopped the file upload.',
);
$this->apiJson->addAlert('error', 'Failed to upload attachment. ' .
$phpFileUploadErrors[$err]);
R::trash($attachment);
return $this->jsonResponse($response, 500);
}
$actor = R::load('user', Auth::GetUserId($request));
$this->dbLogger->logChange($actor->id,
$actor->username . ' added attachment.', '', json_encode($attachment),
'attachment', $attachment->id);
$actor->username . ' added attachment ' . $attachment->filename, '',
json_encode($attachment), 'attachment', $attachment->task_id);
$this->apiJson->setSuccess();
$this->apiJson->addAlert('success', 'Attachment added.');
return $this->jsonResponse($response);
}
@ -97,8 +175,7 @@ class Attachments extends BaseController {
if ((int)$actor->security_level === SecurityLevel::USER) {
if ($actor->id !== $attachment->user_id) {
$this->apiJson->addAlert('error',
'You do not have sufficient permissions ' .
'to remove this attachment.');
'You do not have sufficient permissions to remove this attachment.');
return $this->jsonResponse($response);
}
@ -120,11 +197,15 @@ class Attachments extends BaseController {
$before = $attachment;
R::trash($attachment);
unlink('uploads/' . $before->diskfilename);
try {
unlink('uploads/' . $before->diskfilename);
} catch (Exception $ex){
$ex; // Ignore errors
}
$this->dbLogger->logChange($actor->id,
$actor->username .' removed attachment ' . $before->name,
json_encode($before), '', 'attachment', $id);
json_encode($before), '', 'attachment', $before->task_id);
$this->apiJson->setSuccess();
$this->apiJson->addAlert('success',

View File

@ -62,9 +62,10 @@ class Comments extends BaseController {
$actor = R::load('user', Auth::GetUserId($request));
$this->dbLogger->logChange($actor->id,
$actor->username . ' added comment ' . $comment->id . '.',
'', json_encode($comment), 'comment', $comment->id);
'', json_encode($comment), 'comment', $comment->task_id);
$this->apiJson->setSuccess();
$this->apiJson->addData(R::exportAll($task));
$this->apiJson->addAlert('success', 'Comment added.');
return $this->jsonResponse($response);
@ -94,8 +95,7 @@ class Comments extends BaseController {
if ((int)$actor->security_level === SecurityLevel::USER) {
if ($actor->id !== $comment->user_id) {
$this->apiJson->addAlert('error',
'You do not have sufficient permissions ' .
'to update this comment.');
'You do not have sufficient permissions to update this comment.');
return $this->jsonResponse($response);
}
@ -123,8 +123,7 @@ class Comments extends BaseController {
$this->dbLogger->logChange($actor->id,
$actor->username . ' updated comment ' . $update->id,
json_encode($comment), json_encode($update),
'comment', $update->id);
json_encode($comment), json_encode($update), 'comment', $update->task_id);
$this->apiJson->setSuccess();
$this->apiJson->addAlert('success', 'Comment updated.');
@ -175,8 +174,8 @@ class Comments extends BaseController {
R::trash($comment);
$this->dbLogger->logChange($actor->id,
$actor->username . ' removed comment ' . $before->id,
json_encode($before), '', 'comment', $id);
$actor->username . ' removed comment ' . $id,
json_encode($before), '', 'comment', $before->task_id);
$this->apiJson->setSuccess();
$this->apiJson->addAlert('success', 'Comment removed.');

View File

@ -77,9 +77,12 @@ $app->post('/comments/{id}', 'Comments:updateComment'); // BoardAdmin or submitt
$app->delete('/comments/{id}', 'Comments:removeComment'); // BoardAdmin or submitter (with board access)
$app->get('/attachments/{id}', 'Attachments:getAttachment'); // User (with board access)
$app->get('/attachments/hash/{hash}', 'Attachments:getAttachmentByHash'); // User (with board access)
$app->post('/attachments', 'Attachments:addAttachment'); // User (with board access)
$app->delete('/attachments/{id}', 'Attachments:removeAttachment'); // BoardAdmin or submitter (with board access)
$app->post('/upload/{hash}', 'Attachments:uploadFile'); // User (with board access)
$app->get('/users', 'Users:getAllUsers'); // User (by board access)
$app->get('/users/{id}', 'Users:getUser'); // User (by board access)
$app->post('/users', 'Users:addUser'); // Admin