From 269c51069d38aafe2ab2b452c3acd5ede2db8ffd Mon Sep 17 00:00:00 2001 From: Peter Rotich <peter@osticket.com> Date: Sun, 10 Feb 2013 16:19:48 -0500 Subject: [PATCH] Refactor how online file upload is processed Add routine to import emailed & api files --- include/class.mailfetch.php | 24 +++++++--------------- include/class.osticket.php | 9 ++++---- include/class.ticket.php | 41 +++++++++++++++++++++++++++++++++++-- open.php | 8 ++------ tickets.php | 11 +++++----- 5 files changed, 58 insertions(+), 35 deletions(-) diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php index 68f0b6592..b86aca4dd 100644 --- a/include/class.mailfetch.php +++ b/include/class.mailfetch.php @@ -327,7 +327,7 @@ class MailFetcher { return array( array( 'name' => $this->mime_decode($filename), - 'mime' => $this->getMimeType($part), + 'type' => $this->getMimeType($part), 'encoding' => $part->encoding, 'index' => ($index?$index:1) ) @@ -446,23 +446,13 @@ class MailFetcher { && $struct->parts && ($attachments=$this->getAttachments($struct))) { - //We're just checking the type of file - not size or number of attachments... - // Restrictions are mainly due to PHP file uploads limitations foreach($attachments as $a ) { - if($ost->isFileTypeAllowed($a['name'], $a['mime'])) { - $file = array( - 'name' => $a['name'], - 'type' => $a['mime'], - 'data' => $this->decode($a['encoding'], imap_fetchbody($this->mbox, $mid, $a['index'])) - ); - $ticket->saveAttachment($file, $msgid, 'M'); - } else { - //This should be really a comment on message - NoT an internal note. - //TODO: support comments on Messages and Responses. - $error = sprintf('Attachment %s [%s] rejected because of file type', $a['name'], $a['mime']); - $ticket->postNote('Email Attachment Rejected', $error, 'SYSTEM', false); - $ost->logDebug('Email Attachment Rejected (Ticket #'.$ticket->getExtId().')', $error); - } + $file = array( + 'name' => $a['name'], + 'type' => $a['type'], + 'data' => $this->decode(imap_fetchbody($this->mbox, $mid, $a['index']), $a['encoding']) + ); + $ticket->importAttachments(array($file), $msgid, 'M'); } } diff --git a/include/class.osticket.php b/include/class.osticket.php index 89fd3603c..8b2978692 100644 --- a/include/class.osticket.php +++ b/include/class.osticket.php @@ -149,7 +149,7 @@ class osTicket { /* Function expects a well formatted array - see Format::files() It's up to the caller to reject the upload on error. */ - function validateFileUploads(&$files) { + function validateFileUploads(&$files, $checkFileTypes=true) { $errors=0; foreach($files as &$file) { @@ -160,11 +160,12 @@ class osTicket { $file['error'] = 'File upload error #'.$file['error']; elseif(!$file['tmp_name'] || !is_uploaded_file($file['tmp_name'])) $file['error'] = 'Invalid or bad upload POST'; - elseif(!$this->isFileTypeAllowed($file)) - $file['error'] = 'Invalid file type for '.$file['name']; + elseif($checkFileTypes && !$this->isFileTypeAllowed($file)) + $file['error'] = 'Invalid file type for '.Format::htmlchars($file['name']); elseif($file['size']>$this->getConfig()->getMaxFileSize()) $file['error'] = sprintf('File (%s) is too big. Maximum of %s allowed', - $file['name'], Format::file_size($this->getConfig()->getMaxFileSize())); + Format::htmlchars($file['name']), + Format::file_size($this->getConfig()->getMaxFileSize())); if($file['error']) $errors++; } diff --git a/include/class.ticket.php b/include/class.ticket.php index b9857d39a..6e2936624 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -1735,10 +1735,11 @@ class Ticket { } //online based attached files. - function uploadAttachments($files, $refid, $type) { + function uploadAttachments($files, $refid, $type, $checkFileTypes=false) { global $ost; $uploaded=array(); + $ost->validateFileUploads($files, $checkFileTypes); //Validator sets errors - if any foreach($files as $file) { if(!$file['error'] && ($id=AttachmentFile::upload($file)) @@ -1762,8 +1763,44 @@ class Ticket { return $uploaded; } + /* Wrapper or uploadAttachments + - used on client interface + - file type check is forced + - $_FILES is passed. + */ + function uploadFiles($files, $refid, $type) { + return $this->uploadAttachments(Format::files($files), $refid, $type, true); + } + + /* Emailed & API attachments handler */ + function importAttachments($attachments, $refid, $type, $checkFileTypes=true) { + global $ost; + + if(!$attachments || !is_array($attachments)) return null; + + $files = array(); + foreach ($attachments as &$info) { + //Do error checking... + if ($checkFileTypes && !$ost->isFileTypeAllowed($info)) + $info['error'] = 'Invalid file type (ext) for '.Format::htmlchars($info['name']); + elseif ($info['encoding'] && !strcasecmp($info['encoding'], 'base64')) { + if(!($info['data'] = base64_decode($info['data'], true))) + $info['error'] = sprintf('%s: Poorly encoded base64 data', Format::htmlchars($info['name'])); + } + + if($info['error']) { + $this->logNote('File Import Error', $error, 'SYSTEM', false); + } elseif (($id=$this->saveAttachment($info, $refid, $type))) { + $files[] = $id; + } + } + + return $files; + } + + /* - Save attachment to the DB. uploads (above), email or json/xml. + Save attachment to the DB. upload/import (above). @file is a mixed var - can be ID or file hash. */ diff --git a/open.php b/open.php index a7f064fb9..e6f5b5297 100644 --- a/open.php +++ b/open.php @@ -33,12 +33,8 @@ if($_POST): if(($ticket=Ticket::create($_POST,$errors,SOURCE))){ $msg='Support ticket request created'; //Upload attachments... - if($cfg->allowOnlineAttachments() - && $_FILES['attachments'] - && ($files=Format::files($_FILES['attachments']))) { - $ost->validateFileUploads($files); //Validator sets errors - if any. - $ticket->uploadAttachments($files, $ticket->getLastMsgId(), 'M'); - } + if($cfg->allowOnlineAttachments() && $_FILES['attachments']) + $ticket->uploadFiles($_FILES['attachments'], $ticket->getLastMsgId(), 'M'); //Logged in...simply view the newly created ticket. if($thisclient && $thisclient->isValid()) { diff --git a/tickets.php b/tickets.php index 4ee69a8ef..626b41474 100644 --- a/tickets.php +++ b/tickets.php @@ -41,12 +41,11 @@ if($_POST && is_object($ticket) && $ticket->getId()): if(!$errors) { //Everything checked out...do the magic. if(($msgid=$ticket->postMessage($_POST['message'],'Web'))) { - if($cfg->allowOnlineAttachments() - && $_FILES['attachments'] - && ($files=Format::files($_FILES['attachments']))) { - $ost->validateFileUploads($files); //Validator sets errors - if any. - $ticket->uploadAttachments($files, $msgid, 'M'); - } + + //Upload files + if($cfg->allowOnlineAttachments() && $_FILES['attachments']) + $ticket->uploadFiles($_FILES['attachments'], $msgid, 'M'); + $msg='Message Posted Successfully'; } else { $errors['err']='Unable to post the message. Try again'; -- GitLab