/** * Checks if the provided CURRENT password is correct and calls the parent * class function if so. Otherwise provides error message. * * @see the parent class function for parameters and return value */ public function recordUserSettings() { try { $passwordCurrent = Common::getRequestvar('passwordCurrent', false); $passwordCurrent = Crypto::decrypt($passwordCurrent); // Note: Compare loosely, so both, "" (password input empty; forms send strings) // and "password input not sent" are covered - see // https://secure.php.net/manual/en/types.comparisons.php if ($passwordCurrent != "") { $userName = Piwik::getCurrentUserLogin(); // gets username as string or "anonymous" // see Piwik\Plugins\Login\Auth for used password hash function // (in setPassword()) and access to hashed password (in getTokenAuthSecret()) if ($userName != 'anonymous') { $model = new Model(); $user = $model->getUser($userName); if (UsersManagerEncrypted::getPasswordHash($passwordCurrent) === $user['password']) { $toReturn = parent::recordUserSettings(); } else { throw new Exception(Piwik::translate('UsersManagerEncrypted_CurrentPasswordIncorrect')); } } else { throw new Exception(Piwik::translate('UsersManagerEncrypted_UserNotAuthenticated')); } } else { throw new Exception(Piwik::translate('UsersManagerEncrypted_CurrentPasswordNotProvided')); } } catch (Exception $e) { $response = new ResponseBuilder(Common::getRequestVar('format')); $toReturn = $response->getResponseException($e); } return $toReturn; }
/** * Records Global settings when user submit changes */ public function setGlobalSettings() { $response = new ResponseBuilder(Common::getRequestVar('format')); try { $this->checkTokenInUrl(); $timezone = Common::getRequestVar('timezone', false); $excludedIps = Common::getRequestVar('excludedIps', false); $excludedQueryParameters = Common::getRequestVar('excludedQueryParameters', false); $excludedUserAgents = Common::getRequestVar('excludedUserAgents', false); $currency = Common::getRequestVar('currency', false); $searchKeywordParameters = Common::getRequestVar('searchKeywordParameters', $default = ""); $searchCategoryParameters = Common::getRequestVar('searchCategoryParameters', $default = ""); $enableSiteUserAgentExclude = Common::getRequestVar('enableSiteUserAgentExclude', $default = 0); $keepURLFragments = Common::getRequestVar('keepURLFragments', $default = 0); $api = API::getInstance(); $api->setDefaultTimezone($timezone); $api->setDefaultCurrency($currency); $api->setGlobalExcludedQueryParameters($excludedQueryParameters); $api->setGlobalExcludedIps($excludedIps); $api->setGlobalExcludedUserAgents($excludedUserAgents); $api->setGlobalSearchParameters($searchKeywordParameters, $searchCategoryParameters); $api->setSiteSpecificUserAgentExcludeEnabled($enableSiteUserAgentExclude == 1); $api->setKeepURLFragmentsGlobal($keepURLFragments); $toReturn = $response->getResponse(); } catch (Exception $e) { $toReturn = $response->getResponseException($e); } return $toReturn; }
public function dispatch() { $module = Common::getRequestVar('module', '', 'string'); $action = Common::getRequestVar('action', '', 'string'); if ($module == 'CoreUpdater' || $module == 'Proxy' || $module == 'Installation' || $module == 'LanguagesManager' && $action == 'saveLanguage') { return; } $updater = new PiwikCoreUpdater(); $updates = $updater->getComponentsWithNewVersion(array('core' => Version::VERSION)); if (!empty($updates)) { Filesystem::deleteAllCacheOnUpdate(); } if ($updater->getComponentUpdates() !== null) { if (FrontController::shouldRethrowException()) { throw new Exception("Piwik and/or some plugins have been upgraded to a new version. \n" . "--> Please run the update process first. See documentation: http://piwik.org/docs/update/ \n"); } elseif ($module === 'API') { $outputFormat = strtolower(Common::getRequestVar('format', 'xml', 'string', $_GET + $_POST)); $response = new ResponseBuilder($outputFormat); $e = new Exception('Database Upgrade Required. Your Piwik database is out-of-date, and must be upgraded before you can continue.'); echo $response->getResponseException($e); Common::sendResponseCode(503); exit; } else { Piwik::redirectToModule('CoreUpdater'); } } }
public static function formatScreenMessage(&$message, $level, $tag, $datetime, $log) { if ($message instanceof \Exception) { Common::sendHeader('Content-Type: text/html; charset=utf-8'); $outputFormat = strtolower(Common::getRequestVar('format', 'html', 'string')); $response = new ResponseBuilder($outputFormat); $message = $response->getResponseException(new \Exception($message->getMessage())); } }
/** * The constructor * Initialize some local variables from the request * @param int $idSite * @param Date $date ($this->date from controller) * @param null|string $graphType * @throws Exception */ public function __construct($idSite, $date, $graphType = null) { $this->apiMethod = Common::getRequestVar('apiMethod', '', 'string'); if (empty($this->apiMethod)) { throw new Exception("Parameter apiMethod not set."); } $this->label = ResponseBuilder::getLabelFromRequest($_GET); if (!is_array($this->label)) { throw new Exception("Expected label to be an array, got instead: " . $this->label); } $this->label = $this->label[0]; if ($this->label === '') { throw new Exception("Parameter label not set."); } $this->period = Common::getRequestVar('period', '', 'string'); if (empty($this->period)) { throw new Exception("Parameter period not set."); } $this->idSite = $idSite; $this->graphType = $graphType; if ($this->period != 'range') { // handle day, week, month and year: display last X periods $end = $date->toString(); list($this->date, $lastN) = EvolutionViz::getDateRangeAndLastN($this->period, $end); } $this->segment = \Piwik\API\Request::getRawSegmentFromRequest(); $this->loadEvolutionReport(); }
public function getRowEvolution($idSite, $period, $date, $apiModule, $apiAction, $label = false, $segment = false, $column = false, $language = false, $idGoal = false, $legendAppendMetric = true, $labelUseAbsoluteUrl = true) { // validation of requested $period & $date if ($period == 'range') { // load days in the range $period = 'day'; } if (!Period::isMultiplePeriod($date, $period)) { throw new Exception("Row evolutions can not be processed with this combination of \\'date\\' and \\'period\\' parameters."); } $label = ResponseBuilder::unsanitizeLabelParameter($label); $labels = Piwik::getArrayFromApiParameter($label); $metadata = $this->getRowEvolutionMetaData($idSite, $period, $date, $apiModule, $apiAction, $language, $idGoal); $dataTable = $this->loadRowEvolutionDataFromAPI($metadata, $idSite, $period, $date, $apiModule, $apiAction, $labels, $segment, $idGoal); if (empty($labels)) { $labels = $this->getLabelsFromDataTable($dataTable, $labels); $dataTable = $this->enrichRowAddMetadataLabelIndex($labels, $dataTable); } if (count($labels) != 1) { $data = $this->getMultiRowEvolution($dataTable, $metadata, $apiModule, $apiAction, $labels, $column, $legendAppendMetric, $labelUseAbsoluteUrl); } else { $data = $this->getSingleRowEvolution($idSite, $dataTable, $metadata, $apiModule, $apiAction, $labels[0], $labelUseAbsoluteUrl); } return $data; }
/** * Two dimensions mixed array * * @group Core */ public function testConvertMultiDimensionalMixedArrayToJson() { $input = array("firstElement" => "isFirst", array("firstElement", "secondElement"), "thirdElement" => array("firstElement" => "isFirst", "secondElement" => "isSecond")); $expected = json_encode($input); $actual = ResponseBuilder::convertMultiDimensionalArrayToJson($input); $this->assertEquals($expected, $actual); }
private static function getErrorResponse(Exception $ex) { $debugTrace = $ex->getTraceAsString(); $message = $ex->getMessage(); $isHtmlMessage = method_exists($ex, 'isHtmlMessage') && $ex->isHtmlMessage(); if (!$isHtmlMessage && Request::isApiRequest($_GET)) { $outputFormat = strtolower(Common::getRequestVar('format', 'xml', 'string', $_GET + $_POST)); $response = new ResponseBuilder($outputFormat); return $response->getResponseException($ex); } elseif (!$isHtmlMessage) { $message = Common::sanitizeInputValue($message); } $logo = new CustomLogo(); $logoHeaderUrl = false; $logoFaviconUrl = false; try { $logoHeaderUrl = $logo->getHeaderLogoUrl(); $logoFaviconUrl = $logo->getPathUserFavicon(); } catch (Exception $ex) { try { Log::debug($ex); } catch (\Exception $otherEx) { // DI container may not be setup at this point } } $result = Piwik_GetErrorMessagePage($message, $debugTrace, true, true, $logoHeaderUrl, $logoFaviconUrl); try { /** * Triggered before a Piwik error page is displayed to the user. * * This event can be used to modify the content of the error page that is displayed when * an exception is caught. * * @param string &$result The HTML of the error page. * @param Exception $ex The Exception displayed in the error page. */ Piwik::postEvent('FrontController.modifyErrorPage', array(&$result, $ex)); } catch (ContainerDoesNotExistException $ex) { // this can happen when an error occurs before the Piwik environment is created } return $result; }
/** * Records settings from the "User Settings" page * @throws Exception */ public function recordUserSettings() { $response = new ResponseBuilder(Common::getRequestVar('format')); try { $this->checkTokenInUrl(); $defaultReport = Common::getRequestVar('defaultReport'); $defaultDate = Common::getRequestVar('defaultDate'); $language = Common::getRequestVar('language'); $userLogin = Piwik::getCurrentUserLogin(); $this->processPasswordChange($userLogin); LanguagesManager::setLanguageForSession($language); APILanguagesManager::getInstance()->setLanguageForUser($userLogin, $language); APIUsersManager::getInstance()->setUserPreference($userLogin, APIUsersManager::PREFERENCE_DEFAULT_REPORT, $defaultReport); APIUsersManager::getInstance()->setUserPreference($userLogin, APIUsersManager::PREFERENCE_DEFAULT_REPORT_DATE, $defaultDate); $toReturn = $response->getResponse(); } catch (Exception $e) { $toReturn = $response->getResponseException($e); } return $toReturn; }
/** * @internal */ protected function loadDataTableFromAPI() { if (!is_null($this->dataTable)) { // data table is already there // this happens when setDataTable has been used return $this->dataTable; } // we build the request (URL) to call the API $request = $this->buildApiRequestArray(); $module = $this->requestConfig->getApiModuleToRequest(); $method = $this->requestConfig->getApiMethodToRequest(); PluginManager::getInstance()->checkIsPluginActivated($module); $class = ApiRequest::getClassNameAPI($module); $dataTable = Proxy::getInstance()->call($class, $method, $request); $response = new ResponseBuilder($format = 'original', $request); $response->disableSendHeader(); $response->disableDataTablePostProcessor(); $this->dataTable = $response->getResponse($dataTable, $module, $method); }
private function convertDataTableToArrayAndApplyQueuedFilters(DataTable $table, $request) { $request['serialize'] = 0; $request['expanded'] = 0; $request['totals'] = 0; $request['format_metrics'] = 1; $request['disable_generic_filters'] = 1; $responseBuilder = new ResponseBuilder('php', $request); $rows = $responseBuilder->getResponse($table, 'MultiSites', 'getAll'); return $rows; }
protected function getLabelsFromTable($table) { $request = $_GET; $request['serialize'] = 0; // Apply generic filters $response = new ResponseBuilder($format = 'original', $request); $table = $response->getResponse($table); // If period=lastX we only keep the first resultset as we want to return a plain list if ($table instanceof DataTable\Map) { $tables = $table->getDataTables(); $table = current($tables); } // Keep the response simple, only include keywords $keywords = $table->getColumn('label'); return $keywords; }
/** * Dispatches the API request to the appropriate API method and returns the result * after post-processing. * * Post-processing includes: * * - flattening if **flat** is 0 * - running generic filters unless **disable_generic_filters** is set to 1 * - URL decoding label column values * - running queued filters unless **disable_queued_filters** is set to 1 * - removing columns based on the values of the **hideColumns** and **showColumns** query parameters * - filtering rows if the **label** query parameter is set * - converting the result to the appropriate format (ie, XML, JSON, etc.) * * If `'original'` is supplied for the output format, the result is returned as a PHP * object. * * @throws PluginDeactivatedException if the module plugin is not activated. * @throws Exception if the requested API method cannot be called, if required parameters for the * API method are missing or if the API method throws an exception and the **format** * query parameter is **original**. * @return DataTable|Map|string The data resulting from the API call. */ public function process() { // read the format requested for the output data $outputFormat = strtolower(Common::getRequestVar('format', 'xml', 'string', $this->request)); // create the response $response = new ResponseBuilder($outputFormat, $this->request); $corsHandler = new CORSHandler(); $corsHandler->handle(); try { // read parameters $moduleMethod = Common::getRequestVar('method', null, 'string', $this->request); list($module, $method) = $this->extractModuleAndMethod($moduleMethod); $module = $this->renameModule($module); if (!\Piwik\Plugin\Manager::getInstance()->isPluginActivated($module)) { throw new PluginDeactivatedException($module); } $apiClassName = $this->getClassNameAPI($module); self::reloadAuthUsingTokenAuth($this->request); // call the method $returnedValue = Proxy::getInstance()->call($apiClassName, $method, $this->request); $toReturn = $response->getResponse($returnedValue, $module, $method); } catch (Exception $e) { Log::debug($e); $toReturn = $response->getResponseException($e); } return $toReturn; }
public function test_getResponse_shouldReturnAllOnIndexedArray_IfFilterLimitIsMinusOne() { $input = range(0, 100); $builder = new ResponseBuilder('php', array('serialize' => 0, 'filter_limit' => -1)); $response = $builder->getResponse($input); $this->assertEquals($input, $response); }
public function test_getResponse_shouldBeAbleToApplyColumFilterAndLimitFilterOnIndexedAssociativeArray() { $input = array(); for ($i = 0; $i < 10; $i++) { $input[] = array('test' => 'two' . $i, 'test2' => 'three'); } $limit = 3; $builder = new ResponseBuilder('php', array('serialize' => 0, 'filter_limit' => $limit, 'filter_offset' => 3, 'showColumns' => 'test')); $response = $builder->getResponse($input); $this->assertEquals(array(0 => array('test' => 'two3'), 1 => array('test' => 'two4'), 2 => array('test' => 'two5')), $response); }
public function setMailSettings() { Piwik::checkUserHasSuperUserAccess(); if (!self::isGeneralSettingsAdminEnabled()) { // General settings + Beta channel + SMTP settings is disabled return ''; } $response = new ResponseBuilder('json'); try { $this->checkTokenInUrl(); // Update email settings $mail = array(); $mail['transport'] = Common::getRequestVar('mailUseSmtp') == '1' ? 'smtp' : ''; $mail['port'] = Common::getRequestVar('mailPort', ''); $mail['host'] = Common::unsanitizeInputValue(Common::getRequestVar('mailHost', '')); $mail['type'] = Common::getRequestVar('mailType', ''); $mail['username'] = Common::unsanitizeInputValue(Common::getRequestVar('mailUsername', '')); $mail['password'] = Common::unsanitizeInputValue(Common::getRequestVar('mailPassword', '')); $mail['encryption'] = Common::getRequestVar('mailEncryption', ''); Config::getInstance()->mail = $mail; Config::getInstance()->forceSave(); $toReturn = $response->getResponse(); } catch (Exception $e) { $toReturn = $response->getResponseException($e); } return $toReturn; }
protected function callApiAndReturnDataTable($apiModule, $method, $request) { $class = Request::getClassNameAPI($apiModule); $request = $this->manipulateSubtableRequest($request); $request['serialize'] = 0; $request['expanded'] = 0; // don't want to run recursive filters on the subtables as they are loaded, // otherwise the result will be empty in places (or everywhere). instead we // run it on the flattened table. unset($request['filter_pattern_recursive']); $dataTable = Proxy::getInstance()->call($class, $method, $request); $response = new ResponseBuilder($format = 'original', $request); $response->disableSendHeader(); $dataTable = $response->getResponse($dataTable); if (Common::getRequestVar('disable_queued_filters', 0, 'int', $request) == 0) { if (method_exists($dataTable, 'applyQueuedFilters')) { $dataTable->applyQueuedFilters(); } } return $dataTable; }
private function convertDataTableToArrayAndApplyFilters(DataTable $table, $request) { $request['serialize'] = 0; $request['expanded'] = 1; $request['totals'] = 0; $request['format_metrics'] = 1; // filter_sort_column does not work correctly is a bug in MultiSites.getAll if (!empty($request['filter_sort_column']) && $request['filter_sort_column'] === 'nb_pageviews') { $request['filter_sort_column'] = 'Actions_nb_pageviews'; } elseif (!empty($request['filter_sort_column']) && $request['filter_sort_column'] === 'revenue') { $request['filter_sort_column'] = 'Goal_revenue'; } $responseBuilder = new ResponseBuilder('php', $request); $rows = $responseBuilder->getResponse($table, 'MultiSites', 'getAll'); return $rows; }
public function setGeneralSettings() { Piwik::checkUserIsSuperUser(); $response = new ResponseBuilder(Common::getRequestVar('format')); try { $this->checkTokenInUrl(); $this->saveGeneralSettings(); // update trusted host settings $trustedHosts = Common::getRequestVar('trustedHosts', false, 'json'); if ($trustedHosts !== false) { Url::saveTrustedHostnameInConfig($trustedHosts); } // update branding settings $branding = Config::getInstance()->branding; $branding['use_custom_logo'] = Common::getRequestVar('useCustomLogo', '0'); Config::getInstance()->branding = $branding; Config::getInstance()->forceSave(); $toReturn = $response->getResponse(); } catch (Exception $e) { $toReturn = $response->getResponseException($e); } return $toReturn; }
/** * Dispatches the API request to the appropriate API method and returns the result * after post-processing. * * Post-processing includes: * * - flattening if **flat** is 0 * - running generic filters unless **disable_generic_filters** is set to 1 * - URL decoding label column values * - running queued filters unless **disable_queued_filters** is set to 1 * - removing columns based on the values of the **hideColumns** and **showColumns** query parameters * - filtering rows if the **label** query parameter is set * - converting the result to the appropriate format (ie, XML, JSON, etc.) * * If `'original'` is supplied for the output format, the result is returned as a PHP * object. * * @throws PluginDeactivatedException if the module plugin is not activated. * @throws Exception if the requested API method cannot be called, if required parameters for the * API method are missing or if the API method throws an exception and the **format** * query parameter is **original**. * @return DataTable|Map|string The data resulting from the API call. */ public function process() { // read the format requested for the output data $outputFormat = strtolower(Common::getRequestVar('format', 'xml', 'string', $this->request)); // create the response $response = new ResponseBuilder($outputFormat, $this->request); $corsHandler = new CORSHandler(); $corsHandler->handle(); $tokenAuth = Common::getRequestVar('token_auth', '', 'string', $this->request); $shouldReloadAuth = false; try { // read parameters $moduleMethod = Common::getRequestVar('method', null, 'string', $this->request); list($module, $method) = $this->extractModuleAndMethod($moduleMethod); list($module, $method) = self::getRenamedModuleAndAction($module, $method); PluginManager::getInstance()->checkIsPluginActivated($module); $apiClassName = self::getClassNameAPI($module); if ($shouldReloadAuth = self::shouldReloadAuthUsingTokenAuth($this->request)) { $access = Access::getInstance(); $tokenAuthToRestore = $access->getTokenAuth(); $hadSuperUserAccess = $access->hasSuperUserAccess(); self::forceReloadAuthUsingTokenAuth($tokenAuth); } // call the method $returnedValue = Proxy::getInstance()->call($apiClassName, $method, $this->request); $toReturn = $response->getResponse($returnedValue, $module, $method); } catch (Exception $e) { Log::debug($e); $toReturn = $response->getResponseException($e); } if ($shouldReloadAuth) { $this->restoreAuthUsingTokenAuth($tokenAuthToRestore, $hadSuperUserAccess); } return $toReturn; }
public function setGeneralSettings() { Piwik::checkUserHasSuperUserAccess(); $response = new ResponseBuilder(Common::getRequestVar('format')); try { $this->checkTokenInUrl(); $this->saveGeneralSettings(); $customLogo = new CustomLogo(); if (Common::getRequestVar('useCustomLogo', '0')) { $customLogo->enable(); } else { $customLogo->disable(); } $toReturn = $response->getResponse(); } catch (Exception $e) { $toReturn = $response->getResponseException($e); } return $toReturn; }
protected function handleMaintenanceMode() { if (Config::getInstance()->General['maintenance_mode'] == 1 && !Common::isPhpCliMode()) { $format = Common::getRequestVar('format', ''); $message = "Piwik is in scheduled maintenance. Please come back later." . " The administrator can disable maintenance by editing the file piwik/config/config.ini.php and removing the following: " . " maintenance_mode=1 "; if (Config::getInstance()->Tracker['record_statistics'] == 0) { $message .= ' and record_statistics=0'; } $exception = new Exception($message); // extend explain how to re-enable // show error message when record stats = 0 if (empty($format)) { throw $exception; } $response = new ResponseBuilder($format); echo $response->getResponseException($exception); exit; } }