Back to index

d-push  2.0
zpushadmin.php
Go to the documentation of this file.
00001 <?php
00002 /***********************************************
00003 * File      :   zpushadmin.php
00004 * Project   :   Z-Push
00005 * Descr     :   Administration tasks for users and devices
00006 *
00007 * Created   :   23.12.2011
00008 *
00009 * Copyright 2007 - 2011 Zarafa Deutschland GmbH
00010 *
00011 * This program is free software: you can redistribute it and/or modify
00012 * it under the terms of the GNU Affero General Public License, version 3,
00013 * as published by the Free Software Foundation with the following additional
00014 * term according to sec. 7:
00015 *
00016 * According to sec. 7 of the GNU Affero General Public License, version 3,
00017 * the terms of the AGPL are supplemented with the following terms:
00018 *
00019 * "Zarafa" is a registered trademark of Zarafa B.V.
00020 * "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
00021 * The licensing of the Program under the AGPL does not imply a trademark license.
00022 * Therefore any rights, title and interest in our trademarks remain entirely with us.
00023 *
00024 * However, if you propagate an unmodified version of the Program you are
00025 * allowed to use the term "Z-Push" to indicate that you distribute the Program.
00026 * Furthermore you may use our trademarks where it is necessary to indicate
00027 * the intended purpose of a product or service provided you use it in accordance
00028 * with honest practices in industrial or commercial matters.
00029 * If you want to propagate modified versions of the Program under the name "Z-Push",
00030 * you may only do so if you have a written permission by Zarafa Deutschland GmbH
00031 * (to acquire a permission please contact Zarafa at trademark@zarafa.com).
00032 *
00033 * This program is distributed in the hope that it will be useful,
00034 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00035 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00036 * GNU Affero General Public License for more details.
00037 *
00038 * You should have received a copy of the GNU Affero General Public License
00039 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00040 *
00041 * Consult LICENSE file for details
00042 ************************************************/
00043 
00044 class ZPushAdmin {
00058     static public function ListDevices($user = false) {
00059         return ZPush::GetStateMachine()->GetAllDevices($user);
00060     }
00061 
00070     static public function ListUsers($devid) {
00071         try {
00072             $devState = ZPush::GetStateMachine()->GetState($devid, IStateMachine::DEVICEDATA);
00073 
00074             if ($devState instanceof StateObject && isset($devState->devices) && is_array($devState->devices))
00075                 return array_keys($devState->devices);
00076             else
00077                 return array();
00078         }
00079         catch (StateNotFoundException $stnf) {
00080             return array();
00081         }
00082     }
00083 
00094     static public function GetDeviceDetails($devid, $user) {
00095 
00096         try {
00097             $device = new ASDevice($devid, ASDevice::UNDEFINED, $user, ASDevice::UNDEFINED);
00098             $device->SetData(ZPush::GetStateMachine()->GetState($devid, IStateMachine::DEVICEDATA), false);
00099             $device->StripData();
00100 
00101             try {
00102                 $lastsync = SyncCollections::GetLastSyncTimeOfDevice($device);
00103                 if ($lastsync)
00104                     $device->SetLastSyncTime($lastsync);
00105             }
00106             catch (StateInvalidException $sive) {
00107                 ZLog::Write(LOGLEVEL_WARN, sprintf("ZPushAdmin::GetDeviceDetails(): device '%s' of user '%s' has invalid states. Please sync to solve this issue.", $devid, $user));
00108                 $device->SetDeviceError("Invalid states. Please force synchronization!");
00109             }
00110 
00111             return $device;
00112         }
00113         catch (StateNotFoundException $e) {
00114             ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::GetDeviceDetails(): device '%s' of user '%s' can not be found", $devid, $user));
00115             return false;
00116         }
00117     }
00118 
00132     static public function WipeDevice($requestedBy, $user, $devid = false) {
00133         if ($user === false && $devid === false)
00134             return false;
00135 
00136         if ($devid === false) {
00137             $devicesIds = ZPush::GetStateMachine()->GetAllDevices($user);
00138             ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::WipeDevice(): all '%d' devices for user '%s' found to be wiped", count($devicesIds), $user));
00139             foreach ($devicesIds as $deviceid) {
00140                 if (!self::WipeDevice($requestedBy, $user, $deviceid)) {
00141                     ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::WipeDevice(): wipe devices failed for device '%s' of user '%s'. Aborting.", $deviceid, $user));
00142                     return false;
00143                 }
00144             }
00145         }
00146 
00147         // wipe a device completely (for connected users to this device)
00148         else if ($devid !== false && $user === false) {
00149             $users = self::ListUsers($devid);
00150             ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::WipeDevice(): device '%d' is used by '%d' users and will be wiped", $devid, count($users)));
00151             if (count($users) == 0)
00152                 ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::WipeDevice(): no user found on device '%s'. Aborting.", $devid));
00153 
00154             return self::WipeDevice($requestedBy, $users[0], $devid);
00155         }
00156 
00157         else {
00158             // load device data
00159             $device = new ASDevice($devid, ASDevice::UNDEFINED, $user, ASDevice::UNDEFINED);
00160             try {
00161                 $device->SetData(ZPush::GetStateMachine()->GetState($devid, IStateMachine::DEVICEDATA), false);
00162             }
00163             catch (StateNotFoundException $e) {
00164                 ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::WipeDevice(): device '%s' of user '%s' can not be found", $devid, $user));
00165                 return false;
00166             }
00167 
00168             // set wipe status
00169             if ($device->GetWipeStatus() == SYNC_PROVISION_RWSTATUS_WIPED)
00170                 ZLog::Write(LOGLEVEL_INFO, sprintf("ZPushAdmin::WipeDevice(): device '%s' of user '%s' was alread sucessfully remote wiped on %s", $devid , $user, strftime("%Y-%m-%d %H:%M", $device->GetWipeActionOn())));
00171             else
00172                 $device->SetWipeStatus(SYNC_PROVISION_RWSTATUS_PENDING, $requestedBy);
00173 
00174             // save device data
00175             try {
00176                 if ($device->IsNewDevice()) {
00177                     ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::WipeDevice(): data of user '%s' not synchronized on device '%s'. Aborting.", $user, $devid));
00178                     return false;
00179                 }
00180 
00181                 ZPush::GetStateMachine()->SetState($device->GetData(), $devid, IStateMachine::DEVICEDATA);
00182                 ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::WipeDevice(): device '%s' of user '%s' marked to be wiped", $devid, $user));
00183             }
00184             catch (StateNotFoundException $e) {
00185                 ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::WipeDevice(): state for device '%s' of user '%s' can not be saved", $devid, $user));
00186                 return false;
00187             }
00188         }
00189         return true;
00190     }
00191 
00192 
00205     static public function RemoveDevice($user = false, $devid = false) {
00206         if ($user === false && $devid === false)
00207             return false;
00208 
00209         // remove all devices for user
00210         if ($devid === false && $user !== false) {
00211             $devicesIds = ZPush::GetStateMachine()->GetAllDevices($user);
00212             ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::RemoveDevice(): all '%d' devices for user '%s' found to be removed", count($devicesIds), $user));
00213             foreach ($devicesIds as $deviceid) {
00214                 if (!self::RemoveDevice($user, $deviceid)) {
00215                     ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::RemoveDevice(): removing devices failed for device '%s' of user '%s'. Aborting", $deviceid, $user));
00216                     return false;
00217                 }
00218             }
00219         }
00220         // remove a device completely (for connected users to this device)
00221         else if ($devid !== false && $user === false) {
00222             $users = self::ListUsers($devid);
00223             ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::RemoveDevice(): device '%d' is used by '%d' users and will be removed", $devid, count($users)));
00224             foreach ($users as $aUser) {
00225                 if (!self::RemoveDevice($aUser, $devid)) {
00226                     ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::RemoveDevice(): removing user '%s' from device '%s' failed. Aborting", $aUser, $devid));
00227                     return false;
00228                 }
00229             }
00230         }
00231 
00232         // user and deviceid set
00233         else {
00234             // load device data
00235             $device = new ASDevice($devid, ASDevice::UNDEFINED, $user, ASDevice::UNDEFINED);
00236             $devices = array();
00237             try {
00238                 $devicedata = ZPush::GetStateMachine()->GetState($devid, IStateMachine::DEVICEDATA);
00239                 $device->SetData($devicedata, false);
00240                 $devices = $devicedata->devices;
00241             }
00242             catch (StateNotFoundException $e) {
00243                 ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::RemoveDevice(): device '%s' of user '%s' can not be found", $devid, $user));
00244                 return false;
00245             }
00246 
00247             // remove all related states
00248             foreach ($device->GetAllFolderIds() as $folderid)
00249                 StateManager::UnLinkState($device, $folderid);
00250 
00251             // remove hierarchcache
00252             StateManager::UnLinkState($device, false);
00253 
00254             // remove backend storage permanent data
00255             ZPush::GetStateMachine()->CleanStates($device->GetDeviceId(), IStateMachine::BACKENDSTORAGE, false, 99999999999);
00256 
00257             // remove devicedata and unlink user from device
00258             unset($devices[$user]);
00259             if (isset($devicedata->devices))
00260                 $devicedata->devices = $devices;
00261             ZPush::GetStateMachine()->UnLinkUserDevice($user, $devid);
00262 
00263             // no more users linked for device - remove device data
00264             if (count($devices) == 0)
00265                 ZPush::GetStateMachine()->CleanStates($devid, IStateMachine::DEVICEDATA, false);
00266 
00267             // save data if something left
00268             else
00269                 ZPush::GetStateMachine()->SetState($devicedata, $devid, IStateMachine::DEVICEDATA);
00270 
00271             ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::RemoveDevice(): data of device '%s' of user '%s' removed", $devid, $user));
00272         }
00273         return true;
00274     }
00275 
00276 
00287     static public function ResyncFolder($user, $devid, $folderid) {
00288         // load device data
00289         $device = new ASDevice($devid, ASDevice::UNDEFINED, $user, ASDevice::UNDEFINED);
00290         try {
00291             $device->SetData(ZPush::GetStateMachine()->GetState($devid, IStateMachine::DEVICEDATA), false);
00292 
00293             if ($device->IsNewDevice()) {
00294                 ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncFolder(): data of user '%s' not synchronized on device '%s'. Aborting.",$user, $devid));
00295                 return false;
00296             }
00297 
00298             // remove folder state
00299             StateManager::UnLinkState($device, $folderid);
00300 
00301             ZPush::GetStateMachine()->SetState($device->GetData(), $devid, IStateMachine::DEVICEDATA);
00302             ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::ResyncFolder(): folder '%s' on device '%s' of user '%s' marked to be re-synchronized.", $devid, $user));
00303         }
00304         catch (StateNotFoundException $e) {
00305             ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncFolder(): state for device '%s' of user '%s' can not be found or saved", $devid, $user));
00306             return false;
00307         }
00308     }
00309 
00310 
00323     static public function ResyncDevice($user, $devid = false) {
00324 
00325         // search for target devices
00326         if ($devid === false) {
00327             $devicesIds = ZPush::GetStateMachine()->GetAllDevices($user);
00328             ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::ResyncDevice(): all '%d' devices for user '%s' found to be re-synchronized", count($devicesIds), $user));
00329             foreach ($devicesIds as $deviceid) {
00330                 if (!self::ResyncDevice($user, $deviceid)) {
00331                     ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncDevice(): wipe devices failed for device '%s' of user '%s'. Aborting", $deviceid, $user));
00332                     return false;
00333                 }
00334             }
00335         }
00336         else {
00337             // get devicedata
00338             try {
00339                 $devicedata = ZPush::GetStateMachine()->GetState($devid, IStateMachine::DEVICEDATA);
00340             }
00341             catch (StateNotFoundException $e) {
00342                 ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncDevice(): state for device '%s' can not be found", $devid));
00343                 return false;
00344 
00345             }
00346 
00347             // loop through all users which currently use this device
00348             if ($user === false && $devicedata instanceof StateObject && isset($devicedata->devices) &&
00349                 is_array($devicedata->devices) && count($devicedata->devices) > 1) {
00350                 foreach (array_keys($devicedata) as $aUser) {
00351                     if (!self::ResyncDevice($aUser, $devid)) {
00352                         ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncDevice(): re-synchronization failed for device '%s' of user '%s'. Aborting", $devid, $aUser));
00353                         return false;
00354                     }
00355                 }
00356             }
00357 
00358             // load device data
00359             $device = new ASDevice($devid, ASDevice::UNDEFINED, $user, ASDevice::UNDEFINED);
00360             try {
00361                 $device->SetData($devicedata, false);
00362 
00363                 if ($device->IsNewDevice()) {
00364                     ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncDevice(): data of user '%s' not synchronized on device '%s'. Aborting.",$user, $devid));
00365                     return false;
00366                 }
00367 
00368                 // delete all uuids
00369                 foreach ($device->GetAllFolderIds() as $folderid)
00370                     StateManager::UnLinkState($device, $folderid);
00371 
00372                 // remove hierarchcache
00373                 StateManager::UnLinkState($device, false);
00374 
00375                 ZPush::GetStateMachine()->SetState($device->GetData(), $devid, IStateMachine::DEVICEDATA);
00376 
00377                 ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::ResyncDevice(): all folders synchronized to device '%s' of user '%s' marked to be re-synchronized.", $devid, $user));
00378             }
00379             catch (StateNotFoundException $e) {
00380                 ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::ResyncDevice(): state for device '%s' of user '%s' can not be found or saved", $devid, $user));
00381                 return false;
00382             }
00383         }
00384         return true;
00385     }
00386 
00396     static public function ClearLoopDetectionData($user = false, $devid = false) {
00397         $loopdetection = new LoopDetection();
00398         return $loopdetection->ClearData($user, $devid);
00399     }
00400 
00410     static public function GetLoopDetectionData($user, $devid) {
00411         $loopdetection = new LoopDetection();
00412         return $loopdetection->GetCachedData($user, $devid);
00413     }
00414 
00415 
00416 }
00417 
00418 ?>