PluginProbe ʕ •ᴥ•ʔ
WP 2FA – Two-factor authentication for WordPress / 2.2.1
WP 2FA – Two-factor authentication for WordPress v2.2.1
4.1.0 4.0.0 1.7.1 2.0.0 2.0.1 2.1.0 2.2.0 2.2.1 2.3.0 2.4.0 2.4.1 2.4.2 2.5.0 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.8.0 2.9.0 2.9.1 2.9.2 2.9.3 3.0.0 3.0.1 3.1.0 3.1.1 3.1.1.2 trunk 1.2.0 1.3.0 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.6.0 1.6.1 1.6.2 1.7.0
wp-2fa / includes / classes / Admin / Helpers / class-user-helper.php
wp-2fa / includes / classes / Admin / Helpers Last commit date
class-user-helper.php 4 years ago class-wp-helper.php 4 years ago
class-user-helper.php
723 lines
1 <?php
2 /**
3 * Responsible for the User's operations
4 *
5 * @package wp2fa
6 * @subpackage helpers
7 * @since 2.2.0
8 * @copyright 2022 WP White Security
9 * @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
10 * @link https://wordpress.org/plugins/wp-2fa/
11 */
12
13 namespace WP2FA\Admin\Helpers;
14
15 defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
16
17 use WP2FA\Admin\Controllers\Settings;
18
19 /**
20 * User's settings class
21 */
22 if ( ! class_exists( '\WP2FA\Admin\Helpers\User_Helper' ) ) {
23
24 /**
25 * All the user related settings must go trough this class.
26 *
27 * @since 2.2.0
28 */
29 class User_Helper {
30
31 /**
32 * Secret TOTP key meta name
33 */
34 const SECRET_META_KEY = WP_2FA_PREFIX . 'totp_key';
35 /**
36 * Enabled 2fa method for user meta name
37 */
38 const ENABLED_METHODS_META_KEY = WP_2FA_PREFIX . 'enabled_methods';
39 /**
40 * Email token for user meta name
41 */
42 const TOKEN_META_KEY = WP_2FA_PREFIX . 'email_token';
43 /**
44 * Global settings hash for user meta name
45 * That is used to check if user needs to be re-checked / re-configured, if the settings of the plugin are changed, probably the user settings also need to be changed - that meta holds the key to check against
46 */
47 const USER_SETTINGS_HASH = WP_2FA_PREFIX . 'global_settings_hash';
48 /**
49 * The meta name for the user 2FA status in the plugin
50 */
51 const USER_2FA_STATUS = WP_2FA_PREFIX . '2fa_status';
52 /**
53 * The user grace period expired meta key
54 */
55 const USER_GRACE_KEY = WP_2FA_PREFIX . 'user_grace_period_expired';
56 /**
57 * The user grace period expiry date meta key
58 */
59 const USER_GRACE_EXPIRY_KEY = WP_2FA_PREFIX . 'grace_period_expiry';
60 /**
61 * The user enforcement status
62 */
63 const USER_ENFORCED_INSTANTLY = WP_2FA_PREFIX . 'user_enforced_instantly';
64 /**
65 * The user reconfigure 2fa status
66 */
67 const USER_NEEDS_TO_RECONFIGURE_2FA = WP_2FA_PREFIX . 'user_needs_to_reconfigure_2fa';
68
69 /**
70 * The class user variable
71 *
72 * @var \WP_User
73 *
74 * @since 2.2.0
75 */
76 private static $user = null;
77
78 /**
79 * Returns the enabled 2FA method for the user.
80 *
81 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
82 *
83 * @return mixed
84 *
85 * @since 2.2.0
86 */
87 public static function get_enabled_method_for_user( $user = null ) {
88 self::set_proper_user( $user );
89
90 /**
91 * Checks the enabled methods fo the user.
92 *
93 * @param mixed - Value of the method.
94 * @param WP_User - The user which must be checked.
95 *
96 * @since 2.0.0
97 */
98 return apply_filters( WP_2FA_PREFIX . 'user_enabled_methods', self::get_meta( self::ENABLED_METHODS_META_KEY ) );
99 }
100
101 /**
102 * Sets the enabled 2FA method for the user.
103 *
104 * @param string $method - The name of the method to set.
105 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
106 *
107 * @return mixed
108 *
109 * @since 2.2.0
110 */
111 public static function set_enabled_method_for_user( string $method, $user = null ) {
112 self::set_proper_user( $user );
113
114 return self::set_meta( self::ENABLED_METHODS_META_KEY, $method );
115 }
116
117 /**
118 * Removes the 2FA method for the user.
119 *
120 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
121 *
122 * @return void
123 *
124 * @since 2.2.0
125 */
126 public static function remove_enabled_method_for_user( $user = null ) {
127 self::set_proper_user( $user );
128
129 self::remove_meta( self::ENABLED_METHODS_META_KEY, self::$user );
130 }
131
132 /**
133 * Returns the email token for the user.
134 *
135 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
136 *
137 * @return mixed
138 *
139 * @since 2.2.0
140 */
141 public static function get_email_token_for_user( $user = null ) {
142 self::set_proper_user( $user );
143
144 return self::get_meta( self::TOKEN_META_KEY );
145 }
146
147 /**
148 * Sets the email token for the user.
149 *
150 * @param string $token - The token to set for the user.
151 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
152 *
153 * @return mixed
154 *
155 * @since 2.2.0
156 */
157 public static function set_email_token_for_user( string $token, $user = null ) {
158 self::set_proper_user( $user );
159
160 return self::set_meta( self::TOKEN_META_KEY, $token );
161 }
162
163 /**
164 * Removes the email token for the user.
165 *
166 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
167 *
168 * @return void
169 *
170 * @since 2.2.0
171 */
172 public static function remove_email_token_for_user( $user = null ) {
173 self::set_proper_user( $user );
174
175 self::remove_meta( self::TOKEN_META_KEY, self::$user );
176 }
177
178 /**
179 * Returns the global settings hash for the user.
180 *
181 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
182 *
183 * @return mixed
184 *
185 * @since 2.2.0
186 */
187 public static function get_global_settings_hash_for_user( $user = null ) {
188 self::set_proper_user( $user );
189
190 return self::get_meta( self::USER_SETTINGS_HASH );
191 }
192
193 /**
194 * Sets the global settings hash for the user.
195 *
196 * @param string $hash - The global settings hash to set for the user.
197 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
198 *
199 * @return mixed
200 *
201 * @since 2.2.0
202 */
203 public static function set_global_settings_hash_for_user( string $hash, $user = null ) {
204 self::set_proper_user( $user );
205
206 return self::set_meta( self::USER_SETTINGS_HASH, $hash );
207 }
208
209 /**
210 * Removes the global settings hash for the user.
211 *
212 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
213 *
214 * @return void
215 *
216 * @since 2.2.0
217 */
218 public static function remove_global_settings_hash_for_user( $user = null ) {
219 self::set_proper_user( $user );
220
221 self::remove_meta( self::USER_SETTINGS_HASH, self::$user );
222 }
223
224 /**
225 * Returns the current 2FA status for the user.
226 *
227 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
228 *
229 * @return mixed
230 *
231 * @since 2.2.0
232 */
233 public static function get_2fa_status( $user = null ) {
234 self::set_proper_user( $user );
235
236 return self::get_meta( self::USER_2FA_STATUS );
237 }
238
239 /**
240 * Sets the 2FA status for the user.
241 *
242 * @param string $status - The name of the status to set.
243 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
244 *
245 * @return mixed
246 *
247 * @since 2.2.0
248 */
249 public static function set_2fa_status( string $status, $user = null ) {
250 self::set_proper_user( $user );
251
252 return self::set_meta( self::USER_2FA_STATUS, $status );
253 }
254
255 /**
256 * Removes the 2FA status for the user.
257 *
258 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
259 *
260 * @return void
261 *
262 * @since 2.2.0
263 */
264 public static function remove_2fa_status( $user = null ) {
265 self::set_proper_user( $user );
266
267 self::remove_meta( self::USER_2FA_STATUS, self::$user );
268 }
269
270 /**
271 * Returns the current 2FA status for the user.
272 *
273 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
274 *
275 * @return mixed
276 *
277 * @since 2.2.0
278 */
279 public static function get_user_expiry_date( $user = null ) {
280 self::set_proper_user( $user );
281
282 return self::get_meta( self::USER_GRACE_EXPIRY_KEY );
283 }
284
285 /**
286 * Sets the 2FA status for the user.
287 *
288 * @param string $date - The period to set.
289 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
290 *
291 * @return mixed
292 *
293 * @since 2.2.0
294 */
295 public static function set_user_expiry_date( string $date, $user = null ) {
296 self::set_proper_user( $user );
297
298 return self::set_meta( self::USER_GRACE_EXPIRY_KEY, $date );
299 }
300
301 /**
302 * Removes the 2FA status for the user.
303 *
304 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
305 *
306 * @return void
307 *
308 * @since 2.2.0
309 */
310 public static function remove_user_expiry_date( $user = null ) {
311 self::set_proper_user( $user );
312
313 self::remove_meta( self::USER_GRACE_EXPIRY_KEY, self::$user );
314 }
315
316 /**
317 * Returns the current 2FA enforcement status for the user.
318 *
319 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
320 *
321 * @return mixed
322 *
323 * @since 2.2.0
324 */
325 public static function get_user_enforced_instantly( $user = null ) {
326 self::set_proper_user( $user );
327
328 return self::get_meta( self::USER_ENFORCED_INSTANTLY );
329 }
330
331 /**
332 * Sets the 2FA enforcement status for the user.
333 *
334 * @param bool $status - The status for user enforcement.
335 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
336 *
337 * @return mixed
338 *
339 * @since 2.2.0
340 */
341 public static function set_user_enforced_instantly( bool $status, $user = null ) {
342 self::set_proper_user( $user );
343
344 return self::set_meta( self::USER_ENFORCED_INSTANTLY, $status );
345 }
346
347 /**
348 * Removes the 2FA enforcement status for the user.
349 *
350 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
351 *
352 * @return void
353 *
354 * @since 2.2.0
355 */
356 public static function remove_user_enforced_instantly( $user = null ) {
357 self::set_proper_user( $user );
358
359 self::remove_meta( self::USER_ENFORCED_INSTANTLY, self::$user );
360 }
361
362 /**
363 * Returns the current 2FA needs to reconfigure status for the user.
364 *
365 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
366 *
367 * @return mixed
368 *
369 * @since 2.2.0
370 */
371 public static function get_user_needs_to_reconfigure_2fa( $user = null ) {
372 self::set_proper_user( $user );
373
374 return self::get_meta( self::USER_NEEDS_TO_RECONFIGURE_2FA );
375 }
376
377 /**
378 * Sets the 2FA needs to reconfigure status for the user.
379 *
380 * @param bool $status - The status for user enforcement.
381 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
382 *
383 * @return mixed
384 *
385 * @since 2.2.0
386 */
387 public static function set_user_needs_to_reconfigure_2fa( bool $status, $user = null ) {
388 self::set_proper_user( $user );
389
390 return self::set_meta( self::USER_NEEDS_TO_RECONFIGURE_2FA, $status );
391 }
392
393 /**
394 * Removes the 2FA needs to reconfigure status for the user.
395 *
396 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
397 *
398 * @return void
399 *
400 * @since 2.2.0
401 */
402 public static function remove_user_needs_to_reconfigure_2fa( $user = null ) {
403 self::set_proper_user( $user );
404
405 self::remove_meta( self::USER_NEEDS_TO_RECONFIGURE_2FA, self::$user );
406 }
407
408 /**
409 * Every meta call for the user must go through this method, so we can unify the code.
410 *
411 * @param string $meta - The meta name that we should check.
412 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
413 *
414 * @return mixed
415 *
416 * @since 2.2.0
417 */
418 public static function get_meta( string $meta, $user = null ) {
419 self::set_proper_user( $user );
420
421 return \get_user_meta( self::$user->ID, $meta, true );
422 }
423
424 /**
425 * Every meta storing call for the user must go through this method
426 *
427 * @param string $meta - The meta name that we should check.
428 * @param mixed $value - The value which should be stored.
429 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
430 *
431 * @return mixed
432 *
433 * @since 2.2.0
434 */
435 public static function set_meta( string $meta, $value, $user = null ) {
436 self::set_proper_user( $user );
437
438 return \update_user_meta( self::$user->ID, $meta, $value );
439 }
440
441 /**
442 * Removes meta for the given user
443 *
444 * @param string $meta - The name of the meta.
445 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
446 *
447 * @return mixed
448 *
449 * @since 2.2.0
450 */
451 public static function remove_meta( string $meta, $user = null ) {
452 self::set_proper_user( $user );
453
454 return \delete_user_meta( self::$user->ID, $meta );
455 }
456
457 /**
458 * Returns the currently set user.
459 *
460 * @return \WP_User
461 *
462 * @since 2.2.0
463 */
464 public static function get_user() {
465 if ( null === self::$user ) {
466 self::set_user();
467 }
468
469 return self::$user;
470 }
471
472 /**
473 * Returns WP User object.
474 *
475 * @param null|int|\WP_User $user - The WP user that must be used.
476 *
477 * @return \WP_User
478 *
479 * @since 2.2.0
480 */
481 public static function get_user_object( $user = null ) {
482 self::set_user( $user );
483
484 return self::$user;
485 }
486
487 /**
488 * Sets the user
489 *
490 * @param null|int|\WP_User $user - The WP user that must be used.
491 *
492 * @return void
493 *
494 * @since 2.2.0
495 */
496 public static function set_user( $user = null ) {
497 if ( null === $user || ( $user instanceof \WP_User ) ) {
498 if ( isset( self::$user ) && $user === self::$user ) {
499 return;
500 }
501 self::$user = $user;
502 } elseif ( false !== ( filter_var( $user, FILTER_VALIDATE_INT ) ) ) {
503 if ( isset( self::$user ) && $user === self::$user->ID ) {
504 return;
505 }
506 if ( ! function_exists( 'get_user_by' ) ) {
507 require ABSPATH . WPINC . '/pluggable.php';
508 }
509 self::$user = \get_user_by( 'id', $user );
510 } elseif ( is_string( $user ) ) {
511 if ( isset( self::$user ) && $user === self::$user->ID ) {
512 return;
513 }
514 if ( ! function_exists( 'get_user_by' ) ) {
515 require ABSPATH . WPINC . '/pluggable.php';
516 }
517 self::$user = \get_user_by( 'login', $user );
518 } else {
519 self::$user = wp_get_current_user();
520 }
521 }
522
523 /**
524 * Returns the default role for the given user
525 *
526 * @param null|int|\WP_User $user - The WP user.
527 *
528 * @return string
529 *
530 * @since 2.2.0
531 */
532 public static function get_user_role( $user = null ): string {
533 self::set_proper_user( $user );
534
535 $role = reset( self::$user->roles );
536
537 return (string) $role;
538 }
539
540 /**
541 * Checks if the user method is within the selected methods for the given role
542 *
543 * @param null|int|\WP_User $user - The WP user.
544 *
545 * @return boolean
546 *
547 * @since 2.2.0
548 */
549 public static function is_user_method_in_role_enabled_methods( $user = null ): bool {
550 $enabled_method = self::get_enabled_method_for_user( $user );
551 if ( empty( $enabled_method ) ) {
552 return false;
553 }
554 $is_method_available = Settings::is_provider_enabled_for_role( self::get_user_role( $user ), $enabled_method );
555
556 return $is_method_available;
557 }
558
559 /**
560 * Deletes the TOTP secret key for a user.
561 *
562 * @param null|int|\WP_User $user - The WP user that must be used.
563 *
564 * @return void
565 */
566 public static function remove_user_totp_key( $user = null ) {
567 self::set_proper_user( $user );
568
569 self::remove_meta( self::SECRET_META_KEY, self::$user );
570 }
571
572 /**
573 * Returns the TOTP secret key for a user.
574 *
575 * @param null|int|\WP_User $user - The WP user that must be used.
576 *
577 * @return string
578 */
579 public static function get_user_totp_key( $user = null ) {
580 self::set_proper_user( $user );
581
582 return self::get_meta( self::SECRET_META_KEY, self::$user );
583 }
584
585 /**
586 * Updates the TOTP secret key for a user.
587 *
588 * @param string $value - The value of the TOTP key.
589 * @param null|int|\WP_User $user - The WP user that must be used.
590 *
591 * @return void
592 *
593 * @since 2.2.0
594 */
595 public static function set_user_totp_key( string $value, $user = null ) {
596 self::set_proper_user( $user );
597
598 self::set_meta( self::SECRET_META_KEY, $value, self::$user );
599 }
600
601 /**
602 * Removes all the meta keys associated with the given user
603 *
604 * @param null|int|\WP_User $user - The WP user for which we have to remove the meta data.
605 *
606 * @return void
607 *
608 * @since 2.2.0
609 */
610 public static function remove_all_2fa_meta_for_user( $user = null ) {
611 self::set_proper_user( $user );
612
613 $user_meta_values = array_filter(
614 get_user_meta( self::$user->ID ),
615 function( $key ) {
616 return strpos( $key, WP_2FA_PREFIX ) === 0;
617 },
618 ARRAY_FILTER_USE_KEY
619 );
620
621 foreach ( array_keys( $user_meta_values ) as $meta_name ) {
622 self::remove_meta( $meta_name, $user );
623 }
624 }
625
626 /**
627 * Quick boolean check for whether a given user is using two-step.
628 *
629 * @since 2.2.0
630 *
631 * @param null|int|\WP_User $user - The WP user that must be used.
632 * @return bool
633 */
634 public static function is_user_using_two_factor( $user = null ) {
635 self::set_proper_user( $user );
636
637 return ! empty( self::get_enabled_method_for_user() );
638 }
639
640 /**
641 * Gets the user grace period from meta
642 *
643 * @param null|int|\WP_User $user - The WP user that must be used.
644 *
645 * @return mixed
646 *
647 * @since 2.2.0
648 */
649 public static function get_grace_period( $user = null ) {
650 self::set_proper_user( $user );
651
652 return self::get_meta( self::USER_GRACE_KEY, self::$user );
653 }
654
655 /**
656 * Sets the user grace period from meta
657 *
658 * @param string $value - The value of the meta key.
659 * @param null|int|\WP_User $user - The WP user that must be used.
660 *
661 * @return mixed
662 *
663 * @since 2.2.0
664 */
665 public static function set_grace_period( $value, $user = null ) {
666 self::set_proper_user( $user );
667
668 return self::set_meta( self::USER_GRACE_KEY, $value, self::$user );
669 }
670
671 /**
672 * Checks if the user is locked. It only checks a single user meta field to keep this as fast as possible. The
673 * value of the field is updated elsewhere.
674 *
675 * @param null|int|\WP_User $user - The WP user that must be used.
676 *
677 * @return bool True if the user account is locked. False otherwise.
678 *
679 * @since 2.2.0
680 */
681 public static function is_user_locked( $user = null ): bool {
682 return (bool) self::get_grace_period( $user );
683 }
684
685 /**
686 * Checks if the given user has administrator or super administrator privileges
687 *
688 * @param null|int|\WP_User $user - The WP user that must be used.
689 *
690 * @return boolean
691 *
692 * @since 2.2.0
693 */
694 public static function is_admin( $user = null ): bool {
695 self::set_proper_user( $user );
696
697 $is_admin = in_array( 'administrator', self::$user->roles, true ) || ( function_exists( 'is_super_admin' ) && is_super_admin( self::$user->ID ) );
698
699 if ( ! $is_admin ) {
700 return false;
701 }
702 return true;
703 }
704
705 /**
706 * Sets the local variable class based on the given parameter.
707 *
708 * @param null|int|\WP_User $user - The WP user we should extract the meta data for.
709 *
710 * @return void
711 *
712 * @since 2.2.0
713 */
714 private static function set_proper_user( $user = null ) {
715 if ( null !== $user ) {
716 self::set_user( $user );
717 } else {
718 self::get_user();
719 }
720 }
721 }
722 }
723