PluginProbe ʕ •ᴥ•ʔ
Advanced Access Manager – Access Governance for WordPress / 5.9
Advanced Access Manager – Access Governance for WordPress v5.9
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
499 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 * List of all user specific capabilities
34 *
35 * @var array
36 *
37 * @access protected
38 */
39 protected $aamCaps = array();
40
41 /**
42 * Parent subject
43 *
44 * @var AAM_Core_Subject
45 *
46 * @access protected
47 */
48 protected $parent = null;
49
50 /**
51 * Max user level
52 *
53 * @var int
54 *
55 * @access protected
56 */
57 protected $maxLevel = null;
58
59 /**
60 * Constructor
61 *
62 * @param int $id
63 *
64 * @return void
65 *
66 * @access public
67 */
68 public function __construct($id = '') {
69 parent::__construct($id);
70
71 // Retrieve user capabilities set with AAM
72 $aamCaps = get_user_option(self::AAM_CAPKEY, $id);
73
74 if (is_array($aamCaps)) {
75 $this->aamCaps = $aamCaps;
76 }
77 }
78
79 /**
80 *
81 */
82 public function initialize() {
83 $subject = $this->getSubject();
84 $manager = AAM_Core_Policy_Factory::get($this);
85
86 // Retrieve all capabilities set in Access Policy
87 // Load Capabilities from the policy
88 $policyCaps = array();
89
90 foreach($manager->find("/^Capability:[\w]+/i") as $key => $stm) {
91 $chunks = explode(':', $key);
92 $policyCaps[$chunks[1]] = ($stm['Effect'] === 'allow' ? 1 : 0);
93 }
94
95 // Load Roles from the policy
96 $roles = (array) $subject->roles;
97 $allRoles = AAM_Core_API::getRoles();
98 $roleCaps = array();
99
100 foreach($manager->find("/^Role:/i") as $key => $stm) {
101 $chunks = explode(':', $key);
102
103 if ($stm['Effect'] === 'allow') {
104 if (!in_array($chunks[1], $roles, true)) {
105 if ($allRoles->is_role($chunks[1])) {
106 $roleCaps = array_merge($roleCaps, $allRoles->get_role($chunks[1])->capabilities);
107 $roleCaps[] = $chunks[1];
108 }
109 $roles[] = $chunks[1];
110 }
111 } elseif (in_array($chunks[1], $roles, true)) {
112 // Make sure that we delete all instances of the role
113 foreach($roles as $i => $role){
114 if ($role === $chunks[1]) {
115 unset($roles[$i]);
116 }
117 }
118 }
119 }
120
121 $subject->roles = $roles;
122
123 //reset the user capabilities
124 $subject->allcaps = array_merge($subject->allcaps, $roleCaps, $policyCaps, $this->aamCaps);
125 $subject->caps = array_merge($subject->caps, $roleCaps, $policyCaps, $this->aamCaps);
126 }
127
128 /**
129 *
130 */
131 public function validateUserStatus() {
132 //check if user is blocked
133 if ($this->user_status === 1) {
134 wp_logout();
135 }
136
137 //check if user is expired
138 $expired = get_user_meta($this->ID, 'aam_user_expiration', true);
139 if (!empty($expired)) {
140 $parts = explode('|', $expired);
141
142 // Set time
143 // TODO: Remove in Jan 2020
144 if (preg_match('/^[\d]{4}-/', $parts[0])) {
145 $expires = DateTime::createFromFormat('Y-m-d H:i:s', $parts[0]);
146 } else {
147 $expires = DateTime::createFromFormat('m/d/Y, H:i O', $parts[0]);
148 }
149
150 $compare = new DateTime();
151 //TODO - PHP Warning: DateTime::setTimezone(): Can only do this for zones with ID for now in
152 @$compare->setTimezone($expires->getTimezone());
153
154 if ($expires->getTimestamp() <= $compare->getTimestamp()) {
155 $this->triggerExpiredUserAction($parts);
156 }
157 }
158
159 //check if user's role expired
160 $roleExpire = get_user_option('aam-role-expires', $this->ID);
161 if ($roleExpire && ($roleExpire <= time())) {
162 $this->restoreRoles();
163 }
164
165 //finally check if session tracking is enabled and if so, check if used
166 //has to be logged out
167 if (AAM::api()->getConfig('core.session.tracking', false)) {
168 $ttl = AAM::api()->getConfig(
169 "core.session.user.{$this->ID}.ttl",
170 AAM::api()->getConfig("core.session.user.ttl", null)
171 );
172
173 if (!empty($ttl)) {
174 $timestamp = get_user_meta(
175 $this->ID, 'aam-authenticated-timestamp', true
176 );
177
178 if ($timestamp && ($timestamp + intval($ttl) <= time())) {
179 delete_user_meta($this->ID, 'aam-authenticated-timestamp');
180 wp_logout();
181 }
182 }
183 }
184 }
185
186 /**
187 * Expire user
188 *
189 * @param array $config
190 *
191 * @return void
192 *
193 * @access
194 */
195 public function triggerExpiredUserAction($config) {
196 switch($config[1]) {
197 case 'lock':
198 $this->block();
199 break;
200
201 case 'logout':
202 wp_logout();
203 break;
204
205 case 'change-role':
206 if (AAM_Core_API::getRoles()->is_role($config[2])) {
207 $this->getSubject()->set_role($config[2]);
208 delete_user_option($this->getSubject()->ID, 'aam_user_expiration');
209 }
210 break;
211
212 case 'delete':
213 require_once(ABSPATH . 'wp-admin/includes/user.php' );
214 wp_delete_user(
215 $this->getId(), AAM_Core_Config::get('core.reasign.ownership.user')
216 );
217 wp_logout();
218 break;
219
220 default:
221 break;
222 }
223 }
224
225 /**
226 * Block User
227 *
228 * @return boolean
229 *
230 * @access public
231 * @global wpdb $wpdb
232 */
233 public function block() {
234 global $wpdb;
235
236 $status = ($this->getSubject()->user_status ? 0 : 1);
237 $result = $wpdb->update(
238 $wpdb->users,
239 array('user_status' => $status),
240 array('ID' => $this->getId())
241 );
242
243 if ($result) {
244 $this->getSubject()->user_status = $status;
245 clean_user_cache($this->getSubject());
246 }
247
248 return $result;
249 }
250
251 /**
252 *
253 */
254 public function restoreRoles() {
255 $roles = get_user_option('aam-original-roles');
256
257 //remove curren roles
258 foreach((array) $this->roles as $role) {
259 $this->remove_role($role);
260 }
261
262 //add original roles
263 foreach(($roles ? $roles : array('subscriber')) as $role) {
264 $this->add_role($role);
265 }
266
267 //delete options
268 delete_user_option($this->getId(), 'aam-role-expires');
269 delete_user_option($this->getId(), 'aam-original-roles');
270 }
271
272 /**
273 * Retrieve User based on ID
274 *
275 * @return WP_Role
276 *
277 * @access protected
278 */
279 protected function retrieveSubject() {
280 if ($this->getId() === get_current_user_id()) {
281 $subject = wp_get_current_user();
282 } else {
283 $subject = new WP_User($this->getId());
284 }
285
286 return $subject;
287 }
288
289 /**
290 * Get user capabilities
291 *
292 * @return array
293 *
294 * @access public
295 */
296 public function getCapabilities() {
297 return $this->getSubject()->allcaps;
298 }
299
300 /**
301 * Check if user has a capability
302 *
303 * @param string $capability
304 *
305 * @return boolean
306 *
307 * @access public
308 */
309 public function hasCapability($capability) {
310 return user_can($this->getSubject(), $capability);
311 }
312
313 /**
314 * Add capability
315 *
316 * @param string $capability
317 *
318 * @return boolean
319 *
320 * @access public
321 */
322 public function addCapability($capability) {
323 return $this->updateCapability($capability, true);
324 }
325
326 /**
327 * Remove Capability
328 *
329 * @param string $capability
330 *
331 * @return boolean
332 *
333 * @access public
334 */
335 public function removeCapability($capability) {
336 return $this->updateCapability($capability, false);
337 }
338
339 /**
340 * Update User's Capability Set
341 *
342 * @param string $capability
343 * @param boolean $grand
344 *
345 * @return boolean
346 *
347 * @access public
348 */
349 public function updateCapability($capability, $grand) {
350 //update capability
351 $caps = $this->getSubject()->caps;
352 $caps[$capability] = $grand;
353
354 //save and return the result of operation
355 return update_user_option($this->getId(), self::AAM_CAPKEY, $caps);
356 }
357
358 /**
359 * Undocumented function
360 *
361 * @param string $object
362 * @return void
363 */
364 public function resetObject($object) {
365 if ($object === 'capability') {
366 $result = delete_user_option($this->getId(), self::AAM_CAPKEY);
367 } else {
368 $result = parent::resetObject($object);
369 }
370
371 return $result;
372 }
373
374 /**
375 * Update user's option
376 *
377 * @param mixed $value
378 * @param string $object
379 * @param string $id
380 *
381 * @return boolean
382 *
383 * @access public
384 */
385 public function updateOption($value, $object, $id = 0) {
386 return update_user_option(
387 $this->getId(), $this->getOptionName($object, $id), $value
388 );
389 }
390
391 /**
392 * Read user's option
393 *
394 * @param string $object
395 * @param string $id
396 *
397 * @return mixed
398 *
399 * @access public
400 */
401 public function readOption($object, $id = '') {
402 return get_user_option(
403 $this->getOptionName($object, $id), $this->getId()
404 );
405 }
406
407 /**
408 * Read user's option
409 *
410 * @param string $object
411 * @param string $id
412 *
413 * @return mixed
414 *
415 * @access public
416 */
417 public function deleteOption($object, $id = 0) {
418 return delete_user_option(
419 $this->getId(), $this->getOptionName($object, $id)
420 );
421 }
422
423 /**
424 * @inheritdoc
425 */
426 public function getParent() {
427 if (is_null($this->parent)) {
428 //try to get this option from the User's Role
429 $roles = $this->getSubject()->roles;
430 $base = array_shift($roles);
431
432 if ($base) {
433 $this->parent = new AAM_Core_Subject_Role($base);
434
435 // if user has more than one role that set subject as multi
436 if (AAM::api()->getConfig('core.settings.multiSubject', false)
437 && count($roles)) {
438 $siblings = array();
439 foreach($roles as $role) {
440 $siblings[] = new AAM_Core_Subject_Role($role);
441 }
442 $this->parent->setSiblings($siblings);
443 }
444 } else {
445 $this->parent = null;
446 }
447 }
448
449 return $this->parent;
450 }
451
452 /**
453 * Prepare option's name
454 *
455 * @param string $object
456 * @param string|int $id
457 *
458 * @return string
459 *
460 * @access public
461 */
462 public function getOptionName($object, $id) {
463 return "aam_{$object}" . ($id ? "_{$id}" : '');
464 }
465
466 /**
467 * Get Subject UID
468 *
469 * @return string
470 *
471 * @access public
472 */
473 public function getUID() {
474 return self::UID;
475 }
476
477 /**
478 *
479 * @return type
480 */
481 public function getName() {
482 $display = $this->display_name;
483
484 return ($display ? $display : $this->user_nicename);
485 }
486
487 /**
488 *
489 * @return type
490 */
491 public function getMaxLevel() {
492 if (is_null($this->maxLevel)) {
493 $this->maxLevel = AAM_Core_API::maxLevel($this->allcaps);
494 }
495
496 return $this->maxLevel;
497 }
498
499 }