PluginProbe
User Access Manager / 2.0.13
User Access Manager v2.0.13
2.3.20 2.3.19 2.3.18 2.3.17 2.3.16 2.3.15 2.3.14 2.3.13 trunk 0.6 0.6.1 0.6.2 0.7 0.7 Beta 0.7.0.1 0.8 0.8.0.1 0.8.0.2 0.9 0.9.1 0.9.1.1 0.9.1.2 0.9.1.3 0.9.1.4 1.0 All 136 releases
user-access-manager / src / UserAccessManager / AccessHandler / AccessHandler.php

AccessHandler.php in User Access Manager 2.0.13, at src/UserAccessManager/AccessHandler/AccessHandler.php

579 lines 16.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * AccessHandler.php
4 *
5 * The AccessHandler class file.
6 *
7 * PHP versions 5
8 *
9 * @author Alexander Schneider <alexanderschneider85@gmail.com>
10 * @copyright 2008-2017 Alexander Schneider
11 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU General Public License, version 2
12 * @version SVN: $id$
13 * @link http://wordpress.org/extend/plugins/user-access-manager/
14 */
15 namespace UserAccessManager\AccessHandler;
16
17 use UserAccessManager\Cache\Cache;
18 use UserAccessManager\Config\Config;
19 use UserAccessManager\Database\Database;
20 use UserAccessManager\ObjectHandler\ObjectHandler;
21 use UserAccessManager\UserGroup\UserGroup;
22 use UserAccessManager\UserGroup\UserGroupFactory;
23 use UserAccessManager\Util\Util;
24 use UserAccessManager\Wrapper\Wordpress;
25
26 /**
27 * Class AccessHandler
28 *
29 * @package UserAccessManager\AccessHandler
30 */
31 class AccessHandler
32 {
33 /**
34 * @var Wordpress
35 */
36 private $wordpress;
37
38 /**
39 * @var Config
40 */
41 private $config;
42
43 /**
44 * @var Cache
45 */
46 private $cache;
47
48 /**
49 * @var Database
50 */
51 private $database;
52
53 /**
54 * @var ObjectHandler
55 */
56 private $objectHandler;
57
58 /**
59 * @var Util
60 */
61 private $util;
62
63 /**
64 * @var UserGroupFactory
65 */
66 private $userGroupFactory;
67
68 /**
69 * @var null|array
70 */
71 private $userGroups = null;
72
73 /**
74 * @var null|array
75 */
76 private $filteredUserGroups = null;
77
78 /**
79 * @var null|array
80 */
81 private $userGroupsForUser = null;
82
83 /**
84 * @var null|array
85 */
86 private $excludedTerms = null;
87
88 /**
89 * @var null|array
90 */
91 private $excludedPosts = null;
92
93 /**
94 * @var array
95 */
96 private $objectUserGroups = [];
97
98 /**
99 * @var array
100 */
101 private $objectAccess = [];
102
103 /**
104 * The constructor
105 *
106 * @param Wordpress $wordpress
107 * @param Config $config
108 * @param Cache $cache
109 * @param Database $database
110 * @param ObjectHandler $objectHandler
111 * @param Util $util
112 * @param UserGroupFactory $userGroupFactory
113 */
114 public function __construct(
115 Wordpress $wordpress,
116 Config $config,
117 Cache $cache,
118 Database $database,
119 ObjectHandler $objectHandler,
120 Util $util,
121 UserGroupFactory $userGroupFactory
122 ) {
123 $this->wordpress = $wordpress;
124 $this->config = $config;
125 $this->cache = $cache;
126 $this->database = $database;
127 $this->objectHandler = $objectHandler;
128 $this->util = $util;
129 $this->userGroupFactory = $userGroupFactory;
130 }
131
132 /**
133 * Returns all user groups or one requested by the user group id.
134 *
135 * @return UserGroup[]
136 */
137 public function getUserGroups()
138 {
139 if ($this->userGroups === null) {
140 $this->userGroups = [];
141
142 $query = "SELECT ID FROM {$this->database->getUserGroupTable()}";
143 $userGroupsDb = (array)$this->database->getResults($query);
144
145 foreach ($userGroupsDb as $userGroupDb) {
146 $this->userGroups[$userGroupDb->ID] = $this->userGroupFactory->createUserGroup($userGroupDb->ID);
147 }
148 }
149
150 return $this->userGroups;
151 }
152
153 /**
154 * Returns the user groups filtered by the user user groups.
155 *
156 * @return UserGroup[]
157 */
158 public function getFilteredUserGroups()
159 {
160 $userGroups = $this->getUserGroups();
161 $userUserGroups = $this->getUserGroupsForUser();
162 return array_intersect_key($userGroups, $userUserGroups);
163 }
164
165 /**
166 * Adds a user group.
167 *
168 * @param UserGroup $userGroup The user group which we want to add.
169 */
170 public function addUserGroup(UserGroup $userGroup)
171 {
172 $this->getUserGroups();
173 $this->userGroups[$userGroup->getId()] = $userGroup;
174 $this->filteredUserGroups = null;
175 }
176
177 /**
178 * Deletes a user group.
179 *
180 * @param integer $userGroupId The user group _iId which we want to delete.
181 *
182 * @return bool
183 */
184 public function deleteUserGroup($userGroupId)
185 {
186 $userGroups = $this->getUserGroups();
187
188 if (isset($userGroups[$userGroupId])
189 && $userGroups[$userGroupId]->delete() === true
190 ) {
191 unset($this->userGroups[$userGroupId]);
192 $this->filteredUserGroups = null;
193
194 return true;
195 }
196
197 return false;
198 }
199
200 /**
201 * Returns the user groups for the given object.
202 *
203 * @param string $objectType The object type.
204 * @param integer $objectId The _iId of the object.
205 *
206 * @return UserGroup[]
207 */
208 public function getUserGroupsForObject($objectType, $objectId)
209 {
210 if ($this->objectHandler->isValidObjectType($objectType) === false) {
211 return [];
212 } elseif (isset($this->objectUserGroups[$objectType]) === false) {
213 $this->objectUserGroups[$objectType] = [];
214 }
215
216 if (isset($this->objectUserGroups[$objectType][$objectId]) === false) {
217 $cacheKey = $this->cache->generateCacheKey(
218 'getUserGroupsForObject',
219 $objectType,
220 $objectId
221 );
222 $objectUserGroups = $this->cache->getFromCache($cacheKey);
223
224 if ($objectUserGroups !== null) {
225 $this->objectUserGroups[$objectType][$objectId] = $objectUserGroups;
226 } else {
227 $objectUserGroups = [];
228 $userGroups = $this->getUserGroups();
229
230 foreach ($userGroups as $userGroup) {
231 if ($userGroup->isObjectMember($objectType, $objectId) === true) {
232 $objectUserGroups[$userGroup->getId()] = $userGroup;
233 }
234 }
235
236 $this->cache->addToCache($cacheKey, $objectUserGroups);
237 }
238
239 $this->objectUserGroups[$objectType][$objectId] = $objectUserGroups;
240 }
241
242 return $this->objectUserGroups[$objectType][$objectId];
243 }
244
245 /**
246 * Unset the user groups for _aObjects.
247 */
248 public function unsetUserGroupsForObject()
249 {
250 $this->objectUserGroups = [];
251 }
252
253 /**
254 * Converts the ip to an integer.
255 *
256 * @param string $ip
257 *
258 * @return int
259 */
260 private function calculateIp($ip)
261 {
262 if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) {
263 return base_convert(ip2long($ip), 10, 2);
264 } elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
265 return false;
266 }
267
268 $packedIp = inet_pton($ip);
269 $bits = 15; // 16 x 8 bit = 128bit (ipv6)
270 $binaryIp = '';
271
272 while ($bits >= 0) {
273 $binaryIp = sprintf('%08b', (ord($packedIp[$bits]))).$binaryIp;
274 $bits--;
275 }
276
277 return $binaryIp;
278 }
279
280 /**
281 * Checks if the given ip matches with the range.
282 *
283 * @param string $currentIp The ip of the current user.
284 * @param array $ipRanges The ip ranges.
285 *
286 * @return bool
287 */
288 public function isIpInRange($currentIp, array $ipRanges)
289 {
290 $currentIp = $this->calculateIp($currentIp);
291
292 if ($currentIp !== false) {
293 foreach ($ipRanges as $ipRange) {
294 $ipRange = explode('-', $ipRange);
295 $rangeBegin = $ipRange[0];
296 $rangeEnd = isset($ipRange[1]) ? $ipRange[1] : $ipRange[0];
297 $rangeBegin = $this->calculateIp($rangeBegin);
298 $rangeEnd = $this->calculateIp($rangeEnd);
299
300 if ($rangeBegin !== false && $rangeEnd !== false
301 && $rangeBegin <= $currentIp && $currentIp <= $rangeEnd
302 ) {
303 return true;
304 }
305 }
306 }
307
308 return false;
309 }
310
311 /**
312 * Returns the user groups for the user.
313 *
314 * @return UserGroup[]
315 */
316 public function getUserGroupsForUser()
317 {
318 if ($this->checkUserAccess('manage_user_groups') === true) {
319 return $this->getUserGroups();
320 }
321
322 if ($this->userGroupsForUser === null) {
323 $currentUser = $this->wordpress->getCurrentUser();
324 $userGroupsForUser = $this->getUserGroupsForObject(
325 ObjectHandler::GENERAL_USER_OBJECT_TYPE,
326 $currentUser->ID
327 );
328
329 $userGroups = $this->getUserGroups();
330
331 foreach ($userGroups as $userGroup) {
332 if (isset($userGroupsForUser[$userGroup->getId()]) === false
333 && ($this->isIpInRange($_SERVER['REMOTE_ADDR'], $userGroup->getIpRangeArray())
334 || $this->config->atAdminPanel() === false && $userGroup->getReadAccess() === 'all'
335 || $this->config->atAdminPanel() === true && $userGroup->getWriteAccess() === 'all')
336 ) {
337 $userGroupsForUser[$userGroup->getId()] = $userGroup;
338 }
339 }
340
341 $this->userGroupsForUser = $userGroupsForUser;
342 }
343
344 return $this->userGroupsForUser;
345 }
346
347 /**
348 * Returns the user groups for the object filtered by the user user groups.
349 *
350 * @param string $objectType
351 * @param int $objectId
352 *
353 * @return UserGroup[]
354 */
355 public function getFilteredUserGroupsForObject($objectType, $objectId)
356 {
357 $userGroups = $this->getUserGroupsForObject($objectType, $objectId);
358 $userUserGroups = $this->getUserGroupsForUser();
359 return array_intersect_key($userGroups, $userUserGroups);
360 }
361
362 /**
363 * Return the role of the user.
364 *
365 * @param \WP_User|false $user The user.
366 *
367 * @return array
368 */
369 private function getUserRole($user)
370 {
371 if ($user instanceof \WP_User && isset($user->{$this->database->getPrefix().'capabilities'}) === true) {
372 $capabilities = (array)$user->{$this->database->getPrefix().'capabilities'};
373 } else {
374 $capabilities = [];
375 }
376
377 return (count($capabilities) > 0) ? array_keys($capabilities) : [UserGroup::NONE_ROLE];
378 }
379
380 /**
381 * Checks the user access by user level.
382 *
383 * @param bool|string $allowedCapability If set check also for the capability.
384 *
385 * @return bool
386 */
387 public function checkUserAccess($allowedCapability = false)
388 {
389 $currentUser = $this->wordpress->getCurrentUser();
390
391 if ($this->wordpress->isSuperAdmin($currentUser->ID) === true
392 || $allowedCapability !== false && $currentUser->has_cap($allowedCapability) === true
393 ) {
394 return true;
395 }
396
397 $roles = $this->getUserRole($currentUser);
398 $rolesMap = array_flip($roles);
399
400 $orderedRoles = [UserGroup::NONE_ROLE, 'subscriber', 'contributor', 'author', 'editor', 'administrator'];
401 $orderedRolesMap = array_flip($orderedRoles);
402
403 $userRoles = array_intersect_key($orderedRolesMap, $rolesMap);
404 $rightsLevel = (count($userRoles) > 0) ? end($userRoles) : -1;
405 $fullAccessRole = $this->config->getFullAccessRole();
406
407 return (isset($orderedRolesMap[$fullAccessRole]) === true && $rightsLevel >= $orderedRolesMap[$fullAccessRole]
408 || isset($rolesMap['administrator']) === true
409 );
410 }
411
412 /**
413 * Checks if the user is an admin user
414 *
415 * @param integer $userId The user id.
416 *
417 * @return bool
418 */
419 public function userIsAdmin($userId)
420 {
421 $user = $this->objectHandler->getUser($userId);
422 $roles = $this->getUserRole($user);
423 $rolesMap = array_flip($roles);
424
425 return (isset($rolesMap['administrator']) === true || $this->wordpress->isSuperAdmin($userId) === true);
426 }
427
428 /**
429 * Checks if the current_user has access to the given post.
430 *
431 * @param string $objectType The object type which should be checked.
432 * @param integer $objectId The id of the object.
433 *
434 * @return bool
435 */
436 public function checkObjectAccess($objectType, $objectId)
437 {
438 if ($this->objectHandler->isValidObjectType($objectType) === false) {
439 return true;
440 } elseif (isset($this->objectAccess[$objectType]) === false) {
441 $this->objectAccess[$objectType] = [];
442 }
443
444 if (isset($this->objectAccess[$objectType][$objectId]) === false) {
445 $access = false;
446 $currentUser = $this->wordpress->getCurrentUser();
447
448 if ($this->checkUserAccess('manage_user_groups') === true) {
449 $access = true;
450 } elseif ($this->config->authorsHasAccessToOwn() === true
451 && $this->objectHandler->isPostType($objectType)
452 ) {
453 $post = $this->objectHandler->getPost($objectId);
454 $access = ($post !== false && $currentUser->ID === (int)$post->post_author);
455 }
456
457 if ($access === false) {
458 $membership = $this->getUserGroupsForObject($objectType, $objectId);
459
460 if (count($membership) > 0) {
461 $userUserGroups = $this->getUserGroupsForUser();
462
463 foreach ($membership as $userGroupId => $userGroup) {
464 if (isset($userUserGroups[$userGroupId]) === true) {
465 $access = true;
466 break;
467 }
468 }
469 } else {
470 $access = true;
471 }
472 }
473
474 $this->objectAccess[$objectType][$objectId] = $access;
475 }
476
477 return $this->objectAccess[$objectType][$objectId];
478 }
479
480 /**
481 * Returns the excluded terms for a user.
482 *
483 * @return array
484 */
485 public function getExcludedTerms()
486 {
487 if ($this->checkUserAccess('manage_user_groups')) {
488 $this->excludedTerms = [];
489 }
490
491 if ($this->excludedTerms === null) {
492 $excludedTerms = [];
493 $userGroups = $this->getUserGroups();
494
495 $userUserGroups = $this->getUserGroupsForUser();
496
497 foreach ($userGroups as $userGroup) {
498 $excludedTerms += $userGroup->getFullTerms();
499 }
500
501 foreach ($userUserGroups as $userGroup) {
502 $excludedTerms = array_diff_key($excludedTerms, $userGroup->getFullTerms());
503 }
504
505 $termIds = array_keys($excludedTerms);
506 $this->excludedTerms = array_combine($termIds, $termIds);
507 }
508
509 return $this->excludedTerms;
510 }
511
512 /**
513 * Returns the excluded posts.
514 *
515 * @return array
516 */
517 public function getExcludedPosts()
518 {
519 if ($this->checkUserAccess('manage_user_groups')) {
520 $this->excludedPosts = [];
521 }
522
523 if ($this->excludedPosts === null) {
524 $excludedPosts = [];
525 $userGroups = $this->getUserGroups();
526
527 $userUserGroups = $this->getUserGroupsForUser();
528
529 foreach ($userGroups as $userGroup) {
530 $excludedPosts += $userGroup->getFullPosts();
531 }
532
533 foreach ($userUserGroups as $userGroup) {
534 $excludedPosts = array_diff_key($excludedPosts, $userGroup->getFullPosts());
535 }
536
537 if ($this->config->authorsHasAccessToOwn() === true) {
538 $query = $this->database->prepare(
539 "SELECT ID
540 FROM {$this->database->getPostsTable()}
541 WHERE post_author = %d",
542 $this->wordpress->getCurrentUser()->ID
543 );
544
545 $ownPosts = $this->database->getResults($query);
546 $ownPostIds = [];
547
548 foreach ($ownPosts as $ownPost) {
549 $ownPostIds[$ownPost->ID] = $ownPost->ID;
550 }
551
552 $excludedPosts = array_diff_key($excludedPosts, $ownPostIds);
553 }
554
555 if ($this->wordpress->isAdmin() === false) {
556 $noneHiddenPostTypes = [];
557 $postTypes = $this->objectHandler->getPostTypes();
558
559 foreach ($postTypes as $postType) {
560 if ($this->config->hidePostType($postType) === false) {
561 $noneHiddenPostTypes[$postType] = $postType;
562 }
563 }
564
565 foreach ($excludedPosts as $postId => $type) {
566 if (isset($noneHiddenPostTypes[$type]) === true) {
567 unset($excludedPosts[$postId]);
568 }
569 }
570 }
571
572 $postIds = array_keys($excludedPosts);
573 $this->excludedPosts = array_combine($postIds, $postIds);
574 }
575
576 return $this->excludedPosts;
577 }
578 }
579