PageRenderTime 57ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/plugins/UsersManager/Controller.php

https://github.com/CodeYellowBV/piwik
PHP | 395 lines | 284 code | 54 blank | 57 comment | 33 complexity | 1bc6267f55cc8ab9dac40daa6b8f1a57 MD5 | raw file
Possible License(s): LGPL-3.0, JSON, MIT, GPL-3.0, LGPL-2.1, GPL-2.0, AGPL-1.0, BSD-2-Clause, BSD-3-Clause
  1. <?php
  2. /**
  3. * Piwik - free/libre analytics platform
  4. *
  5. * @link http://piwik.org
  6. * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  7. *
  8. */
  9. namespace Piwik\Plugins\UsersManager;
  10. use Exception;
  11. use Piwik\API\ResponseBuilder;
  12. use Piwik\Common;
  13. use Piwik\MetricsFormatter;
  14. use Piwik\Piwik;
  15. use Piwik\Plugins\LanguagesManager\API as APILanguagesManager;
  16. use Piwik\Plugins\LanguagesManager\LanguagesManager;
  17. use Piwik\Plugins\SitesManager\API as APISitesManager;
  18. use Piwik\Plugins\UsersManager\API as APIUsersManager;
  19. use Piwik\Site;
  20. use Piwik\Tracker\IgnoreCookie;
  21. use Piwik\Url;
  22. use Piwik\View;
  23. /**
  24. *
  25. */
  26. class Controller extends \Piwik\Plugin\ControllerAdmin
  27. {
  28. static function orderByName($a, $b)
  29. {
  30. return strcmp($a['name'], $b['name']);
  31. }
  32. /**
  33. * The "Manage Users and Permissions" Admin UI screen
  34. */
  35. function index()
  36. {
  37. Piwik::checkUserIsNotAnonymous();
  38. $view = new View('@UsersManager/index');
  39. $IdSitesAdmin = APISitesManager::getInstance()->getSitesIdWithAdminAccess();
  40. $idSiteSelected = 1;
  41. if (count($IdSitesAdmin) > 0) {
  42. $defaultWebsiteId = $IdSitesAdmin[0];
  43. $idSiteSelected = Common::getRequestVar('idSite', $defaultWebsiteId);
  44. }
  45. if ($idSiteSelected === 'all') {
  46. $usersAccessByWebsite = array();
  47. $defaultReportSiteName = Piwik::translate('UsersManager_ApplyToAllWebsites');
  48. } else {
  49. $usersAccessByWebsite = APIUsersManager::getInstance()->getUsersAccessFromSite($idSiteSelected);
  50. $defaultReportSiteName = Site::getNameFor($idSiteSelected);
  51. }
  52. // we dont want to display the user currently logged so that the user can't change his settings from admin to view...
  53. $currentlyLogged = Piwik::getCurrentUserLogin();
  54. $usersLogin = APIUsersManager::getInstance()->getUsersLogin();
  55. foreach ($usersLogin as $login) {
  56. if (!isset($usersAccessByWebsite[$login])) {
  57. $usersAccessByWebsite[$login] = 'noaccess';
  58. }
  59. }
  60. unset($usersAccessByWebsite[$currentlyLogged]);
  61. // $usersAccessByWebsite is not supposed to contain unexistant logins, but it does when upgrading from some old Piwik version
  62. foreach ($usersAccessByWebsite as $login => $access) {
  63. if (!in_array($login, $usersLogin)) {
  64. unset($usersAccessByWebsite[$login]);
  65. continue;
  66. }
  67. }
  68. ksort($usersAccessByWebsite);
  69. $users = array();
  70. $superUsers = array();
  71. $usersAliasByLogin = array();
  72. if (Piwik::isUserHasSomeAdminAccess()) {
  73. $view->showLastSeen = true;
  74. $users = APIUsersManager::getInstance()->getUsers();
  75. foreach ($users as $index => $user) {
  76. $usersAliasByLogin[$user['login']] = $user['alias'];
  77. $lastSeen = LastSeenTimeLogger::getLastSeenTimeForUser($user['login']);
  78. $users[$index]['last_seen'] = $lastSeen == 0
  79. ? false : MetricsFormatter::getPrettyTimeFromSeconds(time() - $lastSeen);
  80. }
  81. if (Piwik::hasUserSuperUserAccess()) {
  82. foreach ($users as $user) {
  83. if ($user['superuser_access']) {
  84. $superUsers[] = $user['login'];
  85. }
  86. }
  87. }
  88. }
  89. $view->anonymousHasViewAccess = $this->hasAnonymousUserViewAccess($usersAccessByWebsite);
  90. $view->idSiteSelected = $idSiteSelected;
  91. $view->defaultReportSiteName = $defaultReportSiteName;
  92. $view->users = $users;
  93. $view->superUserLogins = $superUsers;
  94. $view->usersAliasByLogin = $usersAliasByLogin;
  95. $view->usersCount = count($users) - 1;
  96. $view->usersAccessByWebsite = $usersAccessByWebsite;
  97. $websites = APISitesManager::getInstance()->getSitesWithAdminAccess();
  98. uasort($websites, array('Piwik\Plugins\UsersManager\Controller', 'orderByName'));
  99. $view->websites = $websites;
  100. $this->setBasicVariablesView($view);
  101. return $view->render();
  102. }
  103. private function hasAnonymousUserViewAccess($usersAccessByWebsite)
  104. {
  105. $anonymousHasViewAccess = false;
  106. foreach ($usersAccessByWebsite as $login => $access) {
  107. if ($login == 'anonymous'
  108. && $access != 'noaccess'
  109. ) {
  110. $anonymousHasViewAccess = true;
  111. }
  112. }
  113. return $anonymousHasViewAccess;
  114. }
  115. /**
  116. * Returns default date for Piwik reports
  117. *
  118. * @param string $user
  119. * @return string today, yesterday, week, month, year
  120. */
  121. protected function getDefaultDateForUser($user)
  122. {
  123. return APIUsersManager::getInstance()->getUserPreference($user, APIUsersManager::PREFERENCE_DEFAULT_REPORT_DATE);
  124. }
  125. /**
  126. * Returns the enabled dates that users can select,
  127. * in their User Settings page "Report date to load by default"
  128. *
  129. * @throws
  130. * @return array
  131. */
  132. protected function getDefaultDates()
  133. {
  134. $dates = array(
  135. 'today' => Piwik::translate('General_Today'),
  136. 'yesterday' => Piwik::translate('General_Yesterday'),
  137. 'previous7' => Piwik::translate('General_PreviousDays', 7),
  138. 'previous30' => Piwik::translate('General_PreviousDays', 30),
  139. 'last7' => Piwik::translate('General_LastDays', 7),
  140. 'last30' => Piwik::translate('General_LastDays', 30),
  141. 'week' => Piwik::translate('General_CurrentWeek'),
  142. 'month' => Piwik::translate('General_CurrentMonth'),
  143. 'year' => Piwik::translate('General_CurrentYear'),
  144. );
  145. $mappingDatesToPeriods = array(
  146. 'today' => 'day',
  147. 'yesterday' => 'day',
  148. 'previous7' => 'range',
  149. 'previous30' => 'range',
  150. 'last7' => 'range',
  151. 'last30' => 'range',
  152. 'week' => 'week',
  153. 'month' => 'month',
  154. 'year' => 'year',
  155. );
  156. // assertion
  157. if(count($dates) != count($mappingDatesToPeriods)) {
  158. throw new Exception("some metadata is missing in getDefaultDates()");
  159. }
  160. $allowedPeriods = self::getEnabledPeriodsInUI();
  161. $allowedDates = array_intersect($mappingDatesToPeriods, $allowedPeriods);
  162. $dates = array_intersect_key($dates, $allowedDates);
  163. /**
  164. * Triggered when the list of available dates is requested, for example for the
  165. * User Settings > Report date to load by default.
  166. *
  167. * @param array &$dates Array of (date => translation)
  168. */
  169. Piwik::postEvent('UsersManager.getDefaultDates', array(&$dates));
  170. return $dates;
  171. }
  172. /**
  173. * The "User Settings" admin UI screen view
  174. */
  175. public function userSettings()
  176. {
  177. Piwik::checkUserIsNotAnonymous();
  178. $view = new View('@UsersManager/userSettings');
  179. $userLogin = Piwik::getCurrentUserLogin();
  180. $user = APIUsersManager::getInstance()->getUser($userLogin);
  181. $view->userAlias = $user['alias'];
  182. $view->userEmail = $user['email'];
  183. $userPreferences = new UserPreferences();
  184. $defaultReport = $userPreferences->getDefaultWebsiteId();
  185. if ($defaultReport === false) {
  186. $defaultReport = $this->getDefaultWebsiteId();
  187. }
  188. $view->defaultReport = $defaultReport;
  189. if ($defaultReport == 'MultiSites') {
  190. $userPreferences = new UserPreferences();
  191. $view->defaultReportSiteName = Site::getNameFor($userPreferences->getDefaultWebsiteId());
  192. } else {
  193. $view->defaultReportSiteName = Site::getNameFor($defaultReport);
  194. }
  195. $view->defaultDate = $this->getDefaultDateForUser($userLogin);
  196. $view-> availableDefaultDates = $this->getDefaultDates();
  197. $view->languages = APILanguagesManager::getInstance()->getAvailableLanguageNames();
  198. $view->currentLanguageCode = LanguagesManager::getLanguageCodeForCurrentUser();
  199. $view->ignoreCookieSet = IgnoreCookie::isIgnoreCookieFound();
  200. $this->initViewAnonymousUserSettings($view);
  201. $view->piwikHost = Url::getCurrentHost();
  202. $this->setBasicVariablesView($view);
  203. return $view->render();
  204. }
  205. protected function getDefaultWebsiteId()
  206. {
  207. $sitesId = \Piwik\Plugins\SitesManager\API::getInstance()->getSitesIdWithAdminAccess();
  208. if (!empty($sitesId)) {
  209. return $sitesId[0];
  210. }
  211. return false;
  212. }
  213. public function setIgnoreCookie()
  214. {
  215. Piwik::checkUserHasSomeViewAccess();
  216. Piwik::checkUserIsNotAnonymous();
  217. $this->checkTokenInUrl();
  218. IgnoreCookie::setIgnoreCookie();
  219. Piwik::redirectToModule('UsersManager', 'userSettings', array('token_auth' => false));
  220. }
  221. /**
  222. * The Super User can modify Anonymous user settings
  223. * @param View $view
  224. */
  225. protected function initViewAnonymousUserSettings($view)
  226. {
  227. if (!Piwik::hasUserSuperUserAccess()) {
  228. return;
  229. }
  230. $userLogin = 'anonymous';
  231. // Which websites are available to the anonymous users?
  232. $anonymousSitesAccess = APIUsersManager::getInstance()->getSitesAccessFromUser($userLogin);
  233. $anonymousSites = array();
  234. foreach ($anonymousSitesAccess as $info) {
  235. $idSite = $info['site'];
  236. $site = APISitesManager::getInstance()->getSiteFromId($idSite);
  237. // Work around manual website deletion
  238. if (!empty($site)) {
  239. $anonymousSites[$idSite] = $site;
  240. }
  241. }
  242. $view->anonymousSites = $anonymousSites;
  243. // Which report is displayed by default to the anonymous user?
  244. $anonymousDefaultReport = APIUsersManager::getInstance()->getUserPreference($userLogin, APIUsersManager::PREFERENCE_DEFAULT_REPORT);
  245. if ($anonymousDefaultReport === false) {
  246. if (empty($anonymousSites)) {
  247. $anonymousDefaultReport = Piwik::getLoginPluginName();
  248. } else {
  249. // we manually imitate what would happen, in case the anonymous user logs in
  250. // and is redirected to the first website available to him in the list
  251. // @see getDefaultWebsiteId()
  252. reset($anonymousSites);
  253. $anonymousDefaultReport = key($anonymousSites);
  254. }
  255. }
  256. $view->anonymousDefaultReport = $anonymousDefaultReport;
  257. $view->anonymousDefaultDate = $this->getDefaultDateForUser($userLogin);
  258. }
  259. /**
  260. * Records settings for the anonymous users (default report, default date)
  261. */
  262. public function recordAnonymousUserSettings()
  263. {
  264. $response = new ResponseBuilder(Common::getRequestVar('format'));
  265. try {
  266. Piwik::checkUserHasSuperUserAccess();
  267. $this->checkTokenInUrl();
  268. $anonymousDefaultReport = Common::getRequestVar('anonymousDefaultReport');
  269. $anonymousDefaultDate = Common::getRequestVar('anonymousDefaultDate');
  270. $userLogin = 'anonymous';
  271. APIUsersManager::getInstance()->setUserPreference($userLogin,
  272. APIUsersManager::PREFERENCE_DEFAULT_REPORT,
  273. $anonymousDefaultReport);
  274. APIUsersManager::getInstance()->setUserPreference($userLogin,
  275. APIUsersManager::PREFERENCE_DEFAULT_REPORT_DATE,
  276. $anonymousDefaultDate);
  277. $toReturn = $response->getResponse();
  278. } catch (Exception $e) {
  279. $toReturn = $response->getResponseException($e);
  280. }
  281. return $toReturn;
  282. }
  283. /**
  284. * Records settings from the "User Settings" page
  285. * @throws Exception
  286. */
  287. public function recordUserSettings()
  288. {
  289. $response = new ResponseBuilder(Common::getRequestVar('format'));
  290. try {
  291. $this->checkTokenInUrl();
  292. $defaultReport = Common::getRequestVar('defaultReport');
  293. $defaultDate = Common::getRequestVar('defaultDate');
  294. $language = Common::getRequestVar('language');
  295. $userLogin = Piwik::getCurrentUserLogin();
  296. $this->processPasswordChange($userLogin);
  297. LanguagesManager::setLanguageForSession($language);
  298. APILanguagesManager::getInstance()->setLanguageForUser($userLogin, $language);
  299. APIUsersManager::getInstance()->setUserPreference($userLogin,
  300. APIUsersManager::PREFERENCE_DEFAULT_REPORT,
  301. $defaultReport);
  302. APIUsersManager::getInstance()->setUserPreference($userLogin,
  303. APIUsersManager::PREFERENCE_DEFAULT_REPORT_DATE,
  304. $defaultDate);
  305. $toReturn = $response->getResponse();
  306. } catch (Exception $e) {
  307. $toReturn = $response->getResponseException($e);
  308. }
  309. return $toReturn;
  310. }
  311. private function processPasswordChange($userLogin)
  312. {
  313. $alias = Common::getRequestVar('alias');
  314. $email = Common::getRequestVar('email');
  315. $newPassword = false;
  316. $password = Common::getRequestvar('password', false);
  317. $passwordBis = Common::getRequestvar('passwordBis', false);
  318. if (!empty($password)
  319. || !empty($passwordBis)
  320. ) {
  321. if ($password != $passwordBis) {
  322. throw new Exception(Piwik::translate('Login_PasswordsDoNotMatch'));
  323. }
  324. $newPassword = $password;
  325. }
  326. // UI disables password change on invalid host, but check here anyway
  327. if (!Url::isValidHost()
  328. && $newPassword !== false
  329. ) {
  330. throw new Exception("Cannot change password with untrusted hostname!");
  331. }
  332. APIUsersManager::getInstance()->updateUser($userLogin, $newPassword, $email, $alias);
  333. if ($newPassword !== false) {
  334. $newPassword = Common::unsanitizeInputValue($newPassword);
  335. }
  336. // logs the user in with the new password
  337. if ($newPassword !== false) {
  338. \Piwik\Registry::get('auth')->initSession($userLogin, md5($newPassword), $rememberMe = false);
  339. }
  340. }
  341. }