PluginProbe ʕ •ᴥ•ʔ
Advanced Access Manager – Access Governance for WordPress / 5.8.2
Advanced Access Manager – Access Governance for WordPress v5.8.2
6.8.4 6.8.5 6.9.0 6.9.1 6.9.10 6.9.11 6.9.12 6.9.13 6.9.14 6.9.15 6.9.16 6.9.17 6.9.18 6.9.19 6.9.2 6.9.20 6.9.21 6.9.22 6.9.23 6.9.24 6.9.25 6.9.26 6.9.27 6.9.28 6.9.29 6.9.3 6.9.30 6.9.31 6.9.32 6.9.33 6.9.34 6.9.35 6.9.36 6.9.37 6.9.38 6.9.39 6.9.4 6.9.41 6.9.42 6.9.43 6.9.44 6.9.45 6.9.46 6.9.47 6.9.48 6.9.49 6.9.5 6.9.51 6.9.6 6.9.7 6.9.8 6.9.9 7.0.0 7.0.0-alpha.6 7.0.0-alpha.7 7.0.0-beta.1 7.0.0-rc1 7.0.0-rc2 7.0.0-rc3 7.0.1 7.0.10 7.0.11 7.0.2 7.0.3 7.0.4 7.0.5 7.0.6 7.0.7 7.0.8 7.0.9 7.1.0 7.1.1 trunk 3.0 4.0 4.0.1 4.1 4.2 4.3 4.4 4.4.1 4.5 4.6 4.6.1 4.6.2 4.7 4.7.1 4.7.2 4.7.5 4.7.6 4.8 4.8.1 4.9 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 4.9.5.1 4.9.5.2 5.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 5.1.1 5.10 5.11 5.2 5.2.1 5.2.5 5.2.6 5.2.7 5.3 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.4 5.4.1 5.4.2 5.4.3 5.4.3.1 5.4.3.2 5.5 5.5.1 5.5.2 5.6 5.6.1 5.6.1.1 5.7 5.7.1 5.7.2 5.7.3 5.8 5.8.1 5.8.2 5.8.3 5.9 5.9.1 5.9.1.1 5.9.2 5.9.2.1 5.9.3 5.9.4 5.9.5 5.9.6 5.9.6.1 5.9.6.2 5.9.6.3 5.9.7 5.9.7.1 5.9.7.2 5.9.7.3 5.9.8 5.9.8.1 5.9.9 5.9.9.1 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.1.0 6.1.1 6.2.0 6.2.1 6.2.2 6.3.0 6.3.1 6.3.2 6.3.3 6.4.0 6.4.1 6.4.2 6.4.3 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.6.0 6.6.1 6.6.2 6.6.3 6.6.4 6.7.0 6.7.1 6.7.2 6.7.3 6.7.4 6.7.5 6.7.6 6.7.7 6.7.8 6.7.9 6.8.0 6.8.1 6.8.2 6.8.3
advanced-access-manager / Application / Core / Subject / User.php
advanced-access-manager / Application / Core / Subject Last commit date
Default.php 7 years ago Role.php 7 years ago User.php 7 years ago Visitor.php 7 years ago
User.php
495 lines
1 <?php
2
3 /**
4 * ======================================================================
5 * LICENSE: This file is subject to the terms and conditions defined in *
6 * file 'license.txt', which is part of this source code package. *
7 * ======================================================================
8 */
9
10 /**
11 * User subject
12 *
13 * @package AAM
14 * @author Vasyl Martyniuk <vasyl@vasyltech.com>
15 */
16 class AAM_Core_Subject_User extends AAM_Core_Subject {
17
18 /**
19 * Subject UID: USER
20 */
21 const UID = 'user';
22
23 /**
24 * AAM Capability Key
25 *
26 * It is very important to have all user capability changes be stored in
27 * separate options from the wp_capabilities usermeta cause if AAM is not
28 * active as a plugin, it reverts back to the default WordPress settings
29 */
30 const AAM_CAPKEY = 'aam_capability';
31
32 /**
33 *
34 * @var type
35 */
36 protected $aamCaps = array();
37
38 /**
39 *
40 * @var type
41 */
42 protected $parent = null;
43
44 /**
45 *
46 * @var type
47 */
48 protected $maxLevel = null;
49
50 /**
51 *
52 * @param type $id
53 */
54 public function __construct($id = '') {
55 parent::__construct($id);
56
57 // Retrieve user capabilities set with AAM
58 $aamCaps = get_user_option(self::AAM_CAPKEY, $id);
59
60 if (is_array($aamCaps)) {
61 $this->aamCaps = $aamCaps;
62 }
63 }
64
65 /**
66 *
67 */
68 public function validateUserStatus() {
69 //check if user is blocked
70 if ($this->user_status === 1) {
71 wp_logout();
72 }
73
74 //check if user is expired
75 $expired = get_user_meta($this->ID, 'aam_user_expiration', true);
76 if (!empty($expired)) {
77 $parts = explode('|', $expired);
78
79 // Set time
80 // TODO: Remove in Jan 2020
81 if (preg_match('/^[\d]{4}-/', $parts[0])) {
82 $expires = DateTime::createFromFormat('Y-m-d H:i:s', $parts[0]);
83 } else {
84 $expires = DateTime::createFromFormat('m/d/Y, H:i O', $parts[0]);
85 }
86
87 $compare = new DateTime();
88 //TODO - PHP Warning: DateTime::setTimezone(): Can only do this for zones with ID for now in
89 @$compare->setTimezone($expires->getTimezone());
90
91 if ($expires <= $compare) {
92 $this->triggerExpiredUserAction($parts);
93 }
94 }
95
96 //check if user's role expired
97 $roleExpire = get_user_option('aam-role-expires', $this->ID);
98 if ($roleExpire && ($roleExpire <= time())) {
99 $this->restoreRoles();
100 }
101
102 //finally check if session tracking is enabled and if so, check if used
103 //has to be logged out
104 if (AAM::api()->getConfig('core.session.tracking', false)) {
105 $ttl = AAM::api()->getConfig(
106 "core.session.user.{$this->ID}.ttl",
107 AAM::api()->getConfig("core.session.user.ttl", null)
108 );
109
110 if (!empty($ttl)) {
111 $timestamp = get_user_meta(
112 $this->ID, 'aam-authenticated-timestamp', true
113 );
114
115 if ($timestamp && ($timestamp + intval($ttl) <= time())) {
116 delete_user_meta($this->ID, 'aam-authenticated-timestamp');
117 wp_logout();
118 }
119 }
120 }
121 }
122
123 /**
124 * Expire user
125 *
126 * @param array $config
127 *
128 * @return void
129 *
130 * @access
131 */
132 public function triggerExpiredUserAction($config) {
133 switch($config[1]) {
134 case 'lock':
135 $this->block();
136 break;
137
138 case 'logout':
139 wp_logout();
140 break;
141
142 case 'change-role':
143 if (AAM_Core_API::getRoles()->is_role($config[2])) {
144 $this->getSubject()->set_role($config[2]);
145 delete_user_option($this->getSubject()->ID, 'aam_user_expiration');
146 }
147 break;
148
149 case 'delete':
150 require_once(ABSPATH . 'wp-admin/includes/user.php' );
151 wp_delete_user(
152 $this->getId(), AAM_Core_Config::get('core.reasign.ownership.user')
153 );
154 wp_logout();
155 break;
156
157 default:
158 break;
159 }
160 }
161
162 /**
163 * Block User
164 *
165 * @return boolean
166 *
167 * @access public
168 * @global wpdb $wpdb
169 */
170 public function block() {
171 global $wpdb;
172
173 $status = ($this->getSubject()->user_status ? 0 : 1);
174 $result = $wpdb->update(
175 $wpdb->users,
176 array('user_status' => $status),
177 array('ID' => $this->getId())
178 );
179
180 if ($result) {
181 $this->getSubject()->user_status = $status;
182 clean_user_cache($this->getSubject());
183 }
184
185 return $result;
186 }
187
188 /**
189 *
190 */
191 public function restoreRoles() {
192 $roles = get_user_option('aam-original-roles');
193
194 //remove curren roles
195 foreach((array) $this->roles as $role) {
196 $this->remove_role($role);
197 }
198
199 //add original roles
200 foreach(($roles ? $roles : array('subscriber')) as $role) {
201 $this->add_role($role);
202 }
203
204 //delete options
205 delete_user_option($this->getId(), 'aam-role-expires');
206 delete_user_option($this->getId(), 'aam-original-roles');
207 }
208
209 /**
210 * Retrieve User based on ID
211 *
212 * @return WP_Role
213 *
214 * @access protected
215 */
216 protected function retrieveSubject() {
217 if ($this->getId() === get_current_user_id()) {
218 $subject = wp_get_current_user();
219 } else {
220 $subject = new WP_User($this->getId());
221 }
222
223 return $subject;
224 }
225
226 /**
227 *
228 */
229 public function initialize($isolated = false) {
230 $subject = $this->getSubject();
231
232 // Retrieve all capabilities set in Access Policy
233 // Load Capabilities from the policy
234 $stms = AAM_Core_Policy_Manager::getInstance()->find(
235 "/^Capability:/i", ($isolated ? $this : null)
236 );
237
238 $policyCaps = array();
239
240 foreach($stms as $key => $stm) {
241 $chunks = explode(':', $key);
242 if (count($chunks) === 2) {
243 $policyCaps[$chunks[1]] = ($stm['Effect'] === 'allow' ? 1 : 0);
244 }
245 }
246
247 // Load Roles from the policy
248 $stms = AAM_Core_Policy_Manager::getInstance()->find(
249 "/^Role:/i", ($isolated ? $this : null)
250 );
251
252 $roles = (array) $subject->roles;
253
254 $allRoles = AAM_Core_API::getRoles();
255 $roleCaps = array();
256
257 foreach($stms as $key => $stm) {
258 $chunks = explode(':', $key);
259
260 if ($stm['Effect'] === 'allow') {
261 if (!in_array($chunks[1], $roles, true)) {
262 if ($allRoles->is_role($chunks[1])) {
263 $roleCaps = array_merge($roleCaps, $allRoles->get_role($chunks[1])->capabilities);
264 $roleCaps[] = $chunks[1];
265 }
266 $roles[] = $chunks[1];
267 }
268 } elseif (in_array($chunks[1], $roles, true)) {
269 // Make sure that we delete all instanses of the role
270 foreach($roles as $i => $role){
271 if ($role === $chunks[1]) {
272 unset($roles[$i]);
273 }
274 }
275 }
276 }
277
278 $subject->roles = $roles;
279
280 //reset the user capabilities
281 $subject->allcaps = array_merge($subject->allcaps, $roleCaps, $policyCaps, $this->aamCaps);
282 $subject->caps = array_merge($subject->caps, $roleCaps, $policyCaps, $this->aamCaps);
283 }
284
285 /**
286 * Get user capabilities
287 *
288 * @return array
289 *
290 * @access public
291 */
292 public function getCapabilities() {
293 return $this->getSubject()->allcaps;
294 }
295
296 /**
297 * Check if user has a capability
298 *
299 * @param string $capability
300 *
301 * @return boolean
302 *
303 * @access public
304 */
305 public function hasCapability($capability) {
306 return user_can($this->getSubject(), $capability);
307 }
308
309 /**
310 * Add capability
311 *
312 * @param string $capability
313 *
314 * @return boolean
315 *
316 * @access public
317 */
318 public function addCapability($capability) {
319 return $this->updateCapability($capability, true);
320 }
321
322 /**
323 * Remove Capability
324 *
325 * @param string $capability
326 *
327 * @return boolean
328 *
329 * @access public
330 */
331 public function removeCapability($capability) {
332 return $this->updateCapability($capability, false);
333 }
334
335 /**
336 * Update User's Capability Set
337 *
338 * @param string $capability
339 * @param boolean $grand
340 *
341 * @return boolean
342 *
343 * @access public
344 */
345 public function updateCapability($capability, $grand) {
346 //update capability
347 $caps = $this->getSubject()->caps;
348 $caps[$capability] = $grand;
349
350 //save and return the result of operation
351 return update_user_option($this->getId(), self::AAM_CAPKEY, $caps);
352 }
353
354 /**
355 * Undocumented function
356 *
357 * @param string $object
358 * @return void
359 */
360 public function resetObject($object) {
361 if ($object === 'capability') {
362 $result = delete_user_option($this->getId(), self::AAM_CAPKEY);
363 } else {
364 $result = parent::resetObject($object);
365 }
366
367 return $result;
368 }
369
370 /**
371 * Update user's option
372 *
373 * @param mixed $value
374 * @param string $object
375 * @param string $id
376 *
377 * @return boolean
378 *
379 * @access public
380 */
381 public function updateOption($value, $object, $id = 0) {
382 return update_user_option(
383 $this->getId(), $this->getOptionName($object, $id), $value
384 );
385 }
386
387 /**
388 * Read user's option
389 *
390 * @param string $object
391 * @param string $id
392 *
393 * @return mixed
394 *
395 * @access public
396 */
397 public function readOption($object, $id = '') {
398 return get_user_option(
399 $this->getOptionName($object, $id), $this->getId()
400 );
401 }
402
403 /**
404 * Read user's option
405 *
406 * @param string $object
407 * @param string $id
408 *
409 * @return mixed
410 *
411 * @access public
412 */
413 public function deleteOption($object, $id = 0) {
414 return delete_user_option(
415 $this->getId(), $this->getOptionName($object, $id)
416 );
417 }
418
419 /**
420 * @inheritdoc
421 */
422 public function getParent() {
423 if (is_null($this->parent)) {
424 //try to get this option from the User's Role
425 $roles = $this->getSubject()->roles;
426 $base = array_shift($roles);
427
428 if ($base) {
429 $this->parent = new AAM_Core_Subject_Role($base);
430
431 // if user has more than one role that set subject as multi
432 if (AAM::api()->getConfig('core.settings.multiSubject', false)
433 && count($roles)) {
434 $siblings = array();
435 foreach($roles as $role) {
436 $siblings[] = new AAM_Core_Subject_Role($role);
437 }
438 $this->parent->setSiblings($siblings);
439 }
440 } else {
441 $this->parent = null;
442 }
443 }
444
445 return $this->parent;
446 }
447
448 /**
449 * Prepare option's name
450 *
451 * @param string $object
452 * @param string|int $id
453 *
454 * @return string
455 *
456 * @access public
457 */
458 public function getOptionName($object, $id) {
459 return "aam_{$object}" . ($id ? "_{$id}" : '');
460 }
461
462 /**
463 * Get Subject UID
464 *
465 * @return string
466 *
467 * @access public
468 */
469 public function getUID() {
470 return self::UID;
471 }
472
473 /**
474 *
475 * @return type
476 */
477 public function getName() {
478 $display = $this->display_name;
479
480 return ($display ? $display : $this->user_nicename);
481 }
482
483 /**
484 *
485 * @return type
486 */
487 public function getMaxLevel() {
488 if (is_null($this->maxLevel)) {
489 $this->maxLevel = AAM_Core_API::maxLevel($this->allcaps);
490 }
491
492 return $this->maxLevel;
493 }
494
495 }