Commit cf751b71 authored by Sebastian Kummer's avatar Sebastian Kummer

ZP-1177 Renamed ImportChangesICS->isMessageInSyncInterval() into

ImportChangesICS->isModificationAllowed() which also fails if a private
object in a shared store is edited. Refactored code into
MAPIUtils::IsMessageSharedAndPrivate().

Released under the Affero GNU General Public License (AGPL) version 3.
parent 43ef5d64
...@@ -240,39 +240,55 @@ class ImportChangesICS implements IImportChanges { ...@@ -240,39 +240,55 @@ class ImportChangesICS implements IImportChanges {
} }
/** /**
* Checks if a message is in the synchronization interval (window) * Checks if a message may be modified. This involves checking:
* if a filter (e.g. Sync items two weeks back) or limits this synchronization. * - if there is a synchronization interval and if so, if the message is in it (sync window).
* These checks only apply to Emails and Appointments only, Contacts, Tasks and Notes do not have time restrictions. * These checks only apply to Emails and Appointments only, Contacts, Tasks and Notes do not have time restrictions.
* - if the message is not marked as private in a shared folder.
* *
* @param string $messageid the message id to be checked * @param string $messageid the message id to be checked
* *
* @access private * @access private
* @return boolean * @return boolean
*/ */
private function isMessageInSyncInterval($messageid) { private function isModificationAllowed($messageid) {
// if there is no restriciton we do not need to check
if ($this->cutoffdate === false)
return true;
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ImportChangesICS->isMessageInSyncInterval('%s'): cut off date is: %s", $messageid, $this->cutoffdate)); $sharedUser = ZPush::GetAdditionalSyncFolderStore(bin2hex($this->folderid));
// if this is either a user folder or SYSTEM and no restriction is set, we don't need to check
if (($sharedUser == false || $sharedUser == 'SYSTEM') && $this->cutoffdate === false) {
return true;
}
// open the existing object
$entryid = mapi_msgstore_entryidfromsourcekey($this->store, $this->folderid, hex2bin($messageid)); $entryid = mapi_msgstore_entryidfromsourcekey($this->store, $this->folderid, hex2bin($messageid));
if(!$entryid) { if(!$entryid) {
ZLog::Write(LOGLEVEL_WARN, sprintf("ImportChangesICS->isMessageInSyncInterval('%s'): Error, unable to resolve message id: 0x%X", $messageid, mapi_last_hresult())); ZLog::Write(LOGLEVEL_WARN, sprintf("ImportChangesICS->isModificationAllowed('%s'): Error, unable to resolve message id: 0x%X", $messageid, mapi_last_hresult()));
return false; return false;
} }
$mapimessage = mapi_msgstore_openentry($this->store, $entryid); $mapimessage = mapi_msgstore_openentry($this->store, $entryid);
if(!$mapimessage) { if(!$mapimessage) {
ZLog::Write(LOGLEVEL_WARN, sprintf("ImportChangesICS->isMessageInSyncInterval('%s'): Error, unable to open entry id: 0x%X", $messageid, mapi_last_hresult())); ZLog::Write(LOGLEVEL_WARN, sprintf("ImportChangesICS->isModificationAllowed('%s'): Error, unable to open entry id: 0x%X", $messageid, mapi_last_hresult()));
return false; return false;
} }
if ($this->contentClass == "Email") // check the sync interval
return MAPIUtils::IsInEmailSyncInterval($this->store, $mapimessage, $this->cutoffdate); if ($this->cutoffdate !== false) {
elseif ($this->contentClass == "Calendar") ZLog::Write(LOGLEVEL_DEBUG, sprintf("ImportChangesICS->isModificationAllowed('%s'): cut off date is: %s", $messageid, $this->cutoffdate));
return MAPIUtils::IsInCalendarSyncInterval($this->store, $mapimessage, $this->cutoffdate); if ( ($this->contentClass == "Email" && !MAPIUtils::IsInEmailSyncInterval($this->store, $mapimessage, $this->cutoffdate)) ||
($this->contentClass == "Calendar" && !MAPIUtils::IsInCalendarSyncInterval($this->store, $mapimessage, $this->cutoffdate)) ) {
ZLog::Write(LOGLEVEL_WARN, sprintf("ImportChangesICS->isModificationAllowed('%s'): Message in %s is outside the sync interval. Data not saved.", $messageid, $this->contentClass));
return false;
}
}
// check if not private
if (MAPIUtils::IsMessageSharedAndPrivate($this->folderid, $mapimessage)) {
ZLog::Write(LOGLEVEL_WARN, sprintf("ImportChangesICS->isModificationAllowed('%s'): Message is shared and marked as private. Data not saved.", $messageid));
return false;
}
// yes, modification allowed
return true; return true;
} }
...@@ -378,9 +394,9 @@ class ImportChangesICS implements IImportChanges { ...@@ -378,9 +394,9 @@ class ImportChangesICS implements IImportChanges {
list(, $sk) = Utils::SplitMessageId($id); list(, $sk) = Utils::SplitMessageId($id);
$props[PR_SOURCE_KEY] = hex2bin($sk); $props[PR_SOURCE_KEY] = hex2bin($sk);
// on editing an existing message, check if it is in the synchronization interval // check if message is in the synchronization interval and/or shared+private
if (!$this->isMessageInSyncInterval($sk)) if (!$this->isModificationAllowed($sk))
throw new StatusException(sprintf("ImportChangesICS->ImportMessageChange('%s','%s'): Message is outside the sync interval. Data not saved.", $id, get_class($message)), SYNC_STATUS_SYNCCANNOTBECOMPLETED); throw new StatusException(sprintf("ImportChangesICS->ImportMessageChange('%s','%s'): Message modification is not allowed. Data not saved.", $id, get_class($message)), SYNC_STATUS_SYNCCANNOTBECOMPLETED);
// check for conflicts // check for conflicts
$this->lazyLoadConflicts(); $this->lazyLoadConflicts();
...@@ -439,9 +455,10 @@ class ImportChangesICS implements IImportChanges { ...@@ -439,9 +455,10 @@ class ImportChangesICS implements IImportChanges {
*/ */
public function ImportMessageDeletion($id, $asSoftDelete = false) { public function ImportMessageDeletion($id, $asSoftDelete = false) {
list(,$sk) = Utils::SplitMessageId($id); list(,$sk) = Utils::SplitMessageId($id);
// check if the message is in the current syncinterval
if (!$this->isMessageInSyncInterval($sk)) // check if message is in the synchronization interval and/or shared+private
throw new StatusException(sprintf("ImportChangesICS->ImportMessageDeletion('%s'): Message is outside the sync interval and so far not deleted.", $id), SYNC_STATUS_OBJECTNOTFOUND); if (!$this->isModificationAllowed($id))
throw new StatusException(sprintf("ImportChangesICS->ImportMessageDeletion('%s'): Message deletion is not allowed. Deletion not executed.", $id), SYNC_STATUS_OBJECTNOTFOUND);
// check for conflicts // check for conflicts
$this->lazyLoadConflicts(); $this->lazyLoadConflicts();
...@@ -482,9 +499,9 @@ class ImportChangesICS implements IImportChanges { ...@@ -482,9 +499,9 @@ class ImportChangesICS implements IImportChanges {
// read flag change for our current folder // read flag change for our current folder
if ($this->folderidHex == $fsk || empty($fsk)) { if ($this->folderidHex == $fsk || empty($fsk)) {
// check if the message is in the current syncinterval // check if it is in the synchronization interval and/or shared+private
if (!$this->isMessageInSyncInterval($sk)) if (!$this->isModificationAllowed($sk))
throw new StatusException(sprintf("ImportChangesICS->ImportMessageReadFlag('%s','%d'): Message is outside the sync interval. Flags not updated.", $id, $flags), SYNC_STATUS_OBJECTNOTFOUND); throw new StatusException(sprintf("ImportChangesICS->ImportMessageReadFlag('%s','%d'): Flag update is not allowed. Flags not updated.", $id, $flags), SYNC_STATUS_OBJECTNOTFOUND);
// check for conflicts // check for conflicts
/* /*
...@@ -561,9 +578,9 @@ class ImportChangesICS implements IImportChanges { ...@@ -561,9 +578,9 @@ class ImportChangesICS implements IImportChanges {
throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to %s: 0x%X", $sk, $newfolder, $errorCase, mapi_last_hresult()), $code); throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to %s: 0x%X", $sk, $newfolder, $errorCase, mapi_last_hresult()), $code);
} }
// check if the source message is in the current syncinterval // check if it is in the synchronization interval and/or shared+private
if (!$this->isMessageInSyncInterval($sk)) if (!$this->isModificationAllowed($sk))
throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Source message is outside the sync interval. Move not performed.", $sk, $newfolder), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID); throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Source message move is not allowed. Move not performed.", $id, $newfolder), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
// get correct mapi store for the destination folder // get correct mapi store for the destination folder
$dststore = ZPush::GetBackend()->GetMAPIStoreForFolderId(ZPush::GetAdditionalSyncFolderStore($newfolder), $newfolder); $dststore = ZPush::GetBackend()->GetMAPIStoreForFolderId(ZPush::GetAdditionalSyncFolderStore($newfolder), $newfolder);
......
...@@ -117,9 +117,7 @@ class PHPWrapper { ...@@ -117,9 +117,7 @@ class PHPWrapper {
$message = $this->mapiprovider->GetMessage($mapimessage, $this->contentparameters); $message = $this->mapiprovider->GetMessage($mapimessage, $this->contentparameters);
// strip or do not send private messages from shared folders to the device // strip or do not send private messages from shared folders to the device
$sensitivity = mapi_getprops($mapimessage, array(PR_SENSITIVITY)); if (MAPIUtils::IsMessageSharedAndPrivate($this->folderid, $mapimessage)) {
$sharedUser = ZPush::GetAdditionalSyncFolderStore(bin2hex($this->folderid));
if ($sharedUser != false && $sharedUser != 'SYSTEM' && isset($sensitivity[PR_SENSITIVITY]) && $sensitivity[PR_SENSITIVITY] >= SENSITIVITY_PRIVATE) {
if ($message->SupportsPrivateStripping()) { if ($message->SupportsPrivateStripping()) {
ZLog::Write(LOGLEVEL_DEBUG, "PHPWrapper->ImportMessageChange(): stripping data of private message from a shared folder"); ZLog::Write(LOGLEVEL_DEBUG, "PHPWrapper->ImportMessageChange(): stripping data of private message from a shared folder");
$message->StripData(Streamer::STRIP_PRIVATE_DATA); $message->StripData(Streamer::STRIP_PRIVATE_DATA);
......
...@@ -353,6 +353,26 @@ class MAPIUtils { ...@@ -353,6 +353,26 @@ class MAPIUtils {
return false; return false;
} }
/**
* Checks if mapimessage is in a shared folder and private.
*
* @param string $folderid binary folderid of the message
* @param MAPIMessage $mapimessage the mapi message to be checked
* @param long $timestamp the lower time limit
*
* @access public
* @return boolean
*/
public static function IsMessageSharedAndPrivate($folderid, $mapimessage) {
$sensitivity = mapi_getprops($mapimessage, array(PR_SENSITIVITY));
$sharedUser = ZPush::GetAdditionalSyncFolderStore(bin2hex($folderid));
if ($sharedUser != false && $sharedUser != 'SYSTEM' && isset($sensitivity[PR_SENSITIVITY]) && $sensitivity[PR_SENSITIVITY] >= SENSITIVITY_PRIVATE) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("MAPIUtils->IsMessageSharedAndPrivate(): Message is in shared store '%s' and marked as private", $sharedUser));
return true;
}
return false;
}
/** /**
* Reads data of large properties from a stream * Reads data of large properties from a stream
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment