44use function Automattic \VIP \Security \Utils \get_module_configs ;
55
66class Highlight_MFA_Users {
7- const MFA_SKIP_USER_IDS_OPTION_KEY = 'vip_security_mfa_skip_user_ids ' ;
8- const ROLE_COLUMN_KEY = 'role ' ;
7+ const MFA_SKIP_USER_IDS_OPTION_KEY = 'vip_security_mfa_skip_user_ids ' ;
8+ const ROLE_COLUMN_KEY = 'role ' ;
9+ const DEFAULT_ADMIN_EDITOR_ROLE_SLUGS = [ 'administrator ' , 'editor ' ];
910
1011 /**
1112 * The roles used to highlight users without MFA.
@@ -17,15 +18,15 @@ class Highlight_MFA_Users {
1718 public static function init () {
1819 // Feature is always active unless specific users are skipped via option.
1920 $ highlight_mfa_configs = get_module_configs ( 'highlight-mfa-users ' );
20- self ::$ roles = $ highlight_mfa_configs ['roles ' ] ?? [ ' administrator ' , ' editor ' ] ; // Default to administrator and editor if not configured
21+ self ::$ roles = $ highlight_mfa_configs ['roles ' ] ?? self :: DEFAULT_ADMIN_EDITOR_ROLE_SLUGS ; // Default to administrator and editor if not configured
2122
2223 if ( ! is_array ( self ::$ roles ) ) {
2324 self ::$ roles = [ self ::$ roles ];
2425 }
2526 self ::$ roles = array_filter ( self ::$ roles );
2627 // If after filtering, the array is empty, default back to administrator and editor
2728 if ( empty ( self ::$ roles ) ) {
28- self ::$ roles = [ ' administrator ' , ' editor ' ] ;
29+ self ::$ roles = self :: DEFAULT_ADMIN_EDITOR_ROLE_SLUGS ;
2930 }
3031
3132 add_action ( 'admin_notices ' , [ __CLASS__ , 'display_mfa_disabled_notice ' ] );
@@ -66,6 +67,14 @@ public static function display_mfa_disabled_notice() {
6667 return ;
6768 }
6869
70+ // Determine notice text based on role configuration
71+ // self::$roles is already an array and populated from init().
72+ $ configured_roles_for_comparison = self ::$ roles ;
73+ \sort ( $ configured_roles_for_comparison ); // Use global sort
74+
75+ // unordered array check with ==
76+ $ is_default_config = ( self ::DEFAULT_ADMIN_EDITOR_ROLE_SLUGS === $ configured_roles_for_comparison || empty ( $ configured_roles_for_comparison ) );
77+
6978 $ skipped_user_ids = get_option ( self ::MFA_SKIP_USER_IDS_OPTION_KEY , [] );
7079 if ( ! is_array ( $ skipped_user_ids ) ) {
7180 $ skipped_user_ids = [];
@@ -100,45 +109,104 @@ public static function display_mfa_disabled_notice() {
100109 $ is_filtered = isset ( $ _GET ['filter_mfa_disabled ' ] ) && '1 ' === $ _GET ['filter_mfa_disabled ' ];
101110
102111 if ( $ is_filtered ) {
103- // Display notice for when the list IS filtered
104- $ show_all_url = remove_query_arg ( 'filter_mfa_disabled ' , admin_url ( 'users.php ' ) );
112+ // Display info notice for when the list IS filtered
113+ $ show_all_url = remove_query_arg ( 'filter_mfa_disabled ' , admin_url ( 'users.php ' ) );
114+ $ notice_message_text = self ::get_missing_mfa_notice_message_text ( $ mfa_disabled_count , $ is_default_config );
115+
105116 printf (
106117 '<div class="notice notice-info"><p>%s <a href="%s">%s</a></p></div> ' ,
107- esc_html ( sprintf (
108- /* Translators: %d is the number of users without 2FA enabled being shown in the filtered list. */
109- _n (
110- 'Showing %d user without Two-Factor Authentication enabled. ' ,
111- 'Showing %d users without Two-Factor Authentication enabled. ' ,
112- $ mfa_disabled_count ,
113- 'wpvip '
114- ),
115- number_format_i18n ( $ mfa_disabled_count )
116- ) ),
118+ esc_html ( $ notice_message_text ),
117119 esc_url ( $ show_all_url ),
118120 esc_html__ ( 'Show all users. ' , 'wpvip ' )
119121 );
120122 } else {
121123 // Display the original notice when the list is NOT filtered
122- $ filter_url = add_query_arg ( 'filter_mfa_disabled ' , '1 ' , admin_url ( 'users.php ' ) );
124+ $ filter_url = add_query_arg ( 'filter_mfa_disabled ' , '1 ' , admin_url ( 'users.php ' ) );
125+ $ notice_message_text = self ::get_filtering_mfa_info_message_text ( $ mfa_disabled_count , $ is_default_config );
126+
123127 printf (
124128 '<div class="notice notice-error"><p>%s <a href="%s">%s</a></p></div> ' ,
125- esc_html ( sprintf (
126- /* Translators: %d is the number of users without 2FA enabled. */
127- _n (
128- 'There is %d user with Two-Factor Authentication disabled. ' ,
129- 'There are %d users with Two-Factor Authentication disabled. ' ,
130- $ mfa_disabled_count ,
131- 'wpvip '
132- ),
133- number_format_i18n ( $ mfa_disabled_count )
134- ) ),
129+ esc_html ( $ notice_message_text ),
135130 esc_url ( $ filter_url ),
136131 esc_html__ ( 'Filter list to show these users. ' , 'wpvip ' )
137132 );
138133 }
139134 }
140135 }
141136
137+ /**
138+ * Get the notice message text for when users with missing MFA are shown.
139+ *
140+ * @param int $mfa_disabled_count The number of users with missing MFA.
141+ * @param bool $is_default_config Whether the default roles are being used.
142+ * @return string The notice message text.
143+ */
144+ protected static function get_missing_mfa_notice_message_text ( $ mfa_disabled_count , $ is_default_config ) {
145+ $ notice_message_text = '' ;
146+ if ( $ is_default_config ) {
147+ // Default roles: Administrator, Editor
148+ $ notice_message_text = sprintf (
149+ /* Translators: %d is the number of users with Administrator or Editor roles without 2FA enabled being shown. */
150+ _n (
151+ 'Showing %d user with Administrator or Editor roles without Two-Factor Authentication enabled. ' ,
152+ 'Showing %d users with Administrator or Editor roles without Two-Factor Authentication enabled. ' ,
153+ $ mfa_disabled_count ,
154+ 'wpvip '
155+ ),
156+ number_format_i18n ( $ mfa_disabled_count )
157+ );
158+ } else {
159+ // Custom roles
160+ $ notice_message_text = sprintf (
161+ /* Translators: %d is the number of users with high-privileges without 2FA enabled being shown. */
162+ _n (
163+ 'Showing %d user with high-privileges without Two-Factor Authentication enabled. ' ,
164+ 'Showing %d users with high-privileges without Two-Factor Authentication enabled. ' ,
165+ $ mfa_disabled_count ,
166+ 'wpvip '
167+ ),
168+ number_format_i18n ( $ mfa_disabled_count )
169+ );
170+ }
171+
172+ return $ notice_message_text ;
173+ }
174+
175+ /**
176+ * Get the notice message text for when users with missing MFA are filtered.
177+ *
178+ * @param int $mfa_disabled_count The number of users with missing MFA.
179+ * @param bool $is_default_config Whether the default roles are being used.
180+ * @return string The notice message text.
181+ */
182+ protected static function get_filtering_mfa_info_message_text ( $ mfa_disabled_count , $ is_default_config ) {
183+ $ notice_message_text = '' ;
184+ if ( $ is_default_config ) {
185+ $ notice_message_text = sprintf (
186+ /* Translators: %d is the number of users with Administrator or Editor roles and 2FA disabled. */
187+ _n (
188+ 'There is %d user with Administrator or Editor roles with Two-Factor Authentication disabled. ' ,
189+ 'There are %d users with Administrator or Editor roles with Two-Factor Authentication disabled. ' ,
190+ $ mfa_disabled_count ,
191+ 'wpvip '
192+ ),
193+ number_format_i18n ( $ mfa_disabled_count )
194+ );
195+ } else {
196+ $ notice_message_text = sprintf (
197+ /* Translators: %d is the number of high-privilege users with 2FA disabled. */
198+ _n (
199+ 'There is %d user with high-privileges with Two-Factor Authentication disabled. ' ,
200+ 'There are %d users with high-privileges with Two-Factor Authentication disabled. ' ,
201+ $ mfa_disabled_count ,
202+ 'wpvip '
203+ ),
204+ number_format_i18n ( $ mfa_disabled_count )
205+ );
206+ }
207+ return $ notice_message_text ;
208+ }
209+
142210 /**
143211 * Modify the user query on the Users page to filter by MFA status if requested.
144212 * @param \WP_User_Query $query The WP_User_Query instance (passed by reference).
0 commit comments