/** * handler for JSON api requests * * @return JSON */ public function handle() { 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(); 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 exceptoins 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($server, $request, $exception); } echo $response; }
/** * handle request * * @return void */ public function handle() { try { Tinebase_Core::initFramework(); $exception = FALSE; } catch (Exception $exception) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' initFramework exception: ' . $exception); } // handle all kind of session exceptions as 'Not Authorised' if ($exception instanceof Zend_Session_Exception) { $exception = new Tinebase_Exception_AccessDenied('Not Authorised', 401); // expire session cookie for client Zend_Session::expireSessionCookie(); } } $server = new Zend_Json_Server(); $server->setAutoEmitResponse(false); $server->setAutoHandleExceptions(false); //$server->setUseNamedParams(true); $json = file_get_contents('php://input'); 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($server, $request, $exception) : $this->_handle($server, $request); } else { if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Got empty request options: skip request.'); } $response[] = NULL; } } echo $isBatchedRequest ? '[' . implode(',', $response) . ']' : $response[0]; }
/** * get JSON from cache or new instance * * @param array $classes for Zend_Cache_Frontend_File * @return Zend_Json_Server */ protected static function _getServer($classes = null) { // setup cache if available if (is_array($classes) && Tinebase_Core::getCache()) { $masterFiles = array(); $dirname = dirname(__FILE__) . '/../../'; foreach ($classes as $class => $namespace) { $masterFiles[] = $dirname . str_replace('_', '/', $class) . '.php'; } try { $cache = new Zend_Cache_Frontend_File(array('master_files' => $masterFiles, 'lifetime' => null, 'automatic_serialization' => true, 'automatic_cleaning_factor' => 0, 'write_control' => false, 'logging' => Tinebase_Core::isLogLevel(Zend_Log::DEBUG), 'logger' => Tinebase_Core::getLogger())); $cache->setBackend(Tinebase_Core::getCache()->getBackend()); $cacheId = Tinebase_Helper::convertCacheId('_handle_' . sha1(Zend_Json_Encoder::encode($classes)) . '_' . (self::userIsRegistered() ? Tinebase_Core::getUser()->getId() : 'anon')); $server = $cache->load($cacheId); if ($server instanceof Zend_Json_Server) { return $server; } } catch (Zend_Cache_Exception $zce) { if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . " Failed to create cache. Exception: \n" . $zce); } } } $server = new Zend_Json_Server(); $server->setAutoEmitResponse(false); $server->setAutoHandleExceptions(false); if (is_array($classes)) { foreach ($classes as $class => $namespace) { try { $server->setClass($class, $namespace); } catch (Exception $e) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Failed to add JSON API for '{$class}' => '{$namespace}' Exception: \n" . $e); } } } } if (self::userIsRegistered()) { $definitions = self::_getModelConfigMethods(); $server->loadFunctions($definitions); } if (isset($cache)) { $cache->save($server, $cacheId, array(), null); } return $server; }