/** * (non-PHPdoc) * @see Tinebase_Server_Interface::handle() */ public function handle(\Zend\Http\Request $request = null, $body = null) { Tinebase_Session::setSessionOptions(array('use_cookies' => 0, 'use_only_cookies' => 0)); Tinebase_Core::initFramework(); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' is snom xml request. method: ' . $this->getRequestMethod()); } $server = new Tinebase_Http_Server(); $server->setClass('Voipmanager_Frontend_Snom', 'Voipmanager'); $server->setClass('Phone_Frontend_Snom', 'Phone'); $server->handle($_REQUEST); }
/** * startSetupSession * * TODO remove redundancy with Tinebase_Core::startCoreSession() */ public static function startSetupSession() { Tinebase_Session::setSessionBackend(); Zend_Session::start(); $setupSession = Setup_Session::getSessionNamespace(); if (isset($setupSession->setupuser)) { self::set(self::USER, $setupSession->setupuser); } if (!isset($setupSession->jsonKey)) { $setupSession->jsonKey = Tinebase_Record_Abstract::generateUID(); } self::set('jsonKey', $setupSession->jsonKey); }
/** * (non-PHPdoc) * @see Tinebase_Server_Interface::handle() */ public function handle(\Zend\Http\Request $request = null, $body = null) { Tinebase_Session_Abstract::setSessionEnabled('TINE20SETUPSESSID'); if (Tinebase_Session::sessionExists()) { Setup_Core::startSetupSession(); } Setup_Core::initFramework(); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' is http request. method: ' . $this->getRequestMethod()); } $server = new Tinebase_Http_Server(); $server->setClass('Setup_Frontend_Http', 'Setup'); $server->setClass('Tinebase_Frontend_Http', 'Tinebase'); // needed for fetching translation in DEVELOPMENT mode if (empty($_REQUEST['method'])) { $_REQUEST['method'] = 'Setup.mainScreen'; } $server->handle($_REQUEST); }
/** * @group ServerTests * * @see 0011760: create smd from model definition */ public function testHandleRequestForDynamicAPI() { // handle jsonkey check $jsonkey = 'myawsomejsonkey'; $_SERVER['HTTP_X_TINE20_JSONKEY'] = $jsonkey; $coreSession = Tinebase_Session::getSessionNamespace(); $coreSession->jsonKey = $jsonkey; $server = new Tinebase_Server_Json(); $request = \Zend\Http\PhpEnvironment\Request::fromString('POST /index.php?requestType=JSON HTTP/1.1' . "\r\n" . 'Host: localhost' . "\r\n" . 'User-Agent: Mozilla/5.0 (X11; Linux i686; rv:15.0) Gecko/20120824 Thunderbird/15.0 Lightning/1.7' . "\r\n" . 'Content-Type: application/json' . "\r\n" . 'X-Tine20-Transactionid: 18da265bc0eb66a36081bfd42689c1675ed68bab' . "\r\n" . 'X-Requested-With: XMLHttpRequest' . "\r\n" . 'Accept: */*' . "\r\n" . 'Referer: http://tine20.vagrant/' . "\r\n" . 'Accept-Encoding: gzip, deflate' . "\r\n" . 'Accept-Language: en-US,en;q=0.8,de-DE;q=0.6,de;q=0.4' . "\r\n" . "\r\n" . '{"jsonrpc":"2.0","method":"Inventory.searchInventoryItems","params":{"filter":[], "paging":{}},"id":6}' . "\r\n"); ob_start(); $server->handle($request); $out = ob_get_clean(); //echo $out; $this->assertTrue(!empty($out), 'request should not be empty'); $this->assertNotContains('Not Authorised', $out); $this->assertNotContains('Method not found', $out); $this->assertNotContains('No Application Controller found', $out); $this->assertNotContains('"error"', $out); $this->assertNotContains('PHP Fatal error', $out); $this->assertContains('"result"', $out); }
/** * (non-PHPdoc) * @see Tinebase_Server_Interface::handle() */ public function handle(\Zend\Http\Request $request = null, $body = null) { try { // init server and request first $server = new Zend_Json_Server(); $server->setClass('Setup_Frontend_Json', 'Setup'); $server->setClass('Tinebase_Frontend_Json', 'Tinebase'); $server->setAutoHandleExceptions(false); $server->setAutoEmitResponse(false); $request = new Zend_Json_Server_Request_Http(); if (Tinebase_Session::sessionExists()) { Setup_Core::startSetupSession(); } Setup_Core::initFramework(); $method = $request->getMethod(); $jsonKey = isset($_SERVER['HTTP_X_TINE20_JSONKEY']) ? $_SERVER['HTTP_X_TINE20_JSONKEY'] : ''; Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' is JSON request. method: ' . $method); $anonymnousMethods = array('Setup.getAllRegistryData', 'Setup.login', 'Tinebase.getAvailableTranslations', 'Tinebase.getTranslations', 'Tinebase.setLocale'); if (!Setup_Core::configFileExists()) { $anonymnousMethods = array_merge($anonymnousMethods, array('Setup.envCheck')); } // check json key for all methods but some exceptions if (!in_array($method, $anonymnousMethods) && Setup_Core::configFileExists() && (empty($jsonKey) || $jsonKey != Setup_Core::get('jsonKey') || !Setup_Core::isRegistered(Setup_Core::USER))) { if (!Setup_Core::isRegistered(Setup_Core::USER)) { Setup_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Attempt to request a privileged Json-API method without authorisation from "' . $_SERVER['REMOTE_ADDR'] . '". (session timeout?)'); throw new Tinebase_Exception_AccessDenied('Not Authorised', 401); } else { Setup_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Fatal: got wrong json key! (' . $jsonKey . ') Possible CSRF attempt!' . ' affected account: ' . print_r(Setup_Core::getUser(), true) . ' request: ' . print_r($_REQUEST, true)); throw new Tinebase_Exception_AccessDenied('Not Authorised', 401); } } $response = $server->handle($request); } catch (Exception $exception) { $response = $this->_handleException($request, $exception); } echo $response; }
/** * authenticate user * * @param string $_username * @param string $_password * @return Zend_Auth_Result */ public function authenticate($_username, $_password) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Trying to authenticate ' . $_username); } try { $this->_backend->setIdentity($_username); } catch (Zend_Auth_Adapter_Exception $zaae) { return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, $_username, array($zaae->getMessage())); } $this->_backend->setCredential($_password); if (Tinebase_Session::isStarted()) { Zend_Auth::getInstance()->setStorage(new Zend_Auth_Storage_Session()); } else { Zend_Auth::getInstance()->setStorage(new Zend_Auth_Storage_NonPersistent()); } $result = Zend_Auth::getInstance()->authenticate($this->_backend); return $result; }
/** * Even if the database backend is PostgreSQL, we have to verify * if the extension Unaccent is installed and loaded. * This is done in Tinebase_Core::checkUnaccentExtension. * * @return boolean */ protected function _hasUnaccentExtension() { try { $session = Tinebase_Session::getSessionNamespace(); if (isset($session->dbcapabilities) && (isset($session->dbcapabilities['unaccent']) || array_key_exists('unaccent', $session->dbcapabilities))) { $result = $session->dbcapabilities['unaccent']; } else { $result = $this->_adapter->hasUnaccentExtension(); $capabilities['unaccent'] = $result; $session->dbcapabilities = $capabilities; } } catch (Zend_Session_Exception $zse) { $result = $this->_adapter->hasUnaccentExtension(); } return $result; }
/** * update flags * - use session/writeClose to allow following requests * * @param string $folderId id of active folder * @param integer $time update time in seconds * @return array */ public function updateFlags($folderId, $time) { // close session to allow other requests Tinebase_Session::writeClose(true); $folder = Felamimail_Controller_Cache_Message::getInstance()->updateFlags($folderId, $time); return $this->_recordToJson($folder); }
/** * returns true if user account has been changed * * @return boolean */ public function userAccountChanged() { try { $session = Tinebase_Session::getSessionNamespace(); } catch (Zend_Session_Exception $zse) { $session = null; } return $session instanceof Zend_Session_Namespace && isset($session->userAccountChanged) ? $session->userAccountChanged : false; }
/** * downloads an image/thumbnail at a given size * * @param unknown_type $application * @param string $id * @param string $location * @param int $width * @param int $height * @param int $ratiomode */ public function getImage($application, $id, $location, $width, $height, $ratiomode) { $this->checkAuth(); // close session to allow other requests Tinebase_Session::writeClose(true); $clientETag = null; $ifModifiedSince = null; if (isset($_SERVER['If_None_Match'])) { $clientETag = trim($_SERVER['If_None_Match'], '"'); $ifModifiedSince = trim($_SERVER['If_Modified_Since'], '"'); } elseif (isset($_SERVER['HTTP_IF_NONE_MATCH']) && isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $clientETag = trim($_SERVER['HTTP_IF_NONE_MATCH'], '"'); $ifModifiedSince = trim($_SERVER['HTTP_IF_MODIFIED_SINCE'], '"'); } if ($application == 'Tinebase' && $location == 'tempFile') { $tempFile = Tinebase_TempFile::getInstance()->getTempFile($id); $imgInfo = Tinebase_ImageHelper::getImageInfoFromBlob(file_get_contents($tempFile->path)); $image = new Tinebase_Model_Image($imgInfo + array('application' => $application, 'id' => $id, 'location' => $location)); } else { $image = Tinebase_Controller::getInstance()->getImage($application, $id, $location); } $serverETag = sha1($image->blob . $width . $height . $ratiomode); // cache for 3600 seconds $maxAge = 3600; header('Cache-Control: private, max-age=' . $maxAge); header("Expires: " . gmdate('D, d M Y H:i:s', Tinebase_DateTime::now()->addSecond($maxAge)->getTimestamp()) . " GMT"); // overwrite Pragma header from session header("Pragma: cache"); // if the cache id is still valid if ($clientETag == $serverETag) { header("Last-Modified: " . $ifModifiedSince); header("HTTP/1.0 304 Not Modified"); header('Content-Length: 0'); } else { #$cache = Tinebase_Core::getCache(); #if ($cache->test($serverETag) === true) { # $image = $cache->load($serverETag); #} else { if ($width != -1 && $height != -1) { Tinebase_ImageHelper::resize($image, $width, $height, $ratiomode); } # $cache->save($image, $serverETag); #} header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header('Content-Type: ' . $image->mime); header('Etag: "' . $serverETag . '"'); flush(); die($image->blob); } }
/** * get cache record (try to find in session first, then DB) * * @param string $id * @return Tinebase_Model_CredentialCache */ protected function _getCache($id) { try { $session = Tinebase_Session::getSessionNamespace(); $credentialSessionCache = $session->{self::SESSION_NAMESPACE}; if (isset($credentialSessionCache) && isset($credentialSessionCache[$id])) { return new Tinebase_Model_CredentialCache($credentialSessionCache[$id]); } } catch (Zend_Session_Exception $zse) { // nothing to do } /** @var Tinebase_Model_CredentialCache $result */ $result = $this->get($id); $this->_saveInSession($result); return $result; }
/** * (non-PHPdoc) * @see Tinebase_Server_Interface::handle() */ public function handle(\Zend\Http\Request $request = null, $body = null) { $this->_request = $request instanceof \Zend\Http\Request ? $request : Tinebase_Core::get(Tinebase_Core::REQUEST); $this->_body = $body !== null ? $body : fopen('php://input', 'r'); $request = $request instanceof \Zend\Http\Request ? $request : new \Zend\Http\PhpEnvironment\Request(); // only for debugging //Tinebase_Core::getLogger()->DEBUG(__METHOD__ . '::' . __LINE__ . " raw request: " . $request->__toString()); // handle CORS requests if ($request->getHeaders()->has('ORIGIN') && !$request->getHeaders()->has('X-FORWARDED-HOST')) { /** * First the client sends a preflight request * * METHOD: OPTIONS * Access-Control-Request-Headers:x-requested-with, content-type * Access-Control-Request-Method:POST * Origin:http://other.site * Referer:http://other.site/example.html * User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36 * * We have to respond with * * Access-Control-Allow-Credentials:true * Access-Control-Allow-Headers:x-requested-with, x-tine20-request-type, content-type, x-tine20-jsonkey * Access-Control-Allow-Methods:POST * Access-Control-Allow-Origin:http://other.site * * Then the client sends the standard JSON request with two additional headers * * METHOD: POST * Origin:http://other.site * Referer:http://other.site/example.html * Standard-JSON-Rquest-Headers... * * We have to add two additional headers to our standard response * * Access-Control-Allow-Credentials:true * Access-Control-Allow-Origin:http://other.site */ $origin = $request->getHeaders('ORIGIN')->getFieldValue(); $uri = \Zend\Uri\UriFactory::factory($origin); if (in_array($uri->getScheme(), array('http', 'https'))) { $allowedOrigins = array_merge((array) Tinebase_Core::getConfig()->get(Tinebase_Config::ALLOWEDJSONORIGINS, array()), array($this->_request->getServer('SERVER_NAME'))); if (in_array($uri->getHost(), $allowedOrigins)) { // this headers have to be sent, for any CORS'ed JSON request header('Access-Control-Allow-Origin: ' . $origin); header('Access-Control-Allow-Credentials: true'); } // check for CORS preflight request if ($request->getMethod() == \Zend\Http\Request::METHOD_OPTIONS && $request->getHeaders()->has('ACCESS-CONTROL-REQUEST-METHOD')) { $this->_methods = array('handleCors'); if (in_array($uri->getHost(), $allowedOrigins)) { header('Access-Control-Allow-Methods: POST'); header('Access-Control-Allow-Headers: x-requested-with, x-tine20-request-type, content-type, x-tine20-jsonkey'); header('Access-Control-Max-Age: 3600'); // cache result of OPTIONS request for 1 hour } else { Tinebase_Core::getLogger()->WARN(__METHOD__ . '::' . __LINE__ . " unhandled CORS preflight request from {$origin}"); Tinebase_Core::getLogger()->INFO(__METHOD__ . '::' . __LINE__ . " you may want to set \"'allowedJsonOrigins' => array('{$uri->getHost()}'),\" to config.inc.php"); Tinebase_Core::getLogger()->DEBUG(__METHOD__ . '::' . __LINE__ . " allowed origins: " . print_r($allowedOrigins, TRUE)); } // stop further processing => is OPTIONS request return; } } } $exception = false; if (Tinebase_Session::sessionExists()) { try { Tinebase_Core::startCoreSession(); } catch (Zend_Session_Exception $zse) { $exception = new Tinebase_Exception_AccessDenied('Not Authorised', 401); // expire session cookie for client Tinebase_Session::expireSessionCookie(); } } if ($exception === false) { try { Tinebase_Core::initFramework(); } catch (Exception $exception) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' initFramework exception: ' . $exception); } } } $json = $request->getContent(); $json = Tinebase_Core::filterInputForDatabase($json); if (substr($json, 0, 1) == '[') { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' batched request'); } $isBatchedRequest = true; $requests = Zend_Json::decode($json); } else { $isBatchedRequest = false; $requests = array(Zend_Json::decode($json)); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { $_requests = $requests; foreach (array('password', 'oldPassword', 'newPassword') as $field) { if (isset($requests[0]["params"][$field])) { $_requests[0]["params"][$field] = "*******"; } } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' is JSON request. rawdata: ' . print_r($_requests, true)); } } $response = array(); foreach ($requests as $requestOptions) { if ($requestOptions !== NULL) { $request = new Zend_Json_Server_Request(); $request->setOptions($requestOptions); $response[] = $exception ? $this->_handleException($request, $exception) : $this->_handle($request); } else { if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Got empty request options: skip request.'); } $response[] = NULL; } } if (!headers_sent()) { header('Content-type: application/json'); } echo $isBatchedRequest ? '[' . implode(',', $response) . ']' : $response[0]; }
/** * Gets one entry (by id) * * @param string $_id * @param boolean $_useCache true to get folder from cache * @return Tinebase_Record_Interface * @throws Tinebase_Exception_NotFound * * @todo test to do a getQuota() shoudn't be hardcoded * */ public function get($_id, $_useCache = TRUE) { $cache = Tinebase_Core::getCache(); $cacheKey = $this->getFolderCacheId($_id); $folderFromCache = $_useCache ? $cache->load($cacheKey) : FALSE; if ($folderFromCache) { return $folderFromCache; } $folderDecoded = self::decodeFolderUid($_id); if (isset($folderDecoded['accountId'])) { $imap = Expressomail_Backend_ImapFactory::factory($folderDecoded['accountId'], TRUE); $account = Expressomail_Controller_Account::getInstance()->get($folderDecoded['accountId']); $ns_other = preg_replace('/\\/$/', '', $account->ns_other); $delimiter = $account->delimiter; $folder = $imap->getFolders('', $folderDecoded['globalName'], $this->_accounts[$folderDecoded['accountId']]); $acls = $imap->getFolderAcls($folderDecoded['globalName'], TRUE); $status = $imap->getFolderStatus($folderDecoded['globalName']); if ($status === FALSE) { // we can not access folder, create Model as unselectable $globalname = $folderDecoded['globalName']; $auxlocalname = explode(self::IMAPDELIMITER, $globalname); $localname = array_pop($auxlocalname); $translate = Tinebase_Translation::getTranslation("Expressomail"); if (preg_match("/^user\\/[0-9]{11}\$/", $globalname)) { try { $aux = Tinebase_User::getInstance()->getFullUserByLoginName($localname)->toArray(); $localname = $aux["accountFullName"]; } catch (Exception $exc) { Tinebase_Core::getLogger()->debug(__METHOD__ . "::" . __LINE__ . ":: Account with loginName {$localname} not found in the system for loginName to accountFullName translation."); } } $newFolder = new Expressomail_Model_Folder(array('id' => $_id, 'account_id' => Tinebase_Core::getPreference('Expressomail')->{Expressomail_Preference::DEFAULTACCOUNT}, 'localname' => $localname == 'user' ? $translate->_("Shared Folders") : $localname, 'globalname' => $folderDecoded['globalName'], 'parent' => $globalname === 'user' ? '' : substr($globalname, 0, strrpos($globalname, self::IMAPDELIMITER)), 'delimiter' => self::IMAPDELIMITER, 'is_selectable' => 0, 'has_children' => 1, 'system_folder' => 1, 'imap_status' => Expressomail_Model_Folder::IMAP_STATUS_OK, 'imap_timestamp' => Tinebase_DateTime::now(), 'cache_status' => 'complete', 'cache_timestamp' => Tinebase_DateTime::now(), 'cache_job_lowestuid' => 0, 'cache_job_startuid' => 0, 'cache_job_actions_est' => 0, 'cache_job_actions_done' => 0), true); $newFolder->setSharingValues($acls); // Saving cache with tags relating to model and account_id for bulky cleaning $cache->save($newFolder, $cacheKey, array(self::EXPRESSOMAIL_MODEL_FOLDER, $newFolder->account_id)); return $newFolder; } $globalName = $folderDecoded['globalName']; if ($globalName == 'INBOX' || $globalName == 'user') { $folder[$folderDecoded['globalName']]['parent'] = ''; } else { $folder[$folderDecoded['globalName']]['parent'] = substr($globalName, 0, strrpos($globalName, self::IMAPDELIMITER)); } /* * @todo must see if it is not better do this on the model directly */ $systemFolders = FALSE; if (strtolower($globalName) === 'inbox' || strtolower($folder[$folderDecoded['globalName']]['parent']) === 'user') { $systemFolders = TRUE; } else { if (strtolower($folder[$folderDecoded['globalName']]['parent']) === 'inbox' && strtolower($folder[$folderDecoded['globalName']]['localName']) !== 'inbox') { $systemFolders = in_array(strtolower($folder[$folderDecoded['globalName']]['localName']), Expressomail_Controller_Folder::getInstance()->getSystemFolders($folderDecoded['accountId'])); } else { if (preg_match('/^user\\/[^\\/]+$/i', $folder[$folderDecoded['globalName']]['parent'])) { $systemFolders = in_array(strtolower($folder[$folderDecoded['globalName']]['localName']), Expressomail_Controller_Folder::getInstance()->getSystemFolders($folderDecoded['accountId'])); } } } $localName = Expressomail_Model_Folder::decodeFolderName($folder[$folderDecoded['globalName']]['localName']); if (preg_match("/^user\\/[0-9]{11}\$/", Expressomail_Model_Folder::decodeFolderName($folder[$folderDecoded['globalName']]['globalName']))) { try { $aux = Tinebase_User::getInstance()->getFullUserByLoginName($localName)->toArray(); $localName = $aux["accountFullName"]; } catch (Exception $exc) { } } try { $expressomailSession = Expressomail_Session::getSessionNamespace(); } catch (Zend_Session_Exception $zse) { Tinebase_Core::getLogger()->warn(__METHOD__ . "::" . __LINE__ . ":: It was not possible to get Expressomail Session Namespace"); $expressomailSession = null; } $userNameSpace = $imap->getUserNameSpace() . self::IMAPDELIMITER; $arrDecodedFolder = explode(self::IMAPDELIMITER, $folderDecoded['globalName']); if ($folderDecoded['globalName'] === 'INBOX' || $folderDecoded['globalName'] === 'INBOX' . self::IMAPDELIMITER . 'Arquivo Remoto' || substr($folderDecoded['globalName'], 0, strlen($userNameSpace)) === $userNameSpace && (!isset($arrDecodedFolder[2]) || $arrDecodedFolder[2] === 'Arquivo Remoto')) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Getting quota from IMAP for ' . $folderDecoded['globalName']); } $quota = $imap->getQuota($folderDecoded['globalName']); if ($expressomailSession instanceof Zend_Session_Namespace && Tinebase_Session::isWritable()) { $expressomailSession->quota[$folderDecoded['globalName']] = $quota; } } else { if ($arrDecodedFolder[0] === 'INBOX' && isset($arrDecodedFolder[1]) && $arrDecodedFolder[1] === 'Arquivo Remoto') { $globalNameFolder = $arrDecodedFolder[0] . self::IMAPDELIMITER . $arrDecodedFolder[1]; } else { $globalNameFolder = $arrDecodedFolder[0]; } if ($arrDecodedFolder[0] !== 'INBOX') { $globalNameFolder .= isset($arrDecodedFolder[1]) ? self::IMAPDELIMITER . $arrDecodedFolder[1] : ''; } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Getting quota from Session for ' . $folderDecoded['globalName']); } $quota = 0; if ($expressomailSession instanceof Zend_Session_Namespace && isset($expressomailSession->quota) && isset($expressomailSession->quota[$globalNameFolder])) { $quota = $expressomailSession->quota[$globalNameFolder]; } } $return = new Expressomail_Model_Folder(array('id' => $_id, 'account_id' => $folderDecoded['accountId'], 'localname' => $localName, 'globalname' => Expressomail_Model_Folder::decodeFolderName($folder[$folderDecoded['globalName']]['globalName']), 'parent' => Expressomail_Model_Folder::decodeFolderName($folder[$folderDecoded['globalName']]['parent']), 'delimiter' => $folder[$folderDecoded['globalName']]['delimiter'], 'is_selectable' => $folder[$folderDecoded['globalName']]['isSelectable'], 'has_children' => $folder[$folderDecoded['globalName']]['hasChildren'], 'system_folder' => $systemFolders, 'imap_status' => Expressomail_Model_Folder::IMAP_STATUS_OK, 'imap_uidvalidity' => $status['uidvalidity'], 'imap_totalcount' => array_key_exists('messages', $status) ? $status['messages'] : '', 'imap_timestamp' => Tinebase_DateTime::now(), 'cache_status' => 'complete', 'cache_totalcount' => array_key_exists('messages', $status) ? $status['messages'] : '', 'cache_recentcount' => array_key_exists('recent', $status) ? $status['recent'] : '', 'cache_unreadcount' => array_key_exists('unseen', $status) ? $status['unseen'] : '', 'cache_timestamp' => Tinebase_DateTime::now(), 'cache_job_lowestuid' => 0, 'cache_job_startuid' => 0, 'cache_job_actions_est' => 0, 'cache_job_actions_done' => 0, 'quota_usage' => !empty($quota) ? $quota['STORAGE']['usage'] : 0, 'quota_limit' => !empty($quota) ? $quota['STORAGE']['limit'] : 0), true); $return->setSharingValues($acls); // Saving cache with tags relating to model and account_id for bulky cleaning $cache->save($return, $cacheKey, array(self::EXPRESSOMAIL_MODEL_FOLDER, $return->account_id)); return $return; } }
/** * handler for JSON api requests * @todo session expire handling * * @param $request * @return JSON */ protected function _handle($request) { try { $method = $request->getMethod(); Tinebase_Core::getLogger()->INFO(__METHOD__ . '::' . __LINE__ . ' is JSON request. method: ' . $method); $jsonKey = isset($_SERVER['HTTP_X_TINE20_JSONKEY']) ? $_SERVER['HTTP_X_TINE20_JSONKEY'] : ''; $this->_checkJsonKey($method, $jsonKey); if (empty($method)) { // SMD request return self::getServiceMap(); } $this->_methods[] = $method; $classes = array(); // add json apis which require no auth $classes['Tinebase_Frontend_Json'] = 'Tinebase'; // register additional Json apis only available for authorised users if (Tinebase_Session::isStarted() && Zend_Auth::getInstance()->hasIdentity()) { $applicationParts = explode('.', $method); $applicationName = ucfirst($applicationParts[0]); switch ($applicationName) { // additional Tinebase json apis case 'Tinebase_Container': $classes['Tinebase_Frontend_Json_Container'] = 'Tinebase_Container'; break; case 'Tinebase_PersistentFilter': $classes['Tinebase_Frontend_Json_PersistentFilter'] = 'Tinebase_PersistentFilter'; break; default: if (Tinebase_Core::getUser() && Tinebase_Core::getUser()->hasRight($applicationName, Tinebase_Acl_Rights_Abstract::RUN)) { $classes[$applicationName . '_Frontend_Json'] = $applicationName; } break; } } $server = self::_getServer($classes); $response = $server->handle($request); if ($response->isError()) { Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' Got response error: ' . print_r($response->getError()->toArray(), true)); } return $response; } catch (Exception $exception) { return $this->_handleException($request, $exception); } }
/** * create the search results dialogue * * @param string $mac the mac address of the phone * @param string $query the string to search the contacts for */ public function searchContacts($mac, $query) { $baseUrl = $this->_getBaseUrl(); // do nothing if search string is empty if (empty($query)) { $xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?> <SnomIPPhoneText> <Title>Nothing found!</Title> <Text>Nothing found!</Text> <fetch mil="1000">' . $baseUrl . '?method=Phone.directory&TINE20SESSID=' . Tinebase_Session::getId() . '&mac=' . $mac . '</fetch> </SnomIPPhoneText> '); header('Content-Type: text/xml'); echo $xml->asXML(); return; } $this->_authenticate(); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' phone ' . $mac . ' search for ' . $query); } $phone = Voipmanager_Controller_Snom_Phone::getInstance()->getByMacAddress($mac); $contactsBackend = Addressbook_Backend_Factory::factory(Addressbook_Backend_Factory::SQL); $tbContainer = Tinebase_Container::getInstance(); $readAbleContainer = array(); foreach ($phone->rights as $right) { if ($right->account_type == Tinebase_Acl_Rights::ACCOUNT_TYPE_USER) { $containers = $tbContainer->getContainerByACL($right->account_id, 'Addressbook', Tinebase_Model_Grants::GRANT_READ); $readAbleContainer = array_merge($readAbleContainer, $containers->getArrayOfIds()); } } $readAbleContainer = array_unique($readAbleContainer); $filter = new Addressbook_Model_ContactFilter(array(array('field' => 'query', 'operator' => 'contains', 'value' => $query), array('field' => 'container', 'operator' => 'in', 'value' => $readAbleContainer))); $contacts = $contactsBackend->search($filter, new Tinebase_Model_Pagination()); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' found ' . count($contacts) . ' contacts'); } if (count($contacts) == 0) { $baseUrl = $this->_getBaseUrl(); $xml = '<SnomIPPhoneText> <Title>Nothing found!</Title> <Text>Nothing found!</Text> <fetch mil="1000">' . $baseUrl . '?method=Phone.directory&TINE20SESSID=' . Tinebase_Session::getId() . '&mac=' . $mac . '</fetch> </SnomIPPhoneText> '; } else { $xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?> <SnomIPPhoneDirectory> <Title>Directory</Title> <Prompt>Dial</Prompt> </SnomIPPhoneDirectory> '); foreach ($contacts as $contact) { if (!empty($contact->tel_work)) { $directoryEntry = $xml->addChild('DirectoryEntry'); $directoryEntry->addChild('Name', $contact->n_fileas . ' Work'); $directoryEntry->addChild('Telephone', $contact->tel_work); } if (!empty($contact->tel_cell)) { $directoryEntry = $xml->addChild('DirectoryEntry'); $directoryEntry->addChild('Name', $contact->n_fileas . ' Cell'); $directoryEntry->addChild('Telephone', $contact->tel_cell); } if (!empty($contact->tel_home)) { $directoryEntry = $xml->addChild('DirectoryEntry'); $directoryEntry->addChild('Name', $contact->n_fileas . ' Home'); $directoryEntry->addChild('Telephone', $contact->tel_home); } if (!empty($contact->tel_cell_private)) { $directoryEntry = $xml->addChild('DirectoryEntry'); $directoryEntry->addChild('Name', $contact->n_fileas . ' CellP'); $directoryEntry->addChild('Telephone', $contact->tel_cell_private); } } $xml = $xml->asXML(); } header('Content-Type: text/xml'); echo $xml; }
/** * returns TRUE if filesystem is available * * - value is stored in session and registry for caching * * @return boolean */ public static function isFilesystemAvailable() { $isFileSystemAvailable = self::get('FILESYSTEM'); if ($isFileSystemAvailable === null) { try { $session = Tinebase_Session::getSessionNamespace(); if (isset($session->filesystemAvailable)) { $isFileSystemAvailable = $session->filesystemAvailable; self::set('FILESYSTEM', $isFileSystemAvailable); return $isFileSystemAvailable; } } catch (Zend_Session_Exception $zse) { $session = null; } $isFileSystemAvailable = !empty(Tinebase_Core::getConfig()->filesdir) && is_writeable(Tinebase_Core::getConfig()->filesdir); if ($session instanceof Zend_Session_Namespace) { if (Tinebase_Session::isWritable()) { $session->filesystemAvailable = $isFileSystemAvailable; } } if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Filesystem available: ' . ($isFileSystemAvailable ? 'yes' : 'no')); } self::set('FILESYSTEM', $isFileSystemAvailable); } return $isFileSystemAvailable; }
/** * testChangeUserAccount * * @see 0009984: allow to change user role */ public function testChangeUserAccount() { // allow test user to sign in as sclever Tinebase_Config::getInstance()->set(Tinebase_Config::ROLE_CHANGE_ALLOWED, new Tinebase_Config_Struct(array(Tinebase_Core::getUser()->accountLoginName => array('sclever')))); $sclever = $this->_personas['sclever']; $result = $this->_instance->changeUserAccount('sclever'); $this->assertEquals(array('success' => true), $result); // make sure, we are sclever $this->assertEquals('sclever', Tinebase_Core::getUser()->accountLoginName); $this->assertEquals('sclever', Tinebase_Session::getSessionNamespace()->currentAccount->accountLoginName); // reset to original user Tinebase_Controller::getInstance()->initUser($this->_originalTestUser, false); Tinebase_Session::getSessionNamespace()->userAccountChanged = false; }
/** * destroy session * * @return array */ public function logout() { Tinebase_Controller::getInstance()->logout($_SERVER['REMOTE_ADDR']); Tinebase_Auth_CredentialCache::getInstance()->getCacheAdapter()->resetCache(); if (Tinebase_Session::isStarted()) { Tinebase_Session::destroyAndRemoveCookie(); } $result = array('success' => true); return $result; }
/** * Gets Tinebase User session namespace * * @param string $sessionNamespace (optional) * @throws Zend_Session_Exception * @return Zend_Session_Namespace */ public static function getSessionNamespace($sessionNamespace = 'Default') { if (!Tinebase_Session::isStarted()) { throw new Zend_Session_Exception('Session not started'); } if (!self::getSessionEnabled()) { throw new Zend_Session_Exception('Session not enabled for request'); } $sessionNamespace = is_null($sessionNamespace) ? get_called_class() . '_Namespace' : $sessionNamespace; try { return self::_getSessionNamespace($sessionNamespace); } catch (Exception $e) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Session error: ' . $e->getMessage()); Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $e->getTraceAsString()); throw $e; } }
/** * prepare long running request * - execution time * - session write close * * @param integer $executionTime * @return integer old max execution time */ protected function _longRunningRequest($executionTime = 0) { if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Close session to allow other requests and set max execution time to ' . $executionTime); } $oldMaxExcecutionTime = Tinebase_Core::setExecutionLifeTime($executionTime); Tinebase_Session::writeClose(true); return $oldMaxExcecutionTime; }
/** * Gets Tinebase User session namespace * * @throws Zend_Session_Exception * @return Zend_Session_Namespace */ public static function getSessionNamespace() { if (!Tinebase_Session::isStarted()) { throw new Zend_Session_Exception('Session not started'); } if (!self::getSessionEnabled()) { throw new Zend_Session_Exception('Session not enabled for request'); } try { return self::_getSessionNamespace(static::NAMESPACE_NAME); } catch (Exception $e) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Session error: ' . $e->getMessage()); Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $e->getTraceAsString()); throw $e; } }
/** * check if one of the roles the user is in has a given right for a given application * * we read all right for the given user at once and cache them in the internal class cache * * @param string|Tinebase_Model_Application $_application the application (one of: app name, id or record) * @param int $_accountId the numeric id of a user account * @param int $_right the right to check for * @return bool */ public function hasRight($_application, $_accountId, $_right) { try { $application = Tinebase_Application::getInstance()->getApplicationById($_application); } catch (Tinebase_Exception_NotFound $tenf) { return false; } if ($application->status !== Tinebase_Application::ENABLED) { return false; } try { $roleMemberships = $this->getRoleMemberships($_accountId); } catch (Tinebase_Exception_NotFound $tenf) { $roleMemberships = array(); } if (empty($roleMemberships)) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' ' . $_accountId . ' has no role/group memberships.'); if (is_object(Tinebase_Core::getUser()) && Tinebase_Core::getUser()->getId() === $_accountId) { // @todo throw exception in this case? Tinebase_Session::destroyAndRemoveCookie(); } return false; } $classCacheId = Tinebase_Helper::convertCacheId(implode('', $roleMemberships)); if (!isset($this->_classCache[__FUNCTION__][$classCacheId])) { $select = $this->_getDb()->select()->distinct()->from(array('role_rights' => SQL_TABLE_PREFIX . 'role_rights'), array('application_id', 'right'))->where($this->_getDb()->quoteIdentifier('role_id') . ' IN (?)', $roleMemberships); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . $select->__toString()); } $stmt = $this->_getDb()->query($select); $rows = $stmt->fetchAll(Zend_Db::FETCH_ASSOC); $rights = array(); foreach ($rows as $row) { $rights[$row['application_id']][$row['right']] = true; } $this->_classCache[__FUNCTION__][$classCacheId] = $rights; } else { $rights = $this->_classCache[__FUNCTION__][$classCacheId]; } $applicationId = $application->getId(); return isset($rights[$applicationId]) && (isset($rights[$applicationId][$_right]) || isset($rights[$applicationId][Tinebase_Acl_Rights::ADMIN])); }
/** * (non-PHPdoc) * @see Tinebase_Server_Interface::handle() */ public function handle(\Zend\Http\Request $request = null, $body = null) { $this->_request = $request instanceof \Zend\Http\Request ? $request : Tinebase_Core::get(Tinebase_Core::REQUEST); $this->_body = $body !== null ? $body : fopen('php://input', 'r'); $server = new Tinebase_Http_Server(); $server->setClass('Tinebase_Frontend_Http', 'Tinebase'); $server->setClass('Filemanager_Frontend_Download', 'Download'); try { if (Tinebase_Session::sessionExists()) { try { Tinebase_Core::startCoreSession(); } catch (Zend_Session_Exception $zse) { // expire session cookie for client Tinebase_Session::expireSessionCookie(); } } Tinebase_Core::initFramework(); if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Is HTTP request. method: ' . $this->getRequestMethod()); } if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' REQUEST: ' . print_r($_REQUEST, TRUE)); } // register additional HTTP apis only available for authorised users if (Tinebase_Session::isStarted() && Zend_Auth::getInstance()->hasIdentity()) { if (empty($_REQUEST['method'])) { $_REQUEST['method'] = 'Tinebase.mainScreen'; } $applicationParts = explode('.', $this->getRequestMethod()); $applicationName = ucfirst($applicationParts[0]); if (Tinebase_Core::getUser() && Tinebase_Core::getUser()->hasRight($applicationName, Tinebase_Acl_Rights_Abstract::RUN)) { try { $server->setClass($applicationName . '_Frontend_Http', $applicationName); } catch (Exception $e) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . " Failed to add HTTP API for application '{$applicationName}' Exception: \n" . $e); } } } else { if (empty($_REQUEST['method'])) { $_REQUEST['method'] = 'Tinebase.login'; } // sessionId got send by client, but we don't use sessions for non authenticated users if (Tinebase_Session::sessionExists()) { // expire session cookie on client Tinebase_Session::expireSessionCookie(); } } $this->_method = $this->getRequestMethod(); $server->handle($_REQUEST); } catch (Zend_Json_Server_Exception $zjse) { // invalid method requested or not authenticated, etc. Tinebase_Exception::log($zjse); Tinebase_Core::getLogger()->INFO(__METHOD__ . '::' . __LINE__ . ' Attempt to request a privileged Http-API method without valid session from "' . $_SERVER['REMOTE_ADDR']); header('HTTP/1.0 403 Forbidden'); exit; } catch (Exception $exception) { Tinebase_Exception::log($exception, false); try { $setupController = Setup_Controller::getInstance(); if ($setupController->setupRequired()) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Setup required'); } $this->_method = 'Tinebase.setupRequired'; } else { if (preg_match('/download|export/', $this->_method)) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Server error during download/export - exit with 500'); } header('HTTP/1.0 500 Internal Server Error'); exit; } else { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Show mainscreen with setup exception'); } $this->_method = 'Tinebase.exception'; } } $server->handle(array('method' => $this->_method)); } catch (Exception $e) { header('HTTP/1.0 503 Service Unavailable'); die('Service Unavailable'); } } }