Page MenuHomePhorge

D5096.1775300858.diff
No OneTemporary

Authored By
Unknown
Size
11 KB
Referenced Files
None
Subscribers
None

D5096.1775300858.diff

diff --git a/lib/ext/Syncroton/Command/SendMail.php b/lib/ext/Syncroton/Command/SendMail.php
--- a/lib/ext/Syncroton/Command/SendMail.php
+++ b/lib/ext/Syncroton/Command/SendMail.php
@@ -23,6 +23,7 @@
protected $_defaultNameSpace = 'uri:ComposeMail';
protected $_documentElement = 'SendMail';
+ protected $_clientId;
protected $_mime;
protected $_saveInSent;
protected $_source;
@@ -48,6 +49,7 @@
} elseif ($this->_requestBody) {
$xml = simplexml_import_dom($this->_requestBody);
+ $this->_clientId = (string) $xml->ClientId;
$this->_mime = (string) $xml->Mime;
$this->_saveInSent = isset($xml->SaveInSentItems);
$this->_replaceMime = isset($xml->ReplaceMime);
@@ -125,6 +127,6 @@
*/
protected function sendMail($dataController)
{
- $dataController->sendEmail($this->_mime, $this->_saveInSent);
+ $dataController->sendEmail($this->_mime, $this->_saveInSent, $this->_clientId);
}
}
diff --git a/lib/ext/Syncroton/Command/SmartForward.php b/lib/ext/Syncroton/Command/SmartForward.php
--- a/lib/ext/Syncroton/Command/SmartForward.php
+++ b/lib/ext/Syncroton/Command/SmartForward.php
@@ -26,6 +26,12 @@
*/
protected function sendMail($dataController)
{
- $dataController->forwardEmail($this->_source, $this->_mime, $this->_saveInSent, $this->_replaceMime);
+ $dataController->forwardEmail(
+ $this->_source,
+ $this->_mime,
+ $this->_saveInSent,
+ $this->_replaceMime,
+ $this->_clientId
+ );
}
}
diff --git a/lib/ext/Syncroton/Command/SmartReply.php b/lib/ext/Syncroton/Command/SmartReply.php
--- a/lib/ext/Syncroton/Command/SmartReply.php
+++ b/lib/ext/Syncroton/Command/SmartReply.php
@@ -26,6 +26,6 @@
*/
protected function sendMail($dataController)
{
- $dataController->replyEmail($this->_source, $this->_mime, $this->_saveInSent, $this->_replaceMime);
+ $dataController->replyEmail($this->_source, $this->_mime, $this->_saveInSent, $this->_replaceMime, $this->_clientId);
}
}
diff --git a/lib/ext/Syncroton/Data/Email.php b/lib/ext/Syncroton/Data/Email.php
--- a/lib/ext/Syncroton/Data/Email.php
+++ b/lib/ext/Syncroton/Data/Email.php
@@ -31,7 +31,7 @@
* (non-PHPdoc)
* @see Syncroton_Data_IDataEmail::forwardEmail()
*/
- public function forwardEmail($source, $inputStream, $saveInSent, $replaceMime)
+ public function forwardEmail($source, $inputStream, $saveInSent, $replaceMime, $clientId)
{
if ($inputStream == 'triggerException') {
throw new Syncroton_Exception_Status(Syncroton_Exception_Status::MAILBOX_SERVER_OFFLINE);
@@ -59,7 +59,7 @@
* (non-PHPdoc)
* @see Syncroton_Data_IDataEmail::replyEmail()
*/
- public function replyEmail($source, $inputStream, $saveInSent, $replaceMime)
+ public function replyEmail($source, $inputStream, $saveInSent, $replaceMime, $clientId)
{
// forward email
}
@@ -78,7 +78,7 @@
* (non-PHPdoc)
* @see Syncroton_Data_IDataEmail::sendEmail()
*/
- public function sendEmail($inputStream, $saveInSent)
+ public function sendEmail($inputStream, $saveInSent, $clientId)
{
if ($inputStream == 'triggerException') {
throw new Syncroton_Exception_Status(Syncroton_Exception_Status::MAILBOX_SERVER_OFFLINE);
diff --git a/lib/ext/Syncroton/Data/IDataEmail.php b/lib/ext/Syncroton/Data/IDataEmail.php
--- a/lib/ext/Syncroton/Data/IDataEmail.php
+++ b/lib/ext/Syncroton/Data/IDataEmail.php
@@ -21,26 +21,31 @@
/**
* send an email
*
- * @param resource $inputStream
- * @param boolean $saveInSent
+ * @param resource $inputStream
+ * @param bool $saveInSent
+ * @param ?string $clientId
*/
- public function sendEmail($inputStream, $saveInSent);
+ public function sendEmail($inputStream, $saveInSent, $clientId);
/**
* forward an email
*
- * @param string|array $source is either a string(LongId) or an array with following properties collectionId, itemId and instanceId
- * @param string $inputStream
- * @param string $saveInSent
+ * @param string|array $source is either a string(LongId) or an array with following properties collectionId, itemId and instanceId
+ * @param string $inputStream
+ * @param string $saveInSent
+ * @param bool $replaceMime
+ * @param ?string $clientId
*/
- public function forwardEmail($source, $inputStream, $saveInSent, $replaceMime);
+ public function forwardEmail($source, $inputStream, $saveInSent, $replaceMime, $clientId);
/**
* reply to an email
*
- * @param string|array $source is either a string(LongId) or an array with following properties collectionId, itemId and instanceId
- * @param string $inputStream
- * @param string $saveInSent
+ * @param string|array $source is either a string(LongId) or an array with following properties collectionId, itemId and instanceId
+ * @param string $inputStream
+ * @param string $saveInSent
+ * @param bool $replaceMime
+ * @param ?string $clientId
*/
- public function replyEmail($source, $inputStream, $saveInSent, $replaceMime);
+ public function replyEmail($source, $inputStream, $saveInSent, $replaceMime, $clientId);
}
diff --git a/lib/kolab_sync_data_email.php b/lib/kolab_sync_data_email.php
--- a/lib/kolab_sync_data_email.php
+++ b/lib/kolab_sync_data_email.php
@@ -30,6 +30,9 @@
{
public const MAX_SEARCH_RESULT = 200;
+ protected const MAIL_SUBMITTED = 1;
+ protected const MAIL_DONE = 2;
+
/**
* Mapping from ActiveSync Email namespace fields
*/
@@ -823,20 +826,32 @@
* Send an email
*
* @param mixed $message MIME message
- * @param boolean $saveInSent Enables saving the sent message in Sent folder
+ * @param bool $saveInSent Enables saving the sent message in Sent folder
+ * @param ?string $clientId Message client-id
*
* @throws Syncroton_Exception_Status
*/
- public function sendEmail($message, $saveInSent)
+ public function sendEmail($message, $saveInSent, $clientId)
{
+ if (($status = $this->sentMailStatus($clientId, $cache, $cache_key)) === self::MAIL_DONE) {
+ throw new Syncroton_Exception_Status(Syncroton_Exception_Status::MESSAGE_PREVIOUSLY_SENT);
+ }
+
if (!($message instanceof kolab_sync_message)) {
$message = new kolab_sync_message($message);
}
- $sent = $message->send($smtp_error);
+ // Snet the message (if not sent previously)
+ if (!$status) {
+ $sent = $message->send($smtp_error);
- if (!$sent) {
- throw new Syncroton_Exception_Status(Syncroton_Exception_Status::MAIL_SUBMISSION_FAILED);
+ if (!$sent) {
+ throw new Syncroton_Exception_Status(Syncroton_Exception_Status::MAIL_SUBMISSION_FAILED);
+ }
+
+ if (!empty($cache)) {
+ $cache->set($cache_key, self::MAIL_SUBMITTED);
+ }
}
// Save sent message in Sent folder
@@ -844,9 +859,17 @@
$sent_folder = kolab_sync::get_instance()->config->get('sent_mbox');
if (strlen($sent_folder) && $this->storage->folder_exists($sent_folder)) {
- return $this->storage->save_message($sent_folder, $message->source(), '', false, ['SEEN']);
+ $uid = $this->storage->save_message($sent_folder, $message->source(), '', false, ['SEEN']);
+
+ if (!$uid) {
+ throw new Syncroton_Exception_Status(Syncroton_Exception_Status::SERVER_ERROR);
+ }
}
}
+
+ if (!empty($cache)) {
+ $cache->set($cache_key, self::MAIL_DONE);
+ }
}
/**
@@ -855,13 +878,18 @@
* @param array|string $itemId A string LongId or an array with following properties:
* collectionId, itemId and instanceId
* @param resource|string $body MIME message
- * @param boolean $saveInSent Enables saving the sent message in Sent folder
- * @param boolean $replaceMime If enabled, original message would be appended
+ * @param bool $saveInSent Enables saving the sent message in Sent folder
+ * @param bool $replaceMime If enabled, original message would be appended
+ * @param ?string $clientId Message client-id
*
* @throws Syncroton_Exception_Status
*/
- public function forwardEmail($itemId, $body, $saveInSent, $replaceMime)
+ public function forwardEmail($itemId, $body, $saveInSent, $replaceMime, $clientId)
{
+ if ($this->sentMailStatus($clientId) === self::MAIL_DONE) {
+ throw new Syncroton_Exception_Status(Syncroton_Exception_Status::MESSAGE_PREVIOUSLY_SENT);
+ }
+
/*
@TODO:
The SmartForward command can be applied to a meeting. When SmartForward is applied to a recurring meeting,
@@ -903,7 +931,7 @@
}
// Send message
- $this->sendEmail($sync_msg, $saveInSent);
+ $this->sendEmail($sync_msg, $saveInSent, $clientId);
// Set FORWARDED flag on the replied message
if (empty($message->headers->flags['FORWARDED'])) {
@@ -918,13 +946,18 @@
* @param array|string $itemId A string LongId or an array with following properties:
* collectionId, itemId and instanceId
* @param resource|string $body MIME message
- * @param boolean $saveInSent Enables saving the sent message in Sent folder
- * @param boolean $replaceMime If enabled, original message would be appended
+ * @param bool $saveInSent Enables saving the sent message in Sent folder
+ * @param bool $replaceMime If enabled, original message would be appended
+ * @param ?string $clientId Message client-id
*
* @throws Syncroton_Exception_Status
*/
- public function replyEmail($itemId, $body, $saveInSent, $replaceMime)
+ public function replyEmail($itemId, $body, $saveInSent, $replaceMime, $clientId)
{
+ if ($this->sentMailStatus($clientId) === self::MAIL_DONE) {
+ throw new Syncroton_Exception_Status(Syncroton_Exception_Status::MESSAGE_PREVIOUSLY_SENT);
+ }
+
$msg = $this->parseMessageId($itemId);
$message = $this->getObject($itemId);
@@ -954,7 +987,7 @@
}
// Send message
- $this->sendEmail($sync_msg, $saveInSent);
+ $this->sendEmail($sync_msg, $saveInSent, $clientId);
// Set ANSWERED flag on the replied message
if (empty($message->headers->flags['ANSWERED'])) {
@@ -1578,4 +1611,27 @@
return kolab_sync_message::fake_message($headers, $msg);
}
}
+
+ /**
+ * Check in the cache if specified message (client-id) has been previously processed
+ * and with what result. It's used to prevent a duplicate submission.
+ */
+ protected function sentMailStatus($clientId, &$cache = null, &$cache_key = null)
+ {
+ // Note: ClientId is set with ActiveSync version >= 14.0
+ if ($clientId === null || $clientId === '') {
+ return 0;
+ }
+
+ $engine = kolab_sync::get_instance();
+ $status = null;
+ $cache_key = "ClientId:{$clientId}";
+
+ if ($cache_type = $engine->config->get('activesync_cache', 'db')) {
+ $cache = $engine->get_cache('activesync_cache', $cache_type, '1d', false);
+ $status = $cache->get($cache_key);
+ }
+
+ return (int) $status;
+ }
}

File Metadata

Mime Type
text/plain
Expires
Sat, Apr 4, 11:07 AM (2 h, 35 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18829146
Default Alt Text
D5096.1775300858.diff (11 KB)

Event Timeline