PluginProbe
Authorizer / 3.6.0
Authorizer v3.6.0
3.15.3 3.15.2 3.15.1 3.15.0 3.14.3 3.14.4 3.14.2 3.14.1 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.9.0 2.9.1 2.9.10 2.9.11 2.9.12 2.9.13 2.9.2 2.9.3 2.9.6 All 126 releases
authorizer / src / authorizer / class-sync-userdata.php

class-sync-userdata.php in Authorizer 3.6.0, at src/authorizer/class-sync-userdata.php

746 lines 29.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Authorizer
4 *
5 * @license GPL-2.0+
6 * @link https://github.com/uhm-coe/authorizer
7 * @package authorizer
8 */
9
10 namespace Authorizer;
11
12 use Authorizer\Helper;
13 use Authorizer\Options;
14 use Authorizer\Authorization;
15
16 /**
17 * Contains functions for interfacing with WordPress users and syncing between
18 * them and users in the Authorizer lists.
19 */
20 class Sync_Userdata extends Singleton {
21
22 /**
23 * Adds all WordPress users in the current site to the approved list,
24 * unless they are already in the blocked list. Also removes them
25 * from the pending list if they are there.
26 *
27 * Runs in plugin activation hook.
28 *
29 * @return void
30 */
31 public function add_wp_users_to_approved_list() {
32 $options = Options::get_instance();
33 // Add current WordPress users to the approved list.
34 $auth_multisite_settings_access_users_approved = is_multisite() ? get_blog_option( get_network()->blog_id, 'auth_multisite_settings_access_users_approved', array() ) : array();
35 $auth_settings_access_users_pending = $options->get( 'access_users_pending', Helper::SINGLE_CONTEXT );
36 $auth_settings_access_users_approved = $options->get( 'access_users_approved', Helper::SINGLE_CONTEXT );
37 $auth_settings_access_users_blocked = $options->get( 'access_users_blocked', Helper::SINGLE_CONTEXT );
38 $updated = false;
39 foreach ( get_users() as $user ) {
40 // Skip if user is in blocked list.
41 if ( Helper::in_multi_array( $user->user_email, $auth_settings_access_users_blocked ) ) {
42 continue;
43 }
44 // Remove from pending list if there.
45 foreach ( $auth_settings_access_users_pending as $key => $pending_user ) {
46 if ( 0 === strcasecmp( $pending_user['email'], $user->user_email ) ) {
47 unset( $auth_settings_access_users_pending[ $key ] );
48 $updated = true;
49 }
50 }
51 // Skip if user is in multisite approved list.
52 if ( Helper::in_multi_array( $user->user_email, $auth_multisite_settings_access_users_approved ) ) {
53 continue;
54 }
55 // Add to approved list if not there.
56 if ( ! Helper::in_multi_array( $user->user_email, $auth_settings_access_users_approved ) ) {
57 $approved_user = array(
58 'email' => Helper::lowercase( $user->user_email ),
59 'role' => count( $user->roles ) > 0 ? $user->roles[0] : '',
60 'date_added' => wp_date( 'M Y', strtotime( $user->user_registered ) ),
61 'local_user' => true,
62 );
63 array_push( $auth_settings_access_users_approved, $approved_user );
64 $updated = true;
65 }
66 }
67 if ( $updated ) {
68 update_option( 'auth_settings_access_users_pending', $auth_settings_access_users_pending );
69 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
70 }
71 }
72
73
74 /**
75 * On an admin page load, check for edge case (network-approved user who has
76 * not yet been added to this particular blog in a multisite). Note: we do
77 * this because check_user_access() runs on the parse_request hook, which
78 * does not fire on wp-admin pages.
79 *
80 * Action: init
81 *
82 * @return void
83 */
84 public function init__maybe_add_network_approved_user() {
85 global $current_user;
86 $options = Options::get_instance();
87
88 // If this is a multisite install and we have a logged in user that's not
89 // a member of this blog, but is (network) approved, add them to this blog.
90 if (
91 is_admin() &&
92 is_multisite() &&
93 is_user_logged_in() &&
94 ! is_user_member_of_blog() &&
95 Authorization::get_instance()->is_email_in_list( $current_user->user_email, 'approved' )
96 ) {
97 // Get all approved users.
98 $auth_settings_access_users_approved = $options->sanitize_user_list(
99 array_merge(
100 $options->get( 'access_users_approved', Helper::SINGLE_CONTEXT ),
101 $options->get( 'access_users_approved', Helper::NETWORK_CONTEXT )
102 )
103 );
104
105 // Get user info (we need user role).
106 $user_info = Helper::get_user_info_from_list(
107 $current_user->user_email,
108 $auth_settings_access_users_approved
109 );
110
111 // Add user to blog.
112 add_user_to_blog( get_current_blog_id(), $current_user->ID, $user_info['role'] );
113
114 // Refresh user permissions.
115 $current_user = new \WP_User( $current_user->ID ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
116 }
117 }
118
119
120 /**
121 * Send a welcome email message to a newly approved user (if the "Should
122 * email approved users" setting is enabled).
123 *
124 * @param string $email Email address to send welcome email to.
125 * @return bool Whether the email was sent.
126 */
127 public function maybe_email_welcome_message( $email ) {
128 // Get option for whether to email welcome messages.
129 $options = Options::get_instance();
130 $should_email_new_approved_users = $options->get( 'access_should_email_approved_users' );
131
132 // Do not send welcome email if option not enabled.
133 if ( '1' !== $should_email_new_approved_users ) {
134 return false;
135 }
136
137 // Make sure we didn't just email this user (can happen with
138 // multiple admins saving at the same time, or by clicking
139 // Approve button too rapidly).
140 $recently_sent_emails = get_option( 'auth_settings_recently_sent_emails' );
141 if ( false === $recently_sent_emails ) {
142 $recently_sent_emails = array();
143 }
144 foreach ( $recently_sent_emails as $key => $recently_sent_email ) {
145 if ( $recently_sent_email['time'] < strtotime( 'now -1 minutes' ) ) {
146 // Remove emails sent more than 1 minute ago.
147 unset( $recently_sent_emails[ $key ] );
148 } elseif ( $recently_sent_email['email'] === $email ) {
149 // Sent an email to this user within the last 1 minute, so
150 // quit without sending.
151 return false;
152 }
153 }
154 // Add the email we're about to send to the list.
155 $recently_sent_emails[] = array(
156 'email' => $email,
157 'time' => time(),
158 );
159 update_option( 'auth_settings_recently_sent_emails', $recently_sent_emails );
160
161 // Get welcome email subject and body text.
162 $subject = $options->get( 'access_email_approved_users_subject' );
163 $body = apply_filters( 'the_content', $options->get( 'access_email_approved_users_body' ) );
164
165 // Fail if the subject/body options don't exist or are empty.
166 if ( is_null( $subject ) || is_null( $body ) || strlen( $subject ) === 0 || strlen( $body ) === 0 ) {
167 return false;
168 }
169
170 // Replace approved shortcode patterns in subject and body.
171 $site_name = get_bloginfo( 'name' );
172 $site_url = get_site_url();
173 $subject = str_replace( '[site_name]', $site_name, $subject );
174 $body = str_replace( '[site_name]', $site_name, $body );
175 $body = str_replace( '[site_url]', $site_url, $body );
176 $body = str_replace( '[user_email]', $email, $body );
177 $headers = 'Content-type: text/html' . "\r\n";
178
179 // Send email.
180 wp_mail( $email, $subject, $body, $headers );
181
182 // Indicate mail was sent.
183 return true;
184 }
185
186
187 /**
188 * When they successfully log in, make sure WordPress users are in the approved list.
189 *
190 * Action: wp_login
191 *
192 * @param string $user_login Username of the user logging in.
193 * @param object $user WP_User object of the user logging in.
194 * @return void
195 */
196 public function ensure_wordpress_user_in_approved_list_on_login( $user_login, $user ) {
197 $this->add_user_to_authorizer_when_created( $user->user_email, $user->user_registered, $user->roles );
198 }
199
200
201 /**
202 * Keep authorizer approved users' roles in sync with WordPress roles
203 * if someone changes the role via the WordPress Edit User page
204 * (wp-admin/user-edit.php or wp-admin/profile.php).
205 *
206 * Action: user_profile_update_errors
207 *
208 * @param WP_Error $errors Errors object to add any custom errors to (passed by reference).
209 * @param bool $update True if updating existing user, false if saving a new one.
210 * @param stdClass $user Updated WP_User object for user being edited (passed by reference).
211 */
212 public function edit_user_profile_update_role( &$errors, $update, &$user ) {
213 // Do nothing if we're not updating role.
214 if ( ! property_exists( $user, 'role' ) || ! property_exists( $user, 'ID' ) ) {
215 return;
216 }
217
218 // Safety check; will likely not fire if we reach this function.
219 if ( ! current_user_can( 'edit_user', $user->ID ) ) {
220 return;
221 }
222
223 // Don't perform Authorizer updates if we have a WordPress error.
224 $errors_on_user_update = $errors->get_error_codes();
225 if ( ! empty( $errors_on_user_update ) ) {
226 return;
227 }
228
229 // Get original user object (fail if not a real WordPress user).
230 $userdata = get_userdata( $user->ID );
231 if ( ! $userdata ) {
232 return;
233 }
234
235 // If user is in approved list, update his/her associated role.
236 if ( Authorization::get_instance()->is_email_in_list( $userdata->user_email, 'approved' ) ) {
237 $options = Options::get_instance();
238 $auth_settings_access_users_approved = $options->sanitize_user_list( $options->get( 'access_users_approved', Helper::SINGLE_CONTEXT ) );
239 foreach ( $auth_settings_access_users_approved as $key => $check_user ) {
240 if ( 0 === strcasecmp( $check_user['email'], $userdata->user_email ) ) {
241 $auth_settings_access_users_approved[ $key ]['role'] = $user->role;
242 }
243 }
244 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
245 }
246 }
247
248 /**
249 * Update user role in approved list if it's changed via bulk action on the
250 * WordPress list users page.
251 *
252 * @hook set_user_role
253 *
254 * @param integer $user_id The user ID.
255 * @param string $role The new role.
256 * @param array $old_roles An array of the user's previous roles.
257 */
258 public function set_user_role_sync_role( $user_id = 0, $role = '', $old_roles = array() ) {
259 // Ensure valid user ID and user has permission to edit this user.
260 if ( empty( $user_id ) || ! current_user_can( 'edit_user', $user_id ) ) {
261 return;
262 }
263
264 // Get original user object (fail if not a real WordPress user).
265 $userdata = get_userdata( $user_id );
266 if ( ! $userdata ) {
267 return;
268 }
269
270 // If user is in approved list, update his/her associated role.
271 if ( Authorization::get_instance()->is_email_in_list( $userdata->user_email, 'approved' ) ) {
272 $changed = false;
273 $options = Options::get_instance();
274 $auth_settings_access_users_approved = $options->sanitize_user_list( $options->get( 'access_users_approved', Helper::SINGLE_CONTEXT ) );
275 foreach ( $auth_settings_access_users_approved as $key => $check_user ) {
276 if ( 0 === strcasecmp( $check_user['email'], $userdata->user_email ) ) {
277 if ( empty( $role ) ) {
278 unset( $auth_settings_access_users_approved[ $key ] );
279 $changed = true;
280 } elseif ( $auth_settings_access_users_approved[ $key ]['role'] !== $role ) {
281 $auth_settings_access_users_approved[ $key ]['role'] = $role;
282 $changed = true;
283 }
284 }
285 }
286 if ( $changed ) {
287 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
288 }
289 }
290 }
291
292
293 /**
294 * Sync any email address changes to WordPress accounts to the corresponding
295 * entry in the Authorizer approved list.
296 *
297 * Note: This filter fires in wp_update_user() if the update includes an
298 * email address change, and fires after all security and integrity checks
299 * have been performed, so we can simply update the Authorizer approved
300 * list, changing the email address on the approved entry, and removing any
301 * existing entries that also have the new email address (duplicates).
302 *
303 * Filter: send_email_change_email
304 *
305 * @param bool $send Whether to send the email.
306 * @param array $user The original user array.
307 * @param array $userdata The updated user array.
308 */
309 public function edit_user_profile_update_email( $send, $user, $userdata ) {
310 $options = Options::get_instance();
311
312 // If we're in multisite, update the email on all sites in the network
313 // (and remove from any subsites if it's a network-approved user).
314 if ( is_multisite() ) {
315 // If it's a multisite approved user, sync the email there.
316 $changed_user_is_multisite_user = false;
317 if ( Authorization::get_instance()->is_email_in_list( $user['user_email'], 'approved', 'multisite' ) ) {
318 $changed_user_is_multisite_user = true;
319 $auth_multisite_settings_access_users_approved = $options->sanitize_user_list(
320 $options->get( 'access_users_approved', Helper::NETWORK_CONTEXT )
321 );
322 foreach ( $auth_multisite_settings_access_users_approved as $key => $check_user ) {
323 // Update old user email in approved list to the new email.
324 if ( 0 === strcasecmp( $check_user['email'], $user['user_email'] ) ) {
325 $auth_multisite_settings_access_users_approved[ $key ]['email'] = Helper::lowercase( $userdata['user_email'] );
326 }
327 // If new user email is already in approved list, remove that entry.
328 if ( 0 === strcasecmp( $check_user['email'], $userdata['user_email'] ) ) {
329 unset( $auth_multisite_settings_access_users_approved[ $key ] );
330 }
331 }
332 update_blog_option( get_network()->blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
333 }
334
335 // Go through all approved lists on individual sites and sync this user there.
336 // phpcs:ignore WordPress.WP.DeprecatedFunctions.wp_get_sitesFound
337 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
338 foreach ( $sites as $site ) {
339 $updated = false;
340 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
341 $auth_settings_access_users_approved = get_blog_option( $blog_id, 'auth_settings_access_users_approved', array() );
342 foreach ( $auth_settings_access_users_approved as $key => $check_user ) {
343 // Update old user email in approved list to the new email.
344 if ( 0 === strcasecmp( $check_user['email'], $user['user_email'] ) ) {
345 // But if the user is already a multisite user, just remove the entry in the subsite.
346 if ( $changed_user_is_multisite_user ) {
347 unset( $auth_settings_access_users_approved[ $key ] );
348 } else {
349 $auth_settings_access_users_approved[ $key ]['email'] = Helper::lowercase( $userdata['user_email'] );
350 }
351 $updated = true;
352 }
353 // If new user email is already in approved list, remove that entry.
354 if ( 0 === strcasecmp( $check_user['email'], $userdata['user_email'] ) ) {
355 unset( $auth_settings_access_users_approved[ $key ] );
356 $updated = true;
357 }
358 }
359 if ( $updated ) {
360 update_blog_option( $blog_id, 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
361 }
362 }
363 } else {
364 // In a single site environment, just find the old user in the approved list and update the email.
365 if ( Authorization::get_instance()->is_email_in_list( $user['user_email'], 'approved' ) ) {
366 $auth_settings_access_users_approved = $options->sanitize_user_list( $options->get( 'access_users_approved', Helper::SINGLE_CONTEXT ) );
367 foreach ( $auth_settings_access_users_approved as $key => $check_user ) {
368 // Update old user email in approved list to the new email.
369 if ( 0 === strcasecmp( $check_user['email'], $user['user_email'] ) ) {
370 $auth_settings_access_users_approved[ $key ]['email'] = Helper::lowercase( $userdata['user_email'] );
371 }
372 // If new user email is already in approved list, remove that entry.
373 if ( 0 === strcasecmp( $check_user['email'], $userdata['user_email'] ) ) {
374 unset( $auth_settings_access_users_approved[ $key ] );
375 }
376 }
377 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
378 }
379 }
380
381 // We're hooking into this filter merely for its location in the codebase,
382 // so make sure to return the filter value unmodified.
383 return $send;
384 }
385
386
387 /**
388 * Remove user from authorizer lists when that user is deleted in WordPress.
389 *
390 * Action: delete_user
391 *
392 * @param int $user_id User ID to remove.
393 * @return void
394 */
395 public function remove_user_from_authorizer_when_deleted( $user_id ) {
396 $options = Options::get_instance();
397 $user = get_user_by( 'id', $user_id );
398 $deleted_email = $user->user_email;
399
400 // Remove user from pending/approved lists and save.
401 $list_names = array( 'access_users_pending', 'access_users_approved' );
402 foreach ( $list_names as $list_name ) {
403 $user_list = $options->sanitize_user_list( $options->get( $list_name, Helper::SINGLE_CONTEXT ) );
404 $list_changed = false;
405 foreach ( $user_list as $key => $existing_user ) {
406 if ( 0 === strcasecmp( $deleted_email, $existing_user['email'] ) ) {
407 $list_changed = true;
408 unset( $user_list[ $key ] );
409 }
410 }
411 if ( $list_changed ) {
412 update_option( 'auth_settings_' . $list_name, $user_list );
413 }
414 }
415 }
416
417
418 /**
419 * Remove multisite user from authorizer lists when that user is deleted from Network Users.
420 *
421 * Action: wpmu_delete_user
422 *
423 * @param int $user_id User ID to remove.
424 * @return void
425 */
426 public function remove_network_user_from_authorizer_when_deleted( $user_id ) {
427 $options = Options::get_instance();
428 $user = get_user_by( 'id', $user_id );
429 $deleted_email = $user->user_email;
430
431 // Go through multisite approved user list and remove this user.
432 $auth_multisite_settings_access_users_approved = $options->sanitize_user_list(
433 $options->get( 'access_users_approved', Helper::NETWORK_CONTEXT )
434 );
435 $list_changed = false;
436 foreach ( $auth_multisite_settings_access_users_approved as $key => $existing_user ) {
437 if ( 0 === strcasecmp( $deleted_email, $existing_user['email'] ) ) {
438 $list_changed = true;
439 unset( $auth_multisite_settings_access_users_approved[ $key ] );
440 }
441 }
442 if ( $list_changed ) {
443 update_blog_option( get_network()->blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
444 }
445
446 // Go through all pending/approved lists on individual sites and remove this user from them.
447 // phpcs:ignore WordPress.WP.DeprecatedFunctions.wp_get_sitesFound
448 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
449 foreach ( $sites as $site ) {
450 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
451 $this->remove_network_user_from_site_when_removed( $user_id, $blog_id );
452 }
453
454 }
455
456
457 /**
458 * Remove multisite user from a specific site's lists when that user is removed from the site.
459 *
460 * Action: remove_user_from_blog
461 *
462 * @param int $user_id User ID to remove.
463 * @param int $blog_id Blog ID to remove from.
464 * @return void
465 */
466 public function remove_network_user_from_site_when_removed( $user_id, $blog_id ) {
467 $user = get_user_by( 'id', $user_id );
468 $deleted_email = $user->user_email;
469
470 $list_names = array( 'access_users_pending', 'access_users_approved' );
471 foreach ( $list_names as $list_name ) {
472 $user_list = get_blog_option( $blog_id, 'auth_settings_' . $list_name, array() );
473 $list_changed = false;
474 foreach ( $user_list as $key => $existing_user ) {
475 if ( 0 === strcasecmp( $deleted_email, $existing_user['email'] ) ) {
476 $list_changed = true;
477 unset( $user_list[ $key ] );
478 }
479 }
480 if ( $list_changed ) {
481 update_blog_option( $blog_id, 'auth_settings_' . $list_name, $user_list );
482 }
483 }
484 }
485
486
487 /**
488 * Helper: Add multisite user to a specific site's approved list.
489 *
490 * @param int $user_id User ID to add.
491 * @param int $blog_id Blog ID to add to.
492 * @return void
493 */
494 protected function add_network_user_to_site( $user_id, $blog_id ) {
495 // Switch to blog.
496 switch_to_blog( $blog_id );
497
498 // Get user details and role.
499 $options = Options::get_instance();
500 $access_default_role = $options->get( 'access_default_role', Helper::SINGLE_CONTEXT, 'allow override' );
501 $user = get_user_by( 'id', $user_id );
502 $user_email = $user->user_email;
503 $user_role = $user && is_array( $user->roles ) && count( $user->roles ) > 0 ? $user->roles[0] : $access_default_role;
504
505 // Add user to approved list if not already there and not in blocked list.
506 $auth_settings_access_users_approved = $options->get( 'access_users_approved', Helper::SINGLE_CONTEXT );
507 $auth_settings_access_users_blocked = $options->get( 'access_users_blocked', Helper::SINGLE_CONTEXT );
508 if ( ! Helper::in_multi_array( $user_email, $auth_settings_access_users_approved ) && ! Helper::in_multi_array( $user_email, $auth_settings_access_users_blocked ) ) {
509 $approved_user = array(
510 'email' => Helper::lowercase( $user_email ),
511 'role' => $user_role,
512 'date_added' => wp_date( 'M Y', strtotime( $user->user_registered ) ),
513 'local_user' => true,
514 );
515 array_push( $auth_settings_access_users_approved, $approved_user );
516 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
517 }
518
519 // Restore original blog.
520 restore_current_blog();
521 }
522
523
524 /**
525 * Multisite:
526 * When an existing user is invited to the current site (or a new user is created),
527 * add them to the authorizer approved list. This action fires when the admin
528 * doesn't select the "Skip Confirmation Email" option.
529 *
530 * Action: invite_user
531 *
532 * @param int $user_id The invited user's ID.
533 * @param array $role The role of the invited user (or none if a new user creation).
534 * @param string $newuser_key The key of the invitation.
535 */
536 public function add_existing_user_to_authorizer_when_created( $user_id, $role = array(), $newuser_key = '' ) {
537 $user = get_user_by( 'id', $user_id );
538 $this->add_user_to_authorizer_when_created( $user->user_email, $user->user_registered, $user->roles, $role );
539 }
540
541
542 /**
543 * Multisite:
544 * When an existing user is invited to the current site (or a new user is created),
545 * add them to the authorizer approved list. This action fires when the admin
546 * selects the "Skip Confirmation Email" option.
547 *
548 * Action: added_existing_user
549 *
550 * @param int $user_id The invited user's ID.
551 * @param mixed $result True on success or a WP_Error object if the user doesn't exist.
552 */
553 public function add_existing_user_to_authorizer_when_created_noconfirmation( $user_id, $result ) {
554 $user = get_user_by( 'id', $user_id );
555 $this->add_user_to_authorizer_when_created( $user->user_email, $user->user_registered, $user->roles );
556 }
557
558
559 /**
560 * Multisite:
561 * When a new user is invited to the current site (or a new user is created),
562 * add them to the authorizer approved list.
563 *
564 * Action: after_signup_user
565 *
566 * @param string $user User's requested login name.
567 * @param string $user_email User's email address.
568 * @param string $key User's activation key.
569 * @param array $meta Additional signup meta, including initially set roles.
570 */
571 public function add_new_user_to_authorizer_when_created( $user, $user_email, $key, $meta ) {
572 $user_roles = isset( $meta['new_role'] ) ? array( $meta['new_role'] ) : array();
573 $this->add_user_to_authorizer_when_created( $user_email, time(), $user_roles );
574 }
575
576
577 /**
578 * Single site:
579 * When a new user is added in single site mode, add them to the authorizer
580 * approved list.
581 *
582 * Action: edit_user_created_user
583 *
584 * @param int $user_id ID of the newly created user.
585 * @param string $notify Type of notification that should happen. See
586 * wp_send_new_user_notifications() for more
587 * information on possible values.
588 */
589 public function add_new_user_to_authorizer_when_created_single_site( $user_id, $notify ) {
590 $user = get_user_by( 'id', $user_id );
591 $this->add_user_to_authorizer_when_created( $user->user_email, $user->user_registered, $user->roles );
592 }
593
594
595 /**
596 * Helper: When a new user is added/invited to the current site (or a new
597 * user is created), add them to the authorizer approved list.
598 *
599 * @param string $user_email Email address of user to add.
600 * @param string $date_registered Date user registered.
601 * @param array $user_roles Role to add for user.
602 * @param array $default_role Default role, if no role specified.
603 */
604 protected function add_user_to_authorizer_when_created( $user_email, $date_registered, $user_roles = array(), $default_role = array() ) {
605 $options = Options::get_instance();
606 $auth_multisite_settings_access_users_approved = is_multisite() ? get_blog_option( get_network()->blog_id, 'auth_multisite_settings_access_users_approved', array() ) : array();
607 $auth_settings_access_users_pending = $options->get( 'access_users_pending', Helper::SINGLE_CONTEXT );
608 $auth_settings_access_users_approved = $options->get( 'access_users_approved', Helper::SINGLE_CONTEXT );
609 $auth_settings_access_users_blocked = $options->get( 'access_users_blocked', Helper::SINGLE_CONTEXT );
610
611 // Get default role if one isn't specified.
612 if ( count( $default_role ) < 1 ) {
613 $default_role = '';
614 } else {
615 // If default role was provided, it came from the invite_user hook, and
616 // only contains the role's display name. Here we look up the actual role
617 // name to save (and default to no role if the display name isn't found).
618 global $wp_roles;
619 $default_role_display_name = $default_role['name'];
620 $default_role = '';
621 foreach ( $wp_roles->role_names as $role_name => $display_name ) {
622 if ( $default_role_display_name === $display_name ) {
623 $default_role = $role_name;
624 break;
625 }
626 }
627 }
628
629 $updated = false;
630
631 // Skip if user is in blocked list.
632 if ( Helper::in_multi_array( $user_email, $auth_settings_access_users_blocked ) ) {
633 return;
634 }
635 // Remove from pending list if there.
636 foreach ( $auth_settings_access_users_pending as $key => $pending_user ) {
637 if ( 0 === strcasecmp( $pending_user['email'], $user_email ) ) {
638 unset( $auth_settings_access_users_pending[ $key ] );
639 $updated = true;
640 }
641 }
642 // Skip if user is in multisite approved list.
643 if ( Helper::in_multi_array( $user_email, $auth_multisite_settings_access_users_approved ) ) {
644 return;
645 }
646 // Add to approved list if not there.
647 if ( ! Helper::in_multi_array( $user_email, $auth_settings_access_users_approved ) ) {
648 $approved_user = array(
649 'email' => Helper::lowercase( $user_email ),
650 'role' => is_array( $user_roles ) && count( $user_roles ) > 0 ? $user_roles[0] : $default_role,
651 'date_added' => wp_date( 'M Y', strtotime( $date_registered ) ),
652 'local_user' => true,
653 );
654 array_push( $auth_settings_access_users_approved, $approved_user );
655 $updated = true;
656 }
657
658 if ( $updated ) {
659 update_option( 'auth_settings_access_users_pending', $auth_settings_access_users_pending );
660 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
661 }
662 }
663
664
665 /**
666 * Multisite:
667 * When a user is granted super admin status (checkbox on network user edit
668 * screen), add them to the authorizer network approved list. Also remove
669 * them from pending/approved list on any individual sites.
670 *
671 * Action: grant_super_admin
672 *
673 * @param int $user_id The user's ID.
674 */
675 public function grant_super_admin__add_to_network_approved( $user_id ) {
676 $options = Options::get_instance();
677 $user = get_user_by( 'id', $user_id );
678 $user_email = $user->user_email;
679
680 // Add user to multisite approved user list (if not already there).
681 $auth_multisite_settings_access_users_approved = $options->sanitize_user_list(
682 $options->get( 'access_users_approved', Helper::NETWORK_CONTEXT )
683 );
684 if ( ! Helper::in_multi_array( $user_email, $auth_multisite_settings_access_users_approved ) ) {
685 $multisite_approved_user = array(
686 'email' => Helper::lowercase( $user_email ),
687 'role' => count( $user->roles ) > 0 ? $user->roles[0] : 'administrator',
688 'date_added' => wp_date( 'M Y', strtotime( $user->user_registered ) ),
689 'local_user' => true,
690 );
691 array_push( $auth_multisite_settings_access_users_approved, $multisite_approved_user );
692 update_blog_option( get_network()->blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
693 }
694
695 // Go through all pending/approved lists on individual sites and remove this user from them.
696 // phpcs:ignore WordPress.WP.DeprecatedFunctions.wp_get_sitesFound
697 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
698 foreach ( $sites as $site ) {
699 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
700 $this->remove_network_user_from_site_when_removed( $user_id, $blog_id );
701 }
702
703 }
704
705
706 /**
707 * Multisite:
708 * When a user's super admin status is revoked (checkbox on network user edit
709 * screen), remove them from the authorizer network approved list. Also add
710 * them to approved list on any individual sites they are already a part of.
711 *
712 * Action: revoke_super_admin
713 *
714 * @param int $user_id The user's ID.
715 */
716 public function revoke_super_admin__remove_from_network_approved( $user_id ) {
717 $options = Options::get_instance();
718 $user = get_user_by( 'id', $user_id );
719 $revoked_email = $user->user_email;
720
721 // Go through multisite approved user list and remove this user.
722 $auth_multisite_settings_access_users_approved = $options->sanitize_user_list(
723 $options->get( 'access_users_approved', Helper::NETWORK_CONTEXT )
724 );
725 $list_changed = false;
726 foreach ( $auth_multisite_settings_access_users_approved as $key => $existing_user ) {
727 if ( 0 === strcasecmp( $revoked_email, $existing_user['email'] ) ) {
728 $list_changed = true;
729 unset( $auth_multisite_settings_access_users_approved[ $key ] );
730 }
731 }
732 if ( $list_changed ) {
733 update_blog_option( get_network()->blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
734 }
735
736 // Go through this user's current sites and add them to the approved list
737 // (since they are no longer on the network approved list).
738 $sites_of_user = get_blogs_of_user( $user_id );
739 foreach ( $sites_of_user as $site ) {
740 $blog_id = $site->userblog_id;
741 $this->add_network_user_to_site( $user_id, $blog_id );
742 }
743 }
744
745 }
746