PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / trunk
Matomo Analytics – Powerful, Privacy-First Insights for WordPress vtrunk
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / core / Access.php
matomo / app / core Last commit date
API 1 month ago Access 3 months ago Application 1 month ago Archive 1 month ago ArchiveProcessor 1 month ago Archiver 2 years ago AssetManager 1 month ago Auth 6 months ago Category 6 months ago Changes 1 month ago CliMulti 1 year ago Columns 1 month ago Concurrency 1 month ago Config 1 month ago Container 1 month ago CronArchive 3 months ago DataAccess 1 month ago DataFiles 2 years ago DataTable 2 weeks ago Db 2 weeks ago DeviceDetector 1 year ago Email 2 years ago Exception 4 months ago Http 4 months ago Intl 3 months ago Log 2 years ago Mail 1 year ago Measurable 6 months ago Menu 1 month ago Metrics 3 months ago Notification 6 months ago Period 1 month ago Plugin 2 weeks ago Policy 1 month ago ProfessionalServices 1 year ago Report 1 year ago ReportRenderer 3 months ago Request 3 months ago Scheduler 1 month ago Segment 1 month ago Session 2 weeks ago Settings 1 month ago Tracker 2 weeks ago Translation 1 month ago Twig 1 year ago UpdateCheck 3 months ago Updater 1 month ago Updates 2 days ago Validators 1 year ago View 1 month ago ViewDataTable 2 weeks ago Visualization 1 year ago Widget 1 month ago .htaccess 2 years ago Access.php 1 month ago Archive.php 1 month ago ArchiveProcessor.php 1 month ago AssetManager.php 1 month ago Auth.php 6 months ago AuthResult.php 6 months ago BaseFactory.php 2 years ago Cache.php 2 years ago CacheId.php 4 months ago CliMulti.php 1 month ago Common.php 2 weeks ago Config.php 1 month ago Console.php 3 months ago Context.php 2 years ago Cookie.php 1 year ago CronArchive.php 1 month ago DI.php 3 months ago DataArray.php 1 month ago DataTable.php 1 month ago Date.php 1 month ago Db.php 1 month ago DbHelper.php 1 month ago Development.php 1 year ago ErrorHandler.php 6 months ago EventDispatcher.php 1 month ago ExceptionHandler.php 4 months ago FileIntegrity.php 1 month ago Filechecks.php 1 year ago Filesystem.php 1 month ago FrontController.php 4 months ago Http.php 1 month ago IP.php 1 year ago Log.php 3 months ago LogDeleter.php 1 year ago Mail.php 1 year ago Metrics.php 1 month ago NoAccessException.php 2 years ago Nonce.php 6 months ago Notification.php 1 month ago NumberFormatter.php 5 months ago Option.php 5 months ago Period.php 1 month ago Piwik.php 1 month ago Plugin.php 1 month ago Process.php 1 month ago Profiler.php 6 months ago ProxyHeaders.php 4 months ago ProxyHttp.php 5 months ago QuickForm2.php 3 months ago RankingQuery.php 1 month ago ReportRenderer.php 1 month ago Request.php 1 month ago Segment.php 1 month ago Sequence.php 6 months ago Session.php 2 weeks ago SettingsPiwik.php 1 month ago SettingsServer.php 1 year ago Singleton.php 2 years ago Site.php 1 month ago SiteContentDetector.php 1 month ago SupportedBrowser.php 2 years ago TCPDF.php 1 year ago Theme.php 1 year ago Timer.php 1 month ago Tracker.php 1 month ago Twig.php 1 month ago Unzip.php 1 year ago UpdateCheck.php 1 month ago Updater.php 1 month ago UpdaterErrorException.php 2 years ago Updates.php 3 months ago Url.php 3 months ago UrlHelper.php 1 month ago Version.php 2 days ago View.php 1 month ago bootstrap.php 1 year ago dispatch.php 2 years ago testMinimumPhpVersion.php 6 months ago
Access.php
655 lines
1 <?php
2
3 /**
4 * Matomo - free/libre analytics platform
5 *
6 * @link https://matomo.org
7 * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8 */
9 namespace Piwik;
10
11 use Exception;
12 use Piwik\Access\CapabilitiesProvider;
13 use Piwik\API\Request;
14 use Piwik\Access\RolesProvider;
15 use Piwik\Http\BadRequestException;
16 use Piwik\Request\AuthenticationToken;
17 use Piwik\Container\StaticContainer;
18 use Piwik\Plugins\SitesManager\API as SitesManagerApi;
19 use Piwik\Session\SessionAuth;
20 /**
21 * Singleton that manages user access to Piwik resources.
22 *
23 * To check whether a user has access to a resource, use one of the {@link Piwik Piwik::checkUser...}
24 * methods.
25 *
26 * In Piwik there are four different access levels:
27 *
28 * - **no access**: Users with this access level cannot view the resource.
29 * - **view access**: Users with this access level can view the resource, but cannot modify it.
30 * - **admin access**: Users with this access level can view and modify the resource.
31 * - **Super User access**: Only the Super User has this access level. It means the user can do
32 * whatever they want.
33 *
34 * Super user access is required to set some configuration options.
35 * All other options are specific to the user or to a website.
36 *
37 * Access is granted per website. Uses with access for a website can view all
38 * data associated with that website.
39 *
40 */
41 class Access
42 {
43 /**
44 * Array of idsites available to the current user, indexed by permission level
45 * @see getSitesIdWith*()
46 *
47 * @var array
48 */
49 protected $idsitesByAccess = null;
50 /**
51 * Login of the current user
52 *
53 * @var string
54 */
55 protected $login = null;
56 /**
57 * token_auth of the current user
58 *
59 * @var string
60 */
61 protected $token_auth = null;
62 /**
63 * Defines if the current user is the Super User
64 * @see hasSuperUserAccess()
65 *
66 * @var bool
67 */
68 protected $hasSuperUserAccess = \false;
69 /**
70 * Authentification object (see Auth)
71 *
72 * @var Auth
73 */
74 private $auth = null;
75 /**
76 * @var bool
77 */
78 private $sessionExpired = \false;
79 /**
80 * Gets the singleton instance. Creates it if necessary.
81 *
82 * @return self
83 */
84 public static function getInstance()
85 {
86 return StaticContainer::get('Piwik\\Access');
87 }
88 /**
89 * @var CapabilitiesProvider
90 */
91 protected $capabilityProvider;
92 /**
93 * @var RolesProvider
94 */
95 private $roleProvider;
96 public function __construct(?RolesProvider $roleProvider = null, ?CapabilitiesProvider $capabilityProvider = null)
97 {
98 if (!isset($roleProvider)) {
99 $roleProvider = StaticContainer::get('Piwik\\Access\\RolesProvider');
100 }
101 if (!isset($capabilityProvider)) {
102 $capabilityProvider = StaticContainer::get('Piwik\\Access\\CapabilitiesProvider');
103 }
104 $this->roleProvider = $roleProvider;
105 $this->capabilityProvider = $capabilityProvider;
106 $this->resetSites();
107 }
108 private function resetSites()
109 {
110 $this->idsitesByAccess = array('view' => array(), 'write' => array(), 'admin' => array(), 'superuser' => array());
111 }
112 /**
113 * Loads the access levels for the current user.
114 *
115 * Calls the authentication method to try to log the user in the system.
116 * If the user credentials are not correct we don't load anything.
117 * If the login/password is correct the user is either the SuperUser or a normal user.
118 * We load the access levels for this user for all the websites.
119 *
120 * @param null|Auth $auth Auth adapter
121 * @return bool true on success, false if reloading access failed (when auth object wasn't specified and user is not enforced to be Super User)
122 */
123 public function reloadAccess(?\Piwik\Auth $auth = null)
124 {
125 $this->resetSites();
126 if (isset($auth)) {
127 $this->auth = $auth;
128 }
129 if ($this->hasSuperUserAccess()) {
130 $this->makeSureLoginNameIsSet();
131 return \true;
132 }
133 $this->token_auth = null;
134 $this->login = null;
135 // if the Auth wasn't set, we may be in the special case of setSuperUser(), otherwise we fail TODO: docs + review
136 if (!isset($this->auth)) {
137 return \false;
138 }
139 $result = null;
140 $isApiRequest = \Piwik\Piwik::getModule() === 'API' && (\Piwik\Piwik::getAction() === 'index' || !\Piwik\Piwik::getAction());
141 $apiMethod = Request::getMethodIfApiRequest(null);
142 $isGetApiRequest = !empty($apiMethod) && 1 === substr_count($apiMethod, '.') && strpos($apiMethod, '.get') > 0;
143 $token = StaticContainer::get(AuthenticationToken::class);
144 if ($isApiRequest && $token->isSessionToken() && ($token->wasTokenAuthProvidedSecurely() || $isGetApiRequest)) {
145 $tokenAuth = $token->getAuthToken();
146 \Piwik\Session::start();
147 $auth = StaticContainer::get(SessionAuth::class);
148 $auth->setTokenAuth($tokenAuth);
149 $result = $auth->authenticate();
150 // Note: We do not post a failed login event at this point on purpose
151 // If using the SessionAuth doesn't work, the FrontController will try to reload the Auth using
152 // the token_auth only. If that works everything is "fine" and the `force_api_session` parameter was
153 // unneeded. If that fails as well it will trigger the failed login event
154 // See FrontController::init() or Request::reloadAuthUsingTokenAuth()
155 \Piwik\Session::close();
156 // if not successful, we will fallback to regular auth
157 }
158 // access = array ( idsite => accessIdSite, idsite2 => accessIdSite2)
159 if (!$result || !$result->wasAuthenticationSuccessful()) {
160 $result = $this->auth->authenticate();
161 }
162 if (!$result->wasAuthenticationSuccessful()) {
163 return \false;
164 }
165 $this->login = $result->getIdentity();
166 $this->token_auth = $result->getTokenAuth();
167 // case the superUser is logged in
168 if ($result->hasSuperUserAccess()) {
169 $this->setSuperUserAccess(\true);
170 }
171 return \true;
172 }
173 public function getRawSitesWithSomeViewAccess($login)
174 {
175 $sql = self::getSqlAccessSite("access, t2.idsite");
176 return \Piwik\Db::fetchAll($sql, $login);
177 }
178 /**
179 * Returns the SQL query joining sites and access table for a given login
180 *
181 * @param string $select Columns or expression to SELECT FROM table, eg. "MIN(ts_created)"
182 * @return string SQL query
183 */
184 public static function getSqlAccessSite($select)
185 {
186 $access = \Piwik\Common::prefixTable('access');
187 $siteTable = \Piwik\Common::prefixTable('site');
188 return "SELECT " . $select . " FROM `" . $access . "` as t1\n\t\t\t\tJOIN `" . $siteTable . "` as t2 USING (idsite) WHERE login = ?";
189 }
190 /**
191 * Make sure a login name is set
192 */
193 protected function makeSureLoginNameIsSet() : void
194 {
195 if (empty($this->login)) {
196 // flag to force non empty login so Super User is not mistaken for anonymous
197 $this->login = 'super user was set';
198 }
199 }
200 protected function loadSitesIfNeeded()
201 {
202 if ($this->hasSuperUserAccess) {
203 if (empty($this->idsitesByAccess['superuser'])) {
204 try {
205 $api = SitesManagerApi::getInstance();
206 $allSitesId = $api->getAllSitesId();
207 } catch (\Exception $e) {
208 $allSitesId = array();
209 }
210 $this->idsitesByAccess['superuser'] = $allSitesId;
211 }
212 } elseif (isset($this->login)) {
213 if (empty($this->idsitesByAccess['view']) && empty($this->idsitesByAccess['write']) && empty($this->idsitesByAccess['admin'])) {
214 // we join with site in case there are rows in access for an idsite that doesn't exist anymore
215 // (backward compatibility ; before we deleted the site without deleting rows in _access table)
216 $accessRaw = $this->getRawSitesWithSomeViewAccess($this->login);
217 foreach ($accessRaw as $access) {
218 $accessType = $access['access'];
219 $this->idsitesByAccess[$accessType][] = $access['idsite'];
220 if ($this->roleProvider->isValidRole($accessType)) {
221 foreach ($this->capabilityProvider->getAllCapabilities() as $capability) {
222 if ($capability->hasRoleCapability($accessType)) {
223 // we automatically add this capability
224 if (!isset($this->idsitesByAccess[$capability->getId()])) {
225 $this->idsitesByAccess[$capability->getId()] = array();
226 }
227 $this->idsitesByAccess[$capability->getId()][] = $access['idsite'];
228 }
229 }
230 }
231 }
232 /**
233 * Triggered after the initial access levels and permissions for the current user are loaded. Use this
234 * event to modify the current user's permissions (for example, making sure every user has view access
235 * to a specific site).
236 *
237 * **Example**
238 *
239 * function (&$idsitesByAccess, $login) {
240 * if ($login == 'somespecialuser') {
241 * return;
242 * }
243 *
244 * $idsitesByAccess['view'][] = $mySpecialIdSite;
245 * }
246 *
247 * @param array[] &$idsitesByAccess The current user's access levels for individual sites. Maps role and
248 * capability IDs to list of site IDs, eg:
249 *
250 * ```
251 * [
252 * 'view' => [1, 2, 3],
253 * 'write' => [4, 5],
254 * 'admin' => [],
255 * ]
256 * ```
257 * @param string $login The current user's login.
258 */
259 \Piwik\Piwik::postEvent('Access.modifyUserAccess', [&$this->idsitesByAccess, $this->login]);
260 }
261 }
262 }
263 /**
264 * We bypass the normal auth method and give the current user Super User rights.
265 * This should be very carefully used.
266 *
267 * @param bool $bool
268 */
269 public function setSuperUserAccess($bool = \true)
270 {
271 $this->hasSuperUserAccess = (bool) $bool;
272 if ($bool) {
273 $this->makeSureLoginNameIsSet();
274 } else {
275 $this->resetSites();
276 }
277 }
278 /**
279 * Returns true if the current user is logged in as the Super User
280 *
281 * @return bool
282 */
283 public function hasSuperUserAccess()
284 {
285 return $this->hasSuperUserAccess;
286 }
287 /**
288 * Returns the current user login
289 *
290 * @return string|null
291 */
292 public function getLogin()
293 {
294 return $this->login;
295 }
296 /**
297 * Returns the token_auth used to authenticate this user in the API
298 *
299 * @return string|null
300 */
301 public function getTokenAuth()
302 {
303 return $this->token_auth;
304 }
305 /**
306 * Returns an array of ID sites for which the user has at least a VIEW access.
307 * Which means VIEW OR WRITE or ADMIN or SUPERUSER.
308 *
309 * @return array Example if the user is ADMIN for 4
310 * and has VIEW access for 1 and 7, it returns array(1, 4, 7);
311 */
312 public function getSitesIdWithAtLeastViewAccess()
313 {
314 $this->loadSitesIfNeeded();
315 return array_unique(array_merge($this->idsitesByAccess['view'], $this->idsitesByAccess['write'], $this->idsitesByAccess['admin'], $this->idsitesByAccess['superuser']));
316 }
317 /**
318 * Returns an array of ID sites for which the user has at least a WRITE access.
319 * Which means WRITE or ADMIN or SUPERUSER.
320 *
321 * @return array Example if the user is WRITE for 4 and 8
322 * and has VIEW access for 1 and 7, it returns array(4, 8);
323 */
324 public function getSitesIdWithAtLeastWriteAccess()
325 {
326 $this->loadSitesIfNeeded();
327 return array_unique(array_merge($this->idsitesByAccess['write'], $this->idsitesByAccess['admin'], $this->idsitesByAccess['superuser']));
328 }
329 /**
330 * Returns an array of ID sites for which the user has an ADMIN access.
331 *
332 * @return array Example if the user is ADMIN for 4 and 8
333 * and has VIEW access for 1 and 7, it returns array(4, 8);
334 */
335 public function getSitesIdWithAdminAccess()
336 {
337 $this->loadSitesIfNeeded();
338 return array_unique(array_merge($this->idsitesByAccess['admin'], $this->idsitesByAccess['superuser']));
339 }
340 /**
341 * Returns an array of ID sites for which the user has a VIEW access only.
342 *
343 * @return array Example if the user is ADMIN for 4
344 * and has VIEW access for 1 and 7, it returns array(1, 7);
345 * @see getSitesIdWithAtLeastViewAccess()
346 */
347 public function getSitesIdWithViewAccess()
348 {
349 $this->loadSitesIfNeeded();
350 return $this->idsitesByAccess['view'];
351 }
352 /**
353 * Returns an array of ID sites for which the user has a WRITE access only.
354 *
355 * @return array Example if the user is ADMIN for 4
356 * and has WRITE access for 1 and 7, it returns array(1, 7);
357 * @see getSitesIdWithAtLeastWriteAccess()
358 */
359 public function getSitesIdWithWriteAccess()
360 {
361 $this->loadSitesIfNeeded();
362 return $this->idsitesByAccess['write'];
363 }
364 /**
365 * Throws an exception if the user is not the SuperUser
366 *
367 * @throws \Piwik\NoAccessException
368 */
369 public function checkUserHasSuperUserAccess()
370 {
371 if (!$this->hasSuperUserAccess()) {
372 $this->throwNoAccessException(\Piwik\Piwik::translate('General_ExceptionPrivilege', array("'superuser'")));
373 }
374 }
375 /**
376 * Returns `true` if the current user has admin access to at least one site.
377 *
378 * @return bool
379 */
380 public function isUserHasSomeWriteAccess()
381 {
382 if ($this->hasSuperUserAccess()) {
383 return \true;
384 }
385 $idSitesAccessible = $this->getSitesIdWithAtLeastWriteAccess();
386 return count($idSitesAccessible) > 0;
387 }
388 /**
389 * Returns `true` if the current user has admin access to at least one site.
390 *
391 * @return bool
392 */
393 public function isUserHasSomeAdminAccess()
394 {
395 if ($this->hasSuperUserAccess()) {
396 return \true;
397 }
398 $idSitesAccessible = $this->getSitesIdWithAdminAccess();
399 return count($idSitesAccessible) > 0;
400 }
401 /**
402 * If the user doesn't have an WRITE access for at least one website, throws an exception
403 *
404 * @throws \Piwik\NoAccessException
405 */
406 public function checkUserHasSomeWriteAccess()
407 {
408 if (!$this->isUserHasSomeWriteAccess()) {
409 $this->throwNoAccessException(\Piwik\Piwik::translate('General_ExceptionPrivilegeAtLeastOneWebsite', array('write')));
410 }
411 }
412 /**
413 * If the user doesn't have an ADMIN access for at least one website, throws an exception
414 *
415 * @throws \Piwik\NoAccessException
416 */
417 public function checkUserHasSomeAdminAccess()
418 {
419 if (!$this->isUserHasSomeAdminAccess()) {
420 $this->throwNoAccessException(\Piwik\Piwik::translate('General_ExceptionPrivilegeAtLeastOneWebsite', array('admin')));
421 }
422 }
423 /**
424 * If the user doesn't have any view permission, throw exception
425 *
426 * @throws \Piwik\NoAccessException
427 */
428 public function checkUserHasSomeViewAccess()
429 {
430 if ($this->hasSuperUserAccess()) {
431 return;
432 }
433 $idSitesAccessible = $this->getSitesIdWithAtLeastViewAccess();
434 if (count($idSitesAccessible) == 0) {
435 $this->throwNoAccessException(\Piwik\Piwik::translate('General_ExceptionPrivilegeAtLeastOneWebsite', array('view')));
436 }
437 }
438 /**
439 * This method checks that the user has ADMIN access for the given list of websites.
440 * If the user doesn't have ADMIN access for at least one website of the list, we throw an exception.
441 *
442 * @param int|array $idSites List of ID sites to check
443 * @throws \Piwik\NoAccessException If for any of the websites the user doesn't have an ADMIN access
444 */
445 public function checkUserHasAdminAccess($idSites)
446 {
447 if ($this->hasSuperUserAccess()) {
448 return;
449 }
450 $idSites = $this->getIdSites($idSites);
451 $idSitesAccessible = $this->getSitesIdWithAdminAccess();
452 foreach ($idSites as $idsite) {
453 if (!in_array($idsite, $idSitesAccessible)) {
454 $this->throwNoAccessException(\Piwik\Piwik::translate('General_ExceptionPrivilegeAccessWebsite', array("'admin'", $idsite)));
455 }
456 }
457 }
458 /**
459 * This method checks that the user has VIEW or ADMIN access for the given list of websites.
460 * If the user doesn't have VIEW or ADMIN access for at least one website of the list, we throw an exception.
461 *
462 * @param int|array|string $idSites List of ID sites to check (integer, array of integers, string comma separated list of integers)
463 * @throws \Piwik\NoAccessException If for any of the websites the user doesn't have an VIEW or ADMIN access
464 */
465 public function checkUserHasViewAccess($idSites)
466 {
467 if ($this->hasSuperUserAccess()) {
468 return;
469 }
470 $idSites = $this->getIdSites($idSites);
471 $idSitesAccessible = $this->getSitesIdWithAtLeastViewAccess();
472 foreach ($idSites as $idsite) {
473 if (!in_array($idsite, $idSitesAccessible)) {
474 $this->throwNoAccessException(\Piwik\Piwik::translate('General_ExceptionPrivilegeAccessWebsite', array("'view'", $idsite)));
475 }
476 }
477 }
478 /**
479 * This method checks that the user has VIEW or ADMIN access for the given list of websites.
480 * If the user doesn't have VIEW or ADMIN access for at least one website of the list, we throw an exception.
481 *
482 * @param int|array|string $idSites List of ID sites to check (integer, array of integers, string comma separated list of integers)
483 * @throws \Piwik\NoAccessException If for any of the websites the user doesn't have an VIEW or ADMIN access
484 */
485 public function checkUserHasWriteAccess($idSites)
486 {
487 if ($this->hasSuperUserAccess()) {
488 return;
489 }
490 $idSites = $this->getIdSites($idSites);
491 $idSitesAccessible = $this->getSitesIdWithAtLeastWriteAccess();
492 foreach ($idSites as $idsite) {
493 if (!in_array($idsite, $idSitesAccessible)) {
494 $this->throwNoAccessException(\Piwik\Piwik::translate('General_ExceptionPrivilegeAccessWebsite', array("'write'", $idsite)));
495 }
496 }
497 }
498 public function checkUserIsNotAnonymous()
499 {
500 if ($this->hasSuperUserAccess()) {
501 return;
502 }
503 if (\Piwik\Piwik::isUserIsAnonymous()) {
504 $this->throwNoAccessException(\Piwik\Piwik::translate('General_YouMustBeLoggedIn'));
505 }
506 }
507 private function getSitesIdWithCapability($capability)
508 {
509 if (!empty($this->idsitesByAccess[$capability])) {
510 return $this->idsitesByAccess[$capability];
511 }
512 return array();
513 }
514 public function checkUserHasCapability($idSites, $capability)
515 {
516 if ($this->hasSuperUserAccess()) {
517 return;
518 }
519 $idSites = $this->getIdSites($idSites);
520 $idSitesAccessible = $this->getSitesIdWithCapability($capability);
521 foreach ($idSites as $idsite) {
522 if (!in_array($idsite, $idSitesAccessible)) {
523 $this->throwNoAccessException(\Piwik\Piwik::translate('General_ExceptionCapabilityAccessWebsite', array("'" . $capability . "'", $idsite)));
524 }
525 }
526 // a capability applies only when the user also has at least view access
527 $this->checkUserHasViewAccess($idSites);
528 }
529 /**
530 * @param int|array|string $idSites
531 * @return array
532 * @throws BadRequestException
533 */
534 protected function getIdSites($idSites)
535 {
536 if ($idSites === 'all' || $idSites === ['all']) {
537 $idSites = $this->getSitesIdWithAtLeastViewAccess();
538 }
539 $idSites = \Piwik\Site::getIdSitesFromIdSitesString($idSites, \false, \true);
540 if (empty($idSites)) {
541 throw new BadRequestException("The parameter 'idSite=' is missing from the request.");
542 }
543 return $idSites;
544 }
545 /**
546 * Executes a callback with superuser privileges, making sure those privileges are rescinded
547 * before this method exits. Privileges will be rescinded even if an exception is thrown.
548 *
549 * Use this method with care, as it might open up attack vectors
550 *
551 * @param callable $function The callback to execute. Should accept no arguments.
552 * @return mixed The result of `$function`.
553 * @throws Exception rethrows any exceptions thrown by `$function`.
554 * @api
555 */
556 public static function doAsSuperUser($function)
557 {
558 $isSuperUser = self::getInstance()->hasSuperUserAccess();
559 if ($isSuperUser) {
560 return $function();
561 }
562 $access = self::getInstance();
563 $login = $access->getLogin();
564 $shouldResetLogin = empty($login);
565 // make sure to reset login if a login was set by "makeSureLoginNameIsSet()"
566 $access->setSuperUserAccess(\true);
567 try {
568 $result = $function();
569 } catch (\Throwable $ex) {
570 $access->setSuperUserAccess($isSuperUser);
571 if ($shouldResetLogin) {
572 $access->login = null;
573 }
574 throw $ex;
575 }
576 if ($shouldResetLogin) {
577 $access->login = null;
578 }
579 $access->setSuperUserAccess($isSuperUser);
580 return $result;
581 }
582 /**
583 * Returns the level of access the current user has to the given site.
584 *
585 * @param int $idSite The site to check.
586 * @return string The access level, eg, 'view', 'admin', 'noaccess'.
587 */
588 public function getRoleForSite($idSite)
589 {
590 if ($this->hasSuperUserAccess || in_array($idSite, $this->getSitesIdWithAdminAccess())) {
591 return 'admin';
592 }
593 if (in_array($idSite, $this->getSitesIdWithWriteAccess())) {
594 return 'write';
595 }
596 if (in_array($idSite, $this->getSitesIdWithViewAccess())) {
597 return 'view';
598 }
599 return 'noaccess';
600 }
601 /**
602 * Returns the capabilities the current user has for a given site.
603 *
604 * @param int $idSite The site to check.
605 * @return string[] The capabilities the user has.
606 */
607 public function getCapabilitiesForSite($idSite)
608 {
609 $result = [];
610 foreach ($this->capabilityProvider->getAllCapabilityIds() as $capabilityId) {
611 if (empty($this->idsitesByAccess[$capabilityId])) {
612 continue;
613 }
614 if (in_array($idSite, $this->idsitesByAccess[$capabilityId])) {
615 $result[] = $capabilityId;
616 }
617 }
618 return $result;
619 }
620 /**
621 * Throw a NoAccessException with the given message, or a more generic 'You need to log in' message if the
622 * user is not currently logged in (e.g. if session has expired).
623 *
624 * @param $message
625 * @throws NoAccessException
626 */
627 private function throwNoAccessException($message)
628 {
629 if (\Piwik\Piwik::isUserIsAnonymous() && !Request::isRootRequestApiRequest()) {
630 $message = \Piwik\Piwik::translate('General_YouMustBeLoggedIn');
631 if ($this->sessionExpired) {
632 $message = \Piwik\Piwik::translate('General_YourSessionHasExpired');
633 }
634 }
635 throw new \Piwik\NoAccessException($message);
636 }
637 public function setSessionExpired(bool $sessionExpired) : void
638 {
639 $this->sessionExpired = $sessionExpired;
640 }
641 public function wasSessionExpired() : bool
642 {
643 return $this->sessionExpired;
644 }
645 /**
646 * Returns true if the current user is logged in or not.
647 *
648 * @return bool
649 */
650 public function isUserLoggedIn()
651 {
652 return !empty($this->login);
653 }
654 }
655