PluginProbe ʕ •ᴥ•ʔ
WP 2FA – Two-factor authentication for WordPress / 2.4.2
WP 2FA – Two-factor authentication for WordPress v2.4.2
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 / class-user-listing.php
wp-2fa / includes / classes / Admin Last commit date
Controllers 3 years ago Helpers 3 years ago SettingsPages 3 years ago Views 3 years ago class-help-contact-us.php 3 years ago class-premium-features.php 3 years ago class-settings-page.php 3 years ago class-settingspage.php 3 years ago class-setup-wizard.php 3 years ago class-user-listing.php 3 years ago class-user-notices.php 3 years ago class-user-profile.php 3 years ago class-user-registered.php 3 years ago class-user.php 3 years ago index.php 5 years ago
class-user-listing.php
239 lines
1 <?php
2 /**
3 * Responsible for user listing in admin manipulation.
4 *
5 * @package wp2fa
6 * @subpackage user-utils
7 * @copyright 2023 WP White Security
8 * @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
9 * @link https://wordpress.org/plugins/wp-2fa/
10 */
11
12 declare(strict_types=1);
13
14 namespace WP2FA\Admin;
15
16 use WP2FA\Utils\User_Utils;
17 use WP2FA\Admin\Helpers\User_Helper;
18 use WP2FA\Extensions\TrustedDevices\Core;
19
20 defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
21
22 /**
23 * User_Listing class with user listing filters
24 */
25 if ( ! class_exists( '\WP2FA\Admin\User_Listing' ) ) {
26
27 /**
28 * User_Listing - Shows extra column in user table wit WP2FA status forevery user
29 */
30 class User_Listing {
31
32 /**
33 * The users table column name
34 *
35 * @var string
36 */
37 private static $column_name = '2fa-status';
38
39 /**
40 * Inits all the hooks used for showing the extra user data in the users column
41 *
42 * @return void
43 */
44 public static function init() {
45 \add_filter( 'manage_users_columns', array( __CLASS__, 'add_wp_2fa_column' ) );
46 \add_filter( 'wpmu_users_columns', array( __CLASS__, 'add_wp_2fa_column' ) );
47 \add_filter( 'manage_users_custom_column', array( __CLASS__, 'show_column_data' ), 10, 3 );
48 \add_filter( 'bulk_actions-users', array( __CLASS__, 'add_bulk_action' ), 10, 1 );
49 \add_filter( 'handle_bulk_actions-users', array( __CLASS__, 'handle_bulk_actions' ), 10, 3 );
50 \add_action( 'admin_notices', array( __CLASS__, 'show_admin_notice' ) );
51 \add_filter( 'user_row_actions', array( __CLASS__, 'add_users_hover' ), 10, 2 );
52 }
53
54 /**
55 * Sets the column in the admin users table
56 *
57 * @param array $columns - Array with all the columns.
58 *
59 * @return array
60 */
61 public static function add_wp_2fa_column( array $columns ): array {
62 $columns[ self::$column_name ] = __( '2FA Status', 'wp-2fa' );
63 return $columns;
64 }
65
66 /**
67 * Shows the user WP 2FA status data in the users table
68 *
69 * @param [type] $value - The value of the column.
70 * @param string $column_name - The name of the column.
71 * @param int $user_id - the ID of the user.
72 *
73 * @return mixed
74 */
75 public static function show_column_data( $value, string $column_name, $user_id ) {
76
77 switch ( $column_name ) {
78 case self::$column_name:
79 return self::get_user2fa_status( $user_id );
80 default:
81 }
82
83 return $value;
84 }
85
86 /**
87 * Retrieves the translated 2FA status label for given user.
88 *
89 * This is performance optimized version that bypasses the User class on purpose. It loads the 2FA status meta
90 * field directly and turns it into a label.
91 *
92 * There is also some temporary code to figure out the 2FA status meta field if it doesn't exist. This will be
93 * removed in future versions and exist purely so we don't end up with no values in the column after migration
94 * to version 1.7.0 when this was introduced.
95 *
96 * @param int $user_id - The id of the user for which the info should be extracted.
97 *
98 * @return string
99 * @see WP2FA\Admin\User
100 * @since 1.7.0
101 */
102 private static function get_user2fa_status( $user_id ) {
103 // try to get the user status "id" from user's meta data.
104 $status_meta_value = User_Helper::get_2fa_status( $user_id );
105 if ( ! empty( $status_meta_value ) ) {
106 // the status id is available, grab the label to display.
107 $status_data = User_Utils::extract_statuses( array( $status_meta_value ) );
108 if ( ! empty( $status_data ) ) {
109 return $status_data['label'];
110 }
111 }
112
113 // If the user status is not saved in user meta (this can be the case prior to version 1.7.0), we figure it
114 // out and store it against the user in DB. This is not ideal in terms of performance and this is only
115 // a temporary solution.
116 // @todo remove this in future versions.
117 return User_Helper::set_user_status( new \WP_User( $user_id ) );
118 }
119
120 /**
121 * Returns the users table column name
122 *
123 * @return string
124 */
125 public static function get_column_name(): string {
126 return self::$column_name;
127 }
128
129 /**
130 * Adds bulk action to the WP users menu
131 *
132 * @param array $bulk_actions - Array of bulk actions.
133 *
134 * @return array
135 *
136 * @since 2.2.2
137 */
138 public static function add_bulk_action( $bulk_actions ) {
139 $bulk_actions['remove-2fa'] = __( 'Remove 2FA', 'wp-2fa' );
140 $bulk_actions['remove-2fa-trusted'] = __( 'Reset list of 2FA trusted devices', 'wp-2fa' );
141
142 return $bulk_actions;
143 }
144
145 /**
146 * Removes the 2fa from the list of the selected users.
147 *
148 * @param string $redirect_url - The redirect URL to redirect to when action is performed.
149 * @param string $action - The action to perform.
150 * @param array $user_ids - The user IDs to remove from.
151 *
152 * @return string
153 *
154 * @since 2.2.2
155 */
156 public static function handle_bulk_actions( $redirect_url, $action, $user_ids ) {
157 if ( 'remove-2fa' === $action ) {
158 if ( is_array( $user_ids ) ) {
159 foreach ( $user_ids as $user_id ) {
160 User_Helper::remove_2fa_for_user(
161 $user_id
162 );
163 }
164 $num_of_ids = count( $user_ids );
165 } else {
166 User_Helper::remove_2fa_for_user(
167 $user_ids
168 );
169 $num_of_ids = 1;
170 }
171 $redirect_url = add_query_arg( '2fa-removed', $num_of_ids, $redirect_url );
172 }
173
174 if ( class_exists( '\WP2FA\Extensions\TrustedDevices\Core' ) && 'remove-2fa-trusted' === $action ) {
175 if ( is_array( $user_ids ) ) {
176 Core::remove_trusted_devices_for_users(
177 $user_ids
178 );
179 $num_of_ids = count( $user_ids );
180 } else {
181 Core::remove_trusted_devices_for_users(
182 array( $user_ids )
183 );
184 $num_of_ids = 1;
185 }
186 $redirect_url = add_query_arg( '2fa-trusted-removed', $num_of_ids, $redirect_url );
187 }
188 return $redirect_url;
189 }
190
191 /**
192 * Adds links to the on hover state of the users table row
193 *
194 * @param array $actions - Array with all the actions for the current row.
195 * @param \WP_User $user_object - The user object from the current row.
196 *
197 * @return array
198 *
199 * @since 2.4.0
200 */
201 public static function add_users_hover( $actions, $user_object ): array {
202 if ( class_exists( '\WP2FA\Extensions\TrustedDevices\Core' ) ) {
203 $actions['remove-2fa-trusted'] = "<a class='resetpassword' href='" . \wp_nonce_url( "users.php?action=remove-2fa-trusted&amp;users=$user_object->ID", 'bulk-users' ) . "'>" . __( 'Reset list of 2FA trusted devices', 'wp-2fa' ) . '</a>';
204 }
205 return $actions;
206 }
207
208 /**
209 * Handles the Admin notice for the users removed 2FA.
210 *
211 * @return void
212 *
213 * @since 2.2.2
214 */
215 public static function show_admin_notice() {
216 if ( ! empty( $_REQUEST['2fa-removed'] ) ) {
217 $num_changed = (int) $_REQUEST['2fa-removed'];
218 printf(
219 '<div id="message" class="updated notice is-dismissable"><p>' .
220 // translators: The number of the affected users.
221 esc_html__( 'Removed 2FA from %d users.', 'wp-2fa' ) .
222 '</p></div>',
223 (int) $num_changed
224 );
225 }
226 if ( ! empty( $_REQUEST['2fa-trusted-removed'] ) ) {
227 $num_changed = (int) $_REQUEST['2fa-trusted-removed'];
228 printf(
229 '<div id="message" class="updated notice is-dismissable"><p>' .
230 // translators: The number of the affected users.
231 esc_html__( 'Removed 2FA trusted devices from %d users.', 'wp-2fa' ) .
232 '</p></div>',
233 (int) $num_changed
234 );
235 }
236 }
237 }
238 }
239