Mostly done with attachment uploading

remotes/upstream/api-rewrite
Mike Koch 7 years ago
parent 4fd6595ded
commit 8d484f62ea

@ -1,6 +1,7 @@
<?php <?php
// Responsible for loading in all necessary classes. AKA a poor man's DI solution. // Responsible for loading in all necessary classes. AKA a poor man's DI solution.
use BusinessLogic\Attachments\AttachmentHandler;
use BusinessLogic\Categories\CategoryRetriever; use BusinessLogic\Categories\CategoryRetriever;
use BusinessLogic\Emails\BasicEmailSender; use BusinessLogic\Emails\BasicEmailSender;
use BusinessLogic\Emails\EmailSenderHelper; use BusinessLogic\Emails\EmailSenderHelper;
@ -17,7 +18,9 @@ use BusinessLogic\Tickets\NewTicketValidator;
use BusinessLogic\Tickets\TicketValidators; use BusinessLogic\Tickets\TicketValidators;
use BusinessLogic\Tickets\TrackingIdGenerator; use BusinessLogic\Tickets\TrackingIdGenerator;
use BusinessLogic\Tickets\VerifiedEmailChecker; use BusinessLogic\Tickets\VerifiedEmailChecker;
use DataAccess\Attachments\AttachmentGateway;
use DataAccess\Categories\CategoryGateway; use DataAccess\Categories\CategoryGateway;
use DataAccess\Files\FileWriter;
use DataAccess\Logging\LoggingGateway; use DataAccess\Logging\LoggingGateway;
use DataAccess\Security\BanGateway; use DataAccess\Security\BanGateway;
use DataAccess\Security\UserGateway; use DataAccess\Security\UserGateway;
@ -91,5 +94,12 @@ class ApplicationContext {
$this->get[EmailSenderHelper::class], $this->get[EmailSenderHelper::class],
$this->get[UserGateway::class], $this->get[UserGateway::class],
$this->get[ModsForHeskSettingsGateway::class]); $this->get[ModsForHeskSettingsGateway::class]);
// Attachments
$this->get[FileWriter::class] = new FileWriter();
$this->get[AttachmentGateway::class] = new AttachmentGateway();
$this->get[AttachmentHandler::class] = new AttachmentHandler($this->get[TicketGateway::class],
$this->get[AttachmentGateway::class],
$this->get[FileWriter::class]);
} }
} }

