Commit dff360a6 authored by Manfred Kutas's avatar Manfred Kutas

Merge branch 'develop' into AS14.1

Conflicts:
	src/lib/syncobjects/syncappointment.php
	src/lib/syncobjects/syncrecurrence.php
parents 8e526f4e 17c960da
......@@ -240,39 +240,55 @@ class ImportChangesICS implements IImportChanges {
}
/**
* Checks if a message is in the synchronization interval (window)
* if a filter (e.g. Sync items two weeks back) or limits this synchronization.
* These checks only apply to Emails and Appointments only, Contacts, Tasks and Notes do not have time restrictions.
* Checks if a message may be modified. This involves checking:
* - 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.
* - if the message is not marked as private in a shared folder.
*
* @param string $messageid the message id to be checked
*
* @access private
* @return boolean
*/
private function isMessageInSyncInterval($messageid) {
// if there is no restriciton we do not need to check
if ($this->cutoffdate === false)
return true;
private function isModificationAllowed($messageid) {
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));
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;
}
$mapimessage = mapi_msgstore_openentry($this->store, $entryid);
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;
}
if ($this->contentClass == "Email")
return MAPIUtils::IsInEmailSyncInterval($this->store, $mapimessage, $this->cutoffdate);
elseif ($this->contentClass == "Calendar")
return MAPIUtils::IsInCalendarSyncInterval($this->store, $mapimessage, $this->cutoffdate);
// check the sync interval
if ($this->cutoffdate !== false) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ImportChangesICS->isModificationAllowed('%s'): cut off date is: %s", $messageid, $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;
}
......@@ -378,9 +394,9 @@ class ImportChangesICS implements IImportChanges {
list(, $sk) = Utils::SplitMessageId($id);
$props[PR_SOURCE_KEY] = hex2bin($sk);
// on editing an existing message, check if it is in the synchronization interval
if (!$this->isMessageInSyncInterval($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);
// check if message is in the synchronization interval and/or shared+private
if (!$this->isModificationAllowed($sk))
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
$this->lazyLoadConflicts();
......@@ -439,9 +455,10 @@ class ImportChangesICS implements IImportChanges {
*/
public function ImportMessageDeletion($id, $asSoftDelete = false) {
list(,$sk) = Utils::SplitMessageId($id);
// check if the message is in the current syncinterval
if (!$this->isMessageInSyncInterval($sk))
throw new StatusException(sprintf("ImportChangesICS->ImportMessageDeletion('%s'): Message is outside the sync interval and so far not deleted.", $id), SYNC_STATUS_OBJECTNOTFOUND);
// check if message is in the synchronization interval and/or shared+private
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
$this->lazyLoadConflicts();
......@@ -482,9 +499,9 @@ class ImportChangesICS implements IImportChanges {
// read flag change for our current folder
if ($this->folderidHex == $fsk || empty($fsk)) {
// check if the message is in the current syncinterval
if (!$this->isMessageInSyncInterval($sk))
throw new StatusException(sprintf("ImportChangesICS->ImportMessageReadFlag('%s','%d'): Message is outside the sync interval. Flags not updated.", $id, $flags), SYNC_STATUS_OBJECTNOTFOUND);
// check if it is in the synchronization interval and/or shared+private
if (!$this->isModificationAllowed($sk))
throw new StatusException(sprintf("ImportChangesICS->ImportMessageReadFlag('%s','%d'): Flag update is not allowed. Flags not updated.", $id, $flags), SYNC_STATUS_OBJECTNOTFOUND);
// check for conflicts
/*
......@@ -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);
}
// check if the source message is in the current syncinterval
if (!$this->isMessageInSyncInterval($sk))
throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Source message is outside the sync interval. Move not performed.", $sk, $newfolder), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
// check if it is in the synchronization interval and/or shared+private
if (!$this->isModificationAllowed($sk))
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
$dststore = ZPush::GetBackend()->GetMAPIStoreForFolderId(ZPush::GetAdditionalSyncFolderStore($newfolder), $newfolder);
......
......@@ -114,15 +114,19 @@ class PHPWrapper {
try {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("PHPWrapper->ImportMessageChange(): Getting message from MAPIProvider, sourcekey: '%s', parentsourcekey: '%s', entryid: '%s'", bin2hex($sourcekey), bin2hex($parentsourcekey), bin2hex($entryid)));
// do not send private messages from shared folders to the device
$sensitivity = mapi_getprops($mapimessage, array(PR_SENSITIVITY));
$sharedUser = ZPush::GetAdditionalSyncFolderStore(bin2hex($this->folderid));
if ($sharedUser != false && $sharedUser != 'SYSTEM' && isset($sensitivity[PR_SENSITIVITY]) && $sensitivity[PR_SENSITIVITY] >= SENSITIVITY_PRIVATE) {
ZLog::Write(LOGLEVEL_DEBUG, "PHPWrapper->ImportMessageChange(): ignoring private message from a shared folder");
return SYNC_E_IGNORE;
}
$message = $this->mapiprovider->GetMessage($mapimessage, $this->contentparameters);
// strip or do not send private messages from shared folders to the device
if (MAPIUtils::IsMessageSharedAndPrivate($this->folderid, $mapimessage)) {
if ($message->SupportsPrivateStripping()) {
ZLog::Write(LOGLEVEL_DEBUG, "PHPWrapper->ImportMessageChange(): stripping data of private message from a shared folder");
$message->StripData(Streamer::STRIP_PRIVATE_DATA);
}
else {
ZLog::Write(LOGLEVEL_DEBUG, "PHPWrapper->ImportMessageChange(): ignoring private message from a shared folder");
return SYNC_E_IGNORE;
}
}
}
catch (SyncObjectBrokenException $mbe) {
$brokenSO = $mbe->GetSyncObject();
......
......@@ -353,6 +353,25 @@ class MAPIUtils {
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
*
* @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
......
......@@ -175,18 +175,20 @@ class ASDevice extends StateObject {
}
/**
* Removes internal data from the object, so this data can not be exposed
* Removes internal data from the object, so this data can not be exposed.
*
* @param boolean $stripHierarchyCache (opt) strips the hierarchy cache - default: true
*
* @access public
* @return boolean
*/
public function StripData() {
public function StripData($stripHierarchyCache = true) {
unset($this->changed);
unset($this->unsetdata);
unset($this->hierarchyCache);
unset($this->forceSave);
unset($this->newdevice);
unset($this->ignoredMessageIds);
unset($this->backend2folderidCache);
if (isset($this->ignoredmessages) && is_array($this->ignoredmessages)) {
$imessages = $this->ignoredmessages;
......@@ -199,6 +201,14 @@ class ASDevice extends StateObject {
$this->ignoredmessages = $unserializedMessage;
}
if (!$stripHierarchyCache && $this->hierarchyCache !== false && $this->hierarchyCache instanceof ChangesMemoryWrapper) {
$this->hierarchyCache->StripData();
}
else {
unset($this->hierarchyCache);
}
return true;
}
......
......@@ -403,4 +403,19 @@ class ChangesMemoryWrapper extends HierarchyCache implements IImportChanges, IEx
$this->changes = array();
$this->step = 0;
}
/**
* Removes internal data from the object, so this data can not be exposed.
*
* @access public
* @return boolean
*/
public function StripData() {
unset($this->changes);
unset($this->step);
unset($this->destinationImporter);
unset($this->exportImporter);
return parent::StripData();
}
}
......@@ -181,6 +181,21 @@ class HierarchyCache {
return sprintf("HierarchyCache is %s - Cached objects: %d", ((isset($this->cacheById))?"up":"down"), ((isset($this->cacheById))?count($this->cacheById):"0"));
}
/**
* Removes internal data from the object, so this data can not be exposed.
*
* @access public
* @return boolean
*/
public function StripData() {
unset($this->changed);
unset($this->cacheByIdOld);
foreach ($this->cacheById as $id => $folder) {
$folder->StripData();
}
return true;
}
/**
* Returns objects which should be persistent
* called before serialization
......
......@@ -48,6 +48,9 @@ class Streamer implements Serializable {
const STREAMER_TYPE_MULTIPART = 10;
const STREAMER_TYPE_STREAM_ASBASE64 = 11;
const STREAMER_TYPE_STREAM_ASPLAIN = 12;
const STREAMER_PRIVATE = 13;
const STRIP_PRIVATE_DATA = 1;
const STRIP_PRIVATE_SUBSTITUTE = 'Private';
protected $mapping;
public $flags;
......@@ -353,22 +356,40 @@ class Streamer implements Serializable {
* @access public
* @return boolean
*/
public function StripData() {
public function StripData($flags = 0) {
foreach ($this->mapping as $k=>$v) {
if (isset($this->{$v[self::STREAMER_VAR]})) {
if (is_object($this->{$v[self::STREAMER_VAR]}) && method_exists($this->{$v[self::STREAMER_VAR]}, "StripData") ) {
$this->{$v[self::STREAMER_VAR]}->StripData();
$this->{$v[self::STREAMER_VAR]}->StripData($flags);
}
else if (isset($v[self::STREAMER_ARRAY]) && !empty($this->{$v[self::STREAMER_VAR]})) {
foreach ($this->{$v[self::STREAMER_VAR]} as $element) {
if (is_object($element) && method_exists($element, "StripData") ) {
$element->StripData();
$element->StripData($flags);
}
elseif ($flags === Streamer::STRIP_PRIVATE_DATA && isset($v[self::STREAMER_PRIVATE])) {
if ($v[self::STREAMER_PRIVATE] !== true) {
$this->{$v[self::STREAMER_VAR]} = $v[self::STREAMER_PRIVATE];
}
else {
unset($this->{$v[self::STREAMER_VAR]});
}
}
}
}
elseif ($flags === Streamer::STRIP_PRIVATE_DATA && isset($v[self::STREAMER_PRIVATE])) {
if ($v[self::STREAMER_PRIVATE] !== true) {
$this->{$v[self::STREAMER_VAR]} = $v[self::STREAMER_PRIVATE];
}
else {
unset($this->{$v[self::STREAMER_VAR]});
}
}
}
}
unset($this->mapping);
if ($flags === 0) {
unset($this->mapping);
}
return true;
}
......
......@@ -82,13 +82,17 @@ class SyncAppointment extends SyncObject {
SYNC_POOMCAL_SUBJECT => array ( self::STREAMER_VAR => "subject",
self::STREAMER_CHECKS => array( self::STREAMER_CHECK_REQUIRED => self::STREAMER_CHECK_SETEMPTY),
self::STREAMER_RONOTIFY => true),
self::STREAMER_RONOTIFY => true,
self::STREAMER_PRIVATE => self::STRIP_PRIVATE_SUBSTITUTE ),
SYNC_POOMCAL_UID => array ( self::STREAMER_VAR => "uid"),
SYNC_POOMCAL_ORGANIZERNAME => array ( self::STREAMER_VAR => "organizername"), // verified below
SYNC_POOMCAL_ORGANIZEREMAIL => array ( self::STREAMER_VAR => "organizeremail"), // verified below
SYNC_POOMCAL_ORGANIZERNAME => array ( self::STREAMER_VAR => "organizername", // verified below
self::STREAMER_PRIVATE => 'Undisclosed Organizer' ),
SYNC_POOMCAL_ORGANIZEREMAIL => array ( self::STREAMER_VAR => "organizeremail", // verified below
self::STREAMER_PRIVATE => 'undisclosed@localhost' ),
SYNC_POOMCAL_LOCATION => array ( self::STREAMER_VAR => "location",
self::STREAMER_RONOTIFY => true),
self::STREAMER_RONOTIFY => true,
self::STREAMER_PRIVATE => true),
SYNC_POOMCAL_ENDTIME => array ( self::STREAMER_VAR => "endtime",
self::STREAMER_TYPE => self::STREAMER_TYPE_DATE,
self::STREAMER_CHECKS => array( self::STREAMER_CHECK_CMPHIGHER => SYNC_POOMCAL_STARTTIME ),
......@@ -121,6 +125,7 @@ class SyncAppointment extends SyncObject {
self::STREAMER_CHECKS => array( self::STREAMER_CHECK_REQUIRED => self::STREAMER_CHECK_SETTWO,
self::STREAMER_CHECK_ONEVALUEOF => array(0,1,2,3,4) ),
self::STREAMER_RONOTIFY => true,
self::STREAMER_PRIVATE => 2, // if private is stripped, value will be set to 2 (busy)
self::STREAMER_VALUEMAP => array( 0 => "Free",
1 => "Tentative",
2 => "Busy",
......@@ -135,9 +140,11 @@ class SyncAppointment extends SyncObject {
SYNC_POOMCAL_REMINDER => array ( self::STREAMER_VAR => "reminder",
self::STREAMER_CHECKS => array( self::STREAMER_CHECK_CMPHIGHER => -1),
self::STREAMER_RONOTIFY => true),
self::STREAMER_RONOTIFY => true,
self::STREAMER_PRIVATE => true ), // if private is stripped, value will be unset (no reminder)
SYNC_POOMCAL_RTF => array ( self::STREAMER_VAR => "rtf"),
SYNC_POOMCAL_RTF => array ( self::STREAMER_VAR => "rtf",
self::STREAMER_PRIVATE => true),
// Meetingstatus values
// 0 = is not a meeting
......@@ -165,11 +172,14 @@ class SyncAppointment extends SyncObject {
SYNC_POOMCAL_ATTENDEES => array ( self::STREAMER_VAR => "attendees",
self::STREAMER_TYPE => "SyncAttendee",
self::STREAMER_ARRAY => SYNC_POOMCAL_ATTENDEE,
self::STREAMER_RONOTIFY => true),
self::STREAMER_RONOTIFY => true,
self::STREAMER_PRIVATE => true),
SYNC_POOMCAL_BODY => array ( self::STREAMER_VAR => "body",
self::STREAMER_RONOTIFY => true),
SYNC_POOMCAL_BODYTRUNCATED => array ( self::STREAMER_VAR => "bodytruncated"),
self::STREAMER_RONOTIFY => true,
self::STREAMER_PRIVATE => true),
SYNC_POOMCAL_BODYTRUNCATED => array ( self::STREAMER_VAR => "bodytruncated",
self::STREAMER_PRIVATE => true),
SYNC_POOMCAL_EXCEPTIONS => array ( self::STREAMER_VAR => "exceptions",
self::STREAMER_TYPE => "SyncAppointmentException",
self::STREAMER_ARRAY => SYNC_POOMCAL_EXCEPTION,
......@@ -177,13 +187,16 @@ class SyncAppointment extends SyncObject {
SYNC_POOMCAL_CATEGORIES => array ( self::STREAMER_VAR => "categories",
self::STREAMER_ARRAY => SYNC_POOMCAL_CATEGORY,
self::STREAMER_RONOTIFY => true),
self::STREAMER_RONOTIFY => true,
self::STREAMER_PRIVATE => true),
);
if (Request::GetProtocolVersion() >= 12.0) {
$mapping[SYNC_AIRSYNCBASE_BODY] = array ( self::STREAMER_VAR => "asbody",
self::STREAMER_TYPE => "SyncBaseBody",
self::STREAMER_RONOTIFY => true);
self::STREAMER_RONOTIFY => true,
self::STREAMER_PRIVATE => true
);
$mapping[SYNC_AIRSYNCBASE_NATIVEBODYTYPE] = array ( self::STREAMER_VAR => "nativebodytype");
......@@ -193,7 +206,8 @@ class SyncAppointment extends SyncObject {
if(Request::GetProtocolVersion() >= 14.0) {
$mapping[SYNC_POOMCAL_DISALLOWNEWTIMEPROPOSAL] = array ( self::STREAMER_VAR => "disallownewtimeprop",
self::STREAMER_RONOTIFY => true);
self::STREAMER_RONOTIFY => true,
self::STREAMER_PRIVATE => 1); // don't permit new time proposal
$mapping[SYNC_POOMCAL_RESPONSEREQUESTED] = array ( self::STREAMER_VAR => "responserequested",
self::STREAMER_RONOTIFY => true);
$mapping[SYNC_POOMCAL_RESPONSETYPE] = array ( self::STREAMER_VAR => "responsetype",
......@@ -207,7 +221,10 @@ class SyncAppointment extends SyncObject {
self::STREAMER_RONOTIFY => true);
}
parent::SyncObject($mapping);
parent::__construct($mapping);
// Indicates that this SyncObject supports the private flag and stripping of private data.
$this->supportsPrivateStripping = true;
}
/**
......
......@@ -61,5 +61,8 @@ class SyncAppointmentException extends SyncAppointment {
$this->mapping[SYNC_POOMCAL_REMINDER][self::STREAMER_RONOTIFY] = true;
$this->mapping[SYNC_POOMCAL_EXCEPTIONS][self::STREAMER_CHECKS] = array(self::STREAMER_CHECK_NOTALLOWED => true);
// Indicates that this SyncObject supports the private flag and stripping of private data.
// It behaves as a SyncAppointment.
$this->supportsPrivateStripping = true;
}
}
......@@ -35,20 +35,29 @@ class SyncAttendee extends SyncObject {
$mapping = array(
SYNC_POOMCAL_EMAIL => array ( self::STREAMER_VAR => "email",
self::STREAMER_CHECKS => array( self::STREAMER_CHECK_REQUIRED => self::STREAMER_CHECK_SETEMPTY),
self::STREAMER_RONOTIFY => true),
self::STREAMER_RONOTIFY => true,
self::STREAMER_PRIVATE => 'attendee@localhost'),
SYNC_POOMCAL_NAME => array ( self::STREAMER_VAR => "name",
self::STREAMER_CHECKS => array( self::STREAMER_CHECK_REQUIRED => self::STREAMER_CHECK_SETEMPTY),
self::STREAMER_RONOTIFY => true)
self::STREAMER_RONOTIFY => true,
self::STREAMER_PRIVATE => 'Undisclosed Attendee')
);
if (Request::GetProtocolVersion() >= 12.0) {
$mapping[SYNC_POOMCAL_ATTENDEESTATUS] = array ( self::STREAMER_VAR => "attendeestatus",
self::STREAMER_RONOTIFY => true);
self::STREAMER_RONOTIFY => true,
self::STREAMER_PRIVATE => true
);
$mapping[SYNC_POOMCAL_ATTENDEETYPE] = array ( self::STREAMER_VAR => "attendeetype",
self::STREAMER_RONOTIFY => true);
self::STREAMER_RONOTIFY => true,
self::STREAMER_PRIVATE => true
);
}
parent::__construct($mapping);
// Indicates that this SyncObject supports the private flag and stripping of private data.
$this->supportsPrivateStripping = true;
}
}
......@@ -36,16 +36,23 @@ class SyncBaseBody extends SyncObject {
function __construct() {
$mapping = array(
SYNC_AIRSYNCBASE_TYPE => array (self::STREAMER_VAR => "type"),
SYNC_AIRSYNCBASE_ESTIMATEDDATASIZE => array (self::STREAMER_VAR => "estimatedDataSize"),
SYNC_AIRSYNCBASE_ESTIMATEDDATASIZE => array (self::STREAMER_VAR => "estimatedDataSize",
self::STREAMER_PRIVATE => 0), // when stripping private we remove the body, so the size needs to be 0
SYNC_AIRSYNCBASE_TRUNCATED => array (self::STREAMER_VAR => "truncated"),
SYNC_AIRSYNCBASE_DATA => array (self::STREAMER_VAR => "data",
self::STREAMER_TYPE => self::STREAMER_TYPE_STREAM_ASPLAIN,
self::STREAMER_RONOTIFY => true),
self::STREAMER_RONOTIFY => true,
self::STREAMER_PRIVATE => true), // just remove the body when stripping private
);
if(Request::GetProtocolVersion() >= 14.0) {
$mapping[SYNC_AIRSYNCBASE_PREVIEW] = array (self::STREAMER_VAR => "preview");
$mapping[SYNC_AIRSYNCBASE_PREVIEW] = array (self::STREAMER_VAR => "preview",
self::STREAMER_PRIVATE => true
);
}
parent::__construct($mapping);
// Indicates that this SyncObject supports the private flag and stripping of private data.
$this->supportsPrivateStripping = true;
}
}
......@@ -44,10 +44,12 @@ abstract class SyncObject extends Streamer {
const STREAMER_CHECK_EMAIL = 16;
protected $unsetVars;
protected $supportsPrivateStripping;
public function __construct($mapping) {
$this->unsetVars = array();
$this->supportsPrivateStripping = false;
parent::__construct($mapping);
}
......@@ -368,11 +370,22 @@ abstract class SyncObject extends Streamer {
* @access public
* @return boolean
*/
public function StripData() {
if (isset($this->unsetVars)) {
public function StripData($flags = 0) {
if ($flags === 0 && isset($this->unsetVars)) {
unset($this->unsetVars);
}
return parent::StripData();
return parent::StripData($flags);
}
/**
* Indicates if a SyncObject supports the private flag and stripping of private data.
* If an object does not support it, it will not be sent to the client but permanently be excluded from the sync.
*
* @access public
* @return boolean - default false defined in constructor - overwritten by implementation
*/
public function SupportsPrivateStripping() {
return $this->supportsPrivateStripping;
}
/**
......
......@@ -125,6 +125,10 @@ class SyncRecurrence extends SyncObject {
self::STREAMER_RONOTIFY => true);
}
parent::SyncObject($mapping);
parent::__construct($mapping);
// Indicates that this SyncObject supports the private flag and stripping of private data.
// There is nothing concrete to be stripped here, but as it's part of an appointment it supports it.
$this->supportsPrivateStripping = true;
}
}
......@@ -69,16 +69,16 @@ class ZPushAdmin {
*
* @param string $devid device id
* @param string $user user to be looked up
* @param boolean $withHierarchyCache (opt) includes the HierarchyCache - default: false
*
* @return ASDevice object
* @access public
*/
static public function GetDeviceDetails($devid, $user) {
static public function GetDeviceDetails($devid, $user, $withHierarchyCache = false) {
try {
$device = new ASDevice($devid, ASDevice::UNDEFINED, $user, ASDevice::UNDEFINED);
$device->SetData(ZPush::GetStateMachine()->GetState($devid, IStateMachine::DEVICEDATA), false);
$device->StripData();
try {
// we need a StateManager for this operation
......@@ -128,6 +128,7 @@ class ZPushAdmin {
}
}
}
$device->StripData(!$withHierarchyCache);
return $device;
}
catch (StateNotFoundException $e) {
......
......@@ -50,16 +50,18 @@ class WebserviceDevice {
/**
* Returns the details of a given deviceid of the Request::GetGETUser().
*
* @param boolean $withHierarchyCache (opt) includes the HierarchyCache - default: false
*
* @access public
* @return ASDevice object
*/
public function GetDeviceDetails($deviceId) {
public function GetDeviceDetails($deviceId, $withHierarchyCache = false) {
$user = Request::GetGETUser();
$deviceId = preg_replace("/[^A-Za-z0-9]/", "", $deviceId);
ZLog::Write(LOGLEVEL_INFO, sprintf("WebserviceDevice::GetDeviceDetails('%s'): getting device details from state of user '%s'", $deviceId, $user));
ZPush::GetTopCollector()->AnnounceInformation(sprintf("Retrieved details of device '%s'", $deviceId), true);
return ZPushAdmin::GetDeviceDetails($deviceId, $user);
return ZPushAdmin::GetDeviceDetails($deviceId, $user, $withHierarchyCache);
}
/**
......
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