Commit ae73cd3f authored by Sebastian Kummer's avatar Sebastian Kummer

Merge branch 'develop' into bugfix/ZP-1085-update-trademark

parents 6797670b bc817b64
......@@ -158,7 +158,7 @@ class BackendKopano implements IBackend, ISearchProvider {
if (mapi_last_hresult()) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("KopanoBackend->Logon(): login failed with error code: 0x%X", mapi_last_hresult()));
if (mapi_last_hresult() == MAPI_E_NETWORK_ERROR)
throw new HTTPReturnCodeException("Error connecting to KC (login)", 503, null, LOGLEVEL_INFO);
throw new ServiceUnavailableException("Error connecting to KC (login)");
}
}
catch (MAPIException $ex) {
......@@ -175,7 +175,7 @@ class BackendKopano implements IBackend, ISearchProvider {
$this->defaultstore = $this->openMessageStore($this->mainUser);
if (mapi_last_hresult() == MAPI_E_FAILONEPROVIDER)
throw new HTTPReturnCodeException("Error connecting to KC (open store)", 503, null, LOGLEVEL_INFO);
throw new ServiceUnavailableException("Error connecting to KC (open store)");
if($this->defaultstore === false)
throw new AuthenticationRequiredException(sprintf("KopanoBackend->Logon(): User '%s' has no default store", $user));
......
......@@ -254,6 +254,14 @@
define('SYNC_TIMEOUT_MEDIUM_DEVICETYPES', "SAMSUNGGTI");
define('SYNC_TIMEOUT_LONG_DEVICETYPES', "iPod, iPad, iPhone, WP, WindowsOutlook");
// Time in seconds the device should wait whenever the service is unavailable,
// e.g. when a backend service is unavailable.
// Z-Push sends a "Retry-After" header in the response with the here defined value.
// It is up to the device to respect or not this directive so even if this option is set,
// the device might not wait requested time frame.
// Number of seconds before retry, to disable set to: false
define('RETRY_AFTER_DELAY', 300);
/**********************************************************************************
* Backend settings
*/
......
......@@ -923,11 +923,13 @@ class ASDevice extends StateObject {
* @param string $folderid the folder id of the additional folder.
* @param string $name the name of the additional folder (has to be unique for all folders on the device).
* @param int $flags Additional flags, like DeviceManager::FLD_FLAGS_REPLYASUSER
* @param string $parentid the parentid of this folder.
* @param boolean $checkDups indicates if duplicate names and ids should be verified. Default: true
*
* @access public
* @return boolean
*/
public function EditAdditionalFolder($folderid, $name, $flags) {
public function EditAdditionalFolder($folderid, $name, $flags, $parentid = 0, $checkDups = true) {
// check if a folderid and name were sent
if (!$folderid || !$name) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->EditAdditionalFolder(): No valid folderid ('%s') or name ('%s') sent. Aborting. ", $folderid, $name));
......@@ -949,11 +951,15 @@ class ASDevice extends StateObject {
}
// check if a folder with the new name is already known on the device (regular folder)
foreach($this->GetHierarchyCache()->ExportFolders() as $syncedFolderid => $folder) {
// $folder is a SyncFolder object here
if ($folder->displayname == $name && $folderid !== $folder->BackendId && $folderid !== $syncedFolderid) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->EditAdditionalFolder(): folder can not be edited because there is already a folder with the same name synchronized: '%s'", $folderid));
return false;
if ($checkDups) {
// in order to check for the parent-ids we need a shortid
$parentShortId = $this->GetFolderIdForBackendId($parentid, false, null, null);
foreach($this->GetHierarchyCache()->ExportFolders() as $syncedFolderid => $folder) {
// $folder is a SyncFolder object here
if ($folder->displayname == $name && $folderid !== $folder->BackendId && $folderid !== $syncedFolderid && ($folder->parentid == $parentid || $folder->parentid == $parentShortId)) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->EditAdditionalFolder(): folder can not be edited because there is already a folder with the same name synchronized: '%s'", $folderid));
return false;
}
}
}
......@@ -961,6 +967,7 @@ class ASDevice extends StateObject {
$af = $this->additionalfolders;
$af[$folderid]['name'] = $name;
$af[$folderid]['flags'] = $flags;
$af[$folderid]['parentid'] = $parentid;
$this->additionalfolders = $af;
return true;
......
......@@ -422,11 +422,16 @@ class SyncCollections implements Iterator {
* previousily set or saved in a collection
*
* @access public
* @return int returns 600 as default if nothing set or not available
* @return int returns PING_HIGHER_BOUND_LIFETIME as default if nothing set or not available.
* If PING_HIGHER_BOUND_LIFETIME is not set, returns 600.
*/
public function GetLifetime() {
if (!isset( $this->refLifetime) || $this->refLifetime === false)
if (!isset($this->refLifetime) || $this->refLifetime === false) {
if (PING_HIGHER_BOUND_LIFETIME !== false) {
return PING_HIGHER_BOUND_LIFETIME;
}
return 600;
}
return $this->refLifetime;
}
......@@ -717,7 +722,6 @@ class SyncCollections implements Iterator {
*/
private function countHierarchyChange($exportChanges = false) {
$folderid = false;
$spa = $this->GetCollection($folderid);
// Check with device manager if the hierarchy should be reloaded.
// New additional folders are loaded here.
......
......@@ -325,6 +325,13 @@ class ZPush {
throw new FatalMisconfigurationException("The PING_HIGHER_BOUND_LIFETIME value must be greater or equal to PING_LOWER_BOUND_LIFETIME.");
}
if (!defined('RETRY_AFTER_DELAY')) {
define('RETRY_AFTER_DELAY', 300);
}
elseif (RETRY_AFTER_DELAY !== false && (!is_int(RETRY_AFTER_DELAY) || RETRY_AFTER_DELAY < 1)) {
throw new FatalMisconfigurationException("The RETRY_AFTER_DELAY value must be 'false' or a number greater than 0.");
}
// Check KOE flags
if (!defined('KOE_CAPABILITY_GAB')) {
define('KOE_CAPABILITY_GAB', false);
......@@ -437,7 +444,7 @@ class ZPush {
if (ZPush::$stateMachine->GetStateVersion() !== ZPush::GetLatestStateVersion()) {
if (class_exists("TopCollector")) self::GetTopCollector()->AnnounceInformation("Run migration script!", true);
throw new HTTPReturnCodeException(sprintf("The state version available to the %s is not the latest version - please run the state upgrade script. See release notes for more information.", get_class(ZPush::$stateMachine), 503));
throw new ServiceUnavailableException(sprintf("The state version available to the %s is not the latest version - please run the state upgrade script. See release notes for more information.", get_class(ZPush::$stateMachine)));
}
}
return ZPush::$stateMachine;
......
......@@ -984,6 +984,7 @@ define("HTTP_CODE_200", 200);
define("HTTP_CODE_401", 401);
define("HTTP_CODE_449", 449);
define("HTTP_CODE_500", 500);
define("HTTP_CODE_503", 503);
define("WINDOW_SIZE_MAX", 512);
......
<?php
/***********************************************
* File : serviceunavailableexception.php
* Project : Z-Push
* Descr : Exception sending a '503 Service Unavailable' to the mobile.
*
* Created : 09.08.2016
*
* Copyright 2007 - 2016 Zarafa Deutschland GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation with the following additional
* term according to sec. 7:
*
* According to sec. 7 of the GNU Affero General Public License, version 3,
* the terms of the AGPL are supplemented with the following terms:
*
* "Zarafa" is a registered trademark of Zarafa B.V.
* "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
* The licensing of the Program under the AGPL does not imply a trademark license.
* Therefore any rights, title and interest in our trademarks remain entirely with us.
*
* However, if you propagate an unmodified version of the Program you are
* allowed to use the term "Z-Push" to indicate that you distribute the Program.
* Furthermore you may use our trademarks where it is necessary to indicate
* the intended purpose of a product or service provided you use it in accordance
* with honest practices in industrial or commercial matters.
* If you want to propagate modified versions of the Program under the name "Z-Push",
* you may only do so if you have a written permission by Zarafa Deutschland GmbH
* (to acquire a permission please contact Zarafa at trademark@zarafa.com).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Consult LICENSE file for details
************************************************/
class ServiceUnavailableException extends HTTPReturnCodeException {
protected $defaultLogLevel = LOGLEVEL_INFO;
protected $httpReturnCode = HTTP_CODE_503;
protected $httpReturnMessage = "Service Unavailable";
protected $httpHeaders = array();
protected $showLegal = false;
public function __construct($message = "", $code = 0, $previous = NULL, $logLevel = false) {
parent::__construct($message, $code, $previous, $logLevel);
if (RETRY_AFTER_DELAY !== false) {
$this->httpHeaders[] = 'Retry-After: ' . RETRY_AFTER_DELAY;
}
}
}
\ No newline at end of file
......@@ -290,7 +290,7 @@ class Search extends RequestProcessor {
}
$searchprovider->Disconnect();
self::$topCollector->AnnounceInformation(sprintf("'%s' search found %d results", $searchname, $rows['searchtotal']), true);
self::$topCollector->AnnounceInformation(sprintf("'%s' search found %d results", $searchname, (isset($rows['searchtotal']) ? $rows['searchtotal'] : 0) ), true);
self::$encoder->startWBXML();
self::$encoder->startTag(SYNC_SEARCH_SEARCH);
......
......@@ -34,7 +34,6 @@ class SendMail extends RequestProcessor {
* @return boolean
*/
public function Handle($commandCode) {
$status = SYNC_COMMONSTATUS_SUCCESS;
$sm = new SyncSendMail();
$reply = $forward = $parent = $sendmail = $smartreply = $smartforward = false;
......@@ -123,6 +122,7 @@ class SendMail extends RequestProcessor {
self::$topCollector->AnnounceInformation(sprintf("SendMail(): Sending email with %d bytes", strlen($sm->mime)), true);
$statusMessage = '';
try {
$status = self::$backend->SendMail($sm);
}
......
......@@ -115,14 +115,16 @@ class ZPushAdmin {
if ($fstatus !== false && isset($fstatus[ASDevice::FOLDERSYNCSTATUS])) {
$spa = $sc->GetCollection($folderid);
$total = $spa->GetFolderSyncTotal();
$todo = $spa->GetFolderSyncRemaining();
$fstatus['status'] = ($fstatus[ASDevice::FOLDERSYNCSTATUS] == 1)?'Initialized':'Synchronizing';
$fstatus['total'] = $total;
$fstatus['done'] = $total - $todo;
$fstatus['todo'] = $todo;
$device->SetFolderSyncStatus($folderid, $fstatus);
if ($spa) {
$total = $spa->GetFolderSyncTotal();
$todo = $spa->GetFolderSyncRemaining();
$fstatus['status'] = ($fstatus[ASDevice::FOLDERSYNCSTATUS] == 1) ? 'Initialized' : 'Synchronizing';
$fstatus['total'] = $total;
$fstatus['done'] = $total - $todo;
$fstatus['todo'] = $todo;
$device->SetFolderSyncStatus($folderid, $fstatus);
}
}
}
}
......@@ -959,17 +961,17 @@ class ZPushAdmin {
}
/**
* Fixes potentially missing flags on additional folders.
* Fixes missing flags or parentids on additional folders.
*
* @access public
* @return array(seenDevices, devicesWithAdditionalFolders, fixedAdditionalFolders)
*/
static public function FixStatesAdditionalFolderFlags() {
static public function FixStatesAdditionalFolders() {
$devices = 0;
$devicesWithAddFolders = 0;
$fixed = 0;
$asdevices = ZPush::GetStateMachine()->GetAllDevices(false);
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::FixStatesAdditionalFolderFlags(): found %d devices", count($asdevices)));
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::FixStatesAdditionalFolders(): found %d devices", count($asdevices)));
foreach ($asdevices as $devid) {
try {
......@@ -986,8 +988,14 @@ class ZPushAdmin {
if ($addFolders) {
$devicesWithAddFolders++;
foreach($addFolders as $df) {
if (!isset($df['flags'])) {
$device->EditAdditionalFolder($df['folderid'], $df['name'], 0);
if (!isset($df['flags']) || !isset($df['parentid']) ) {
if (!isset($df['flags'])) {
$df['flags'] = 0;
}
if (!isset($df['parentid'])) {
$df['parentid'] = 0;
}
$device->EditAdditionalFolder($df['folderid'], $df['name'], $df['flags'], $df['parentid']);
$needsFixing = true;
}
}
......@@ -998,12 +1006,12 @@ class ZPushAdmin {
}
if ($needsFixing) {
ZPush::GetStateMachine()->SetState($devicedata, $devid, IStateMachine::DEVICEDATA);
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::FixStatesAdditionalFolderFlags(): updated device '%s' because flags were fixed", $devid));
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ZPushAdmin::FixStatesAdditionalFolders(): updated device '%s' because flags or parentids were fixed", $devid));
$fixed++;
}
}
catch (StateNotFoundException $e) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::FixStatesAdditionalFolderFlags(): state for device '%s' can not be found", $devid));
ZLog::Write(LOGLEVEL_ERROR, sprintf("ZPushAdmin::FixStatesAdditionalFolders(): state for device '%s' can not be found", $devid));
}
}
return array($devices, $devicesWithAddFolders, $fixed);
......
......@@ -112,6 +112,7 @@ return array(
'Search' => $baseDir . '/lib/request/search.php',
'SearchProvider' => $baseDir . '/lib/default/searchprovider.php',
'SendMail' => $baseDir . '/lib/request/sendmail.php',
'ServiceUnavailableException' => $baseDir . '/lib/exceptions/serviceunavailableexception.php',
'Settings' => $baseDir . '/lib/request/settings.php',
'SimpleMutex' => $baseDir . '/lib/default/simplemutex.php',
'SqlStateMachine' => $baseDir . '/backend/sqlstatemachine/sqlstatemachine.php',
......
......@@ -119,6 +119,7 @@ class ComposerStaticInitd6749fc2fb9944bbe86b2b7d79a7852f
'Search' => __DIR__ . '/../..' . '/lib/request/search.php',
'SearchProvider' => __DIR__ . '/../..' . '/lib/default/searchprovider.php',
'SendMail' => __DIR__ . '/../..' . '/lib/request/sendmail.php',
'ServiceUnavailableException' => __DIR__ . '/../..' . '/lib/exceptions/serviceunavailableexception.php',
'Settings' => __DIR__ . '/../..' . '/lib/request/settings.php',
'SimpleMutex' => __DIR__ . '/../..' . '/lib/default/simplemutex.php',
'SqlStateMachine' => __DIR__ . '/../..' . '/backend/sqlstatemachine/sqlstatemachine.php',
......
......@@ -728,7 +728,7 @@ class ZPushAdminCLI {
echo ZLog::GetLastMessage(LOGLEVEL_ERROR) . "\n";
echo "\tChecking flags of shared folders: ";
if (($stat = ZPushAdmin::FixStatesAdditionalFolderFlags()) !== false)
if (($stat = ZPushAdmin::FixStatesAdditionalFolders()) !== false)
printf("Devices: %d - Devices with additional folders: %d - Fixed: %d\n", $stat[0], $stat[1], $stat[2]);
else
echo ZLog::GetLastMessage(LOGLEVEL_ERROR) . "\n";
......
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