@ -32,16 +32,17 @@ class AttachmentHandler {
* @return TicketAttachment the newly created attachment * @return TicketAttachment the newly created attachment
*/ */
function createAttachmentForTicket($createAttachmentModel, $heskSettings) { function createAttachmentForTicket($createAttachmentModel, $heskSettings) {
$this->validate($createAttachmentModel); $this->validate($createAttachmentModel, $heskSettings);
$decodedAttachment = base64_decode($createAttachmentModel->attachmentContents); $decodedAttachment = base64_decode($createAttachmentModel->attachmentContents);
$ticket = $this->ticketGateway->getTicketById($createAttachmentModel->ticketId, $heskSettings); $ticket = $this->ticketGateway->getTicketById($createAttachmentModel->ticketId, $heskSettings);
$cleanedFileName = $this->cleanFileName($createAttachmentModel->displayName); $cleanedFileName = $this->cleanFileName($createAttachmentModel->displayName);
$fileParts = pathinfo($cleanedFileName);
$ticketAttachment = new TicketAttachment(); $ticketAttachment = new TicketAttachment();
$ticketAttachment->savedName = $this->generateSavedName($ticket->trackingId, $ticketAttachment->savedName = $this->generateSavedName($ticket->trackingId,
$cleanedFileName, $createAttachmentModel->fileExtension); $cleanedFileName, $fileParts['extension']);
$ticketAttachment->displayName = $cleanedFileName; $ticketAttachment->displayName = $cleanedFileName;
$ticketAttachment->ticketTrackingId = $ticket->trackingId; $ticketAttachment->ticketTrackingId = $ticket->trackingId;
$ticketAttachment->type = $createAttachmentModel->type; $ticketAttachment->type = $createAttachmentModel->type;
@ -58,9 +59,10 @@ class AttachmentHandler {
/** /**
* @param $createAttachmentModel CreateAttachmentForTicketModel * @param $createAttachmentModel CreateAttachmentForTicketModel
* @param $heskSettings array
* @throws ValidationException * @throws ValidationException
*/ */
private function validate($createAttachmentModel) { private function validate($createAttachmentModel, $heskSettings) {
$errorKeys = array(); $errorKeys = array();
if ($createAttachmentModel->attachmentContents === null || if ($createAttachmentModel->attachmentContents === null ||
trim($createAttachmentModel->attachmentContents) === '') { trim($createAttachmentModel->attachmentContents) === '') {
@ -85,7 +87,21 @@ class AttachmentHandler {
$errorKeys[] = 'INVALID_ATTACHMENT_TYPE'; $errorKeys[] = 'INVALID_ATTACHMENT_TYPE';
} }
//-- TODO Extension, size $fileParts = pathinfo($createAttachmentModel->displayName);
if (!isset($fileParts['extension']) || !in_array(".{$fileParts['extension']}", $heskSettings['attachments']['allowed_types'])) {
$errorKeys[] = 'EXTENSION_NOT_PERMITTED';
}
$fileContents = base64_decode($createAttachmentModel->attachmentContents);
if (function_exists('mb_strlen')) {
$fileSize = mb_strlen($fileContents, '8bit');
} else {
$fileSize = strlen($fileContents);
}
if ($fileSize > $heskSettings['attachments']['max_size']) {
$errorKeys[] = 'FILE_SIZE_TOO_LARGE';
}
if (count($errorKeys) > 0) { if (count($errorKeys) > 0) {
$validationModel = new ValidationModel(); $validationModel = new ValidationModel();
@ -96,6 +112,7 @@ class AttachmentHandler {
} }
private function generateSavedName($trackingId, $displayName, $fileExtension) { private function generateSavedName($trackingId, $displayName, $fileExtension) {
$fileExtension = ".{$fileExtension}";
$useChars = 'AEUYBDGHJLMNPQRSTVWXZ123456789'; $useChars = 'AEUYBDGHJLMNPQRSTVWXZ123456789';
$tmp = uniqid(); $tmp = uniqid();
for ($j = 1; $j < 10; $j++) { for ($j = 1; $j < 10; $j++) {

@ -10,9 +10,6 @@ class CreateAttachmentModel {
/* @var $displayName string */ /* @var $displayName string */
public $displayName; public $displayName;
/* @var $fileExtension string */
public $fileExtension;
/* @var $id int */ /* @var $id int */
public $fileSize; public $fileSize;

@ -1,10 +0,0 @@
<?php
namespace Controllers\Attachments;
class StaffAttachmentsController {
function post() {
}
}

@ -0,0 +1,39 @@
<?php
namespace Controllers\Attachments;
use BusinessLogic\Attachments\AttachmentHandler;
use BusinessLogic\Attachments\CreateAttachmentForTicketModel;
use BusinessLogic\Exceptions\ApiFriendlyException;
use BusinessLogic\Helpers;
use Controllers\JsonRetriever;
class StaffTicketAttachmentsController {
function post() {
global $hesk_settings, $applicationContext;
if (!$hesk_settings['attachments']['use']) {
throw new ApiFriendlyException('Attachments are disabled on this server', 'Attachments Disabled', 404);
}
/* @var $attachmentHandler AttachmentHandler */
$attachmentHandler = $applicationContext->get[AttachmentHandler::class];
$createAttachmentForTicketModel = $this->createModel(JsonRetriever::getJsonData());
$createdAttachment = $attachmentHandler->createAttachmentForTicket($createAttachmentForTicketModel, $hesk_settings);
return output($createdAttachment, 201);
}
private function createModel($json) {
$model = new CreateAttachmentForTicketModel();
$model->attachmentContents = Helpers::safeArrayGet($json, 'data');
$model->displayName = Helpers::safeArrayGet($json, 'displayName');
$model->ticketId = Helpers::safeArrayGet($json, 'ticketId');
$model->type = Helpers::safeArrayGet($json, 'type');
return $model;
}
}

@ -33,7 +33,7 @@ class TicketController {
//else if assigned to owner, email new owner //else if assigned to owner, email new owner
//else email all staff //else email all staff
return output($ticket); return output($ticket, 201);
} }
/** /**

@ -36,13 +36,17 @@ class AttachmentHandlerTest extends TestCase {
$this->attachmentGateway = $this->createMock(AttachmentGateway::class); $this->attachmentGateway = $this->createMock(AttachmentGateway::class);
$this->fileWriter = $this->createMock(FileWriter::class); $this->fileWriter = $this->createMock(FileWriter::class);
$this->heskSettings = array( $this->heskSettings = array(
'attach_dir' => 'attachments' 'attach_dir' => 'attachments',
'attachments' => array(
'allowed_types' => array('.txt'),
'max_size' => 999
)
); );
$this->attachmentHandler = new AttachmentHandler($this->ticketGateway, $this->attachmentGateway, $this->fileWriter); $this->attachmentHandler = new AttachmentHandler($this->ticketGateway, $this->attachmentGateway, $this->fileWriter);
$this->createAttachmentForTicketModel = new CreateAttachmentForTicketModel(); $this->createAttachmentForTicketModel = new CreateAttachmentForTicketModel();
$this->createAttachmentForTicketModel->attachmentContents = base64_encode('string'); $this->createAttachmentForTicketModel->attachmentContents = base64_encode('string');
$this->createAttachmentForTicketModel->displayName = 'DisplayName'; $this->createAttachmentForTicketModel->displayName = 'DisplayName.txt';
$this->createAttachmentForTicketModel->ticketId = 1; $this->createAttachmentForTicketModel->ticketId = 1;
$this->createAttachmentForTicketModel->type = AttachmentType::MESSAGE; $this->createAttachmentForTicketModel->type = AttachmentType::MESSAGE;
} }
@ -143,6 +147,32 @@ class AttachmentHandlerTest extends TestCase {
$this->attachmentHandler->createAttachmentForTicket($this->createAttachmentForTicketModel, $this->heskSettings); $this->attachmentHandler->createAttachmentForTicket($this->createAttachmentForTicketModel, $this->heskSettings);
} }
function testThatValidateThrowsAnExceptionWhenTheFileExtensionIsNotPermitted() {
//-- Arrange
$this->heskSettings['attachments']['allowed_types'] = array('.gif');
$this->createAttachmentForTicketModel->ticketId = 0;
//-- Assert
$this->expectException(ValidationException::class);
$this->expectExceptionMessageRegExp('/EXTENSION_NOT_PERMITTED/');
//-- Act
$this->attachmentHandler->createAttachmentForTicket($this->createAttachmentForTicketModel, $this->heskSettings);
}
function testThatValidateThrowsAnExceptionWhenTheFileSizeIsLargerThanMaxPermitted() {
//-- Arrange
$this->createAttachmentForTicketModel->attachmentContents = base64_encode("msg");
$this->heskSettings['attachments']['max_size'] = 1;
//-- Assert
$this->expectException(ValidationException::class);
$this->expectExceptionMessageRegExp('/FILE_SIZE_TOO_LARGE/');
//-- Act
$this->attachmentHandler->createAttachmentForTicket($this->createAttachmentForTicketModel, $this->heskSettings);
}
function testItSavesATicketWithTheProperProperties() { function testItSavesATicketWithTheProperProperties() {
//-- Arrange //-- Arrange
$this->createAttachmentForTicketModel->ticketId = 1; $this->createAttachmentForTicketModel->ticketId = 1;

Loading…
Cancel
Save