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 / Controllers / class-settings.php
wp-2fa / includes / classes / Admin / Controllers Last commit date
class-login-attempts.php 3 years ago class-methods.php 3 years ago class-settings.php 3 years ago
class-settings.php
376 lines
1 <?php
2 /**
3 * Responsible for the plugin settings iterations
4 *
5 * @package wp2fa
6 * @subpackage admin_controllers
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 namespace WP2FA\Admin\Controllers;
13
14 use WP2FA\WP2FA;
15 use WP2FA\Admin\User;
16 use \WP2FA\Admin\Settings_Page;
17 use WP2FA\Admin\Helpers\WP_Helper;
18 use WP2FA\Admin\Helpers\User_Helper;
19
20 defined( 'ABSPATH' ) || exit; // Exit if accessed directly.
21
22 /**
23 * WP2FA Settings controller
24 */
25 class Settings {
26
27 /**
28 * The link to the WP admin settings page
29 *
30 * @var string
31 */
32 private static $settings_page_link = '';
33
34 /**
35 * The name of the WP2FA WP admin setup page
36 *
37 * @var string
38 */
39 private static $setup_page_name = 'wp-2fa-setup';
40
41 /**
42 * The link to the WP admin setup page
43 *
44 * @var string
45 */
46 private static $setup_page_link = '';
47
48 /**
49 * The link to the custom settings page (if one is presented)
50 *
51 * @var string
52 */
53 private static $custom_setup_page_link = null;
54
55 /**
56 * Array with all the backup methods available
57 *
58 * @var array
59 *
60 * @since 2.0.0
61 */
62 private static $backup_methods = null;
63
64 /**
65 * All available providers for the plugin
66 * For the specific role @see get_all_providers_for_role()
67 *
68 * @var array
69 *
70 * @since 2.2.0
71 */
72 private static $all_providers = array();
73
74 /**
75 * All the available providers by user roles
76 *
77 * @var array
78 *
79 * @since 2.2.0
80 */
81 private static $all_providers_for_roles = array();
82
83 /**
84 * Returns the link to the WP admin settings page, based on the current WP install
85 *
86 * @return string
87 */
88 public static function get_settings_page_link() {
89 if ( '' === self::$settings_page_link ) {
90 if ( WP_Helper::is_multisite() ) {
91 self::$settings_page_link = add_query_arg( 'page', Settings_Page::TOP_MENU_SLUG, network_admin_url( 'admin.php' ) );
92 } else {
93 self::$settings_page_link = add_query_arg( 'page', Settings_Page::TOP_MENU_SLUG, admin_url( 'admin.php' ) );
94 }
95 }
96
97 return self::$settings_page_link;
98 }
99
100 /**
101 * Returns the link to the WP admin settings page, based on the current WP install
102 *
103 * @return string
104 */
105 public static function get_setup_page_link() {
106 if ( '' === self::$setup_page_link ) {
107 if ( WP_Helper::is_multisite() ) {
108 self::$setup_page_link = add_query_arg( 'show', self::$setup_page_name, get_admin_url( get_current_blog_id(), 'profile.php' ) );
109 } else {
110 self::$setup_page_link = add_query_arg( 'show', self::$setup_page_name, admin_url( 'profile.php' ) );
111 }
112 }
113
114 return self::$setup_page_link;
115 }
116
117 /**
118 * Extracts the custom settings page URL
119 *
120 * @param mixed $user - User for which to extract the setting, null, \WP_User or user id - @see get_role_or_default_setting method of this class.
121 *
122 * @return string
123 */
124 public static function get_custom_page_link( $user = null ): string {
125 if ( null === self::$custom_setup_page_link ) {
126 self::$custom_setup_page_link = self::get_role_or_default_setting( 'custom-user-page-id', $user );
127
128 if ( ! empty( self::$custom_setup_page_link ) ) {
129 $custom_slug = '';
130 if ( WP_Helper::is_multisite() ) {
131 switch_to_blog( get_main_site_id() );
132
133 $custom_slug = get_post_field( 'post_name', get_post( self::$custom_setup_page_link ) );
134 self::$custom_setup_page_link = trailingslashit( get_site_url() ) . $custom_slug;
135
136 restore_current_blog();
137 } else {
138 $custom_slug = get_post_field( 'post_name', get_post( self::$custom_setup_page_link ) );
139 self::$custom_setup_page_link = trailingslashit( get_site_url() ) . $custom_slug;
140 }
141 }
142 }
143
144 return self::$custom_setup_page_link;
145 }
146
147 /**
148 * Check all the roles for given setting
149 *
150 * @param string $setting_name - The name of the setting to check for.
151 *
152 * @return boolean
153 *
154 * @since 2.0.0
155 */
156 public static function check_setting_in_all_roles( string $setting_name ): bool {
157 $roles = WP_Helper::get_roles();
158
159 foreach ( $roles as $role ) {
160 if ( ! empty( WP2FA::get_wp2fa_setting( $setting_name, false, false, $role ) ) ) {
161 return true;
162 }
163 }
164
165 return false;
166 }
167
168 /**
169 * Return setting specific for the given role or default setting (based on user)
170 *
171 * @param string $setting_name - The name of the setting.
172 * @param mixed $user - \WP_User or any string or null - if string the current user will be used, if null global plugin setting will be used.
173 * @param mixed $role - The name of the role (or null).
174 * @param boolean $get_default_on_empty - Get default setting on empty setting value.
175 * @param boolean $get_default_value - Extracts default value.
176 *
177 * @return mixed
178 *
179 * @since 2.0.0
180 */
181 public static function get_role_or_default_setting( string $setting_name, $user = null, $role = null, $get_default_on_empty = false, $get_default_value = false ) {
182 /**
183 * No user specified - get the default settings
184 */
185 if ( null === $user || \WP_2FA_PREFIX . 'no-user' === $user ) {
186 return WP2FA::get_wp2fa_setting( $setting_name, $get_default_on_empty, $get_default_value );
187 }
188
189 /**
190 * There is an User - extract the role
191 */
192 if ( $user instanceof \WP_User || is_int( $user ) ) {
193 if ( null === $role ) {
194 $role = User_Helper::get_user_role( $user );
195 }
196 return WP2FA::get_wp2fa_setting( $setting_name, $get_default_on_empty, $get_default_value, $role );
197 }
198
199 /**
200 * Current user - lets extract the role
201 */
202 if ( null === $role ) {
203 /**
204 * No logged in current user, ergo no roles - fall back to defaults
205 */
206 if ( 0 === User::get_instance()->get_2fa_wp_user()->ID ) {
207 return WP2FA::get_wp2fa_setting( $setting_name, $get_default_on_empty, $get_default_value );
208 }
209
210 $role = User_Helper::get_user_role();
211 }
212
213 return WP2FA::get_wp2fa_setting( $setting_name, $get_default_on_empty, $get_default_value, $role );
214 }
215
216 /**
217 * Returns all the backup methods currently supported
218 *
219 * @return array
220 *
221 * @since 2.0.0
222 */
223 public static function get_backup_methods(): array {
224
225 if ( null === self::$backup_methods ) {
226
227 /**
228 * Gives the ability to add additional backup methods
229 *
230 * @param array The array with all the backup methods currently supported.
231 *
232 * @since 2.0.0
233 */
234 self::$backup_methods = apply_filters( WP_2FA_PREFIX . 'backup_methods_list', array() );
235 }
236
237 return self::$backup_methods;
238 }
239
240 /**
241 * Get backup methods enabled for user based on its role
242 *
243 * @param \WP_User $user - The WP user which we must check.
244 *
245 * @return array
246 *
247 * @since 2.0.0
248 */
249 public static function get_enabled_backup_methods_for_user_role( \WP_User $user ): array {
250 $backup_methods = self::get_backup_methods();
251
252 /**
253 * Extensions could change the enabled backup methods array.
254 *
255 * @param array - Backup methods array.
256 * @param \WP_User - The user to check for.
257 *
258 * @since 2.0.0
259 */
260 return apply_filters( WP_2FA_PREFIX . 'backup_methods_enabled', $backup_methods, $user );
261 }
262
263 /**
264 * Returns all enabled providers for specific role
265 *
266 * @param string $role - The name of the role to check for.
267 *
268 * @return array
269 *
270 * @throws \Exception - if the role is wrong - throws an exception.
271 *
272 * @since 2.2.0
273 */
274 public static function get_enabled_providers_for_role( string $role ) {
275
276 if ( WP_Helper::is_role_exists( $role ) ) {
277 self::get_all_roles_providers();
278
279 return self::$all_providers_for_roles[ $role ];
280 } else {
281 if ( '' === $role ) {
282 return array();
283 } else {
284 throw new \Exception( 'Role provided does not exists - "' . $role . '"' );
285 }
286 }
287 }
288
289 /**
290 * Checks if given provider is enabled for the given role.
291 *
292 * @param string $role - The name of the role.
293 * @param string $provider - The name of the provider.
294 *
295 * @return boolean
296 *
297 * @throws \Exception - If the provider is not registered in the plugin.
298 *
299 * @since 2.2.0
300 */
301 public static function is_provider_enabled_for_role( string $role, string $provider ): bool {
302 self::get_providers();
303
304 if ( in_array( $provider, self::$all_providers, true ) ) {
305 self::get_enabled_providers_for_role( $role );
306 if ( isset( self::$all_providers_for_roles[ $role ][ $provider ] ) ) {
307 return true;
308 }
309
310 return false;
311 }
312
313 throw new \Exception( 'Non existing provider ' . $provider );
314 }
315
316 /**
317 * Returns all providers by roles.
318 * If given role does not have specified settings set - falls back to the default settings.
319 *
320 * @return array
321 *
322 * @since 2.2.0
323 */
324 public static function get_all_roles_providers() {
325 if ( empty( self::$all_providers_for_roles ) ) {
326 $roles = WP_Helper::get_roles();
327 $providers = self::get_providers();
328
329 foreach ( $roles as $role ) {
330 self::$all_providers_for_roles[ $role ] = array();
331 foreach ( $providers as $provider ) {
332 if ( 'backup_codes' === $provider ) {
333 self::$all_providers_for_roles[ $role ][ $provider ] = WP2FA::get_wp2fa_setting( $provider . '_enabled', false, false, $role );
334 } elseif ( 'backup_email' === $provider ) {
335 self::$all_providers_for_roles[ $role ][ $provider ] = WP2FA::get_wp2fa_setting( 'enable-email-backup', false, false, $role );
336 } elseif ( 'oob' === $provider ) {
337 self::$all_providers_for_roles[ $role ][ $provider ] = WP2FA::get_wp2fa_setting( 'enable_' . $provider . '_email', false, false, $role );
338 } else {
339 self::$all_providers_for_roles[ $role ][ $provider ] = WP2FA::get_wp2fa_setting( 'enable_' . $provider, false, false, $role );
340 }
341 }
342 self::$all_providers_for_roles[ $role ] = array_filter( self::$all_providers_for_roles[ $role ] );
343 }
344 }
345
346 return self::$all_providers_for_roles;
347 }
348
349 /**
350 * Grab list of all register providers in the plugin.
351 *
352 * @return array
353 */
354 public static function get_providers() {
355 if ( empty( self::$all_providers ) ) {
356 self::$all_providers = array(
357 'totp',
358 'email',
359 'backup_codes',
360 );
361
362 /**
363 * Filter the supplied providers.
364 *
365 * This lets third-parties either remove providers (such as Email), or
366 * add their own providers (such as text message or Clef).
367 *
368 * @param array $provider array if available options.
369 */
370 self::$all_providers = apply_filters( WP_2FA_PREFIX . 'providers', self::$all_providers );
371 }
372
373 return self::$all_providers;
374 }
375 }
376