1<?php 2/** 3 * Matomo - free/libre analytics platform 4 * 5 * @link https://matomo.org 6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later 7 * 8 */ 9namespace Piwik\Plugins\UsersManager; 10 11use Exception; 12use Piwik\API\Request; 13use Piwik\API\ResponseBuilder; 14use Piwik\Common; 15use Piwik\Container\StaticContainer; 16use Piwik\Date; 17use Piwik\Nonce; 18use Piwik\Notification; 19use Piwik\Option; 20use Piwik\Piwik; 21use Piwik\Plugin; 22use Piwik\Plugin\ControllerAdmin; 23use Piwik\Plugins\LanguagesManager\API as APILanguagesManager; 24use Piwik\Plugins\LanguagesManager\LanguagesManager; 25use Piwik\Plugins\Login\PasswordVerifier; 26use Piwik\Plugins\TagManager\Validators\TriggerIds; 27use Piwik\Plugins\UsersManager\API as APIUsersManager; 28use Piwik\SettingsPiwik; 29use Piwik\Site; 30use Piwik\Tracker\IgnoreCookie; 31use Piwik\Translation\Translator; 32use Piwik\Url; 33use Piwik\Validators\BaseValidator; 34use Piwik\Validators\CharacterLength; 35use Piwik\Validators\NotEmpty; 36use Piwik\View; 37use Piwik\Session\SessionInitializer; 38use Piwik\Plugins\CoreAdminHome\Emails\TokenAuthCreatedEmail; 39use Piwik\Plugins\CoreAdminHome\Emails\TokenAuthDeletedEmail; 40 41class Controller extends ControllerAdmin 42{ 43 const NONCE_CHANGE_PASSWORD = 'changePasswordNonce'; 44 const NONCE_ADD_AUTH_TOKEN = 'addAuthTokenNonce'; 45 const NONCE_DELETE_AUTH_TOKEN = 'deleteAuthTokenNonce'; 46 47 /** 48 * @var Translator 49 */ 50 private $translator; 51 52 /** 53 * @var PasswordVerifier 54 */ 55 private $passwordVerify; 56 57 /** 58 * @var Model 59 */ 60 private $userModel; 61 62 public function __construct(Translator $translator, PasswordVerifier $passwordVerify, Model $userModel) 63 { 64 $this->translator = $translator; 65 $this->passwordVerify = $passwordVerify; 66 $this->userModel = $userModel; 67 68 parent::__construct(); 69 } 70 71 static function orderByName($a, $b) 72 { 73 return strcmp($a['name'], $b['name']); 74 } 75 76 /** 77 * The "Manage Users and Permissions" Admin UI screen 78 */ 79 public function index() 80 { 81 Piwik::checkUserIsNotAnonymous(); 82 Piwik::checkUserHasSomeAdminAccess(); 83 UsersManager::dieIfUsersAdminIsDisabled(); 84 85 $view = new View('@UsersManager/index'); 86 87 $IdSitesAdmin = Request::processRequest('SitesManager.getSitesIdWithAdminAccess'); 88 $idSiteSelected = 1; 89 90 if (count($IdSitesAdmin) > 0) { 91 $defaultWebsiteId = $IdSitesAdmin[0]; 92 $idSiteSelected = $this->idSite ?: $defaultWebsiteId; 93 } 94 95 if (!Piwik::isUserHasAdminAccess($idSiteSelected) && count($IdSitesAdmin) > 0) { 96 // make sure to show a website where user actually has admin access 97 $idSiteSelected = $IdSitesAdmin[0]; 98 } 99 100 $defaultReportSiteName = Site::getNameFor($idSiteSelected); 101 102 $view->idSiteSelected = $idSiteSelected; 103 $view->defaultReportSiteName = $defaultReportSiteName; 104 $view->currentUserRole = Piwik::hasUserSuperUserAccess() ? 'superuser' : 'admin'; 105 $view->accessLevels = [ 106 ['key' => 'noaccess', 'value' => Piwik::translate('UsersManager_PrivNone')], 107 ['key' => 'view', 'value' => Piwik::translate('UsersManager_PrivView')], 108 ['key' => 'write', 'value' => Piwik::translate('UsersManager_PrivWrite')], 109 ['key' => 'admin', 'value' => Piwik::translate('UsersManager_PrivAdmin')], 110 ['key' => 'superuser', 'value' => Piwik::translate('Installation_SuperUser'), 'disabled' => true], 111 ]; 112 $view->filterAccessLevels = [ 113 ['key' => '', 'value' => Piwik::translate('UsersManager_ShowAll')], 114 ['key' => 'noaccess', 'value' => Piwik::translate('UsersManager_PrivNone')], 115 ['key' => 'some', 'value' => Piwik::translate('UsersManager_AtLeastView')], 116 ['key' => 'view', 'value' => Piwik::translate('UsersManager_PrivView')], 117 ['key' => 'write', 'value' => Piwik::translate('UsersManager_PrivWrite')], 118 ['key' => 'admin', 'value' => Piwik::translate('UsersManager_PrivAdmin')], 119 ['key' => 'superuser', 'value' => Piwik::translate('Installation_SuperUser')], 120 ]; 121 122 $capabilities = Request::processRequest('UsersManager.getAvailableCapabilities', [], []); 123 foreach ($capabilities as $capability) { 124 $capabilityEntry = [ 125 'key' => $capability['id'], 'value' => $capability['category'] . ': ' . $capability['name'], 126 ]; 127 $view->accessLevels[] = $capabilityEntry; 128 $view->filterAccessLevels[] = $capabilityEntry; 129 } 130 131 $this->setBasicVariablesView($view); 132 133 return $view->render(); 134 } 135 136 /** 137 * Returns default date for Piwik reports 138 * 139 * @param string $user 140 * @return string today, yesterday, week, month, year 141 */ 142 protected function getDefaultDateForUser($user) 143 { 144 return APIUsersManager::getInstance()->getUserPreference(APIUsersManager::PREFERENCE_DEFAULT_REPORT_DATE, $user); 145 } 146 147 /** 148 * Returns the enabled dates that users can select, 149 * in their User Settings page "Report date to load by default" 150 * 151 * @throws 152 * @return array 153 */ 154 protected function getDefaultDates() 155 { 156 $dates = array( 157 'today' => $this->translator->translate('Intl_Today'), 158 'yesterday' => $this->translator->translate('Intl_Yesterday'), 159 'previous7' => $this->translator->translate('General_PreviousDays', 7), 160 'previous30' => $this->translator->translate('General_PreviousDays', 30), 161 'last7' => $this->translator->translate('General_LastDays', 7), 162 'last30' => $this->translator->translate('General_LastDays', 30), 163 'week' => $this->translator->translate('General_CurrentWeek'), 164 'month' => $this->translator->translate('General_CurrentMonth'), 165 'year' => $this->translator->translate('General_CurrentYear'), 166 ); 167 168 $mappingDatesToPeriods = array( 169 'today' => 'day', 170 'yesterday' => 'day', 171 'previous7' => 'range', 172 'previous30' => 'range', 173 'last7' => 'range', 174 'last30' => 'range', 175 'week' => 'week', 176 'month' => 'month', 177 'year' => 'year', 178 ); 179 180 // assertion 181 if (count($dates) != count($mappingDatesToPeriods)) { 182 throw new Exception("some metadata is missing in getDefaultDates()"); 183 } 184 185 $allowedPeriods = self::getEnabledPeriodsInUI(); 186 $allowedDates = array_intersect($mappingDatesToPeriods, $allowedPeriods); 187 $dates = array_intersect_key($dates, $allowedDates); 188 189 /** 190 * Triggered when the list of available dates is requested, for example for the 191 * User Settings > Report date to load by default. 192 * 193 * @param array &$dates Array of (date => translation) 194 */ 195 Piwik::postEvent('UsersManager.getDefaultDates', array(&$dates)); 196 197 return $dates; 198 } 199 200 /** 201 * The "User Settings" admin UI screen view 202 */ 203 public function userSettings() 204 { 205 Piwik::checkUserIsNotAnonymous(); 206 207 $view = new View('@UsersManager/userSettings'); 208 209 $userLogin = Piwik::getCurrentUserLogin(); 210 $user = Request::processRequest('UsersManager.getUser', array('userLogin' => $userLogin)); 211 $view->userEmail = $user['email']; 212 $view->userTokenAuth = Piwik::getCurrentUserTokenAuth(); 213 $view->ignoreSalt = $this->getIgnoreCookieSalt(); 214 $view->isUsersAdminEnabled = UsersManager::isUsersAdminEnabled(); 215 216 $newsletterSignupOptionKey = NewsletterSignup::NEWSLETTER_SIGNUP_OPTION . $userLogin; 217 $view->showNewsletterSignup = Option::get($newsletterSignupOptionKey) === false 218 && SettingsPiwik::isInternetEnabled(); 219 220 $userPreferences = new UserPreferences(); 221 $defaultReport = $userPreferences->getDefaultReport(); 222 223 if ($defaultReport === false) { 224 $defaultReport = $userPreferences->getDefaultWebsiteId(); 225 } 226 227 $view->defaultReport = $defaultReport; 228 229 if ($defaultReport == 'MultiSites') { 230 231 $defaultSiteId = $userPreferences->getDefaultWebsiteId(); 232 $reportOptionsValue = $defaultSiteId; 233 234 $view->defaultReportIdSite = $defaultSiteId; 235 $view->defaultReportSiteName = Site::getNameFor($defaultSiteId); 236 } else { 237 $reportOptionsValue = $defaultReport; 238 $view->defaultReportIdSite = $defaultReport; 239 $view->defaultReportSiteName = Site::getNameFor($defaultReport); 240 } 241 242 $defaultReportOptions = array(); 243 if (Plugin\Manager::getInstance()->isPluginActivated('MultiSites')) { 244 $defaultReportOptions[] = array('key' => 'MultiSites', 'value' => Piwik::translate('General_AllWebsitesDashboard')); 245 } 246 247 $defaultReportOptions[] = array('key' => $reportOptionsValue, 'value' => Piwik::translate('General_DashboardForASpecificWebsite')); 248 249 $view->defaultReportOptions = $defaultReportOptions; 250 $view->defaultDate = $this->getDefaultDateForUser($userLogin); 251 $view->availableDefaultDates = $this->getDefaultDates(); 252 253 $languages = APILanguagesManager::getInstance()->getAvailableLanguageNames(); 254 $languageOptions = array(); 255 foreach ($languages as $language) { 256 $languageOptions[] = array( 257 'key' => $language['code'], 258 'value' => $language['name'] 259 ); 260 } 261 262 $view->languageOptions = $languageOptions; 263 $view->currentLanguageCode = LanguagesManager::getLanguageCodeForCurrentUser(); 264 $view->currentTimeformat = (int) LanguagesManager::uses12HourClockForCurrentUser(); 265 $view->ignoreCookieSet = IgnoreCookie::isIgnoreCookieFound(); 266 $view->piwikHost = Url::getCurrentHost(); 267 $this->setBasicVariablesView($view); 268 269 $view->timeFormats = array( 270 '1' => Piwik::translate('General_12HourClock'), 271 '0' => Piwik::translate('General_24HourClock') 272 ); 273 274 return $view->render(); 275 } 276 277 /** 278 * The "User Security" admin UI screen view 279 */ 280 public function userSecurity() 281 { 282 Piwik::checkUserIsNotAnonymous(); 283 284 $tokens = $this->userModel->getAllNonSystemTokensForLogin(Piwik::getCurrentUserLogin()); 285 $tokens = array_map(function ($token){ 286 foreach (['date_created', 'last_used', 'date_expired'] as $key) { 287 if (!empty($token[$key])) { 288 $token[$key] = Date::factory($token[$key])->getLocalized(Date::DATE_FORMAT_LONG); 289 } 290 } 291 292 return $token; 293 }, $tokens); 294 $hasTokensWithExpireDate = !empty(array_filter(array_column($tokens, 'date_expired'))); 295 296 return $this->renderTemplate('userSecurity', array( 297 'isUsersAdminEnabled' => UsersManager::isUsersAdminEnabled(), 298 'changePasswordNonce' => Nonce::getNonce(self::NONCE_CHANGE_PASSWORD), 299 'deleteTokenNonce' => Nonce::getNonce(self::NONCE_DELETE_AUTH_TOKEN), 300 'hasTokensWithExpireDate' => $hasTokensWithExpireDate, 301 'tokens' => $tokens 302 )); 303 } 304 305 /** 306 * The "User Security" admin UI screen view 307 */ 308 public function deleteToken() 309 { 310 Piwik::checkUserIsNotAnonymous(); 311 312 $idTokenAuth = Common::getRequestVar('idtokenauth', '', 'string'); 313 314 if (!empty($idTokenAuth)) { 315 $params = array( 316 'module' => 'UsersManager', 317 'action' => 'deleteToken', 318 'idtokenauth' => $idTokenAuth, 319 'nonce' => Nonce::getNonce(self::NONCE_DELETE_AUTH_TOKEN) 320 ); 321 322 if (!$this->passwordVerify->requirePasswordVerifiedRecently($params)) { 323 throw new Exception('Not allowed'); 324 } 325 326 Nonce::checkNonce(self::NONCE_DELETE_AUTH_TOKEN); 327 328 if ($idTokenAuth === 'all') { 329 $this->userModel->deleteAllTokensForUser(Piwik::getCurrentUserLogin()); 330 331 $notification = new Notification(Piwik::translate('UsersManager_TokensSuccessfullyDeleted')); 332 $notification->context = Notification::CONTEXT_SUCCESS; 333 Notification\Manager::notify('successdeletetokens', $notification); 334 335 $container = StaticContainer::getContainer(); 336 $email = $container->make(TokenAuthDeletedEmail::class, array( 337 'login' => Piwik::getCurrentUserLogin(), 338 'emailAddress' => Piwik::getCurrentUserEmail(), 339 'tokenDescription' => '', 340 'all' => true 341 )); 342 $email->safeSend(); 343 } elseif (is_numeric($idTokenAuth)) { 344 $description = $this->userModel->getUserTokenDescriptionByIdTokenAuth($idTokenAuth, Piwik::getCurrentUserLogin()); 345 $this->userModel->deleteToken($idTokenAuth, Piwik::getCurrentUserLogin()); 346 347 $notification = new Notification(Piwik::translate('UsersManager_TokenSuccessfullyDeleted')); 348 $notification->context = Notification::CONTEXT_SUCCESS; 349 Notification\Manager::notify('successdeletetoken', $notification); 350 351 $container = StaticContainer::getContainer(); 352 $email = $container->make(TokenAuthDeletedEmail::class, array( 353 'login' => Piwik::getCurrentUserLogin(), 354 'emailAddress' => Piwik::getCurrentUserEmail(), 355 'tokenDescription' => $description 356 )); 357 $email->safeSend(); 358 } 359 } 360 361 $this->redirectToIndex('UsersManager', 'userSecurity'); 362 } 363 364 /** 365 * The "User Security" admin UI screen view 366 */ 367 public function addNewToken() 368 { 369 Piwik::checkUserIsNotAnonymous(); 370 371 $params = array('module' => 'UsersManager', 'action' => 'addNewToken'); 372 373 if (!$this->passwordVerify->requirePasswordVerifiedRecently($params)) { 374 throw new Exception('Not allowed'); 375 } 376 377 $noDescription = false; 378 379 if (!empty($_POST['description'])) { 380 Nonce::checkNonce(self::NONCE_ADD_AUTH_TOKEN); 381 382 $description = Common::getRequestVar('description', '', 'string'); 383 $login = Piwik::getCurrentUserLogin(); 384 385 $generatedToken = $this->userModel->generateRandomTokenAuth(); 386 387 $this->userModel->addTokenAuth($login, $generatedToken, $description, Date::now()->getDatetime()); 388 389 $container = StaticContainer::getContainer(); 390 $email = $container->make(TokenAuthCreatedEmail::class, array( 391 'login' => Piwik::getCurrentUserLogin(), 392 'emailAddress' => Piwik::getCurrentUserEmail(), 393 'tokenDescription' => $description 394 )); 395 $email->safeSend(); 396 397 return $this->renderTemplate('addNewTokenSuccess', array('generatedToken' => $generatedToken)); 398 } elseif (isset($_POST['description'])) { 399 $noDescription = true; 400 } 401 402 return $this->renderTemplate('addNewToken', array( 403 'nonce' => Nonce::getNonce(self::NONCE_ADD_AUTH_TOKEN), 404 'noDescription' => $noDescription 405 )); 406 } 407 408 /** 409 * The "Anonymous Settings" admin UI screen view 410 */ 411 public function anonymousSettings() 412 { 413 Piwik::checkUserHasSuperUserAccess(); 414 415 $view = new View('@UsersManager/anonymousSettings'); 416 417 $view->availableDefaultDates = $this->getDefaultDates(); 418 419 $this->initViewAnonymousUserSettings($view); 420 $this->setBasicVariablesView($view); 421 422 return $view->render(); 423 } 424 425 public function setIgnoreCookie() 426 { 427 Piwik::checkUserHasSomeViewAccess(); 428 Piwik::checkUserIsNotAnonymous(); 429 430 $salt = Common::getRequestVar('ignoreSalt', false, 'string'); 431 if ($salt !== $this->getIgnoreCookieSalt()) { 432 throw new Exception("Not authorized"); 433 } 434 435 IgnoreCookie::setIgnoreCookie(); 436 Piwik::redirectToModule('UsersManager', 'userSettings', array('token_auth' => false)); 437 } 438 439 /** 440 * The Super User can modify Anonymous user settings 441 * @param View $view 442 */ 443 protected function initViewAnonymousUserSettings($view) 444 { 445 if (!Piwik::hasUserSuperUserAccess()) { 446 return; 447 } 448 449 $userLogin = 'anonymous'; 450 451 // Which websites are available to the anonymous users? 452 453 $anonymousSitesAccess = Request::processRequest('UsersManager.getSitesAccessFromUser', array('userLogin' => $userLogin)); 454 $anonymousSites = array(); 455 $idSites = array(); 456 foreach ($anonymousSitesAccess as $info) { 457 $idSite = $info['site']; 458 $idSites[] = $idSite; 459 460 $site = Request::processRequest('SitesManager.getSiteFromId', array('idSite' => $idSite)); 461 // Work around manual website deletion 462 if (!empty($site)) { 463 $anonymousSites[] = array('key' => $idSite, 'value' => Common::unsanitizeInputValue($site['name'])); 464 } 465 } 466 $view->anonymousSites = $anonymousSites; 467 468 $anonymousDefaultSite = ''; 469 470 // Which report is displayed by default to the anonymous user? 471 $anonymousDefaultReport = Request::processRequest('UsersManager.getUserPreference', array('userLogin' => $userLogin, 'preferenceName' => APIUsersManager::PREFERENCE_DEFAULT_REPORT)); 472 if ($anonymousDefaultReport === false) { 473 if (empty($anonymousSites)) { 474 $anonymousDefaultReport = Piwik::getLoginPluginName(); 475 } else { 476 // we manually imitate what would happen, in case the anonymous user logs in 477 // and is redirected to the first website available to them in the list 478 // @see getDefaultWebsiteId() 479 $anonymousDefaultReport = '1'; 480 $anonymousDefaultSite = $anonymousSites[0]['key']; 481 } 482 } 483 484 if (is_numeric($anonymousDefaultReport)) { 485 $anonymousDefaultSite = $anonymousDefaultReport; 486 $anonymousDefaultReport = '1'; // a website is selected, we make sure "Dashboard for a specific site" gets pre-selected 487 } 488 489 if ((empty($anonymousDefaultSite) || !in_array($anonymousDefaultSite, $idSites)) && !empty($idSites)) { 490 $anonymousDefaultSite = $anonymousSites[0]['key']; 491 } 492 493 $view->anonymousDefaultReport = $anonymousDefaultReport; 494 $view->anonymousDefaultSite = $anonymousDefaultSite; 495 $view->anonymousDefaultDate = $this->getDefaultDateForUser($userLogin); 496 497 $view->defaultReportOptions = array( 498 array('key' => 'Login', 'value' => Piwik::translate('UsersManager_TheLoginScreen')), 499 array('key' => 'MultiSites', 'value' => Piwik::translate('General_AllWebsitesDashboard'), 'disabled' => empty($anonymousSites)), 500 array('key' => '1', 'value' => Piwik::translate('General_DashboardForASpecificWebsite')), 501 ); 502 } 503 504 /** 505 * Records settings for the anonymous users (default report, default date) 506 */ 507 public function recordAnonymousUserSettings() 508 { 509 $response = new ResponseBuilder(Common::getRequestVar('format')); 510 try { 511 Piwik::checkUserHasSuperUserAccess(); 512 $this->checkTokenInUrl(); 513 514 $anonymousDefaultReport = Common::getRequestVar('anonymousDefaultReport'); 515 $anonymousDefaultDate = Common::getRequestVar('anonymousDefaultDate'); 516 $userLogin = 'anonymous'; 517 APIUsersManager::getInstance()->setUserPreference($userLogin, 518 APIUsersManager::PREFERENCE_DEFAULT_REPORT, 519 $anonymousDefaultReport); 520 APIUsersManager::getInstance()->setUserPreference($userLogin, 521 APIUsersManager::PREFERENCE_DEFAULT_REPORT_DATE, 522 $anonymousDefaultDate); 523 $toReturn = $response->getResponse(); 524 } catch (Exception $e) { 525 $toReturn = $response->getResponseException($e); 526 } 527 528 return $toReturn; 529 } 530 531 /** 532 * Records settings from the "User Settings" page 533 * @throws Exception 534 */ 535 public function recordUserSettings() 536 { 537 $response = new ResponseBuilder(Common::getRequestVar('format')); 538 try { 539 $this->checkTokenInUrl(); 540 541 $defaultReport = Common::getRequestVar('defaultReport'); 542 $defaultDate = Common::getRequestVar('defaultDate'); 543 $language = Common::getRequestVar('language'); 544 $timeFormat = Common::getRequestVar('timeformat'); 545 $userLogin = Piwik::getCurrentUserLogin(); 546 547 Piwik::checkUserHasSuperUserAccessOrIsTheUser($userLogin); 548 549 $this->processEmailChange($userLogin); 550 551 LanguagesManager::setLanguageForSession($language); 552 553 Request::processRequest('LanguagesManager.setLanguageForUser', [ 554 'login' => $userLogin, 555 'languageCode' => $language, 556 ]); 557 Request::processRequest('LanguagesManager.set12HourClockForUser', [ 558 'login' => $userLogin, 559 'use12HourClock' => $timeFormat, 560 ]); 561 562 APIUsersManager::getInstance()->setUserPreference($userLogin, 563 APIUsersManager::PREFERENCE_DEFAULT_REPORT, 564 $defaultReport); 565 APIUsersManager::getInstance()->setUserPreference($userLogin, 566 APIUsersManager::PREFERENCE_DEFAULT_REPORT_DATE, 567 $defaultDate); 568 $toReturn = $response->getResponse(); 569 } catch (Exception $e) { 570 $toReturn = $response->getResponseException($e); 571 } 572 573 return $toReturn; 574 } 575 576 577 /** 578 * Records settings from the "User Settings" page 579 * @throws Exception 580 */ 581 public function recordPasswordChange() 582 { 583 $userLogin = Piwik::getCurrentUserLogin(); 584 585 Piwik::checkUserHasSuperUserAccessOrIsTheUser($userLogin); 586 Nonce::checkNonce(self::NONCE_CHANGE_PASSWORD); 587 588 $this->processPasswordChange($userLogin); 589 590 $notification = new Notification(Piwik::translate('CoreAdminHome_SettingsSaveSuccess')); 591 $notification->context = Notification::CONTEXT_SUCCESS; 592 Notification\Manager::notify('successpass', $notification); 593 $this->redirectToIndex('UsersManager', 'userSecurity'); 594 } 595 596 private function noAdminAccessToWebsite($idSiteSelected, $defaultReportSiteName, $message) 597 { 598 $view = new View('@UsersManager/noWebsiteAdminAccess'); 599 600 $view->idSiteSelected = $idSiteSelected; 601 $view->defaultReportSiteName = $defaultReportSiteName; 602 $view->message = $message; 603 $this->setBasicVariablesView($view); 604 605 return $view->render(); 606 } 607 608 private function processEmailChange($userLogin) 609 { 610 if (!UsersManager::isUsersAdminEnabled()) { 611 return; 612 } 613 614 if (!Url::isValidHost()) { 615 throw new Exception("Cannot change email with untrusted hostname!"); 616 } 617 618 $email = Common::getRequestVar('email'); 619 $passwordCurrent = Common::getRequestvar('passwordConfirmation', false); 620 621 // UI disables password change on invalid host, but check here anyway 622 Request::processRequest('UsersManager.updateUser', [ 623 'userLogin' => $userLogin, 624 'email' => $email, 625 'passwordConfirmation' => $passwordCurrent 626 ], $default = []); 627 } 628 629 private function processPasswordChange($userLogin) 630 { 631 if (!UsersManager::isUsersAdminEnabled()) { 632 return; 633 } 634 635 if (!Url::isValidHost()) { 636 // UI disables password change on invalid host, but check here anyway 637 throw new Exception("Cannot change password with untrusted hostname!"); 638 } 639 640 $newPassword = Common::getRequestvar('password', false); 641 $passwordBis = Common::getRequestvar('passwordBis', false); 642 $passwordCurrent = Common::getRequestvar('passwordConfirmation', false); 643 644 if ($newPassword !== $passwordBis) { 645 throw new Exception($this->translator->translate('Login_PasswordsDoNotMatch')); 646 } 647 648 Request::processRequest('UsersManager.updateUser', [ 649 'userLogin' => $userLogin, 650 'password' => $newPassword, 651 'passwordConfirmation' => $passwordCurrent 652 ], $default = []); 653 654 // logs the user in with the new password 655 $newPassword = Common::unsanitizeInputValue($newPassword); 656 $sessionInitializer = new SessionInitializer(); 657 $auth = StaticContainer::get('Piwik\Auth'); 658 $auth->setTokenAuth(null); // ensure authenticated through password 659 $auth->setLogin($userLogin); 660 $auth->setPassword($newPassword); 661 $sessionInitializer->initSession($auth); 662 } 663 664 /** 665 * @return string 666 */ 667 private function getIgnoreCookieSalt() 668 { 669 return md5(SettingsPiwik::getSalt()); 670 } 671} 672