PluginProbe
Authorizer / 2.7.1
Authorizer v2.7.1
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 / authorizer.php

authorizer.php in Authorizer 2.7.1, at authorizer.php

6,988 lines 328.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Authorizer
4 Plugin URI: https://github.com/uhm-coe/authorizer
5 Description: Authorizer limits login attempts, restricts access to specified users, and authenticates against external sources (e.g., Google, LDAP, or CAS).
6 Version: 2.7.1
7 Author: Paul Ryan
8 Author URI: http://www.linkedin.com/in/paulrryan/
9 Text Domain: authorizer
10 Domain Path: /languages
11 License: GPL2
12 */
13
14
15 /*
16 Copyright 2014 Paul Ryan (email: prar@hawaii.edu)
17
18 This program is free software; you can redistribute it and/or modify
19 it under the terms of the GNU General Public License, version 2, as
20 published by the Free Software Foundation.
21
22 This program is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
26
27 You should have received a copy of the GNU General Public License
28 along with this program; if not, write to the Free Software
29 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 */
31
32
33 /*
34 Portions forked from Restricted Site Access plugin: http://wordpress.org/plugins/restricted-site-access/
35 Portions forked from wpCAS plugin: http://wordpress.org/extend/plugins/cas-authentication/
36 Portions forked from Limit Login Attempts: http://wordpress.org/plugins/limit-login-attempts/
37 */
38
39
40 define( 'MULTISITE_ADMIN', 'multisite_admin' );
41 define( 'SINGLE_ADMIN', 'single_admin' );
42
43
44 // Add phpCAS library if it's not included.
45 // @see https://wiki.jasig.org/display/CASC/phpCAS+installation+guide
46 if ( ! defined( 'PHPCAS_VERSION' ) ) {
47 require_once dirname( __FILE__ ) . '/vendor/CAS-1.3.5/CAS.php';
48 }
49
50
51 if ( ! class_exists( 'WP_Plugin_Authorizer' ) ) {
52 /**
53 * Define class for plugin: Authorizer.
54 *
55 * @category Authentication
56 * @package Authorizer
57 * @author Paul Ryan <prar@hawaii.edu>
58 * @license http://www.gnu.org/licenses/gpl-2.0.html GPL2
59 * @link http://hawaii.edu/coe/dcdc/wordpress/authorizer/doc/
60 */
61 class WP_Plugin_Authorizer {
62
63 /**
64 * Properties.
65 */
66 public $current_site_blog_id = 1;
67
68 /**
69 * Constructor.
70 */
71 public function __construct() {
72 // Save reference to current blog id in the network (support deprecated
73 // constant BLOGID_CURRENT_SITE).
74 if ( defined( 'BLOG_ID_CURRENT_SITE' ) ) {
75 $this->current_site_blog_id = BLOG_ID_CURRENT_SITE;
76 } elseif ( defined( 'BLOGID_CURRENT_SITE' ) ) { // deprecated.
77 $this->current_site->blog_id = BLOGID_CURRENT_SITE;
78 }
79
80 // Installation and uninstallation hooks.
81 register_activation_hook( __FILE__, array( $this, 'activate' ) );
82 register_deactivation_hook( __FILE__, array( $this, 'deactivate' ) );
83
84 // Register filters.
85
86 // Custom wp authentication routine using external service.
87 add_filter( 'authenticate', array( $this, 'custom_authenticate' ), 1, 3 );
88
89 // Custom logout action using external service.
90 add_action( 'wp_logout', array( $this, 'custom_logout' ) );
91
92 // Removing this bypasses Wordpress authentication (so if external auth fails,
93 // no one can log in); with it enabled, it will run if external auth fails.
94 //remove_filter('authenticate', 'wp_authenticate_username_password', 20, 3);
95
96 // Create settings link on Plugins page
97 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'plugin_settings_link' ) );
98 add_filter( 'network_admin_plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'network_admin_plugin_settings_link' ) );
99
100 // Modify login page with a custom password url (if option is set).
101 add_filter( 'lostpassword_url', array( $this, 'custom_lostpassword_url' ) );
102
103 // If we have a custom login error, add the filter to show it.
104 $error = get_option( 'auth_settings_advanced_login_error' );
105 if ( $error && strlen( $error ) > 0 ) {
106 add_filter( 'login_errors', array( $this, 'show_advanced_login_error' ) );
107 }
108
109 // Register actions.
110
111 // Enable localization. Translation files stored in /languages.
112 add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
113
114 // Perform plugin updates if newer version installed.
115 add_action( 'plugins_loaded', array( $this, 'auth_update_check' ) );
116
117 // Update the user meta with this user's failed login attempt.
118 add_action( 'wp_login_failed', array( $this, 'update_login_failed_count' ) );
119
120 // Add users who successfully login to the approved list.
121 add_action( 'wp_login', array( $this, 'ensure_wordpress_user_in_approved_list_on_login' ), 10, 2 );
122
123 // Create menu item in Settings
124 add_action( 'admin_menu', array( $this, 'add_plugin_page' ) );
125
126 // Create options page
127 add_action( 'admin_init', array( $this, 'page_init' ) );
128
129 // Update user role in approved list if it's changed in the WordPress edit user page.
130 add_action( 'user_profile_update_errors', array( $this, 'edit_user_profile_update_role' ), 10, 3 );
131
132 // Update user email in approved list if it's changed in the WordPress edit user page.
133 add_filter( 'send_email_change_email', array( $this, 'edit_user_profile_update_email' ), 10, 3 );
134
135 // Enqueue javascript and css on the plugin's options page, the
136 // dashboard (for the widget), and the network admin.
137 add_action( 'load-settings_page_authorizer', array( $this, 'load_options_page' ) );
138 add_action( 'admin_head-index.php', array( $this, 'load_options_page' ) );
139 add_action( 'load-toplevel_page_authorizer', array( $this, 'load_options_page' ) );
140
141 // Add custom css and js to wp-login.php
142 add_action( 'login_enqueue_scripts', array( $this, 'login_enqueue_scripts_and_styles' ) );
143 add_action( 'login_footer', array( $this, 'load_login_footer_js' ) );
144
145 // Create google nonce cookie when loading wp-login.php if Google is enabled.
146 add_action( 'login_init', array( $this, 'login_init__maybe_set_google_nonce_cookie' ) );
147
148 // Modify login page with external auth links (if enabled; e.g., google or cas)
149 add_action( 'login_form', array( $this, 'login_form_add_external_service_links' ) );
150
151 // Redirect to CAS login when visiting login page (only if option is
152 // enabled, CAS is the only service, and WordPress logins are hidden).
153 // Note: hook into wp_login_errors filter so this fires after the
154 // authenticate hook (where the redirect to CAS happens), but before html
155 // output is started (so the redirect header doesn't complain about data
156 // already being sent).
157 add_filter( 'wp_login_errors', array( $this, 'wp_login_errors__maybe_redirect_to_cas' ), 10, 2 );
158
159 // Verify current user has access to page they are visiting
160 add_action( 'parse_request', array( $this, 'restrict_access' ), 9 );
161 add_action( 'init', array( $this, 'init__maybe_add_network_approved_user' ) );
162
163 // ajax save options from dashboard widget
164 add_action( 'wp_ajax_update_auth_user', array( $this, 'ajax_update_auth_user' ) );
165
166 // ajax save options from multisite options page
167 add_action( 'wp_ajax_save_auth_multisite_settings', array( $this, 'ajax_save_auth_multisite_settings' ) );
168
169 // ajax save usermeta from options page
170 add_action( 'wp_ajax_update_auth_usermeta', array( $this, 'ajax_update_auth_usermeta' ) );
171
172 // ajax verify google login
173 add_action( 'wp_ajax_process_google_login', array( $this, 'ajax_process_google_login' ) );
174 add_action( 'wp_ajax_nopriv_process_google_login', array( $this, 'ajax_process_google_login' ) );
175
176 // ajax refresh approved user list
177 add_action( 'wp_ajax_refresh_approved_user_list', array( $this, 'ajax_refresh_approved_user_list' ) );
178
179 // Add dashboard widget so instructors can add/edit users with access.
180 // Hint: For Multisite Network Admin Dashboard use wp_network_dashboard_setup instead of wp_dashboard_setup.
181 add_action( 'wp_dashboard_setup', array( $this, 'add_dashboard_widgets' ) );
182
183 // If we have a custom admin message, add the action to show it.
184 $notice = get_option( 'auth_settings_advanced_admin_notice' );
185 if ( $notice && strlen( $notice ) > 0 ) {
186 add_action( 'admin_notices', array( $this, 'show_advanced_admin_notice' ) );
187 add_action( 'network_admin_notices', array( $this, 'show_advanced_admin_notice' ) );
188 }
189
190 // Load custom javascript for the main site (e.g., for displaying alerts).
191 add_action( 'wp_enqueue_scripts', array( $this, 'auth_public_scripts' ), 20 );
192
193 // Multisite-specific actions.
194 if ( is_multisite() ) {
195 // Add network admin options page (global settings for all sites)
196 add_action( 'network_admin_menu', array( $this, 'network_admin_menu' ) );
197 }
198
199 // Remove user from authorizer lists when that user is deleted in WordPress.
200 add_action( 'delete_user', array( $this, 'remove_user_from_authorizer_when_deleted' ) );
201 if ( is_multisite() ) {
202 // Remove multisite user from authorizer lists when that user is deleted from Network Users.
203 add_action( 'remove_user_from_blog', array( $this, 'remove_network_user_from_site_when_removed' ), 10, 2 );
204 add_action( 'wpmu_delete_user', array( $this, 'remove_network_user_from_authorizer_when_deleted' ) );
205 }
206
207 // Add user to authorizer approved list when that user is added to a blog from the Users screen.
208 // Multisite: invite_user action fired when adding (inviting) an existing network user to the current site (with email confirmation).
209 add_action( 'invite_user', array( $this, 'add_existing_user_to_authorizer_when_created' ), 10, 3 );
210 // Multisite: added_existing_user action fired when adding an existing network user to the current site (without email confirmation).
211 add_action( 'added_existing_user', array( $this, 'add_existing_user_to_authorizer_when_created_noconfirmation' ), 10, 2 );
212 // Multisite: after_signup_user action fired when adding a new user to the site (with or without email confirmation).
213 add_action( 'after_signup_user', array( $this, 'add_new_user_to_authorizer_when_created' ), 10, 4 );
214 // Single site: edit_user_created_user action fired when adding a new user to the site (with or without email notification).
215 add_action( 'edit_user_created_user', array( $this, 'add_new_user_to_authorizer_when_created_single_site' ), 10, 2 );
216
217 // Add user to network approved users (and remove from individual sites)
218 // when user is elevated to super admin status.
219 add_action( 'grant_super_admin', array( $this, 'grant_super_admin__add_to_network_approved' ) );
220 // Remove user from network approved users (and add them to the approved
221 // list on sites they are already on) when super admin status is removed.
222 add_action( 'revoke_super_admin', array( $this, 'revoke_super_admin__remove_from_network_approved' ) );
223
224 }
225
226
227 /**
228 * Plugin activation hook.
229 * Will also activate the plugin for all sites/blogs if this is a "Network enable."
230 *
231 * @return void
232 */
233 public function activate() {
234 global $wpdb;
235
236 // If we're in a multisite environment, run the plugin activation for each site when network enabling
237 if ( is_multisite() && isset( $_GET['networkwide'] ) && $_GET['networkwide'] == 1 ) {
238
239 // Add super admins to the multisite approved list.
240 $auth_multisite_settings_access_users_approved = get_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', array() );
241 $should_update_auth_multisite_settings_access_users_approved = false;
242 foreach ( get_super_admins() as $super_admin ) {
243 $user = get_user_by( 'login', $super_admin );
244 // Add to approved list if not there.
245 if ( ! $this->in_multi_array( $user->user_email, $auth_multisite_settings_access_users_approved ) ) {
246 $approved_user = array(
247 'email' => $this->lowercase( $user->user_email ),
248 'role' => count( $user->roles ) > 0 ? $user->roles[0] : 'administrator',
249 'date_added' => date( 'M Y', strtotime( $user->user_registered ) ),
250 'local_user' => true,
251 );
252 array_push( $auth_multisite_settings_access_users_approved, $approved_user );
253 $should_update_auth_multisite_settings_access_users_approved = true;
254 }
255 }
256 if ( $should_update_auth_multisite_settings_access_users_approved ) {
257 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
258 }
259
260 // Run plugin activation on each site in the network.
261 $current_blog_id = $wpdb->blogid;
262 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
263 foreach ( $sites as $site ) {
264 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
265 switch_to_blog( $blog_id );
266 // Set default plugin options and add current users to approved list.
267 $this->set_default_options();
268 $this->add_wp_users_to_approved_list();
269 }
270 switch_to_blog( $current_blog_id );
271
272 } else {
273 // Set default plugin options and add current users to approved list.
274 $this->set_default_options();
275 $this->add_wp_users_to_approved_list();
276 }
277
278 }
279
280
281 /**
282 * Adds all WordPress users in the current site to the approved list,
283 * unless they are already in the blocked list. Also removes them
284 * from the pending list if they are there.
285 *
286 * Runs in plugin activation hook.
287 *
288 * @return void
289 */
290 private function add_wp_users_to_approved_list() {
291 // Add current WordPress users to the approved list.
292 $auth_multisite_settings_access_users_approved = is_multisite() ? get_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', array() ) : array();
293 $auth_settings_access_users_pending = $this->get_plugin_option( 'access_users_pending', SINGLE_ADMIN );
294 $auth_settings_access_users_approved = $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN );
295 $auth_settings_access_users_blocked = $this->get_plugin_option( 'access_users_blocked', SINGLE_ADMIN );
296 $updated = false;
297 foreach ( get_users() as $user ) {
298 // Skip if user is in blocked list.
299 if ( $this->in_multi_array( $user->user_email, $auth_settings_access_users_blocked ) ) {
300 continue;
301 }
302 // Remove from pending list if there.
303 foreach ( $auth_settings_access_users_pending as $key => $pending_user ) {
304 if ( 0 === strcasecmp( $pending_user['email'], $user->user_email ) ) {
305 unset( $auth_settings_access_users_pending[$key] );
306 $updated = true;
307 }
308 }
309 // Skip if user is in multisite approved list.
310 if ( $this->in_multi_array( $user->user_email, $auth_multisite_settings_access_users_approved ) ) {
311 continue;
312 }
313 // Add to approved list if not there.
314 if ( ! $this->in_multi_array( $user->user_email, $auth_settings_access_users_approved ) ) {
315 $approved_user = array(
316 'email' => $this->lowercase( $user->user_email ),
317 'role' => count( $user->roles ) > 0 ? $user->roles[0] : '',
318 'date_added' => date( 'M Y', strtotime( $user->user_registered ) ),
319 'local_user' => true,
320 );
321 array_push( $auth_settings_access_users_approved, $approved_user );
322 $updated = true;
323 }
324 }
325 if ( $updated ) {
326 update_option( 'auth_settings_access_users_pending', $auth_settings_access_users_pending );
327 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
328 }
329 }
330
331
332 /**
333 * Plugin deactivation.
334 *
335 * @return void
336 */
337 public function deactivate() {
338 // Do nothing.
339 }
340
341
342
343 /**
344 * ***************************
345 * External Authentication
346 * ***************************
347 */
348
349
350
351 /**
352 * Authenticate against an external service.
353 *
354 * @param WP_User $user user to authenticate
355 * @param string $username optional username to authenticate.
356 * @param string $password optional password to authenticate.
357 *
358 * @return WP_User or WP_Error
359 */
360 public function custom_authenticate( $user, $username, $password ) {
361 // Pass through if already authenticated.
362 if ( is_a( $user, 'WP_User' ) ) {
363 return $user;
364 } else {
365 $user = null;
366 }
367
368 // If username and password are blank, this isn't a log in attempt
369 $is_login_attempt = strlen( $username ) > 0 && strlen( $password ) > 0;
370
371 // Check to make sure that $username is not locked out due to too
372 // many invalid login attempts. If it is, tell the user how much
373 // time remains until they can try again.
374 $unauthenticated_user = $is_login_attempt ? get_user_by( 'login', $username ) : false;
375 $unauthenticated_user_is_blocked = false;
376 if ( $is_login_attempt && $unauthenticated_user !== false ) {
377 $last_attempt = get_user_meta( $unauthenticated_user->ID, 'auth_settings_advanced_lockouts_time_last_failed', true );
378 $num_attempts = get_user_meta( $unauthenticated_user->ID, 'auth_settings_advanced_lockouts_failed_attempts', true );
379 // Also check the auth_blocked user_meta flag (users in blocked list will get this flag)
380 $unauthenticated_user_is_blocked = get_user_meta( $unauthenticated_user->ID, 'auth_blocked', true ) === 'yes';
381 } else {
382 $last_attempt = get_option( 'auth_settings_advanced_lockouts_time_last_failed' );
383 $num_attempts = get_option( 'auth_settings_advanced_lockouts_failed_attempts' );
384 }
385
386 // Inactive users should be treated like deleted users (we just
387 // do this to preserve any content they created, but here we should
388 // pretend they don't exist).
389 if ( $unauthenticated_user_is_blocked ) {
390 remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
391 return new WP_Error( 'empty_password', __( '<strong>ERROR</strong>: Incorrect username or password.', 'authorizer' ) );
392 }
393
394 // Grab plugin settings.
395 $auth_settings = $this->get_plugin_options( SINGLE_ADMIN, 'allow override' );
396
397 // Make sure $last_attempt (time) and $num_attempts are positive integers.
398 // Note: this addresses resetting them if either is unset from above.
399 $last_attempt = abs( intval( $last_attempt ) );
400 $num_attempts = abs( intval( $num_attempts ) );
401
402 // Create semantic lockout variables.
403 $lockouts = $auth_settings['advanced_lockouts'];
404 $time_since_last_fail = time() - $last_attempt;
405 $reset_duration = $lockouts['reset_duration'] * 60; // minutes to seconds
406 $num_attempts_long_lockout = $lockouts['attempts_1'] + $lockouts['attempts_2'];
407 $num_attempts_short_lockout = $lockouts['attempts_1'];
408 $seconds_remaining_long_lockout = $lockouts['duration_2'] * 60 - $time_since_last_fail;
409 $seconds_remaining_short_lockout = $lockouts['duration_1'] * 60 - $time_since_last_fail;
410
411 // Check if we need to institute a lockout delay
412 if ( $is_login_attempt && $time_since_last_fail > $reset_duration ) {
413 // Enough time has passed since the last invalid attempt and
414 // now that we can reset the failed attempt count, and let this
415 // login attempt go through.
416 $num_attempts = 0; // This does nothing, but include it for semantic meaning.
417 } elseif ( $is_login_attempt && $num_attempts > $num_attempts_long_lockout && $seconds_remaining_long_lockout > 0 ) {
418 // Stronger lockout (1st/2nd round of invalid attempts reached)
419 // Note: set the error code to 'empty_password' so it doesn't
420 // trigger the wp_login_failed hook, which would continue to
421 // increment the failed attempt count.
422 remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
423 return new WP_Error(
424 'empty_password',
425 sprintf(
426 __( '<strong>ERROR</strong>: There have been too many invalid login attempts for the username <strong>%1$s</strong>. Please wait <strong id="seconds_remaining" data-seconds="%2$s">%3$s</strong> before trying again. <a href="%4$s" title="Password Lost and Found">Lost your password</a>?', 'authorizer' ),
427 $username,
428 $seconds_remaining_long_lockout,
429 $this->seconds_as_sentence( $seconds_remaining_long_lockout ),
430 wp_lostpassword_url()
431 )
432 );
433 } elseif ( $is_login_attempt && $num_attempts > $num_attempts_short_lockout && $seconds_remaining_short_lockout > 0 ) {
434 // Normal lockout (1st round of invalid attempts reached)
435 // Note: set the error code to 'empty_password' so it doesn't
436 // trigger the wp_login_failed hook, which would continue to
437 // increment the failed attempt count.
438 remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
439 return new WP_Error(
440 'empty_password',
441 sprintf(
442 __( '<strong>ERROR</strong>: There have been too many invalid login attempts for the username <strong>%1$s</strong>. Please wait <strong id="seconds_remaining" data-seconds="%2$s">%3$s</strong> before trying again. <a href="%4$s" title="Password Lost and Found">Lost your password</a>?', 'authorizer' ),
443 $username,
444 $seconds_remaining_short_lockout,
445 $this->seconds_as_sentence( $seconds_remaining_short_lockout ),
446 wp_lostpassword_url()
447 )
448 );
449 }
450
451 // Start external authentication.
452 $externally_authenticated_emails = array();
453 $authenticated_by = '';
454 $result = null;
455
456 // Try Google authentication if it's enabled and we don't have a
457 // successful login yet.
458 if (
459 $auth_settings['google'] === '1' &&
460 count( $externally_authenticated_emails ) === 0 &&
461 ! is_wp_error( $result )
462 ) {
463 $result = $this->custom_authenticate_google( $auth_settings );
464 if ( ! is_null( $result ) && ! is_wp_error( $result ) ) {
465 if ( is_array( $result['email'] ) ) {
466 $externally_authenticated_emails = $result['email'];
467 } else {
468 $externally_authenticated_emails[] = $result['email'];
469 }
470 $authenticated_by = $result['authenticated_by'];
471 }
472 }
473
474 // Try CAS authentication if it's enabled and we don't have a
475 // successful login yet.
476 if (
477 $auth_settings['cas'] === '1' &&
478 count( $externally_authenticated_emails ) === 0 &&
479 ! is_wp_error( $result )
480 ) {
481 $result = $this->custom_authenticate_cas( $auth_settings );
482 if ( ! is_null( $result ) && ! is_wp_error( $result ) ) {
483 if ( is_array( $result['email'] ) ) {
484 $externally_authenticated_emails = $result['email'];
485 } else {
486 $externally_authenticated_emails[] = $result['email'];
487 }
488 $authenticated_by = $result['authenticated_by'];
489 }
490 }
491
492 // Try LDAP authentication if it's enabled and we don't have an
493 // authenticated user yet.
494 if (
495 $auth_settings['ldap'] === '1' &&
496 count( $externally_authenticated_emails ) === 0 &&
497 ! is_wp_error( $result )
498 ) {
499 $result = $this->custom_authenticate_ldap( $auth_settings, $username, $password );
500 if ( ! is_null( $result ) && ! is_wp_error( $result ) ) {
501 if ( is_array( $result['email'] ) ) {
502 $externally_authenticated_emails = $result['email'];
503 } else {
504 $externally_authenticated_emails[] = $result['email'];
505 }
506 $authenticated_by = $result['authenticated_by'];
507 }
508 }
509
510 // Skip to WordPress authentication if we don't have an externally
511 // authenticated user.
512 if ( count( array_filter( $externally_authenticated_emails ) ) < 1 ) {
513 return $result;
514 }
515
516 // Remove duplicate and blank emails, if any.
517 $externally_authenticated_emails = array_filter( array_unique( $externally_authenticated_emails ) );
518
519 // If we've made it this far, we should have an externally
520 // authenticated user. The following should be set:
521 // $externally_authenticated_emails
522 // $authenticated_by
523
524 // Get the external user's WordPress account by email address.
525 foreach ( $externally_authenticated_emails as $externally_authenticated_email ) {
526 $user = get_user_by( 'email', $this->lowercase( $externally_authenticated_email ) );
527
528 // If we've already found a WordPress user associated with one
529 // of the supplied email addresses, don't keep examining other
530 // email addresses associated with the externally authenticated user.
531 if ( $user !== FALSE ) {
532 break;
533 }
534 }
535
536 // Check this external user's access against the access lists
537 // (pending, approved, blocked)
538 $result = $this->check_user_access( $user, $externally_authenticated_emails, $result );
539
540 // Fail with message if there was an error creating/adding the user.
541 if ( is_wp_error( $result ) || $result === 0 ) {
542 return $result;
543 }
544
545 // If we created a new user in check_user_access(), log that user in.
546 if ( get_class( $result ) === 'WP_User' ) {
547 $user = $result;
548 }
549
550 // We'll track how this user was authenticated in user meta.
551 if ( $user ) {
552 update_user_meta( $user->ID, 'authenticated_by', $authenticated_by );
553 }
554
555 // If we haven't exited yet, we have a valid/approved user, so authenticate them.
556 return $user;
557 }
558
559
560 /**
561 * This function will fail with a wp_die() message to the user if they
562 * don't have access.
563 *
564 * @param WP_User $user User to check
565 * @param [type] $user_emails Array of user's plaintext emails (in case current user doesn't have a WP account)
566 * @param [type] $user_data Array of keys for email, username, first_name, last_name,
567 * authenticated_by, google_attributes, cas_attributes, ldap_attributes.
568 * @return WP_Error if there was an error on user creation / adding user to blog
569 * wp_die() if user does not have access
570 * null if user has access (success)
571 * WP_User if user has access and a new account was created for them
572 */
573 private function check_user_access( $user, $user_emails, $user_data = array() ) {
574 // Grab plugin settings.
575 $auth_settings = $this->get_plugin_options( SINGLE_ADMIN, 'allow override' );
576 $auth_settings_access_users_pending = $this->sanitize_user_list(
577 $this->get_plugin_option( 'access_users_pending', SINGLE_ADMIN )
578 );
579 $auth_settings_access_users_approved_single = $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN );
580 $auth_settings_access_users_approved_multi = $this->get_plugin_option( 'access_users_approved', MULTISITE_ADMIN );
581 $auth_settings_access_users_approved = $this->sanitize_user_list(
582 array_merge(
583 $auth_settings_access_users_approved_single,
584 $auth_settings_access_users_approved_multi
585 )
586 );
587
588 /**
589 * Filter whether to block the currently logging in user based on any of
590 * their user attributes.
591 *
592 * @param bool $allow_login Whether to block the currently logging in user.
593 * @param array $user_data User data returned from external service.
594 */
595 $allow_login = apply_filters( 'authorizer_allow_login', true, $user_data );
596 $blocked_by_filter = ! $allow_login; // Use this for better readability.
597
598 // Check our externally authenticated user against the block list.
599 // If any of their email addresses are blocked, set the relevant user
600 // meta field, and show them an error screen.
601 foreach ( $user_emails as $user_email ) {
602 if ( $blocked_by_filter || $this->is_email_in_list( $user_email, 'blocked' ) ) {
603
604 // Add user to blocked list if it was blocked via the filter.
605 if ( $blocked_by_filter && ! $this->is_email_in_list( $user_email, 'blocked' ) ) {
606 $auth_settings_access_users_blocked = $this->sanitize_user_list(
607 $this->get_plugin_option( 'access_users_blocked', SINGLE_ADMIN )
608 );
609 array_push( $auth_settings_access_users_blocked, array(
610 'email' => $this->lowercase( $user_email ),
611 'date_added' => date( 'M Y' ),
612 ));
613 update_option( 'auth_settings_access_users_blocked', $auth_settings_access_users_blocked );
614 }
615
616 // If the blocked external user has a WordPress account, mark it as
617 // blocked (enforce block in this->authenticate()).
618 if ( $user ) {
619 update_user_meta( $user->ID, 'auth_blocked', 'yes' );
620 }
621
622 // Notify user about blocked status and return without authenticating them.
623 $redirect_to = ! empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : home_url();
624 $page_title = sprintf(
625 /* TRANSLATORS: %s: Name of blog */
626 __( '%s - Access Restricted', 'authorizer' ),
627 get_bloginfo( 'name' )
628 );
629 $error_message =
630 apply_filters( 'the_content', $auth_settings['access_blocked_redirect_to_message'] ) .
631 '<hr />' .
632 '<p style="text-align: center;">' .
633 '<a class="button" href="' . wp_logout_url( $redirect_to ) . '">' .
634 __( 'Back', 'authorizer' ) .
635 '</a></p>';
636 update_option( 'auth_settings_advanced_login_error', $error_message );
637 wp_die( $error_message, $page_title );
638 }
639 }
640
641 // Get the default role for this user (or their current role, if they
642 // already have an account).
643 $default_role = $user && is_array( $user->roles ) && count( $user->roles ) > 0 ? $user->roles[0] : $auth_settings['access_default_role'];
644 /**
645 * Filter the role of the user currently logging in. The role will be
646 * set to the default (specified in Authorizer options) for new users,
647 * or the user's current role for existing users. This filter allows
648 * changing user roles based on custom CAS/LDAP attributes.
649 * @param bool $role Role of the user currently logging in.
650 * @param array $user_data User data returned from external service.
651 */
652 $approved_role = apply_filters( 'authorizer_custom_role', $default_role, $user_data );
653
654 /**
655 * Filter whether to automatically approve the currently logging in user
656 * based on any of their user attributes.
657 *
658 * @param bool $automatically_approve_login
659 * Whether to automatically approve the currently logging in user.
660 * @param array $user_data User data returned from external service.
661 */
662 $automatically_approve_login = apply_filters( 'authorizer_automatically_approve_login', false, $user_data );
663
664 // Iterate through each of the email addresses provided by the external
665 // service and determine if any of them have access.
666 $last_email = end( $user_emails );
667 reset( $user_emails );
668 foreach ( $user_emails as $user_email ) {
669 $is_newly_approved_user = false;
670
671 // If this externally authenticated user is an existing administrator
672 // (administrator in single site mode, or super admin in network mode),
673 // and is not in the blocked list, let them in.
674 if ( $user && is_super_admin( $user->ID ) ) {
675 return;
676 }
677
678 // If this externally authenticated user isn't in the approved list
679 // and login access is set to "All authenticated users," or if they were
680 // automatically approved in the "authorizer_approve_login" filter
681 // above, then add them to the approved list (they'll get an account
682 // created below if they don't have one yet).
683 if (
684 ! $this->is_email_in_list( $user_email, 'approved' ) &&
685 ( $auth_settings['access_who_can_login'] === 'external_users' || $automatically_approve_login )
686 ) {
687 $is_newly_approved_user = true;
688
689 // If this user happens to be in the pending list (rare),
690 // remove them from pending before adding them to approved.
691 if ( $this->is_email_in_list( $user_email, 'pending' ) ) {
692 foreach ( $auth_settings_access_users_pending as $key => $pending_user ) {
693 if ( 0 === strcasecmp( $pending_user['email'], $user_email ) ) {
694 unset( $auth_settings_access_users_pending[ $key ] );
695 update_option( 'auth_settings_access_users_pending', $auth_settings_access_users_pending );
696 break;
697 }
698 }
699 }
700
701 // Add this user to the approved list.
702 $approved_user = array(
703 'email' => $this->lowercase( $user_email ),
704 'role' => $approved_role,
705 'date_added' => date( "Y-m-d H:i:s" ),
706 );
707 array_push( $auth_settings_access_users_approved, $approved_user );
708 array_push( $auth_settings_access_users_approved_single, $approved_user );
709 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved_single );
710 }
711
712 // Check our externally authenticated user against the approved
713 // list. If they are approved, log them in (and create their account
714 // if necessary).
715 if ( $is_newly_approved_user || $this->is_email_in_list( $user_email, 'approved' ) ) {
716 $user_info = $is_newly_approved_user ? $approved_user : $this->get_user_info_from_list( $user_email, $auth_settings_access_users_approved );
717
718 // If this user's role was modified above (in the
719 // authorizer_custom_role filter), use that value instead of
720 // whatever is specified in the approved list.
721 if ( $default_role !== $approved_role ) {
722 $user_info['role'] = $approved_role;
723 }
724
725 // If the approved external user does not have a WordPress account, create it
726 if ( ! $user ) {
727 // If there's already a user with this username (e.g.,
728 // johndoe/johndoe@gmail.com exists, and we're trying to add
729 // johndoe/johndoe@example.com), use the full email address
730 // as the username.
731 if ( array_key_exists( 'username', $user_data ) ) {
732 $username = $user_data['username'];
733 } else {
734 $username = explode( '@', $user_info['email'] );
735 $username = $username[0];
736 }
737 if ( get_user_by( 'login', $username ) !== false ) {
738 $username = $user_info['email'];
739 }
740 $result = wp_insert_user(
741 array(
742 'user_login' => strtolower( $username ),
743 'user_pass' => wp_generate_password(), // random password
744 'first_name' => array_key_exists( 'first_name', $user_data ) ? $user_data['first_name'] : '',
745 'last_name' => array_key_exists( 'last_name', $user_data ) ? $user_data['last_name'] : '',
746 'user_email' => $this->lowercase( $user_info['email'] ),
747 'user_registered' => date( 'Y-m-d H:i:s' ),
748 'role' => $user_info['role'],
749 )
750 );
751
752 // Fail with message if error.
753 if ( is_wp_error( $result ) || $result === 0 ) {
754 return $result;
755 }
756
757 // Authenticate as new user
758 $user = new WP_User( $result );
759
760 // If multisite, iterate through all sites in the network and add the user
761 // currently logging in to any of them that have the user on the approved list.
762 // Note: this is useful for first-time logins--some users will have access
763 // to multiple sites, and this prevents them from having to log into each
764 // site individually to get access.
765 if ( is_multisite() ) {
766 $site_ids_of_user = array_map(
767 function ( $site_of_user ) { return $site_of_user->userblog_id; },
768 get_blogs_of_user( $user->ID )
769 );
770
771 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
772 foreach ( $sites as $site ) {
773 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
774
775 // Skip if user is already added to this site.
776 if ( in_array( $blog_id, $site_ids_of_user ) ) {
777 continue;
778 }
779
780 // Check if user is on the approved list of this site they are not added to.
781 $other_auth_settings_access_users_approved = get_blog_option( $blog_id, 'auth_settings_access_users_approved', array() );
782 if ( $this->in_multi_array( $user->user_email, $other_auth_settings_access_users_approved ) ) {
783 $other_user_info = $this->get_user_info_from_list( $user->user_email, $other_auth_settings_access_users_approved );
784 // Add user to other site.
785 add_user_to_blog( $blog_id, $user->ID, $other_user_info['role'] );
786 }
787 }
788 }
789
790 // Check if this new user has any preassigned usermeta
791 // values in their approved list entry, and apply them to
792 // their new WordPress account.
793 if ( array_key_exists( 'usermeta', $user_info ) && is_array( $user_info['usermeta'] ) ) {
794 $meta_key = $this->get_plugin_option( 'advanced_usermeta' );
795
796 if ( array_key_exists( 'meta_key', $user_info['usermeta'] ) && array_key_exists( 'meta_value', $user_info['usermeta'] ) ) {
797 // Only update the usermeta if the stored value matches
798 // the option set in authorizer settings (if they don't
799 // match it's probably old data).
800 if ( $meta_key === $user_info['usermeta']['meta_key'] ) {
801 // Update user's usermeta value for usermeta key stored in authorizer options.
802 if ( strpos( $meta_key, 'acf___' ) === 0 && class_exists( 'acf' ) ) {
803 // We have an ACF field value, so use the ACF function to update it.
804 update_field( str_replace('acf___', '', $meta_key ), $user_info['usermeta']['meta_value'], 'user_' . $user->ID );
805 } else {
806 // We have a normal usermeta value, so just update it via the WordPress function.
807 update_user_meta( $user->ID, $meta_key, $user_info['usermeta']['meta_value'] );
808 }
809 }
810 } elseif ( is_multisite() && count( $user_info['usermeta'] ) > 0 ) {
811 // Update usermeta for each multisite blog defined for this user.
812 foreach ( $user_info['usermeta'] as $blog_id => $usermeta ) {
813 if ( array_key_exists( 'meta_key', $usermeta ) && array_key_exists( 'meta_value', $usermeta ) ) {
814 // Add this new user to the blog before we create their user meta (this step typically happens below, but we need it to happen early so we can create user meta here).
815 if ( ! is_user_member_of_blog( $user->ID, $blog_id ) ) {
816 add_user_to_blog( $blog_id, $user->ID, $user_info['role'] );
817 }
818 switch_to_blog( $blog_id );
819 // Update user's usermeta value for usermeta key stored in authorizer options.
820 if ( strpos( $meta_key, 'acf___' ) === 0 && class_exists( 'acf' ) ) {
821 // We have an ACF field value, so use the ACF function to update it.
822 update_field( str_replace('acf___', '', $meta_key ), $usermeta['meta_value'], 'user_' . $user->ID );
823 } else {
824 // We have a normal usermeta value, so just update it via the WordPress function.
825 update_user_meta( $user->ID, $meta_key, $usermeta['meta_value'] );
826 }
827 restore_current_blog();
828 }
829 }
830 }
831 }
832 } else {
833 // Update first/last names of WordPress user from external
834 // service if that option is set.
835 if ( ( array_key_exists( 'authenticated_by', $user_data ) && $user_data['authenticated_by'] === 'cas' && array_key_exists( 'cas_attr_update_on_login', $auth_settings ) && $auth_settings['cas_attr_update_on_login'] == 1 ) || ( array_key_exists( 'authenticated_by', $user_data ) && $user_data['authenticated_by'] === 'ldap' && array_key_exists( 'ldap_attr_update_on_login', $auth_settings ) && $auth_settings['ldap_attr_update_on_login'] == 1 ) ) {
836 if ( array_key_exists( 'first_name', $user_data ) && strlen( $user_data['first_name'] ) > 0 ) {
837 wp_update_user( array(
838 'ID' => $user->ID,
839 'first_name' => $user_data['first_name'],
840 ));
841 }
842 if ( array_key_exists( 'last_name', $user_data ) && strlen( $user_data['last_name'] ) > 0 ) {
843 wp_update_user( array(
844 'ID' => $user->ID,
845 'last_name' => $user_data['last_name'],
846 ));
847 }
848 }
849
850 // Update this user's role if it was modified in the
851 // authorizer_custom_role filter.
852 if ( $default_role !== $approved_role ) {
853 // Update user's role in WordPress.
854 $user->set_role( $approved_role );
855
856 // Update user's role in this site's approved list and save.
857 foreach ( $auth_settings_access_users_approved_single as $key => $existing_user ) {
858 if ( 0 === strcasecmp( $user->user_email, $existing_user['email'] ) ) {
859 $auth_settings_access_users_approved_single[$key]['role'] = $approved_role;
860 break;
861 }
862 }
863 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved_single );
864 }
865 }
866
867 // If this is multisite, add new user to current blog.
868 if ( is_multisite() && ! is_user_member_of_blog( $user->ID ) ) {
869 $result = add_user_to_blog( get_current_blog_id(), $user->ID, $user_info['role'] );
870
871 // Fail with message if error.
872 if ( is_wp_error( $result ) ) {
873 return $result;
874 }
875 }
876
877 // Ensure user has the same role as their entry in the approved list.
878 if ( $user_info && ! in_array( $user_info['role'], $user->roles ) ) {
879 $user->set_role( $user_info['role'] );
880 }
881
882 return $user;
883
884 // Note: only do this for the last email address we are checking (we need
885 // to iterate through them all to make sure one of them isn't approved).
886 } elseif ( 0 === strcasecmp( $user_email, $last_email ) ) {
887 // User isn't an admin, is not blocked, and is not approved.
888 // Add them to the pending list and notify them and their instructor.
889 if ( strlen( $user_email ) > 0 && ! $this->is_email_in_list( $user_email, 'pending' ) ) {
890 $pending_user = array();
891 $pending_user['email'] = $this->lowercase( $user_email );
892 $pending_user['role'] = $approved_role;
893 $pending_user['date_added'] = '';
894 array_push( $auth_settings_access_users_pending, $pending_user );
895 update_option( 'auth_settings_access_users_pending', $auth_settings_access_users_pending );
896
897 // Create strings used in the email notification.
898 $site_name = get_bloginfo( 'name' );
899 $site_url = get_bloginfo( 'url' );
900 $authorizer_options_url = $auth_settings['advanced_admin_menu'] === 'settings' ? admin_url( 'options-general.php?page=authorizer' ) : admin_url( '?page=authorizer' );
901
902 // Notify users with the role specified in "Which role should
903 // receive email notifications about pending users?".
904 if ( strlen( $auth_settings['access_role_receive_pending_emails'] ) > 0 ) {
905 foreach ( get_users( array( 'role' => $auth_settings['access_role_receive_pending_emails'] ) ) as $user_recipient ) {
906 wp_mail(
907 $user_recipient->user_email,
908 sprintf(
909 /* TRANSLATORS: 1: User email 2: Name of site */
910 __( 'Action required: Pending user %1$s at %2$s', 'authorizer' ),
911 $pending_user['email'],
912 $site_name
913 ),
914 sprintf(
915 /* TRANSLATORS: 1: Name of site 2: URL of site 3: URL of authorizer */
916 __( "A new user has tried to access the %1\$s site you manage at:\n%2\$s\n\nPlease log in to approve or deny their request:\n%3\$s\n", 'authorizer' ),
917 $site_name,
918 $site_url,
919 $authorizer_options_url
920 )
921 );
922 }
923 }
924 }
925
926 // Notify user about pending status and return without authenticating them.
927 $redirect_to = ! empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : home_url();
928 $page_title = get_bloginfo( 'name' ) . ' - Access Pending';
929 $error_message =
930 apply_filters( 'the_content', $auth_settings['access_pending_redirect_to_message'] ) .
931 '<hr />' .
932 '<p style="text-align: center;">' .
933 '<a class="button" href="' . wp_logout_url( $redirect_to ) . '">' .
934 __( 'Back', 'authorizer' ) .
935 '</a></p>';
936 update_option( 'auth_settings_advanced_login_error', $error_message );
937 wp_die( $error_message, $page_title );
938 }
939 }
940
941 // Sanity check: if we made it here without returning, something has gone wrong.
942 return new WP_Error( 'invalid_login', __( 'Invalid login attempted.', 'authorizer' ) );
943
944 }
945
946
947 /**
948 * Verify the Google login and set a session token.
949 *
950 * Flow: "Sign in with Google" button clicked; JS Google library
951 * called; JS function signInCallback() fired with results from Google;
952 * signInCallback() posts code and nonce (via AJAX) to this function;
953 * This function checks the token using the Google PHP library, and
954 * saves it to a session variable if it's authentic; control passes
955 * back to signInCallback(), which will reload the current page
956 * (wp-login.php) on success; wp-login.php reloads; custom_authenticate
957 * hooked into authenticate action fires again, and
958 * custom_authenticate_google() runs to verify the token; once verified
959 * custom_authenticate proceeds as normal with the google email address
960 * as a successfully authenticated external user.
961 *
962 * @return void, but die with the value to return to the success() function in AJAX call signInCallback()
963 */
964 function ajax_process_google_login() {
965 $nonce = array_key_exists( 'nonce', $_POST ) ? $_POST['nonce'] : '';
966 $code = array_key_exists( 'code', $_POST ) ? $_POST['code'] : null;
967
968 // Nonce check.
969 if ( ! wp_verify_nonce( $nonce, 'google_csrf_nonce' ) ) {
970 return '';
971 }
972
973 // Grab plugin settings.
974 $auth_settings = $this->get_plugin_options( SINGLE_ADMIN, 'allow override' );
975
976 // Add Google API PHP Client.
977 // @see https://github.com/google/google-api-php-client branch:v1-master
978 require_once dirname( __FILE__ ) . '/vendor/google-api-php-client/src/Google/autoload.php';
979
980 // Build the Google Client.
981 $client = new Google_Client();
982 $client->setApplicationName( 'WordPress' );
983 $client->setClientId( $auth_settings['google_clientid'] );
984 $client->setClientSecret( $auth_settings['google_clientsecret'] );
985 $client->setRedirectUri( 'postmessage' );
986
987 // If the hosted domain parameter is set, restrict logins to that domain.
988 // Note: Will have to upgrade to google-api-php-client v2 or higher for
989 // this to function server-side; it's not complete in v1, so this check
990 // is performed manually below.
991 // if ( array_key_exists( 'google_hosteddomain', $auth_settings ) && strlen( $auth_settings['google_hosteddomain'] ) > 0 ) {
992 // $google_hosteddomains = explode( "\n", str_replace( "\r", '', $auth_settings['google_hosteddomain'] ) );
993 // $google_hosteddomain = trim( $google_hosteddomains[0] );
994 // $client->setHostedDomain( $google_hosteddomain );
995 // }
996
997 // Get one time use token (if it doesn't exist, we'll create one below)
998 session_start();
999 $token = array_key_exists( 'token', $_SESSION ) ? json_decode( $_SESSION['token'] ) : null;
1000
1001 if ( empty( $token ) ) {
1002 // Exchange the OAuth 2.0 authorization code for user credentials.
1003 $client->authenticate( $code );
1004 $token = json_decode( $client->getAccessToken() );
1005
1006 // Store the token in the session for later use.
1007 $_SESSION['token'] = json_encode( $token );
1008
1009 $response = "Successfully authenticated.";
1010 } else {
1011 $client->setAccessToken( json_encode( $token ) );
1012
1013 $response = 'Already authenticated.';
1014 }
1015
1016 die( $response );
1017 }
1018
1019
1020 /**
1021 * Validate this user's credentials against Google.
1022 *
1023 * @param array $auth_settings Plugin settings
1024 * @return [mixed] Array containing email, authenticated_by,
1025 * first_name, last_name, and username
1026 * strings for the successfully authenticated
1027 * user, or WP_Error() object on failure,
1028 * or null if not attempting a google login.
1029 */
1030 private function custom_authenticate_google( $auth_settings ) {
1031 // Move on if Google auth hasn't been requested here.
1032 if ( empty( $_GET['external'] ) || $_GET['external'] !== 'google' ) {
1033 return null;
1034 }
1035
1036 // Get one time use token
1037 session_start();
1038 $token = array_key_exists( 'token', $_SESSION ) ? json_decode( $_SESSION['token'] ) : null;
1039
1040 // No token, so this is not a succesful Google login.
1041 if ( is_null( $token ) ) {
1042 return null;
1043 }
1044
1045 // Add Google API PHP Client.
1046 // @see https://github.com/google/google-api-php-client branch:v1-master
1047 require_once dirname( __FILE__ ) . '/vendor/google-api-php-client/src/Google/autoload.php';
1048
1049 // Build the Google Client.
1050 $client = new Google_Client();
1051 $client->setApplicationName( 'WordPress' );
1052 $client->setClientId( $auth_settings['google_clientid'] );
1053 $client->setClientSecret( $auth_settings['google_clientsecret'] );
1054 $client->setRedirectUri( 'postmessage' );
1055
1056 // If the hosted domain parameter is set, restrict logins to that domain.
1057 // Note: Will have to upgrade to google-api-php-client v2 or higher for
1058 // this to function server-side; it's not complete in v1, so this check
1059 // is performed manually below.
1060 // if ( array_key_exists( 'google_hosteddomain', $auth_settings ) && strlen( $auth_settings['google_hosteddomain'] ) > 0 ) {
1061 // $google_hosteddomains = explode( "\n", str_replace( "\r", '', $auth_settings['google_hosteddomain'] ) );
1062 // $google_hosteddomain = trim( $google_hosteddomains[0] );
1063 // $client->setHostedDomain( $google_hosteddomain );
1064 // }
1065
1066 // Verify this is a successful Google authentication
1067 try {
1068 $ticket = $client->verifyIdToken( $token->id_token, $auth_settings['google_clientid'] );
1069 } catch ( Google_Auth_Exception $e ) {
1070 // Invalid ticket, so this in not a successful Google login.
1071 return new WP_Error( 'invalid_google_login', __( 'Invalid Google credentials provided.', 'authorizer' ) );
1072 }
1073
1074 // Invalid ticket, so this in not a successful Google login.
1075 if ( ! $ticket ) {
1076 return new WP_Error( 'invalid_google_login', __( 'Invalid Google credentials provided.', 'authorizer' ) );
1077 }
1078
1079 // Get email address
1080 $attributes = $ticket->getAttributes();
1081 $email = $this->lowercase( $attributes['payload']['email'] );
1082 $email_domain = substr( strrchr( $email, '@' ), 1 );
1083 $username = current( explode( '@', $email ) );
1084
1085 // Fail if hd param is set and the logging in user's email address doesn't
1086 // match the allowed hosted domain.
1087 // See: https://developers.google.com/identity/protocols/OpenIDConnect#hd-param
1088 // See: https://github.com/google/google-api-php-client/blob/v1-master/src/Google/Client.php#L407-L416
1089 // Note: Will have to upgrade to google-api-php-client v2 or higher for
1090 // this to function server-side; it's not complete in v1, so this check
1091 // is only performed here.
1092 if ( array_key_exists( 'google_hosteddomain', $auth_settings ) && strlen( $auth_settings['google_hosteddomain'] ) > 0 ) {
1093 // Allow multiple whitelisted domains.
1094 $google_hosteddomains = explode( "\n", str_replace( "\r", '', $auth_settings['google_hosteddomain'] ) );
1095 if ( ! in_array( $email_domain, $google_hosteddomains ) ) {
1096 $this->custom_logout();
1097 return new WP_Error( 'invalid_google_login', __( 'Google credentials do not match the allowed hosted domain', 'authorizer' ) );
1098 }
1099 }
1100
1101 return array(
1102 'email' => $email,
1103 'username' => $username,
1104 'first_name' => '',
1105 'last_name' => '',
1106 'authenticated_by' => 'google',
1107 'google_attributes' => $attributes,
1108 );
1109 }
1110
1111
1112 /**
1113 * Validate this user's credentials against CAS.
1114 *
1115 * @param array $auth_settings Plugin settings
1116 * @return [mixed] Array containing 'email' and 'authenticated_by'
1117 * strings for the successfully authenticated
1118 * user, or WP_Error() object on failure,
1119 * or null if not attempting a CAS login.
1120 */
1121 private function custom_authenticate_cas( $auth_settings ) {
1122 // Move on if CAS hasn't been requested here.
1123 if ( empty( $_GET['external'] ) || $_GET['external'] !== 'cas' ) {
1124 return null;
1125 }
1126
1127 // Get the CAS server version (default to SAML_VERSION_1_1).
1128 // See: https://developer.jasig.org/cas-clients/php/1.3.4/docs/api/group__public.html
1129 $cas_version = SAML_VERSION_1_1;
1130 if ( $auth_settings['cas_version'] === 'CAS_VERSION_3_0' ) {
1131 $cas_version = CAS_VERSION_3_0;
1132 } elseif ( $auth_settings['cas_version'] === 'CAS_VERSION_2_0' ) {
1133 $cas_version = CAS_VERSION_2_0;
1134 } elseif ( $auth_settings['cas_version'] === 'CAS_VERSION_1_0' ) {
1135 $cas_version = CAS_VERSION_1_0;
1136 }
1137
1138 // Set the CAS client configuration
1139 phpCAS::client( $cas_version, $auth_settings['cas_host'], intval( $auth_settings['cas_port'] ), $auth_settings['cas_path'] );
1140
1141 // Update server certificate bundle if it doesn't exist or is older
1142 // than 6 months, then use it to ensure CAS server is legitimate.
1143 // Note: only try to update if the system has the php_openssl extension.
1144 $cacert_url = 'https://curl.haxx.se/ca/cacert.pem';
1145 $cacert_path = plugin_dir_path( __FILE__ ) . 'vendor/cacert.pem';
1146 $time_180_days = 180 * 24 * 60 * 60; // days * hours * minutes * seconds
1147 $time_180_days_ago = time() - $time_180_days;
1148 if (
1149 extension_loaded( 'openssl' ) &&
1150 ( ! file_exists( $cacert_path ) || filemtime( $cacert_path ) < $time_180_days_ago )
1151 ) {
1152 // Get new cacert.pem file from https://curl.haxx.se/ca/cacert.pem.
1153 $response = wp_safe_remote_get( $cacert_url );
1154 if (
1155 is_wp_error( $response ) ||
1156 200 !== wp_remote_retrieve_response_code( $response ) ||
1157 ! array_key_exists( 'body', $response )
1158 ) {
1159 new WP_Error( 'cannot_update_cacert', __( 'Unable to update outdated server certificates from https://curl.haxx.se/ca/cacert.pem.', 'authorizer' ) );
1160 }
1161 $cacert_contents = $response['body'];
1162
1163 // Write out the updated certs to the plugin directory.
1164 file_put_contents( $cacert_path, $cacert_contents );
1165 }
1166 phpCAS::setCasServerCACert( $cacert_path );
1167
1168 // Set the CAS service URL (including the redirect URL for WordPress when it comes back from CAS).
1169 $cas_service_url = site_url( '/wp-login.php?external=cas' );
1170 $login_querystring = array(); parse_str( $_SERVER['QUERY_STRING'], $login_querystring );
1171 if ( isset( $login_querystring['redirect_to'] ) ) {
1172 $cas_service_url .= '&redirect_to=' . urlencode( $login_querystring['redirect_to'] );
1173 }
1174 phpCAS::setFixedServiceURL( $cas_service_url );
1175
1176 // Authenticate against CAS
1177 try {
1178 phpCAS::forceAuthentication();
1179 } catch ( CAS_AuthenticationException $e ) {
1180 // CAS server threw an error in isAuthenticated(), potentially because
1181 // the cached ticket is outdated. Try renewing the authentication.
1182 error_log( __( 'CAS server returned an Authentication Exception. Details:', 'authorizer' ) );
1183 error_log( print_r( $e, true ) );
1184
1185 // CAS server is throwing errors on this login, so try logging the
1186 // user out of CAS and redirecting them to the login page.
1187 phpCAS::logoutWithRedirectService( wp_login_url() );
1188 die();
1189 }
1190
1191 // Get username (as specified by the CAS server).
1192 $username = phpCAS::getUser();
1193
1194 // Get email that successfully authenticated against the external service (CAS).
1195 $externally_authenticated_email = strtolower( $username );
1196 if ( ! filter_var( $externally_authenticated_email, FILTER_VALIDATE_EMAIL ) ) {
1197 // If we can't get the user's email address from a CAS attribute,
1198 // try to guess the domain from the CAS server hostname. This will only
1199 // be used if we can't discover the email address from CAS attributes.
1200 $domain_guess = preg_match( '/[^.]*\.[^.]*$/', $auth_settings['cas_host'], $matches ) === 1 ? $matches[0] : '';
1201 $externally_authenticated_email = $this->lowercase( $username ) . '@' . $domain_guess;
1202 }
1203
1204 // Retrieve the user attributes (e.g., email address, first name, last name) from the CAS server.
1205 $cas_attributes = phpCAS::getAttributes();
1206
1207 // Get user email if it is specified in another field.
1208 if ( array_key_exists( 'cas_attr_email', $auth_settings ) && strlen( $auth_settings['cas_attr_email'] ) > 0 ) {
1209 // If the email attribute starts with an at symbol (@), assume that the
1210 // email domain is manually entered there (instead of a reference to a
1211 // CAS attribute), and combine that with the username to create the email.
1212 // Otherwise, look up the CAS attribute for email.
1213 if ( substr( $auth_settings['cas_attr_email'], 0, 1 ) === '@' ) {
1214 $externally_authenticated_email = $this->lowercase( $username . $auth_settings['cas_attr_email'] );
1215 } elseif (
1216 // If a CAS attribute has been specified as containing the email address, use that instead.
1217 // Email attribute can be a string or an array of strings.
1218 array_key_exists( $auth_settings['cas_attr_email'], $cas_attributes ) && (
1219 (
1220 is_array( $cas_attributes[$auth_settings['cas_attr_email']] ) &&
1221 count( $cas_attributes[$auth_settings['cas_attr_email']] ) > 0
1222 ) || (
1223 is_string( $cas_attributes[$auth_settings['cas_attr_email']] ) &&
1224 strlen( $cas_attributes[$auth_settings['cas_attr_email']] ) > 0
1225 )
1226 )
1227 ) {
1228 // Each of the emails in the array needs to be set to lowercase.
1229 if ( is_array( $cas_attributes[$auth_settings['cas_attr_email']] ) ) {
1230 $externally_authenticated_email = array();
1231 foreach ( $cas_attributes[$auth_settings['cas_attr_email']] as $external_email ) {
1232 $externally_authenticated_email[] = $this->lowercase( $external_email );
1233 }
1234 } else {
1235 $externally_authenticated_email = $this->lowercase( $cas_attributes[$auth_settings['cas_attr_email']] );
1236 }
1237 }
1238 }
1239
1240 // Get user first name and last name.
1241 $first_name = array_key_exists( 'cas_attr_first_name', $auth_settings ) && strlen( $auth_settings['cas_attr_first_name'] ) > 0 && array_key_exists( $auth_settings['cas_attr_first_name'], $cas_attributes ) && strlen( $cas_attributes[$auth_settings['cas_attr_first_name']] ) > 0 ? $cas_attributes[$auth_settings['cas_attr_first_name']] : '';
1242 $last_name = array_key_exists( 'cas_attr_last_name', $auth_settings ) && strlen( $auth_settings['cas_attr_last_name'] ) > 0 && array_key_exists( $auth_settings['cas_attr_last_name'], $cas_attributes ) && strlen( $cas_attributes[$auth_settings['cas_attr_last_name']] ) > 0 ? $cas_attributes[$auth_settings['cas_attr_last_name']] : '';
1243
1244 return array(
1245 'email' => $externally_authenticated_email,
1246 'username' => $username,
1247 'first_name' => $first_name,
1248 'last_name' => $last_name,
1249 'authenticated_by' => 'cas',
1250 'cas_attributes' => $cas_attributes,
1251 );
1252 }
1253
1254
1255 /**
1256 * Validate this user's credentials against LDAP.
1257 *
1258 * @param array $auth_settings Plugin settings
1259 * @param string $username Attempted username from authenticate action
1260 * @param string $password Attempted password from authenticate action
1261 * @return [mixed] Array containing 'email' and 'authenticated_by'
1262 * strings for the successfully authenticated
1263 * user, or WP_Error() object on failure,
1264 * or null if skipping LDAP auth and falling back to WP auth.
1265 */
1266 private function custom_authenticate_ldap( $auth_settings, $username, $password ) {
1267 // Get the FQDN from the LDAP search base domain components (dc). For
1268 // example, ou=people,dc=example,dc=edu,dc=uk would yield user@example.edu.uk
1269 $search_base_components = explode( ',', trim( $auth_settings['ldap_search_base'] ) );
1270 $domain = array();
1271 foreach ( $search_base_components as $search_base_component ) {
1272 $component = explode( '=', $search_base_component );
1273 if ( count( $component ) === 2 && $component[0] === 'dc' ) {
1274 $domain[] = $component[1];
1275 }
1276 }
1277 $domain = implode( '.', $domain );
1278
1279 // If we can't get the logging in user's email address from an LDAP attribute,
1280 // just use the domain from the LDAP host. This will only be used if we
1281 // can't discover the email address from an LDAP attribute.
1282 if ( empty( $domain ) ) {
1283 $domain = preg_match( '/[^.]*\.[^.]*$/', $auth_settings['ldap_host'], $matches ) === 1 ? $matches[0] : '';
1284 }
1285
1286 // remove @domain if it exists in the username (i.e., if user entered their email)
1287 $username = str_replace( '@' . $domain, '', $username );
1288
1289 // Fail silently (fall back to WordPress authentication) if both username
1290 // and password are empty (this will be the case when visiting wp-login.php
1291 // for the first time, or when clicking the Log In button without filling
1292 // out either field.
1293 if ( empty( $username ) && empty( $password ) ) {
1294 return null;
1295 }
1296
1297 // Fail with error message if username or password is blank.
1298 if ( empty( $username ) ) {
1299 return new WP_Error( 'empty_username', __( 'You must provide a username or email.', 'authorizer' ) );
1300 }
1301 if ( empty( $password ) ) {
1302 return new WP_Error( 'empty_password', __( 'You must provide a password.', 'authorizer' ) );
1303 }
1304
1305 // If php5-ldap extension isn't installed on server, fall back to WP auth.
1306 if ( ! function_exists( 'ldap_connect' ) ) {
1307 return null;
1308 }
1309
1310 // Authenticate against LDAP using options provided in plugin settings.
1311 $result = false;
1312 $ldap_user_dn = '';
1313 $first_name = '';
1314 $last_name = '';
1315 $email = '';
1316
1317 // Construct LDAP connection parameters. ldap_connect() takes either a
1318 // hostname or a full LDAP URI as its first parameter (works with OpenLDAP
1319 // 2.x.x or later). If it's an LDAP URI, the second parameter, $port, is
1320 // ignored, and port must be specified in the full URI. An LDAP URI is of
1321 // the form ldap://hostname:port or ldaps://hostname:port.
1322 $ldap_host = $auth_settings['ldap_host'];
1323 $ldap_port = intval( $auth_settings['ldap_port'] );
1324 $parsed_host = parse_url( $ldap_host );
1325 // Fail (fall back to WordPress auth) if invalid host is specified.
1326 if ( $parsed_host === false ) {
1327 return null;
1328 }
1329 // If a scheme is in the LDAP host, use full LDAP URI instead of just hostname.
1330 if ( array_key_exists( 'scheme', $parsed_host ) ) {
1331 // If the port isn't in the LDAP URI, use the one in the LDAP port field.
1332 if ( ! array_key_exists( 'port', $parsed_host ) ) {
1333 $parsed_host['port'] = $ldap_port;
1334 }
1335 $ldap_host = $this->build_url( $parsed_host );
1336 }
1337
1338 // Establish LDAP connection.
1339 $ldap = ldap_connect( $ldap_host, $ldap_port );
1340 ldap_set_option( $ldap, LDAP_OPT_PROTOCOL_VERSION, 3 );
1341 if ( $auth_settings['ldap_tls'] == 1 ) {
1342 if( ! ldap_start_tls( $ldap ) ) {
1343 return null;
1344 }
1345 }
1346
1347 // Set bind credentials; attempt an anonymous bind if not provided.
1348 $bind_rdn = NULL;
1349 $bind_password = NULL;
1350 if ( strlen( $auth_settings['ldap_user'] ) > 0 ) {
1351 $bind_rdn = $auth_settings['ldap_user'];
1352 $bind_password = $this->decrypt( $auth_settings['ldap_password'] );
1353 }
1354
1355 // Attempt LDAP bind.
1356 $result = @ldap_bind( $ldap, $bind_rdn, stripslashes( $bind_password ) );
1357 if ( ! $result ) {
1358 // Can't connect to LDAP, so fall back to WordPress authentication.
1359 return null;
1360 }
1361 // Look up the bind DN (and first/last name) of the user trying to
1362 // log in by performing an LDAP search for the login username in
1363 // the field specified in the LDAP settings. This setup is common.
1364 $ldap_attributes_to_retrieve = array( 'dn' );
1365 if ( array_key_exists( 'ldap_attr_first_name', $auth_settings ) && strlen( $auth_settings['ldap_attr_first_name'] ) > 0 ) {
1366 array_push( $ldap_attributes_to_retrieve, $auth_settings['ldap_attr_first_name'] );
1367 }
1368 if ( array_key_exists( 'ldap_attr_last_name', $auth_settings ) && strlen( $auth_settings['ldap_attr_last_name'] ) > 0 ) {
1369 array_push( $ldap_attributes_to_retrieve, $auth_settings['ldap_attr_last_name'] );
1370 }
1371 if ( array_key_exists( 'ldap_attr_email', $auth_settings ) && strlen( $auth_settings['ldap_attr_email'] ) > 0 && substr( $auth_settings['ldap_attr_email'], 0, 1 ) !== '@' ) {
1372 array_push( $ldap_attributes_to_retrieve, $this->lowercase( $auth_settings['ldap_attr_email'] ) );
1373 }
1374 $ldap_search = ldap_search(
1375 $ldap,
1376 $auth_settings['ldap_search_base'],
1377 "(" . $auth_settings['ldap_uid'] . "=" . $username . ")",
1378 $ldap_attributes_to_retrieve
1379 );
1380 $ldap_entries = ldap_get_entries( $ldap, $ldap_search );
1381
1382 // If we didn't find any users in ldap, fall back to WordPress authentication.
1383 if ( $ldap_entries['count'] < 1 ) {
1384 return null;
1385 }
1386
1387 // Get the bind dn and first/last names; if there are multiple results returned, just get the last one.
1388 for ( $i = 0; $i < $ldap_entries['count']; $i++ ) {
1389 $ldap_user_dn = $ldap_entries[$i]['dn'];
1390
1391 // Get user first name and last name.
1392 $ldap_attr_first_name = array_key_exists( 'ldap_attr_first_name', $auth_settings ) ? $this->lowercase( $auth_settings['ldap_attr_first_name'] ) : '';
1393 if ( strlen( $ldap_attr_first_name ) > 0 && array_key_exists( $ldap_attr_first_name, $ldap_entries[$i] ) && $ldap_entries[$i][$ldap_attr_first_name]['count'] > 0 && strlen( $ldap_entries[$i][$ldap_attr_first_name][0] ) > 0 ) {
1394 $first_name = $ldap_entries[$i][$ldap_attr_first_name][0];
1395 }
1396 $ldap_attr_last_name = array_key_exists( 'ldap_attr_last_name', $auth_settings ) ? $this->lowercase( $auth_settings['ldap_attr_last_name'] ) : '';
1397 if ( strlen( $ldap_attr_last_name ) > 0 && array_key_exists( $ldap_attr_last_name, $ldap_entries[$i] ) && $ldap_entries[$i][$ldap_attr_last_name]['count'] > 0 && strlen( $ldap_entries[$i][$ldap_attr_last_name][0] ) > 0 ) {
1398 $last_name = $ldap_entries[$i][$ldap_attr_last_name][0];
1399 }
1400 // Get user email if it is specified in another field.
1401 $ldap_attr_email = array_key_exists( 'ldap_attr_email', $auth_settings ) ? $this->lowercase( $auth_settings['ldap_attr_email'] ) : '';
1402 if ( strlen( $ldap_attr_email ) > 0 ) {
1403 // If the email attribute starts with an at symbol (@), assume that the
1404 // email domain is manually entered there (instead of a reference to an
1405 // LDAP attribute), and combine that with the username to create the email.
1406 // Otherwise, look up the LDAP attribute for email.
1407 if ( substr( $ldap_attr_email, 0, 1 ) === '@' ) {
1408 $email = $this->lowercase( $username . $ldap_attr_email );
1409 } elseif ( array_key_exists( $ldap_attr_email, $ldap_entries[$i] ) && $ldap_entries[$i][$ldap_attr_email]['count'] > 0 && strlen( $ldap_entries[$i][$ldap_attr_email][0] ) > 0 ) {
1410 $email = $this->lowercase( $ldap_entries[$i][$ldap_attr_email][0] );
1411 }
1412 }
1413 }
1414
1415 $result = @ldap_bind( $ldap, $ldap_user_dn, stripslashes( $password ) );
1416 if ( ! $result ) {
1417 // We have a real ldap user, but an invalid password. Pass
1418 // through to wp authentication after failing LDAP (since
1419 // this could be a local account that happens to be the
1420 // same name as an LDAP user).
1421 return null;
1422 }
1423
1424 // User successfully authenticated against LDAP, so set the relevant variables.
1425 $externally_authenticated_email = $this->lowercase( $username . '@' . $domain );
1426
1427 // If an LDAP attribute has been specified as containing the email address, use that instead.
1428 if ( strlen( $email ) > 0 ) {
1429 $externally_authenticated_email = $this->lowercase( $email );
1430 }
1431
1432 return array(
1433 'email' => $externally_authenticated_email,
1434 'username' => $username,
1435 'first_name' => $first_name,
1436 'last_name' => $last_name,
1437 'authenticated_by' => 'ldap',
1438 'ldap_attributes' => $ldap_entries,
1439 );
1440 }
1441
1442
1443 /**
1444 * Log out of the attached external service.
1445 *
1446 * @return void
1447 */
1448 public function custom_logout() {
1449 // Grab plugin settings.
1450 $auth_settings = $this->get_plugin_options( SINGLE_ADMIN, 'allow override' );
1451
1452 // Reset option containing old error messages.
1453 delete_option( 'auth_settings_advanced_login_error' );
1454
1455 if ( session_id() == '' ) {
1456 session_start();
1457 }
1458
1459 $current_user_authenticated_by = get_user_meta( get_current_user_id(), 'authenticated_by', true );
1460
1461 // If logged in to CAS, Log out of CAS.
1462 if ( $current_user_authenticated_by === 'cas' && $auth_settings['cas'] === '1' ) {
1463 if ( ! array_key_exists( 'PHPCAS_CLIENT', $GLOBALS ) || ! array_key_exists( 'phpCAS', $_SESSION ) ) {
1464
1465 // Get the CAS server version (default to SAML_VERSION_1_1).
1466 // See: https://developer.jasig.org/cas-clients/php/1.3.4/docs/api/group__public.html
1467 $cas_version = SAML_VERSION_1_1;
1468 if ( $auth_settings['cas_version'] === 'CAS_VERSION_3_0' ) {
1469 $cas_version = CAS_VERSION_3_0;
1470 } elseif ( $auth_settings['cas_version'] === 'CAS_VERSION_2_0' ) {
1471 $cas_version = CAS_VERSION_2_0;
1472 } elseif ( $auth_settings['cas_version'] === 'CAS_VERSION_1_0' ) {
1473 $cas_version = CAS_VERSION_1_0;
1474 }
1475
1476 // Set the CAS client configuration if it hasn't been set already.
1477 phpCAS::client( $cas_version, $auth_settings['cas_host'], intval( $auth_settings['cas_port'] ), $auth_settings['cas_path'] );
1478 // Restrict logout request origin to the CAS server only (prevent DDOS).
1479 phpCAS::handleLogoutRequests( true, array( $auth_settings['cas_host'] ) );
1480 }
1481 if ( phpCAS::isAuthenticated() || phpCAS::isInitialized() ) {
1482 // Redirect to home page, or specified page if it's been provided.
1483 $redirect_to = site_url( '/' );
1484 if ( array_key_exists( 'redirect_to', $_REQUEST ) && filter_var( $_REQUEST['redirect_to'], FILTER_VALIDATE_URL ) !== false ) {
1485 $redirect_to = $_REQUEST['redirect_to'];
1486 }
1487
1488 phpCAS::logoutWithRedirectService( $redirect_to );
1489 }
1490 }
1491
1492 // If session token set, log out of Google.
1493 if ( $current_user_authenticated_by === 'google' || array_key_exists( 'token', $_SESSION ) ) {
1494 $token = json_decode( $_SESSION['token'] )->access_token;
1495
1496 // Add Google API PHP Client.
1497 // @see https://github.com/google/google-api-php-client branch:v1-master
1498 require_once dirname( __FILE__ ) . '/vendor/google-api-php-client/src/Google/autoload.php';
1499
1500 // Build the Google Client.
1501 $client = new Google_Client();
1502 $client->setApplicationName( 'WordPress' );
1503 $client->setClientId( $auth_settings['google_clientid'] );
1504 $client->setClientSecret( $auth_settings['google_clientsecret'] );
1505 $client->setRedirectUri( 'postmessage' );
1506
1507 // Revoke the token
1508 $client->revokeToken( $token );
1509
1510 // Remove the credentials from the user's session.
1511 unset( $_SESSION['token'] );
1512 }
1513
1514 }
1515
1516
1517
1518 /**
1519 * ***************************
1520 * Access Restriction
1521 * ***************************
1522 */
1523
1524
1525
1526 /**
1527 * Restrict access to WordPress site based on settings (everyone, logged_in_users).
1528 * Hook: parse_request http://codex.wordpress.org/Plugin_API/Action_Reference/parse_request
1529 *
1530 * @param array $wp WordPress object.
1531 *
1532 * @return void
1533 */
1534 public function restrict_access( $wp ) {
1535 // Grab plugin settings.
1536 $auth_settings = $this->get_plugin_options( SINGLE_ADMIN, 'allow override' );
1537
1538 // Grab current user.
1539 $current_user = wp_get_current_user();
1540
1541 $has_access = (
1542 // Always allow access if WordPress is installing
1543 ( defined( 'WP_INSTALLING' ) && isset( $_GET['key'] ) ) ||
1544 // Always allow access to admins
1545 ( current_user_can( 'create_users' ) ) ||
1546 // Allow access if option is set to 'everyone'
1547 ( $auth_settings['access_who_can_view'] == 'everyone' ) ||
1548 // Allow access to approved external users and logged in users if option is set to 'logged_in_users'
1549 ( $auth_settings['access_who_can_view'] == 'logged_in_users' && $this->is_user_logged_in_and_blog_user() && $this->is_email_in_list( $current_user->user_email, 'approved' ) ) ||
1550 // Allow access for requests to /wp-json/oauth1 so oauth clients can authenticate to use the REST API
1551 ( property_exists( $wp, 'matched_query' ) && stripos( $wp->matched_query, "rest_oauth1=" ) === 0 ) ||
1552 // Allow access for non-GET requests to /wp-json/*, since REST API authentication already covers them
1553 ( property_exists( $wp, 'matched_query' ) && stripos( $wp->matched_query, "rest_route=" ) === 0 && $_SERVER['REQUEST_METHOD'] !== 'GET' ) ||
1554 // Allow access for GET requests to /wp-json/ (root), since REST API discovery calls rely on this
1555 ( property_exists( $wp, 'matched_query' ) && $wp->matched_query === 'rest_route=/' )
1556 // Note that GET requests to a rest endpoint will be restricted by authorizer. In that case, error messages will be returned as JSON.
1557 );
1558
1559 /**
1560 * Developers can use the `authorizer_has_access` filter
1561 * to override restricted access on certain pages. Note that the
1562 * restriction checks happens before WordPress executes any queries, so
1563 * use the global `$wp` variable to investigate what the visitor is
1564 * trying to load.
1565 *
1566 * For example, to unblock an RSS feed, place the following PHP code in
1567 * the theme's functions.php file or in a simple plug-in:
1568 *
1569 * function my_rsa_feed_access_override( $has_access ) {
1570 * global $wp;
1571 * // check query variables to see if this is the feed
1572 * if ( ! empty( $wp->query_vars['feed'] ) )
1573 * $has_access = true;
1574 * return $has_access;
1575 * }
1576 * add_filter( 'authorizer_has_access', 'my_rsa_feed_access_override' );
1577 */
1578 if ( apply_filters( 'authorizer_has_access', $has_access, $wp ) === true ) {
1579 // Turn off the public notice about browsing anonymously
1580 update_option( 'auth_settings_advanced_public_notice', false );
1581
1582 // We've determined that the current user has access, so simply return to grant access.
1583 return $wp;
1584 }
1585
1586 // Allow HEAD requests to the root (usually discovery from a REST client).
1587 if ( $_SERVER['REQUEST_METHOD'] === 'HEAD' && empty( $wp->request ) && empty( $wp->matched_query ) ) {
1588 return $wp;
1589 }
1590
1591 // We've determined that the current user doesn't have access, so we deal with them now.
1592
1593 // Fringe case: In a multisite, a user of a different blog can successfully
1594 // log in, but they aren't on the 'approved' whitelist for this blog.
1595 // If that's the case, add them to the pending list for this blog.
1596 if ( is_multisite() && is_user_logged_in() && ! $has_access ) {
1597 $current_user = wp_get_current_user();
1598
1599 // Check user access; block if not, add them to pending list if open, let them through otherwise.
1600 $result = $this->check_user_access( $current_user, array( $current_user->user_email ) );
1601 }
1602
1603 // Check to see if the requested page is public. If so, show it.
1604 if ( empty( $wp->request ) ) {
1605 $current_page_id = 'home';
1606 } else {
1607 $request_query = isset( $wp->query_vars ) ? new WP_Query( $wp->query_vars ) : null;
1608 $current_page_id = isset( $request_query->post_count ) && $request_query->post_count > 0 ? $request_query->post->ID : '';
1609 }
1610 if ( ! array_key_exists( 'access_public_pages', $auth_settings ) || ! is_array( $auth_settings['access_public_pages'] ) ) {
1611 $auth_settings['access_public_pages'] = array();
1612 }
1613 if ( in_array( $current_page_id, $auth_settings['access_public_pages'] ) ) {
1614 if ( $auth_settings['access_public_warning'] === 'no_warning' ) {
1615 update_option( 'auth_settings_advanced_public_notice', false );
1616 } else {
1617 update_option( 'auth_settings_advanced_public_notice', true );
1618 }
1619 return $wp;
1620 }
1621
1622 // Check to see if any category assigned to the requested page is public. If so, show it.
1623 $current_page_categories = wp_get_post_categories( $current_page_id, array( 'fields' => 'slugs' ) );
1624 foreach( $current_page_categories as $current_page_category ) {
1625 if ( in_array( 'cat_' . $current_page_category, $auth_settings['access_public_pages'] ) ) {
1626 if ( $auth_settings['access_public_warning'] === 'no_warning' ) {
1627 update_option( 'auth_settings_advanced_public_notice', false );
1628 } else {
1629 update_option( 'auth_settings_advanced_public_notice', true );
1630 }
1631 return $wp;
1632 }
1633 }
1634
1635 // Check to see if this page can't be found. If so, allow showing the 404 page.
1636 if ( strlen( $current_page_id ) < 1 ) {
1637 if ( in_array( 'auth_public_404', $auth_settings['access_public_pages'] ) ) {
1638 if ( $auth_settings['access_public_warning'] === 'no_warning' ) {
1639 update_option( 'auth_settings_advanced_public_notice', false );
1640 } else {
1641 update_option( 'auth_settings_advanced_public_notice', true );
1642 }
1643 return $wp;
1644 }
1645 }
1646
1647 // Check to see if the requested category is public. If so, show it.
1648 $current_category_name = property_exists( $wp, 'query_vars' ) && array_key_exists( 'category_name', $wp->query_vars ) && strlen( $wp->query_vars['category_name'] ) > 0 ? $wp->query_vars['category_name'] : '';
1649 if ( $current_category_name ) {
1650 $current_category_name = end( explode( '/', $current_category_name ) );
1651 if ( in_array( 'cat_' . $current_category_name, $auth_settings['access_public_pages'] ) ) {
1652 if ( $auth_settings['access_public_warning'] === 'no_warning' ) {
1653 update_option( 'auth_settings_advanced_public_notice', false );
1654 } else {
1655 update_option( 'auth_settings_advanced_public_notice', true );
1656 }
1657 return $wp;
1658 }
1659 }
1660
1661 // User is denied access, so show them the error message. Render as JSON
1662 // if this is a REST API call; otherwise, show the error message via
1663 // wp_die() (rendered html), or redirect to the login URL.
1664 $current_path = empty( $_SERVER['REQUEST_URI'] ) ? home_url() : $_SERVER['REQUEST_URI'];
1665 if ( property_exists( $wp, 'matched_query' ) && stripos( $wp->matched_query, "rest_route=" ) === 0 && $_SERVER['REQUEST_METHOD'] === 'GET' ) {
1666 wp_send_json( array(
1667 'code' => 'rest_cannot_view',
1668 'message' => strip_tags( $auth_settings['access_redirect_to_message'] ),
1669 'data' => array(
1670 'status' => 401,
1671 ),
1672 ));
1673 } elseif ( $auth_settings['access_redirect'] === 'message' ) {
1674 $page_title = sprintf(
1675 /* TRANSLATORS: %s: Name of blog */
1676 __( '%s - Access Restricted', 'authorizer' ),
1677 get_bloginfo( 'name' )
1678 );
1679 $error_message =
1680 apply_filters( 'the_content', $auth_settings['access_redirect_to_message'] ) .
1681 '<hr />' .
1682 '<p style="text-align: center;margin-bottom: -15px;">' .
1683 '<a class="button" href="' . wp_login_url( $current_path ) . '">' .
1684 __( 'Log In', 'authorizer' ) .
1685 '</a></p>';
1686 wp_die( $error_message, $page_title );
1687 } else { // if ( $auth_settings['access_redirect'] === 'login' ) {
1688 wp_redirect( wp_login_url( $current_path ), 302 );
1689 exit;
1690 }
1691
1692 // Sanity check: we should never get here
1693 wp_die( '<p>Access denied.</p>', 'Site Access Restricted' );
1694 }
1695
1696
1697 /**
1698 * On an admin page load, check for edge case (network-approved user who has
1699 * not yet been added to this particular blog in a multisite). Note: we do
1700 * this because check_user_access() runs on the parse_request hook, which
1701 * does not fire on wp-admin pages.
1702 *
1703 * Hook: admin_menu
1704 */
1705 public function init__maybe_add_network_approved_user() {
1706 global $current_user;
1707
1708 // If this is a multisite install and we have a logged in user that's not
1709 // a member of this blog, but is (network) approved, add them to this blog.
1710 if (
1711 is_admin() &&
1712 is_multisite() &&
1713 is_user_logged_in() &&
1714 ! is_user_member_of_blog() &&
1715 $this->is_email_in_list( $current_user->user_email, 'approved' )
1716 ) {
1717 // Get all approved users.
1718 $auth_settings_access_users_approved = $this->sanitize_user_list(
1719 array_merge(
1720 $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN ),
1721 $this->get_plugin_option( 'access_users_approved', MULTISITE_ADMIN )
1722 )
1723 );
1724
1725 // Get user info (we need user role).
1726 $user_info = $this->get_user_info_from_list(
1727 $current_user->user_email,
1728 $auth_settings_access_users_approved
1729 );
1730
1731 // Add user to blog.
1732 add_user_to_blog( get_current_blog_id(), $current_user->ID, $user_info['role'] );
1733
1734 // Refresh user permissions.
1735 $current_user = new WP_User( $current_user->ID );
1736 }
1737 }
1738
1739
1740
1741 /**
1742 * ***************************
1743 * Login page (wp-login.php)
1744 * ***************************
1745 */
1746
1747
1748
1749 /**
1750 * Add custom error message to login screen.
1751 * Filter: login_errors
1752 */
1753 function show_advanced_login_error( $errors ) {
1754 $error = get_option( 'auth_settings_advanced_login_error' );
1755 delete_option( 'auth_settings_advanced_login_error' );
1756 $errors = ' ' . $error . "<br />\n";
1757 return $errors;
1758 }
1759
1760
1761 /**
1762 * Load external resources for the public-facing site.
1763 */
1764 function auth_public_scripts() {
1765 // Load (and localize) public scripts
1766 $current_path = empty( $_SERVER['REQUEST_URI'] ) ? home_url() : $_SERVER['REQUEST_URI'];
1767 wp_enqueue_script( 'auth_public_scripts', plugins_url( '/js/authorizer-public.js', __FILE__ ), array( 'jquery' ), '2.3.2' );
1768 $auth_localized = array(
1769 'wp_login_url' => wp_login_url( $current_path ),
1770 'public_warning' => get_option( 'auth_settings_advanced_public_notice' ),
1771 'anonymous_notice' => $this->get_plugin_option( 'access_redirect_to_message' ),
1772 'log_in' => esc_html__( 'Log In', 'authorizer' ),
1773 );
1774 wp_localize_script( 'auth_public_scripts', 'auth', $auth_localized );
1775 //update_option( 'auth_settings_advanced_public_notice', false);
1776
1777 // Load public css
1778 wp_register_style( 'authorizer-public-css', plugins_url( 'css/authorizer-public.css', __FILE__ ), array(), '2.3.2' );
1779 wp_enqueue_style( 'authorizer-public-css' );
1780 }
1781
1782
1783 /**
1784 * Enqueue JS scripts and CSS styles appearing on wp-login.php.
1785 *
1786 * @return void
1787 */
1788 function login_enqueue_scripts_and_styles() {
1789 // Grab plugin settings.
1790 $auth_settings = $this->get_plugin_options( SINGLE_ADMIN, 'allow override' );
1791
1792 // Enqueue scripts appearing on wp-login.php.
1793 wp_enqueue_script( 'auth_login_scripts', plugins_url( '/js/authorizer-login.js', __FILE__ ), array( 'jquery' ), '2.3.2' );
1794
1795 // Enqueue styles appearing on wp-login.php.
1796 wp_register_style( 'authorizer-login-css', plugins_url( '/css/authorizer-login.css', __FILE__ ), array(), '2.3.2' );
1797 wp_enqueue_style( 'authorizer-login-css' );
1798
1799 /**
1800 * Developers can use the `authorizer_add_branding_option` filter
1801 * to add a radio button for "Custom WordPress login branding"
1802 * under the "Advanced" tab in Authorizer options. Example:
1803 *
1804 * function my_authorizer_add_branding_option( $branding_options ) {
1805 * $new_branding_option = array(
1806 * 'value' => 'your_brand'
1807 * 'description' => 'Custom Your Brand Login Screen',
1808 * 'css_url' => 'http://url/to/your_brand.css',
1809 * 'js_url' => 'http://url/to/your_brand.js',
1810 * );
1811 * array_push( $branding_options, $new_branding_option );
1812 * return $branding_options;
1813 * }
1814 * add_filter( 'authorizer_add_branding_option', 'my_authorizer_add_branding_option' );
1815 */
1816 $branding_options = array();
1817 $branding_options = apply_filters( 'authorizer_add_branding_option', $branding_options );
1818 foreach ( $branding_options as $branding_option ) {
1819 // Make sure the custom brands have the required values
1820 if ( ! ( is_array( $branding_option ) && array_key_exists( 'value', $branding_option ) && array_key_exists( 'css_url', $branding_option ) && array_key_exists( 'js_url', $branding_option ) ) ) {
1821 continue;
1822 }
1823 if ( $auth_settings['advanced_branding'] === $branding_option['value'] ) {
1824 wp_enqueue_script( 'auth_login_custom_scripts-' . sanitize_title( $branding_option['value'] ), $branding_option['js_url'], array( 'jquery' ), '2.3.2' );
1825 wp_register_style( 'authorizer-login-custom-css-' . sanitize_title( $branding_option['value'] ), $branding_option['css_url'], array(), '2.3.2' );
1826 wp_enqueue_style( 'authorizer-login-custom-css-' . sanitize_title( $branding_option['value'] ) );
1827 }
1828 }
1829
1830 // If we're using Google logins, load those resources.
1831 if ( $auth_settings['google'] === '1' ) {
1832 wp_enqueue_script( 'authorizer-login-custom-google', plugins_url( '/js/authorizer-login-custom_google.js', __FILE__ ), array( 'jquery' ), '2.3.2' ); ?>
1833 <meta name="google-signin-clientid" content="<?php echo $auth_settings['google_clientid']; ?>" />
1834 <meta name="google-signin-scope" content="email" />
1835 <meta name="google-signin-cookiepolicy" content="single_host_origin" />
1836 <?php
1837 }
1838 }
1839
1840
1841 /**
1842 * Load external resources in the footer of the wp-login.php page.
1843 * Run on action hook: login_footer
1844 */
1845 function load_login_footer_js() {
1846 // Grab plugin settings.
1847 $auth_settings = $this->get_plugin_options( SINGLE_ADMIN, 'allow override' ); ?>
1848 <?php if ( $auth_settings['google'] === '1' ): ?>
1849 <script type="text/javascript">
1850 // Reload login page if reauth querystring param exists,
1851 // since reauth interrupts external logins (e.g., google).
1852 if ( location.search.indexOf( 'reauth=1' ) >= 0 ) {
1853 location.href = location.href.replace( 'reauth=1', '' );
1854 }
1855
1856 function auth_update_querystring_param( uri, key, value ) {
1857 var re = new RegExp( '([?&])' + key + '=.*?(&|$)', 'i' );
1858 var separator = uri.indexOf( '?' ) !== -1 ? '&' : '?';
1859 if ( uri.match( re ) ) {
1860 return uri.replace( re, '$1' + key + '=' + value + '$2' );
1861 } else {
1862 return uri + separator + key + '=' + value;
1863 }
1864 }
1865
1866 function signInCallback( authResult ) {
1867 var $ = jQuery;
1868 if ( authResult['status'] && authResult['status']['signed_in'] ) {
1869 // Hide the sign-in button now that the user is authorized, for example:
1870 $( '#googleplus_button' ).attr( 'style', 'display: none' );
1871
1872 // Send the code to the server
1873 var ajaxurl = '<?php echo admin_url( "admin-ajax.php" ); ?>';
1874 $.post(ajaxurl, {
1875 action: 'process_google_login',
1876 'code': authResult['code'],
1877 'nonce': $('#nonce_google_auth-<?php echo $this->get_cookie_value(); ?>' ).val(),
1878 }, function( response ) {
1879 // Handle or verify the server response if necessary.
1880 //console.log( response );
1881
1882 // Reload wp-login.php to continue the authentication process.
1883 var new_href = auth_update_querystring_param( location.href, 'external', 'google' );
1884 if ( location.href === new_href ) {
1885 location.reload();
1886 } else {
1887 location.href = new_href;
1888 }
1889 });
1890 } else {
1891 // Update the app to reflect a signed out user
1892 // Possible error values:
1893 // "user_signed_out" - User is signed-out
1894 // "access_denied" - User denied access to your app
1895 // "immediate_failed" - Could not automatically log in the user
1896 //console.log('Sign-in state: ' + authResult['error']);
1897
1898 // If user denies access, reload the login page.
1899 if ( authResult['error'] === 'access_denied' || authResult['error'] === 'user_signed_out' ) {
1900 window.location.reload();
1901 }
1902 }
1903 }
1904 </script>
1905 <?php endif;
1906 }
1907
1908
1909 /**
1910 * Create links for any external authentication services that are enabled.
1911 */
1912 function login_form_add_external_service_links() {
1913 // Grab plugin settings.
1914 $auth_settings = $this->get_plugin_options( SINGLE_ADMIN, 'allow override' ); ?>
1915 <div id="auth-external-service-login">
1916 <?php if ( $auth_settings['google'] === '1' ): ?>
1917 <p><a id="googleplus_button" class="button button-primary button-external button-google"><span class="dashicons dashicons-googleplus"></span><span class="label"><?php _e( 'Sign in with Google', 'authorizer' ); ?></span></a></p>
1918 <?php wp_nonce_field( 'google_csrf_nonce', 'nonce_google_auth-' . $this->get_cookie_value() ); ?>
1919 <?php endif; ?>
1920
1921 <?php if ( $auth_settings['cas'] === '1' ): ?>
1922 <p><a class="button button-primary button-external button-cas" href="<?php echo $this->modify_current_url_for_cas_login(); ?>">
1923 <span class="dashicons dashicons-lock"></span>
1924 <span class="label"><?php
1925 printf(
1926 /* TRANSLATORS: %s: Custom CAS label from authorizer options */
1927 __( 'Sign in with %s', 'authorizer' ),
1928 $auth_settings['cas_custom_label']
1929 );
1930 ?></span>
1931 </a></p>
1932 <?php endif; ?>
1933
1934 <?php if ( $auth_settings['advanced_hide_wp_login'] === '1' && strpos( $_SERVER['QUERY_STRING'], 'external=wordpress' ) === false ): ?>
1935 <style type="text/css">
1936 #loginform {
1937 padding-bottom: 8px !important;
1938 }
1939 #loginform p>label, #loginform p.forgetmenot, #loginform p.submit, p#nav {
1940 display: none !important;
1941 }
1942 </style>
1943 <?php elseif ( $auth_settings['cas'] === '1' || $auth_settings['google'] === '1' ): ?>
1944 <h3> &mdash; <?php _e( 'or', 'authorizer' ); ?> &mdash; </h3>
1945 <?php endif; ?>
1946 </div>
1947 <?php
1948
1949 }
1950
1951
1952 /**
1953 * Redirect to CAS login when visiting login page (only if option is
1954 * enabled, CAS is the only service, and WordPress logins are hidden).
1955 * Note: hook into wp_login_errors filter so this fires after the
1956 * authenticate hook (where the redirect to CAS happens), but before html
1957 * output is started (so the redirect header doesn't complain about data
1958 * already being sent).
1959 */
1960 function wp_login_errors__maybe_redirect_to_cas( $errors, $redirect_to ) {
1961 // Grab plugin settings.
1962 $auth_settings = $this->get_plugin_options( SINGLE_ADMIN, 'allow override' );
1963
1964 // Check whether we should redirect to CAS.
1965 if (
1966 strpos( $_SERVER['QUERY_STRING'], 'external=wordpress' ) === false &&
1967 array_key_exists( 'cas_auto_login', $auth_settings ) && $auth_settings['cas_auto_login'] === '1' &&
1968 array_key_exists( 'cas', $auth_settings ) && $auth_settings['cas'] === '1' &&
1969 ( ! array_key_exists( 'ldap', $auth_settings ) || $auth_settings['ldap'] !== '1' ) &&
1970 ( ! array_key_exists( 'google', $auth_settings ) || $auth_settings['google'] !== '1' ) &&
1971 array_key_exists( 'advanced_hide_wp_login', $auth_settings ) && $auth_settings['advanced_hide_wp_login'] === '1'
1972 ) {
1973 wp_redirect( $this->modify_current_url_for_cas_login() );
1974 exit;
1975 }
1976
1977 return $errors;
1978 }
1979
1980
1981 /**
1982 * Set a unique cookie to add to Google auth nonce to avoid CSRF detection.
1983 * Note: hook into login_init so this fires at the start of the visit to
1984 * wp-login.php, but before any html output is started (so setting the
1985 * cookie header doesn't complain about data already being sent).
1986 */
1987 function login_init__maybe_set_google_nonce_cookie() {
1988 // Grab plugin settings.
1989 $auth_settings = $this->get_plugin_options( SINGLE_ADMIN, 'allow override' );
1990
1991 // If Google logins are enabled, make sure the cookie is set.
1992 if ( array_key_exists( 'google', $auth_settings ) && $auth_settings['google'] === '1' ) {
1993 if ( ! isset( $_COOKIE['login_unique'] ) ) {
1994 $this->cookie_value = md5( rand() );
1995 setcookie( 'login_unique', $this->cookie_value, time()+1800, '/', defined( 'COOKIE_DOMAIN' ) ? COOKIE_DOMAIN : '' );
1996 $_COOKIE['login_unique'] = $this->cookie_value;
1997 }
1998 }
1999 }
2000
2001
2002 /**
2003 * Implements hook: do_action( 'wp_login_failed', $username );
2004 * Update the user meta for the user that just failed logging in.
2005 * Keep track of time of last failed attempt and number of failed attempts.
2006 */
2007 function update_login_failed_count( $username ) {
2008 // Grab plugin settings.
2009 $auth_settings = $this->get_plugin_options( SINGLE_ADMIN, 'allow override' );
2010
2011 // Get user trying to log in.
2012 // If this isn't a real user, update the global failed attempt
2013 // variables. We'll use these global variables to institute the
2014 // lockouts on nonexistent accounts. We do this so an attacker
2015 // won't be able to determine which accounts are real by which
2016 // accounts get locked out on multiple invalid attempts.
2017 $user = get_user_by( 'login', $username );
2018
2019 if ( $user !== FALSE ) {
2020 $last_attempt = get_user_meta( $user->ID, 'auth_settings_advanced_lockouts_time_last_failed', true );
2021 $num_attempts = get_user_meta( $user->ID, 'auth_settings_advanced_lockouts_failed_attempts', true );
2022 } else {
2023 $last_attempt = get_option( 'auth_settings_advanced_lockouts_time_last_failed' );
2024 $num_attempts = get_option( 'auth_settings_advanced_lockouts_failed_attempts' );
2025 }
2026
2027 // Make sure $last_attempt (time) and $num_attempts are positive integers.
2028 // Note: this addresses resetting them if either is unset from above.
2029 $last_attempt = abs( intval( $last_attempt ) );
2030 $num_attempts = abs( intval( $num_attempts ) );
2031
2032 // Reset the failed attempt count if the time since the last
2033 // failed attempt is greater than the reset duration.
2034 $time_since_last_fail = time() - $last_attempt;
2035 $reset_duration = $auth_settings['advanced_lockouts']['reset_duration'] * 60; // minutes to seconds
2036 if ( $time_since_last_fail > $reset_duration ) {
2037 $num_attempts = 0;
2038 }
2039
2040 // Set last failed time to now and increment last failed count.
2041 if ( $user !== FALSE ) {
2042 update_user_meta( $user->ID, 'auth_settings_advanced_lockouts_time_last_failed', time() );
2043 update_user_meta( $user->ID, 'auth_settings_advanced_lockouts_failed_attempts', $num_attempts + 1 );
2044 } else {
2045 update_option( 'auth_settings_advanced_lockouts_time_last_failed', time() );
2046 update_option( 'auth_settings_advanced_lockouts_failed_attempts', $num_attempts + 1 );
2047 }
2048 }
2049
2050
2051 /**
2052 * When they successfully log in, make sure WordPress users are in the approved list.
2053 *
2054 * @action wp_login
2055 *
2056 * @param string $user_login Username of the user logging in.
2057 * @param WP_User $user WP_User object of the user logging in.
2058 * @return null
2059 */
2060 function ensure_wordpress_user_in_approved_list_on_login( $user_login, $user ) {
2061 $this->add_user_to_authorizer_when_created( $user->user_email, $user->user_registered, $user->roles );
2062 }
2063
2064
2065 /**
2066 * Overwrite the URL for the lost password link on the login form.
2067 * If we're authenticating against an external service, standard
2068 * WordPress password resets won't work.
2069 */
2070 function custom_lostpassword_url( $lostpassword_url ) {
2071 // Grab plugin settings.
2072 $auth_settings = $this->get_plugin_options( SINGLE_ADMIN, 'allow override' );
2073
2074 if (
2075 array_key_exists( 'ldap_lostpassword_url', $auth_settings ) &&
2076 filter_var( $auth_settings['ldap_lostpassword_url'], FILTER_VALIDATE_URL )
2077 ) {
2078 $lostpassword_url = $auth_settings['ldap_lostpassword_url'];
2079 }
2080 return $lostpassword_url;
2081 }
2082
2083
2084
2085 /**
2086 * ***************************
2087 * Options page
2088 * ***************************
2089 */
2090
2091
2092
2093 /**
2094 * Add a link to this plugin's settings page from the WordPress Plugins page.
2095 * Called from "plugin_action_links" filter in __construct() above.
2096 *
2097 * @param array $links array of links in the admin sidebar
2098 *
2099 * @return array of links to show in the admin sidebar.
2100 */
2101 public function plugin_settings_link( $links ) {
2102 $admin_menu = $this->get_plugin_option( 'advanced_admin_menu' );
2103 $settings_url = $admin_menu === 'settings' ? admin_url( 'options-general.php?page=authorizer' ) : admin_url( 'admin.php?page=authorizer' );
2104 array_unshift( $links, '<a href="' . $settings_url . '">' . __( 'Settings', 'authorizer' ) . '</a>' );
2105 return $links;
2106 }
2107
2108
2109 /**
2110 * Add a link to this plugin's network settings page from the WordPress Plugins page.
2111 * Called from "network_admin_plugin_action_links" filter in __construct() above.
2112 *
2113 * @param array $links array of links in the network admin sidebar
2114 *
2115 * @return array of links to show in the network admin sidebar.
2116 */
2117 public function network_admin_plugin_settings_link( $links ) {
2118 $settings_link = '<a href="admin.php?page=authorizer">' . __( 'Network Settings', 'authorizer' ) . '</a>';
2119 array_unshift( $links, $settings_link );
2120 return $links;
2121 }
2122
2123
2124 /**
2125 * Create the options page under Dashboard > Settings
2126 * Run on action hook: admin_menu
2127 */
2128 public function add_plugin_page() {
2129 $admin_menu = $this->get_plugin_option( 'advanced_admin_menu' );
2130 if ( $admin_menu === 'settings' ) {
2131 // @see http://codex.wordpress.org/Function_Reference/add_options_page
2132 add_options_page(
2133 'Authorizer', // Page title
2134 'Authorizer', // Menu title
2135 'create_users', // Capability
2136 'authorizer', // Menu slug
2137 array( $this, 'create_admin_page' ) // function
2138 );
2139 } else {
2140 // @see http://codex.wordpress.org/Function_Reference/add_menu_page
2141 add_menu_page(
2142 'Authorizer', // Page title
2143 'Authorizer', // Menu title
2144 'create_users', // Capability
2145 'authorizer', // Menu slug
2146 array( $this, 'create_admin_page' ), // callback
2147 'dashicons-groups', // icon
2148 '99.0018465' // position (decimal is to make overlap with other plugins less likely)
2149 );
2150 }
2151 }
2152
2153
2154 /**
2155 * Output the HTML for the options page
2156 */
2157 public function create_admin_page() { ?>
2158 <div class="wrap">
2159 <h2><?php _e( 'Authorizer Settings', 'authorizer' ); ?></h2>
2160 <form method="post" action="options.php" autocomplete="off"><?php
2161 // This prints out all hidden settings fields
2162 // @see http://codex.wordpress.org/Function_Reference/settings_fields
2163 settings_fields( 'auth_settings_group' );
2164 // This prints out all the sections
2165 // @see http://codex.wordpress.org/Function_Reference/do_settings_sections
2166 do_settings_sections( 'authorizer' );
2167 submit_button(); ?>
2168 </form>
2169 </div><?php
2170 }
2171
2172
2173 /**
2174 * Load external resources on this plugin's options page.
2175 * Run on action hooks: load-settings_page_authorizer, load-toplevel_page_authorizer, admin_head-index.php
2176 */
2177 public function load_options_page() {
2178 wp_enqueue_script(
2179 'authorizer',
2180 plugins_url( 'js/authorizer.js', __FILE__ ),
2181 array( 'jquery-effects-shake' ), '2.7.0', true
2182 );
2183 wp_localize_script( 'authorizer', 'auth_L10n', array(
2184 'baseurl' => get_bloginfo( 'url' ),
2185 'saved' => esc_html__( 'Saved', 'authorizer' ),
2186 'duplicate' => esc_html__( 'Duplicate', 'authorizer' ),
2187 'failed' => esc_html__( 'Failed', 'authorizer' ),
2188 'local_wordpress_user' => esc_html__( 'Local WordPress user', 'authorizer' ),
2189 'block_ban_user' => esc_html__( 'Block/Ban user', 'authorizer' ),
2190 'remove_user' => esc_html__( 'Remove user', 'authorizer' ),
2191 'no_users_in' => esc_html__( 'No users in', 'authorizer' ),
2192 'save_changes' => esc_html__( 'Save Changes', 'authorizer' ),
2193 'private_pages' => esc_html__( 'Private Pages', 'authorizer' ),
2194 'public_pages' => esc_html__( 'Public Pages', 'authorizer' ),
2195 'first_page' => esc_html__( 'First page' ),
2196 'previous_page' => esc_html__( 'Previous page' ),
2197 'next_page' => esc_html__( 'Next page' ),
2198 'last_page' => esc_html__( 'Last page' ),
2199 'is_network_admin' => is_network_admin(),
2200 ));
2201
2202 wp_enqueue_script(
2203 'jquery-autogrow-textarea',
2204 plugins_url( 'vendor/jquery.autogrow-textarea/jquery.autogrow-textarea.js', __FILE__ ),
2205 array( 'jquery' ), '2.7.0', true
2206 );
2207
2208 wp_enqueue_script(
2209 'jquery.multi-select',
2210 plugins_url( 'vendor/jquery.multi-select/js/jquery.multi-select.js', __FILE__ ),
2211 array( 'jquery' ), '1.8', true
2212 );
2213
2214 wp_register_style( 'authorizer-css', plugins_url( 'css/authorizer.css', __FILE__ ), array(), '2.7.0' );
2215 wp_enqueue_style( 'authorizer-css' );
2216
2217 wp_register_style( 'jquery-multi-select-css', plugins_url( 'vendor/jquery.multi-select/css/multi-select.css', __FILE__ ), array(), '1.8' );
2218 wp_enqueue_style( 'jquery-multi-select-css' );
2219
2220 add_action( 'admin_notices', array( $this, 'admin_notices' ) ); // Add any notices to the top of the options page.
2221 add_action( 'admin_head', array( $this, 'admin_head' ) ); // Add help documentation to the options page.
2222 }
2223
2224
2225 /**
2226 * Show custom admin notice.
2227 * Filter: admin_notice
2228 */
2229 function show_advanced_admin_notice() {
2230 $notice = get_option( 'auth_settings_advanced_admin_notice' );
2231 delete_option( 'auth_settings_advanced_admin_notice' );
2232
2233 if ( $notice && strlen( $notice ) > 0 ) { ?>
2234 <div class="error">
2235 <p><?php echo $notice; ?></p>
2236 </div><?php
2237 }
2238 }
2239
2240
2241 /**
2242 * Add notices to the top of the options page.
2243 * Run on action hook chain: load-settings_page_authorizer > admin_notices
2244 * Description: Check for invalid settings combinations and show a warning message, e.g.:
2245 * if ( cas url inaccessible ) : ?>
2246 * <div class='updated settings-error'><p>Can't reach CAS server.</p></div>
2247 * <?php endif;
2248 */
2249 public function admin_notices() {
2250 // Grab plugin settings.
2251 $auth_settings = $this->get_plugin_options( SINGLE_ADMIN, 'allow override' );
2252
2253 if ( $auth_settings['cas'] === '1' ) :
2254 // Check if provided CAS URL is accessible.
2255 $protocol = in_array( $auth_settings['cas_port'], array( '80', '8080' ) ) ? 'http' : 'https';
2256 $cas_url = $protocol . '://' . $auth_settings['cas_host'] . ':' . $auth_settings['cas_port'] . $auth_settings['cas_path'];
2257 $cas_url = trailingslashit( $cas_url ) . 'login'; // Check the specific CAS login endpoint
2258 if ( ! $this->url_is_accessible( $cas_url ) ) :
2259 $authorizer_options_url = $auth_settings['advanced_admin_menu'] === 'settings' ? admin_url( 'options-general.php?page=authorizer' ) : admin_url( '?page=authorizer' );
2260 ?><div class='notice notice-warning is-dismissible'>
2261 <p><?php _e( "Can't reach CAS server. Please provide", 'authorizer' ); ?> <a href='<?php echo $authorizer_options_url; ?>&tab=external'><?php _e( 'accurate CAS settings', 'authorizer' ); ?></a> <?php _e( 'if you intend to use it.', 'authorizer' ); ?></p>
2262 </div><?php
2263 endif;
2264 endif;
2265 }
2266
2267
2268 /**
2269 * Create sections and options
2270 * Run on action hook: admin_init
2271 */
2272 public function page_init() {
2273 // Create one setting that holds all the options (array)
2274 // @see http://codex.wordpress.org/Function_Reference/register_setting
2275 // @see http://codex.wordpress.org/Function_Reference/add_settings_section
2276 // @see http://codex.wordpress.org/Function_Reference/add_settings_field
2277 register_setting(
2278 'auth_settings_group', // Option group
2279 'auth_settings', // Option name
2280 array( $this, 'sanitize_options' ) // Sanitize callback
2281 );
2282
2283 add_settings_section(
2284 'auth_settings_tabs', // HTML element ID
2285 '', // HTML element Title
2286 array( $this, 'print_section_info_tabs' ), // Callback (echos section content)
2287 'authorizer' // Page this section is shown on (slug)
2288 );
2289
2290 // Create Access Lists section
2291 add_settings_section(
2292 'auth_settings_lists', // HTML element ID
2293 '', // HTML element Title
2294 array( $this, 'print_section_info_access_lists' ), // Callback (echos section content)
2295 'authorizer' // Page this section is shown on (slug)
2296 );
2297
2298 // Create Login Access section
2299 add_settings_section(
2300 'auth_settings_access_login', // HTML element ID
2301 '', // HTML element Title
2302 array( $this, 'print_section_info_access_login' ), // Callback (echos section content)
2303 'authorizer' // Page this section is shown on (slug)
2304 );
2305 add_settings_field(
2306 'auth_settings_access_who_can_login', // HTML element ID
2307 __( 'Who can log into the site?', 'authorizer' ), // HTML element Title
2308 array( $this, 'print_radio_auth_access_who_can_login' ), // Callback (echos form element)
2309 'authorizer', // Page this setting is shown on (slug)
2310 'auth_settings_access_login' // Section this setting is shown on
2311 );
2312 add_settings_field(
2313 'auth_settings_access_role_receive_pending_emails', // HTML element ID
2314 __( 'Which role should receive email notifications about pending users?', 'authorizer' ), // HTML element Title
2315 array( $this, 'print_select_auth_access_role_receive_pending_emails' ), // Callback (echos form element)
2316 'authorizer', // Page this setting is shown on (slug)
2317 'auth_settings_access_login' // Section this setting is shown on
2318 );
2319 add_settings_field(
2320 'auth_settings_access_pending_redirect_to_message', // HTML element ID
2321 __( 'What message should pending users see after attempting to log in?', 'authorizer' ), // HTML element Title
2322 array( $this, 'print_wysiwyg_auth_access_pending_redirect_to_message' ), // Callback (echos form element)
2323 'authorizer', // Page this setting is shown on (slug)
2324 'auth_settings_access_login' // Section this setting is shown on
2325 );
2326 add_settings_field(
2327 'auth_settings_access_blocked_redirect_to_message', // HTML element ID
2328 __( 'What message should blocked users see after attempting to log in?', 'authorizer' ), // HTML element Title
2329 array( $this, 'print_wysiwyg_auth_access_blocked_redirect_to_message' ), // Callback (echos form element)
2330 'authorizer', // Page this setting is shown on (slug)
2331 'auth_settings_access_login' // Section this setting is shown on
2332 );
2333 add_settings_field(
2334 'auth_settings_access_should_email_approved_users', // HTML element ID
2335 __( 'Send welcome email to new approved users?', 'authorizer' ), // HTML element Title
2336 array( $this, 'print_checkbox_auth_access_should_email_approved_users' ), // Callback (echos form element)
2337 'authorizer', // Page this setting is shown on (slug)
2338 'auth_settings_access_login' // Section this setting is shown on
2339 );
2340 add_settings_field(
2341 'auth_settings_access_email_approved_users_subject', // HTML element ID
2342 __( 'Welcome email subject', 'authorizer' ), // HTML element Title
2343 array( $this, 'print_text_auth_access_email_approved_users_subject' ), // Callback (echos form element)
2344 'authorizer', // Page this setting is shown on (slug)
2345 'auth_settings_access_login' // Section this setting is shown on
2346 );
2347 add_settings_field(
2348 'auth_settings_access_email_approved_users_body', // HTML element ID
2349 __( 'Welcome email body', 'authorizer' ), // HTML element Title
2350 array( $this, 'print_wysiwyg_auth_access_email_approved_users_body' ), // Callback (echos form element)
2351 'authorizer', // Page this setting is shown on (slug)
2352 'auth_settings_access_login' // Section this setting is shown on
2353 );
2354
2355
2356 // Create Public Access section
2357 add_settings_section(
2358 'auth_settings_access_public', // HTML element ID
2359 '', // HTML element Title
2360 array( $this, 'print_section_info_access_public' ), // Callback (echos section content)
2361 'authorizer' // Page this section is shown on (slug)
2362 );
2363 add_settings_field(
2364 'auth_settings_access_who_can_view', // HTML element ID
2365 __( 'Who can view the site?', 'authorizer' ), // HTML element Title
2366 array( $this, 'print_radio_auth_access_who_can_view' ), // Callback (echos form element)
2367 'authorizer', // Page this setting is shown on (slug)
2368 'auth_settings_access_public' // Section this setting is shown on
2369 );
2370 add_settings_field(
2371 'auth_settings_access_public_pages', // HTML element ID
2372 __( 'What pages (if any) should be available to everyone?', 'authorizer' ), // HTML element Title
2373 array( $this, 'print_multiselect_auth_access_public_pages' ), // Callback (echos form element)
2374 'authorizer', // Page this setting is shown on (slug)
2375 'auth_settings_access_public' // Section this setting is shown on
2376 );
2377 add_settings_field(
2378 'auth_settings_access_redirect', // HTML element ID
2379 __( 'What happens to people without access when they visit a private page?', 'authorizer' ), // HTML element Title
2380 array( $this, 'print_radio_auth_access_redirect' ), // Callback (echos form element)
2381 'authorizer', // Page this setting is shown on (slug)
2382 'auth_settings_access_public' // Section this setting is shown on
2383 );
2384 add_settings_field(
2385 'auth_settings_access_public_warning', // HTML element ID
2386 __( 'What happens to people without access when they visit a public page?', 'authorizer' ), // HTML element Title
2387 array( $this, 'print_radio_auth_access_public_warning' ), // Callback (echos form element)
2388 'authorizer', // Page this setting is shown on (slug)
2389 'auth_settings_access_public' // Section this setting is shown on
2390 );
2391 add_settings_field(
2392 'auth_settings_access_redirect_to_message', // HTML element ID
2393 __( 'What message should people without access see?', 'authorizer' ), // HTML element Title
2394 array( $this, 'print_wysiwyg_auth_access_redirect_to_message' ), // Callback (echos form element)
2395 'authorizer', // Page this setting is shown on (slug)
2396 'auth_settings_access_public' // Section this setting is shown on
2397 );
2398
2399 // Create External Service Settings section
2400 add_settings_section(
2401 'auth_settings_external', // HTML element ID
2402 '', // HTML element Title
2403 array( $this, 'print_section_info_external' ), // Callback (echos section content)
2404 'authorizer' // Page this section is shown on (slug)
2405 );
2406 add_settings_field(
2407 'auth_settings_access_default_role', // HTML element ID
2408 __( 'Default role for new users', 'authorizer' ), // HTML element Title
2409 array( $this, 'print_select_auth_access_default_role' ), // Callback (echos form element)
2410 'authorizer', // Page this setting is shown on (slug)
2411 'auth_settings_external' // Section this setting is shown on
2412 );
2413 add_settings_field(
2414 'auth_settings_external_google', // HTML element ID
2415 __( 'Google Logins', 'authorizer' ), // HTML element Title
2416 array( $this, 'print_checkbox_auth_external_google' ), // Callback (echos form element)
2417 'authorizer', // Page this setting is shown on (slug)
2418 'auth_settings_external' // Section this setting is shown on
2419 );
2420 add_settings_field(
2421 'auth_settings_google_clientid', // HTML element ID
2422 __( 'Google Client ID', 'authorizer' ), // HTML element Title
2423 array( $this, 'print_text_google_clientid' ), // Callback (echos form element)
2424 'authorizer', // Page this setting is shown on (slug)
2425 'auth_settings_external' // Section this setting is shown on
2426 );
2427 add_settings_field(
2428 'auth_settings_google_clientsecret', // HTML element ID
2429 __( 'Google Client Secret', 'authorizer' ), // HTML element Title
2430 array( $this, 'print_text_google_clientsecret' ), // Callback (echos form element)
2431 'authorizer', // Page this setting is shown on (slug)
2432 'auth_settings_external' // Section this setting is shown on
2433 );
2434 add_settings_field(
2435 'auth_settings_google_hosteddomain', // HTML element ID
2436 __( 'Google Hosted Domain', 'authorizer' ), // HTML element Title
2437 array( $this, 'print_text_google_hosteddomain' ), // Callback (echos form element)
2438 'authorizer', // Page this setting is shown on (slug)
2439 'auth_settings_external' // Section this setting is shown on
2440 );
2441 add_settings_field(
2442 'auth_settings_external_cas', // HTML element ID
2443 __( 'CAS Logins', 'authorizer' ), // HTML element Title
2444 array( $this, 'print_checkbox_auth_external_cas' ), // Callback (echos form element)
2445 'authorizer', // Page this setting is shown on (slug)
2446 'auth_settings_external' // Section this setting is shown on
2447 );
2448 add_settings_field(
2449 'auth_settings_cas_custom_label', // HTML element ID
2450 __( 'CAS custom label', 'authorizer' ), // HTML element Title
2451 array( $this, 'print_text_cas_custom_label' ), // Callback (echos form element)
2452 'authorizer', // Page this setting is shown on (slug)
2453 'auth_settings_external' // Section this setting is shown on
2454 );
2455 add_settings_field(
2456 'auth_settings_cas_host', // HTML element ID
2457 __( 'CAS server hostname', 'authorizer' ), // HTML element Title
2458 array( $this, 'print_text_cas_host' ), // Callback (echos form element)
2459 'authorizer', // Page this setting is shown on (slug)
2460 'auth_settings_external' // Section this setting is shown on
2461 );
2462 add_settings_field(
2463 'auth_settings_cas_port', // HTML element ID
2464 __( 'CAS server port', 'authorizer' ), // HTML element Title
2465 array( $this, 'print_text_cas_port' ), // Callback (echos form element)
2466 'authorizer', // Page this setting is shown on (slug)
2467 'auth_settings_external' // Section this setting is shown on
2468 );
2469 add_settings_field(
2470 'auth_settings_cas_path', // HTML element ID
2471 __( 'CAS server path/context', 'authorizer' ), // HTML element Title
2472 array( $this, 'print_text_cas_path' ), // Callback (echos form element)
2473 'authorizer', // Page this setting is shown on (slug)
2474 'auth_settings_external' // Section this setting is shown on
2475 );
2476 add_settings_field(
2477 'auth_settings_cas_version', // HTML element ID
2478 'CAS server version', // HTML element Title
2479 array( $this, 'print_select_cas_version' ), // Callback (echos form element)
2480 'authorizer', // Page this setting is shown on (slug)
2481 'auth_settings_external' // Section this setting is shown on
2482 );
2483 add_settings_field(
2484 'auth_settings_cas_attr_email', // HTML element ID
2485 __( 'CAS attribute containing email address', 'authorizer' ), // HTML element Title
2486 array( $this, 'print_text_cas_attr_email' ), // Callback (echos form element)
2487 'authorizer', // Page this setting is shown on (slug)
2488 'auth_settings_external' // Section this setting is shown on
2489 );
2490 add_settings_field(
2491 'auth_settings_cas_attr_first_name', // HTML element ID
2492 __( 'CAS attribute containing first name', 'authorizer' ), // HTML element Title
2493 array( $this, 'print_text_cas_attr_first_name' ), // Callback (echos form element)
2494 'authorizer', // Page this setting is shown on (slug)
2495 'auth_settings_external' // Section this setting is shown on
2496 );
2497 add_settings_field(
2498 'auth_settings_cas_attr_last_name', // HTML element ID
2499 __( 'CAS attribute containing last name', 'authorizer' ), // HTML element Title
2500 array( $this, 'print_text_cas_attr_last_name' ), // Callback (echos form element)
2501 'authorizer', // Page this setting is shown on (slug)
2502 'auth_settings_external' // Section this setting is shown on
2503 );
2504 add_settings_field(
2505 'auth_settings_cas_attr_update_on_login', // HTML element ID
2506 __( 'CAS attribute update', 'authorizer' ), // HTML element Title
2507 array( $this, 'print_checkbox_cas_attr_update_on_login' ), // Callback (echos form element)
2508 'authorizer', // Page this setting is shown on (slug)
2509 'auth_settings_external' // Section this setting is shown on
2510 );
2511 add_settings_field(
2512 'auth_settings_cas_auto_login', // HTML element ID
2513 __( 'CAS automatic login', 'authorizer' ), // HTML element Title
2514 array( $this, 'print_checkbox_cas_auto_login' ), // Callback (echos form element)
2515 'authorizer', // Page this setting is shown on (slug)
2516 'auth_settings_external' // Section this setting is shown on
2517 );
2518 add_settings_field(
2519 'auth_settings_external_ldap', // HTML element ID
2520 __( 'LDAP Logins', 'authorizer' ), // HTML element Title
2521 array( $this, 'print_checkbox_auth_external_ldap' ), // Callback (echos form element)
2522 'authorizer', // Page this setting is shown on (slug)
2523 'auth_settings_external' // Section this setting is shown on
2524 );
2525 add_settings_field(
2526 'auth_settings_ldap_host', // HTML element ID
2527 __( 'LDAP Host', 'authorizer' ), // HTML element Title
2528 array( $this, 'print_text_ldap_host' ), // Callback (echos form element)
2529 'authorizer', // Page this setting is shown on (slug)
2530 'auth_settings_external' // Section this setting is shown on
2531 );
2532 add_settings_field(
2533 'auth_settings_ldap_port', // HTML element ID
2534 __( 'LDAP Port', 'authorizer' ), // HTML element Title
2535 array( $this, 'print_text_ldap_port' ), // Callback (echos form element)
2536 'authorizer', // Page this setting is shown on (slug)
2537 'auth_settings_external' // Section this setting is shown on
2538 );
2539 add_settings_field(
2540 'auth_settings_ldap_tls', // HTML element ID
2541 __( 'Use TLS', 'authorizer' ), // HTML element Title
2542 array( $this, 'print_checkbox_ldap_tls' ), // Callback (echos form element)
2543 'authorizer', // Page this setting is shown on (slug)
2544 'auth_settings_external' // Section this setting is shown on
2545 );
2546 add_settings_field(
2547 'auth_settings_ldap_search_base', // HTML element ID
2548 __( 'LDAP Search Base', 'authorizer' ), // HTML element Title
2549 array( $this, 'print_text_ldap_search_base' ), // Callback (echos form element)
2550 'authorizer', // Page this setting is shown on (slug)
2551 'auth_settings_external' // Section this setting is shown on
2552 );
2553 add_settings_field(
2554 'auth_settings_ldap_uid', // HTML element ID
2555 __( 'LDAP attribute containing username', 'authorizer' ), // HTML element Title
2556 array( $this, 'print_text_ldap_uid' ), // Callback (echos form element)
2557 'authorizer', // Page this setting is shown on (slug)
2558 'auth_settings_external' // Section this setting is shown on
2559 );
2560 add_settings_field(
2561 'auth_settings_ldap_attr_email', // HTML element ID
2562 __( 'LDAP attribute containing email address', 'authorizer' ), // HTML element Title
2563 array( $this, 'print_text_ldap_attr_email' ), // Callback (echos form element)
2564 'authorizer', // Page this setting is shown on (slug)
2565 'auth_settings_external' // Section this setting is shown on
2566 );
2567 add_settings_field(
2568 'auth_settings_ldap_user', // HTML element ID
2569 __( 'LDAP Directory User', 'authorizer' ), // HTML element Title
2570 array( $this, 'print_text_ldap_user' ), // Callback (echos form element)
2571 'authorizer', // Page this setting is shown on (slug)
2572 'auth_settings_external' // Section this setting is shown on
2573 );
2574 add_settings_field(
2575 'auth_settings_ldap_password', // HTML element ID
2576 __( 'LDAP Directory User Password', 'authorizer' ), // HTML element Title
2577 array( $this, 'print_password_ldap_password' ), // Callback (echos form element)
2578 'authorizer', // Page this setting is shown on (slug)
2579 'auth_settings_external' // Section this setting is shown on
2580 );
2581 add_settings_field(
2582 'auth_settings_ldap_lostpassword_url', // HTML element ID
2583 __( 'Custom lost password URL', 'authorizer' ), // HTML element Title
2584 array( $this, 'print_text_ldap_lostpassword_url' ), // Callback (echos form element)
2585 'authorizer', // Page this setting is shown on (slug)
2586 'auth_settings_external' // Section this setting is shown on
2587 );
2588 add_settings_field(
2589 'auth_settings_ldap_attr_first_name', // HTML element ID
2590 __( 'LDAP attribute containing first name', 'authorizer' ), // HTML element Title
2591 array( $this, 'print_text_ldap_attr_first_name' ), // Callback (echos form element)
2592 'authorizer', // Page this setting is shown on (slug)
2593 'auth_settings_external' // Section this setting is shown on
2594 );
2595 add_settings_field(
2596 'auth_settings_ldap_attr_last_name', // HTML element ID
2597 __( 'LDAP attribute containing last name', 'authorizer' ), // HTML element Title
2598 array( $this, 'print_text_ldap_attr_last_name' ), // Callback (echos form element)
2599 'authorizer', // Page this setting is shown on (slug)
2600 'auth_settings_external' // Section this setting is shown on
2601 );
2602 add_settings_field(
2603 'auth_settings_ldap_attr_update_on_login', // HTML element ID
2604 __( 'LDAP attribute update', 'authorizer' ), // HTML element Title
2605 array( $this, 'print_checkbox_ldap_attr_update_on_login' ), // Callback (echos form element)
2606 'authorizer', // Page this setting is shown on (slug)
2607 'auth_settings_external' // Section this setting is shown on
2608 );
2609
2610 // Create Advanced Settings section
2611 add_settings_section(
2612 'auth_settings_advanced', // HTML element ID
2613 '', // HTML element Title
2614 array( $this, 'print_section_info_advanced' ), // Callback (echos section content)
2615 'authorizer' // Page this section is shown on (slug)
2616 );
2617 add_settings_field(
2618 'auth_settings_advanced_lockouts', // HTML element ID
2619 __( 'Limit invalid login attempts', 'authorizer' ), // HTML element Title
2620 array( $this, 'print_text_auth_advanced_lockouts' ), // Callback (echos form element)
2621 'authorizer', // Page this setting is shown on (slug)
2622 'auth_settings_advanced' // Section this setting is shown on
2623 );
2624 add_settings_field(
2625 'auth_settings_advanced_hide_wp_login', // HTML element ID
2626 __( 'Hide WordPress Login', 'authorizer' ), // HTML element Title
2627 array( $this, 'print_checkbox_auth_advanced_hide_wp_login' ), // Callback (echos form element)
2628 'authorizer', // Page this setting is shown on (slug)
2629 'auth_settings_advanced' // Section this setting is shown on
2630 );
2631 add_settings_field(
2632 'auth_settings_advanced_branding', // HTML element ID
2633 __( 'Custom WordPress login branding', 'authorizer' ), // HTML element Title
2634 array( $this, 'print_radio_auth_advanced_branding' ), // Callback (echos form element)
2635 'authorizer', // Page this setting is shown on (slug)
2636 'auth_settings_advanced' // Section this setting is shown on
2637 );
2638 add_settings_field(
2639 'auth_settings_advanced_admin_menu', // HTML element ID
2640 __( 'Authorizer admin menu item location', 'authorizer' ), // HTML element Title
2641 array( $this, 'print_radio_auth_advanced_admin_menu' ), // Callback (echos form element)
2642 'authorizer', // Page this setting is shown on (slug)
2643 'auth_settings_advanced' // Section this setting is shown on
2644 );
2645 add_settings_field(
2646 'auth_settings_advanced_usermeta', // HTML element ID
2647 __( 'Show custom usermeta in user list', 'authorizer' ), // HTML element Title
2648 array( $this, 'print_select_auth_advanced_usermeta' ), // Callback (echos form element)
2649 'authorizer', // Page this setting is shown on (slug)
2650 'auth_settings_advanced' // Section this setting is shown on
2651 );
2652 add_settings_field(
2653 'auth_settings_advanced_users_per_page', // HTML element ID
2654 __( 'Number of users per page', 'authorizer' ), // HTML element Title
2655 array( $this, 'print_text_auth_advanced_users_per_page' ), // Callback (echos form element)
2656 'authorizer', // Page this setting is shown on (slug)
2657 'auth_settings_advanced' // Section this setting is shown on
2658 );
2659 add_settings_field(
2660 'auth_settings_advanced_users_sort_by', // HTML element ID
2661 __( 'Approved users sort method', 'authorizer' ), // HTML element Title
2662 array( $this, 'print_select_auth_advanced_users_sort_by' ), // Callback (echos form element)
2663 'authorizer', // Page this setting is shown on (slug)
2664 'auth_settings_advanced' // Section this setting is shown on
2665 );
2666 add_settings_field(
2667 'auth_settings_advanced_users_sort_order', // HTML element ID
2668 __( 'Approved users sort order', 'authorizer' ), // HTML element Title
2669 array( $this, 'print_select_auth_advanced_users_sort_order' ), // Callback (echos form element)
2670 'authorizer', // Page this setting is shown on (slug)
2671 'auth_settings_advanced' // Section this setting is shown on
2672 );
2673 add_settings_field(
2674 'auth_settings_advanced_widget_enabled', // HTML element ID
2675 __( 'Show dashboard widget to admin users', 'authorizer' ), // HTML element Title
2676 array( $this, 'print_checkbox_auth_advanced_widget_enabled' ), // Callback (echos form element)
2677 'authorizer', // Page this setting is shown on (slug)
2678 'auth_settings_advanced' // Section this setting is shown on
2679 );
2680 // On multisite installs, add an option to override all multisite settings on individual sites.
2681 if ( is_multisite() ) {
2682 add_settings_field(
2683 'auth_settings_advanced_override_multisite', // HTML element ID
2684 __( 'Override multisite options', 'authorizer' ), // HTML element Title
2685 array( $this, 'print_checkbox_auth_advanced_override_multisite' ), // Callback (echos form element)
2686 'authorizer', // Page this setting is shown on (slug)
2687 'auth_settings_advanced' // Section this setting is shown on
2688 );
2689 }
2690 }
2691
2692
2693 /**
2694 * Set meaningful defaults for the plugin options.
2695 * Note: This function is called on plugin activation.
2696 */
2697 function set_default_options() {
2698 global $wp_roles;
2699
2700 $auth_settings = get_option( 'auth_settings' );
2701 if ( $auth_settings === FALSE ) {
2702 $auth_settings = array();
2703 }
2704
2705 // Access Lists Defaults.
2706 $auth_settings_access_users_pending = get_option( 'auth_settings_access_users_pending' );
2707 if ( $auth_settings_access_users_pending === FALSE ) {
2708 $auth_settings_access_users_pending = array();
2709 }
2710 $auth_settings_access_users_approved = get_option( 'auth_settings_access_users_approved' );
2711 if ( $auth_settings_access_users_approved === FALSE ) {
2712 $auth_settings_access_users_approved = array();
2713 }
2714 $auth_settings_access_users_blocked = get_option( 'auth_settings_access_users_blocked' );
2715 if ( $auth_settings_access_users_blocked === FALSE ) {
2716 $auth_settings_access_users_blocked = array();
2717 }
2718
2719 // Login Access Defaults.
2720 if ( ! array_key_exists( 'access_who_can_login', $auth_settings ) ) {
2721 $auth_settings['access_who_can_login'] = 'approved_users';
2722 }
2723 if ( ! array_key_exists( 'access_role_receive_pending_emails', $auth_settings ) ) {
2724 $auth_settings['access_role_receive_pending_emails'] = '---';
2725 }
2726 if ( ! array_key_exists( 'access_pending_redirect_to_message', $auth_settings ) ) {
2727 $auth_settings['access_pending_redirect_to_message'] = '<p>' . __( "You're not currently allowed to view this site. Your administrator has been notified, and once he/she has approved your request, you will be able to log in. If you need any other help, please contact your administrator.", 'authorizer' ) . '</p>';
2728 }
2729 if ( ! array_key_exists( 'access_blocked_redirect_to_message', $auth_settings ) ) {
2730 $auth_settings['access_blocked_redirect_to_message'] = '<p>' . __( "You're not currently allowed to log into this site. If you think this is a mistake, please contact your administrator.", 'authorizer' ) . '</p>';
2731 }
2732 if ( ! array_key_exists( 'access_should_email_approved_users', $auth_settings ) ) {
2733 $auth_settings['access_should_email_approved_users'] = '';
2734 }
2735 if ( ! array_key_exists( 'access_email_approved_users_subject', $auth_settings ) ) {
2736 $auth_settings['access_email_approved_users_subject'] = sprintf(
2737 /* TRANSLATORS: %s: Shortcode for name of site */
2738 __( 'Welcome to %s!', 'authorizer' ),
2739 '[site_name]'
2740 );
2741 }
2742 if ( ! array_key_exists( 'access_email_approved_users_body', $auth_settings ) ) {
2743 $auth_settings['access_email_approved_users_body'] = sprintf(
2744 /* TRANSLATORS: 1: Shortcode for user email 2: Shortcode for site name 3: Shortcode for site URL */
2745 __( "Hello %1\$s,\nWelcome to %2\$s! You now have access to all content on the site. Please visit us here:\n%3\$s\n", 'authorizer' ),
2746 '[user_email]',
2747 '[site_name]',
2748 '[site_url]'
2749 );
2750 }
2751
2752 // Public Access to Private Page Defaults.
2753 if ( ! array_key_exists( 'access_who_can_view', $auth_settings ) ) {
2754 $auth_settings['access_who_can_view'] = 'everyone';
2755 }
2756 if ( ! array_key_exists( 'access_public_pages', $auth_settings ) ) {
2757 $auth_settings['access_public_pages'] = array();
2758 }
2759 if ( ! array_key_exists( 'access_redirect', $auth_settings ) ) {
2760 $auth_settings['access_redirect'] = 'login';
2761 }
2762 if ( ! array_key_exists( 'access_public_warning', $auth_settings ) ) {
2763 $auth_settings['access_public_warning'] = 'no_warning';
2764 }
2765 if ( ! array_key_exists( 'access_redirect_to_message', $auth_settings ) ) {
2766 $auth_settings['access_redirect_to_message'] = '<p>' . __( 'Notice: You are browsing this site anonymously, and only have access to a portion of its content.', 'authorizer' ) . '</p>';
2767 }
2768
2769
2770 // External Service Defaults.
2771 if ( ! array_key_exists( 'access_default_role', $auth_settings ) ) {
2772 // Set default role to 'student' if that role exists, 'subscriber' otherwise.
2773 $all_roles = $wp_roles->roles;
2774 $editable_roles = apply_filters( 'editable_roles', $all_roles );
2775 if ( array_key_exists( 'student', $editable_roles ) ) {
2776 $auth_settings['access_default_role'] = 'student';
2777 } else {
2778 $auth_settings['access_default_role'] = 'subscriber';
2779 }
2780 }
2781
2782 if ( ! array_key_exists( 'google', $auth_settings ) ) {
2783 $auth_settings['google'] = '';
2784 }
2785 if ( ! array_key_exists( 'cas', $auth_settings ) ) {
2786 $auth_settings['cas'] = '';
2787 }
2788 if ( ! array_key_exists( 'ldap', $auth_settings ) ) {
2789 $auth_settings['ldap'] = '';
2790 }
2791
2792 if ( ! array_key_exists( 'google_clientid', $auth_settings ) ) {
2793 $auth_settings['google_clientid'] = '';
2794 }
2795 if ( ! array_key_exists( 'google_clientsecret', $auth_settings ) ) {
2796 $auth_settings['google_clientsecret'] = '';
2797 }
2798 if ( ! array_key_exists( 'google_hosteddomain', $auth_settings ) ) {
2799 $auth_settings['google_hosteddomain'] = '';
2800 }
2801
2802 if ( ! array_key_exists( 'cas_custom_label', $auth_settings ) ) {
2803 $auth_settings['cas_custom_label'] = 'CAS';
2804 }
2805 if ( ! array_key_exists( 'cas_host', $auth_settings ) ) {
2806 $auth_settings['cas_host'] = '';
2807 }
2808 if ( ! array_key_exists( 'cas_port', $auth_settings ) ) {
2809 $auth_settings['cas_port'] = '';
2810 }
2811 if ( ! array_key_exists( 'cas_path', $auth_settings ) ) {
2812 $auth_settings['cas_path'] = '';
2813 }
2814 if ( ! array_key_exists( 'cas_version', $auth_settings ) ) {
2815 $auth_settings['cas_version'] = 'SAML_VERSION_1_1';
2816 }
2817 if ( ! array_key_exists( 'cas_attr_email', $auth_settings ) ) {
2818 $auth_settings['cas_attr_email'] = '';
2819 }
2820 if ( ! array_key_exists( 'cas_attr_first_name', $auth_settings ) ) {
2821 $auth_settings['cas_attr_first_name'] = '';
2822 }
2823 if ( ! array_key_exists( 'cas_attr_last_name', $auth_settings ) ) {
2824 $auth_settings['cas_attr_last_name'] = '';
2825 }
2826 if ( ! array_key_exists( 'cas_attr_update_on_login', $auth_settings ) ) {
2827 $auth_settings['cas_attr_update_on_login'] = '';
2828 }
2829 if ( ! array_key_exists( 'cas_auto_login', $auth_settings ) ) {
2830 $auth_settings['cas_auto_login'] = '';
2831 }
2832
2833 if ( ! array_key_exists( 'ldap_host', $auth_settings ) ) {
2834 $auth_settings['ldap_host'] = '';
2835 }
2836 if ( ! array_key_exists( 'ldap_port', $auth_settings ) ) {
2837 $auth_settings['ldap_port'] = '389';
2838 }
2839 if ( ! array_key_exists( 'ldap_tls', $auth_settings ) ) {
2840 $auth_settings['ldap_tls'] = '1';
2841 }
2842 if ( ! array_key_exists( 'ldap_search_base', $auth_settings ) ) {
2843 $auth_settings['ldap_search_base'] = '';
2844 }
2845 if ( ! array_key_exists( 'ldap_uid', $auth_settings ) ) {
2846 $auth_settings['ldap_uid'] = 'uid';
2847 }
2848 if ( ! array_key_exists( 'ldap_attr_email', $auth_settings ) ) {
2849 $auth_settings['ldap_attr_email'] = '';
2850 }
2851 if ( ! array_key_exists( 'ldap_user', $auth_settings ) ) {
2852 $auth_settings['ldap_user'] = '';
2853 }
2854 if ( ! array_key_exists( 'ldap_password', $auth_settings ) ) {
2855 $auth_settings['ldap_password'] = '';
2856 }
2857 if ( ! array_key_exists( 'ldap_lostpassword_url', $auth_settings ) ) {
2858 $auth_settings['ldap_lostpassword_url'] = '';
2859 }
2860 if ( ! array_key_exists( 'ldap_attr_first_name', $auth_settings ) ) {
2861 $auth_settings['ldap_attr_first_name'] = '';
2862 }
2863 if ( ! array_key_exists( 'ldap_attr_last_name', $auth_settings ) ) {
2864 $auth_settings['ldap_attr_last_name'] = '';
2865 }
2866 if ( ! array_key_exists( 'ldap_attr_update_on_login', $auth_settings ) ) {
2867 $auth_settings['ldap_attr_update_on_login'] = '';
2868 }
2869
2870 // Advanced defaults.
2871 if ( ! array_key_exists( 'advanced_lockouts', $auth_settings ) ) {
2872 $auth_settings['advanced_lockouts'] = array(
2873 'attempts_1' => 10,
2874 'duration_1' => 1,
2875 'attempts_2' => 10,
2876 'duration_2' => 10,
2877 'reset_duration' => 120,
2878 );
2879 }
2880 if ( ! array_key_exists( 'advanced_hide_wp_login', $auth_settings ) ) {
2881 $auth_settings['advanced_hide_wp_login'] = '';
2882 }
2883 if ( ! array_key_exists( 'advanced_branding', $auth_settings ) ) {
2884 $auth_settings['advanced_branding'] = 'default';
2885 }
2886 if ( ! array_key_exists( 'advanced_admin_menu', $auth_settings ) ) {
2887 $auth_settings['advanced_admin_menu'] = 'top';
2888 }
2889 if ( ! array_key_exists( 'advanced_usermeta', $auth_settings ) ) {
2890 $auth_settings['advanced_usermeta'] = '';
2891 }
2892 if ( ! array_key_exists( 'advanced_users_per_page', $auth_settings ) ) {
2893 $auth_settings['advanced_users_per_page'] = 20;
2894 }
2895 if ( ! array_key_exists( 'advanced_users_sort_by', $auth_settings ) ) {
2896 $auth_settings['advanced_users_sort_by'] = 'created';
2897 }
2898 if ( ! array_key_exists( 'advanced_users_sort_order', $auth_settings ) ) {
2899 $auth_settings['advanced_users_sort_order'] = 'asc';
2900 }
2901 if ( ! array_key_exists( 'advanced_widget_enabled', $auth_settings ) ) {
2902 $auth_settings['advanced_widget_enabled'] = '1';
2903 }
2904 if ( ! array_key_exists( 'advanced_override_multisite', $auth_settings ) ) {
2905 $auth_settings['advanced_override_multisite'] = '';
2906 }
2907
2908 // Save default options to database.
2909 update_option( 'auth_settings', $auth_settings );
2910 update_option( 'auth_settings_access_users_pending', $auth_settings_access_users_pending );
2911 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
2912 update_option( 'auth_settings_access_users_blocked', $auth_settings_access_users_blocked );
2913
2914 // Multisite defaults.
2915 if ( is_multisite() ) {
2916 $auth_multisite_settings = get_blog_option( $this->current_site_blog_id, 'auth_multisite_settings', array() );
2917
2918 if ( $auth_multisite_settings === FALSE ) {
2919 $auth_multisite_settings = array();
2920 }
2921 // Global switch for enabling multisite options.
2922 if ( ! array_key_exists( 'multisite_override', $auth_multisite_settings ) ) {
2923 $auth_multisite_settings['multisite_override'] = '';
2924 }
2925 // Access Lists Defaults.
2926 $auth_multisite_settings_access_users_approved = get_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved' );
2927 if ( $auth_multisite_settings_access_users_approved === FALSE ) {
2928 $auth_multisite_settings_access_users_approved = array();
2929 }
2930 // Login Access Defaults.
2931 if ( ! array_key_exists( 'access_who_can_login', $auth_multisite_settings ) ) {
2932 $auth_multisite_settings['access_who_can_login'] = 'approved_users';
2933 }
2934 // View Access Defaults.
2935 if ( ! array_key_exists( 'access_who_can_view', $auth_multisite_settings ) ) {
2936 $auth_multisite_settings['access_who_can_view'] = 'everyone';
2937 }
2938 // External Service Defaults.
2939 if ( ! array_key_exists( 'access_default_role', $auth_multisite_settings ) ) {
2940 // Set default role to 'student' if that role exists, 'subscriber' otherwise.
2941 $all_roles = $wp_roles->roles;
2942 $editable_roles = apply_filters( 'editable_roles', $all_roles );
2943 if ( array_key_exists( 'student', $editable_roles ) ) {
2944 $auth_multisite_settings['access_default_role'] = 'student';
2945 } else {
2946 $auth_multisite_settings['access_default_role'] = 'subscriber';
2947 }
2948 }
2949 if ( ! array_key_exists( 'google', $auth_multisite_settings ) ) {
2950 $auth_multisite_settings['google'] = '';
2951 }
2952 if ( ! array_key_exists( 'cas', $auth_multisite_settings ) ) {
2953 $auth_multisite_settings['cas'] = '';
2954 }
2955 if ( ! array_key_exists( 'ldap', $auth_multisite_settings ) ) {
2956 $auth_multisite_settings['ldap'] = '';
2957 }
2958 if ( ! array_key_exists( 'google_clientid', $auth_multisite_settings ) ) {
2959 $auth_multisite_settings['google_clientid'] = '';
2960 }
2961 if ( ! array_key_exists( 'google_clientsecret', $auth_multisite_settings ) ) {
2962 $auth_multisite_settings['google_clientsecret'] = '';
2963 }
2964 if ( ! array_key_exists( 'google_hosteddomain', $auth_multisite_settings ) ) {
2965 $auth_multisite_settings['google_hosteddomain'] = '';
2966 }
2967 if ( ! array_key_exists( 'cas_custom_label', $auth_multisite_settings ) ) {
2968 $auth_multisite_settings['cas_custom_label'] = 'CAS';
2969 }
2970 if ( ! array_key_exists( 'cas_host', $auth_multisite_settings ) ) {
2971 $auth_multisite_settings['cas_host'] = '';
2972 }
2973 if ( ! array_key_exists( 'cas_port', $auth_multisite_settings ) ) {
2974 $auth_multisite_settings['cas_port'] = '';
2975 }
2976 if ( ! array_key_exists( 'cas_path', $auth_multisite_settings ) ) {
2977 $auth_multisite_settings['cas_path'] = '';
2978 }
2979 if ( ! array_key_exists( 'cas_version', $auth_multisite_settings ) ) {
2980 $auth_multisite_settings['cas_version'] = 'SAML_VERSION_1_1';
2981 }
2982 if ( ! array_key_exists( 'cas_attr_email', $auth_multisite_settings ) ) {
2983 $auth_multisite_settings['cas_attr_email'] = '';
2984 }
2985 if ( ! array_key_exists( 'cas_attr_first_name', $auth_multisite_settings ) ) {
2986 $auth_multisite_settings['cas_attr_first_name'] = '';
2987 }
2988 if ( ! array_key_exists( 'cas_attr_last_name', $auth_multisite_settings ) ) {
2989 $auth_multisite_settings['cas_attr_last_name'] = '';
2990 }
2991 if ( ! array_key_exists( 'cas_attr_update_on_login', $auth_multisite_settings ) ) {
2992 $auth_multisite_settings['cas_attr_update_on_login'] = '';
2993 }
2994 if ( ! array_key_exists( 'cas_auto_login', $auth_multisite_settings ) ) {
2995 $auth_multisite_settings['cas_auto_login'] = '';
2996 }
2997 if ( ! array_key_exists( 'ldap_host', $auth_multisite_settings ) ) {
2998 $auth_multisite_settings['ldap_host'] = '';
2999 }
3000 if ( ! array_key_exists( 'ldap_port', $auth_multisite_settings ) ) {
3001 $auth_multisite_settings['ldap_port'] = '389';
3002 }
3003 if ( ! array_key_exists( 'ldap_tls', $auth_multisite_settings ) ) {
3004 $auth_multisite_settings['ldap_tls'] = '1';
3005 }
3006 if ( ! array_key_exists( 'ldap_search_base', $auth_multisite_settings ) ) {
3007 $auth_multisite_settings['ldap_search_base'] = '';
3008 }
3009 if ( ! array_key_exists( 'ldap_uid', $auth_multisite_settings ) ) {
3010 $auth_multisite_settings['ldap_uid'] = 'uid';
3011 }
3012 if ( ! array_key_exists( 'ldap_attr_email', $auth_multisite_settings ) ) {
3013 $auth_multisite_settings['ldap_attr_email'] = '';
3014 }
3015 if ( ! array_key_exists( 'ldap_user', $auth_multisite_settings ) ) {
3016 $auth_multisite_settings['ldap_user'] = '';
3017 }
3018 if ( ! array_key_exists( 'ldap_password', $auth_multisite_settings ) ) {
3019 $auth_multisite_settings['ldap_password'] = '';
3020 }
3021 if ( ! array_key_exists( 'ldap_lostpassword_url', $auth_multisite_settings ) ) {
3022 $auth_multisite_settings['ldap_lostpassword_url'] = '';
3023 }
3024 if ( ! array_key_exists( 'ldap_attr_first_name', $auth_multisite_settings ) ) {
3025 $auth_multisite_settings['ldap_attr_first_name'] = '';
3026 }
3027 if ( ! array_key_exists( 'ldap_attr_last_name', $auth_multisite_settings ) ) {
3028 $auth_multisite_settings['ldap_attr_last_name'] = '';
3029 }
3030 if ( ! array_key_exists( 'ldap_attr_update_on_login', $auth_multisite_settings ) ) {
3031 $auth_multisite_settings['ldap_attr_update_on_login'] = '';
3032 }
3033 // Advanced defaults.
3034 if ( ! array_key_exists( 'advanced_lockouts', $auth_multisite_settings ) ) {
3035 $auth_multisite_settings['advanced_lockouts'] = array(
3036 'attempts_1' => 10,
3037 'duration_1' => 1,
3038 'attempts_2' => 10,
3039 'duration_2' => 10,
3040 'reset_duration' => 120,
3041 );
3042 }
3043 if ( ! array_key_exists( 'advanced_hide_wp_login', $auth_multisite_settings ) ) {
3044 $auth_multisite_settings['advanced_hide_wp_login'] = '';
3045 }
3046 if ( ! array_key_exists( 'advanced_users_per_page', $auth_multisite_settings ) ) {
3047 $auth_multisite_settings['advanced_users_per_page'] = 20;
3048 }
3049 if ( ! array_key_exists( 'advanced_users_sort_by', $auth_multisite_settings ) ) {
3050 $auth_multisite_settings['advanced_users_sort_by'] = 'created';
3051 }
3052 if ( ! array_key_exists( 'advanced_users_sort_order', $auth_multisite_settings ) ) {
3053 $auth_multisite_settings['advanced_users_sort_order'] = 'asc';
3054 }
3055 if ( ! array_key_exists( 'advanced_widget_enabled', $auth_multisite_settings ) ) {
3056 $auth_multisite_settings['advanced_widget_enabled'] = '1';
3057 }
3058 // Save default network options to database.
3059 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings', $auth_multisite_settings );
3060 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
3061 }
3062
3063 return $auth_settings;
3064 }
3065
3066
3067 /**
3068 * List sanitizer.
3069 * $side_effect = 'none' or 'update roles' to make sure WP user roles match
3070 * $multisite_mode = 'single' or 'multisite' to indicate which user roles to change (this site or all sites)
3071 */
3072 function sanitize_user_list( $list, $side_effect = 'none', $multisite_mode = 'single' ) {
3073 // If it's not a list, make it so.
3074 if ( ! is_array( $list ) ) {
3075 $list = array();
3076 }
3077 foreach ( $list as $key => $user_info ) {
3078 if ( strlen( $user_info['email'] ) < 1 ) {
3079 // Make sure there are no empty entries in the list
3080 unset( $list[$key] );
3081 } elseif ( $side_effect === 'update roles' ) {
3082 // Make sure the WordPress user accounts have the same role
3083 // as that indicated in the list.
3084 $wp_user = get_user_by( 'email', $user_info['email'] );
3085 if ( $wp_user ) {
3086 if ( is_multisite() && $multisite_mode === 'multisite' ) {
3087 foreach ( get_blogs_of_user( $wp_user->ID ) as $blog ) {
3088 add_user_to_blog( $blog->userblog_id, $wp_user->ID, $user_info['role'] );
3089 }
3090 } else {
3091 $wp_user->set_role( $user_info['role'] );
3092 }
3093 }
3094 }
3095 }
3096 return $list;
3097 }
3098
3099
3100 /**
3101 * Settings sanitizer callback
3102 */
3103 function sanitize_options( $auth_settings ) {
3104 // Default to "Approved Users" login access restriction.
3105 if ( ! in_array( $auth_settings['access_who_can_login'], array( 'external_users', 'approved_users' ) ) ) {
3106 $auth_settings['access_who_can_login'] = 'approved_users';
3107 }
3108
3109 // Default to "Everyone" view access restriction.
3110 if ( ! in_array( $auth_settings['access_who_can_view'], array( 'everyone', 'logged_in_users' ) ) ) {
3111 $auth_settings['access_who_can_view'] = 'everyone';
3112 }
3113
3114 // Default to WordPress login access redirect.
3115 // Note: this option doesn't exist in multisite options, so we first
3116 // check to see if it exists.
3117 if ( array_key_exists( 'access_redirect', $auth_settings ) && ! in_array( $auth_settings['access_redirect'], array( 'login', 'page', 'message' ) ) ) {
3118 $auth_settings['access_redirect'] = 'login';
3119 }
3120
3121 // Default to warning message for anonymous users on public pages.
3122 // Note: this option doesn't exist in multisite options, so we first
3123 // check to see if it exists.
3124 if ( array_key_exists( 'access_public_warning', $auth_settings ) && ! in_array( $auth_settings['access_public_warning'], array( 'no_warning', 'warning' ) ) ) {
3125 $auth_settings['access_public_warning'] = 'no_warning';
3126 }
3127
3128 // Sanitize Send welcome email (checkbox: value can only be '1' or empty string)
3129 $auth_settings['access_should_email_approved_users'] = array_key_exists( 'access_should_email_approved_users', $auth_settings ) && strlen( $auth_settings['access_should_email_approved_users'] ) > 0 ? '1' : '';
3130
3131 // Sanitize Enable Google Logins (checkbox: value can only be '1' or empty string)
3132 $auth_settings['google'] = array_key_exists( 'google', $auth_settings ) && strlen( $auth_settings['google'] ) > 0 ? '1' : '';
3133
3134 // Sanitize Enable CAS Logins (checkbox: value can only be '1' or empty string)
3135 $auth_settings['cas'] = array_key_exists( 'cas', $auth_settings ) && strlen( $auth_settings['cas'] ) > 0 ? '1' : '';
3136
3137 // Sanitize CAS Host setting
3138 $auth_settings['cas_host'] = filter_var( $auth_settings['cas_host'], FILTER_SANITIZE_URL );
3139
3140 // Sanitize CAS Port (int)
3141 $auth_settings['cas_port'] = filter_var( $auth_settings['cas_port'], FILTER_SANITIZE_NUMBER_INT );
3142
3143 // Sanitize CAS attribute update (checkbox: value can only be '1' or empty string)
3144 $auth_settings['cas_attr_update_on_login'] = array_key_exists( 'cas_attr_update_on_login', $auth_settings ) && strlen( $auth_settings['cas_attr_update_on_login'] ) > 0 ? '1' : '';
3145
3146 // Sanitize CAS auto-login (checkbox: value can only be '1' or empty string)
3147 $auth_settings['cas_auto_login'] = array_key_exists( 'cas_auto_login', $auth_settings ) && strlen( $auth_settings['cas_auto_login'] ) > 0 ? '1' : '';
3148
3149 // Sanitize Enable LDAP Logins (checkbox: value can only be '1' or empty string)
3150 $auth_settings['ldap'] = array_key_exists( 'ldap', $auth_settings ) && strlen( $auth_settings['ldap'] ) > 0 ? '1' : '';
3151
3152 // Sanitize LDAP Host setting
3153 $auth_settings['ldap_host'] = filter_var( $auth_settings['ldap_host'], FILTER_SANITIZE_URL );
3154
3155 // Sanitize LDAP Port (int)
3156 $auth_settings['ldap_port'] = filter_var( $auth_settings['ldap_port'], FILTER_SANITIZE_NUMBER_INT );
3157
3158 // Sanitize LDAP TLS (checkbox: value can only be '1' or empty string)
3159 $auth_settings['ldap_tls'] = array_key_exists( 'ldap_tls', $auth_settings ) && strlen( $auth_settings['ldap_tls'] ) > 0 ? '1' : '';
3160
3161 // Sanitize LDAP attributes (basically make sure they don't have any parentheses)
3162 $auth_settings['ldap_uid'] = filter_var( $auth_settings['ldap_uid'], FILTER_SANITIZE_EMAIL );
3163
3164 // Sanitize LDAP Lost Password URL
3165 $auth_settings['ldap_lostpassword_url'] = filter_var( $auth_settings['ldap_lostpassword_url'], FILTER_SANITIZE_URL );
3166
3167 // Obfuscate LDAP directory user password
3168 if ( strlen( $auth_settings['ldap_password'] ) > 0 ) {
3169 // encrypt the directory user password for some minor obfuscation in the database.
3170 $auth_settings['ldap_password'] = $this->encrypt( $auth_settings['ldap_password'] );
3171 }
3172
3173 // Sanitize LDAP attribute update (checkbox: value can only be '1' or empty string)
3174 $auth_settings['ldap_attr_update_on_login'] = array_key_exists( 'ldap_attr_update_on_login', $auth_settings ) && strlen( $auth_settings['ldap_attr_update_on_login'] ) > 0 ? '1' : '';
3175
3176 // Make sure public pages is an empty array if it's empty
3177 // Note: this option doesn't exist in multisite options, so we first
3178 // check to see if it exists.
3179 if ( array_key_exists( 'access_public_pages', $auth_settings ) && ! is_array( $auth_settings['access_public_pages'] ) ) {
3180 $auth_settings['access_public_pages'] = array();
3181 }
3182
3183 // Make sure all lockout options are integers (attempts_1,
3184 // duration_1, attempts_2, duration_2, reset_duration).
3185 foreach ( $auth_settings['advanced_lockouts'] as $key => $value ) {
3186 $auth_settings['advanced_lockouts'][$key] = filter_var( $value, FILTER_SANITIZE_NUMBER_INT );
3187 }
3188
3189 // Sanitize Hide WordPress logins (checkbox: value can only be '1' or empty string)
3190 $auth_settings['advanced_hide_wp_login'] = array_key_exists( 'advanced_hide_wp_login', $auth_settings ) && strlen( $auth_settings['advanced_hide_wp_login'] ) > 0 ? '1' : '';
3191
3192 // Sanitize Users per page (text: value can only int from 1 to MAX_INT)
3193 $auth_settings['advanced_users_per_page'] = array_key_exists( 'advanced_users_per_page', $auth_settings ) && intval( $auth_settings['advanced_users_per_page'] ) > 0 ? intval( $auth_settings['advanced_users_per_page'] ) : 1;
3194
3195 // Sanitize Sort users by (select: value can be 'email', 'role', 'date_added', 'created')
3196 if ( ! isset( $auth_settings['advanced_users_sort_by'] ) || ! in_array( $auth_settings['advanced_users_sort_by'], array( 'email', 'role', 'date_added', 'created' ) ) ) {
3197 $auth_settings['advanced_users_sort_by'] = 'created';
3198 }
3199
3200 // Sanitize Sort users order (select: value can be 'asc', 'desc')
3201 if ( ! isset( $auth_settings['advanced_users_sort_order'] ) || ! in_array( $auth_settings['advanced_users_sort_order'], array( 'asc', 'desc' ) ) ) {
3202 $auth_settings['advanced_users_sort_order'] = 'asc';
3203 }
3204
3205 // Sanitize Show Dashboard Widget (checkbox: value can only be '1' or empty string)
3206 $auth_settings['advanced_widget_enabled'] = array_key_exists( 'advanced_widget_enabled', $auth_settings ) && strlen( $auth_settings['advanced_widget_enabled'] ) > 0 ? '1' : '';
3207
3208 // Sanitize Override multisite options (checkbox: value can only be '1' or empty string)
3209 $auth_settings['advanced_override_multisite'] = array_key_exists( 'advanced_override_multisite', $auth_settings ) && strlen( $auth_settings['advanced_override_multisite'] ) > 0 ? '1' : '';
3210
3211 return $auth_settings;
3212 }
3213
3214
3215 /**
3216 * Keep authorizer approved users' roles in sync with WordPress roles
3217 * if someone changes the role via the WordPress Edit User page
3218 * (wp-admin/user-edit.php or wp-admin/profile.php).
3219 *
3220 * @action user_profile_update_errors
3221 * @ref https://developer.wordpress.org/reference/hooks/user_profile_update_errors/
3222 * @param WP_Error &$errors Errors object to add any custom errors to
3223 * @param bool $update True if updating existing user, false if saving a new one
3224 * @param stdClass &$user Object with changes to WP_User object for user being edited
3225 */
3226 function edit_user_profile_update_role( &$errors, $update, &$user ) {
3227 // Do nothing if we're not updating role.
3228 if ( ! property_exists( $user, 'role' ) ) {
3229 return;
3230 }
3231
3232 // Safety check; will likely not fire if we reach this function.
3233 if ( ! current_user_can( 'edit_user', $user->ID ) ) {
3234 return;
3235 }
3236
3237 // Don't perform Authorizer updates if we have a WordPress error.
3238 $errors_on_user_update = $errors->get_error_codes();
3239 if ( ! empty( $errors_on_user_update ) ) {
3240 return;
3241 }
3242
3243 // Get original user object (fail if not a real WordPress user).
3244 $userdata = get_userdata( $user->ID );
3245 if ( ! $userdata ) {
3246 return;
3247 }
3248
3249 // If user is in approved list, update his/her associated role.
3250 if ( $this->is_email_in_list( $userdata->user_email, 'approved' ) ) {
3251 $auth_settings_access_users_approved = $this->sanitize_user_list( $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN ) );
3252 foreach ( $auth_settings_access_users_approved as $key => $check_user ) {
3253 if ( 0 === strcasecmp( $check_user['email'], $userdata->user_email ) ) {
3254 $auth_settings_access_users_approved[$key]['role'] = $user->role;
3255 }
3256 }
3257 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
3258 }
3259 }
3260
3261
3262 /**
3263 * Sync any email address changes to WordPress accounts to the corresponding
3264 * entry in the Authorizer approved list.
3265 *
3266 * Note: This filter fires in wp_update_user() if the update includes an
3267 * email address change, and fires after all security and integrity checks
3268 * have been performed, so we can simply update the Authorizer approved
3269 * list, changing the email address on the approved entry, and removing any
3270 * existing entries that also have the new email address (duplicates).
3271 *
3272 * @param bool $send Whether to send the email.
3273 * @param array $user The original user array.
3274 * @param array $userdata The updated user array.
3275 */
3276 function edit_user_profile_update_email( $send, $user, $userdata ) {
3277 // If we're in multisite, update the email on all sites in the network
3278 // (and remove from any subsites if it's a network-approved user).
3279 if ( is_multisite() ) {
3280 // If it's a multisite approved user, sync the email there.
3281 $changed_user_is_multisite_user = false;
3282 if ( $this->is_email_in_list( $user['user_email'], 'approved', 'multisite' ) ) {
3283 $changed_user_is_multisite_user = true;
3284 $auth_multisite_settings_access_users_approved = $this->sanitize_user_list(
3285 $this->get_plugin_option( 'access_users_approved', MULTISITE_ADMIN )
3286 );
3287 foreach ( $auth_multisite_settings_access_users_approved as $key => $check_user ) {
3288 // Update old user email in approved list to the new email.
3289 if ( 0 === strcasecmp( $check_user['email'], $user['user_email'] ) ) {
3290 $auth_multisite_settings_access_users_approved[$key]['email'] = $this->lowercase( $userdata['user_email'] );
3291 }
3292 // If new user email is already in approved list, remove that entry.
3293 if ( 0 === strcasecmp( $check_user['email'], $userdata['user_email'] ) ) {
3294 unset( $auth_multisite_settings_access_users_approved[$key] );
3295 }
3296 }
3297 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
3298 }
3299
3300 // Go through all approved lists on individual sites and sync this user there.
3301 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
3302 foreach ( $sites as $site ) {
3303 $updated = false;
3304 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
3305 $auth_settings_access_users_approved = get_blog_option( $blog_id, 'auth_settings_access_users_approved', array() );
3306 foreach ( $auth_settings_access_users_approved as $key => $check_user ) {
3307 // Update old user email in approved list to the new email.
3308 if ( 0 === strcasecmp( $check_user['email'], $user['user_email'] ) ) {
3309 // But if the user is already a multisite user, just remove the entry in the subsite.
3310 if ( $changed_user_is_multisite_user ) {
3311 unset( $auth_settings_access_users_approved[$key] );
3312 } else {
3313 $auth_settings_access_users_approved[$key]['email'] = $this->lowercase( $userdata['user_email'] );
3314 }
3315 $updated = true;
3316 }
3317 // If new user email is already in approved list, remove that entry.
3318 if ( 0 === strcasecmp( $check_user['email'], $userdata['user_email'] ) ) {
3319 unset( $auth_settings_access_users_approved[$key] );
3320 $updated = true;
3321 }
3322 }
3323 if ( $updated ) {
3324 update_blog_option( $blog_id, 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
3325 }
3326 }
3327 } else {
3328 // In a single site environment, just find the old user in the approved list and update the email.
3329 if ( $this->is_email_in_list( $user['user_email'], 'approved' ) ) {
3330 $auth_settings_access_users_approved = $this->sanitize_user_list( $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN ) );
3331 foreach ( $auth_settings_access_users_approved as $key => $check_user ) {
3332 // Update old user email in approved list to the new email.
3333 if ( 0 === strcasecmp( $check_user['email'], $user['user_email'] ) ) {
3334 $auth_settings_access_users_approved[$key]['email'] = $this->lowercase( $userdata['user_email'] );
3335 }
3336 // If new user email is already in approved list, remove that entry.
3337 if ( 0 === strcasecmp( $check_user['email'], $userdata['user_email'] ) ) {
3338 unset( $auth_settings_access_users_approved[$key] );
3339 }
3340 }
3341 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
3342 }
3343 }
3344
3345 // We're hooking into this filter merely for its location in the codebase,
3346 // so make sure to return the filter value unmodified.
3347 return $send;
3348 }
3349
3350
3351 /**
3352 * Settings print callbacks
3353 */
3354 function print_section_info_tabs( $args = '' ) {
3355 if ( MULTISITE_ADMIN === $this->get_admin_mode( $args )): ?>
3356 <h2 class="nav-tab-wrapper">
3357 <a class="nav-tab nav-tab-access_lists nav-tab-active" href="javascript:choose_tab('access_lists' );"><?php _e( 'Access Lists', 'authorizer' ); ?></a>
3358 <a class="nav-tab nav-tab-external" href="javascript:choose_tab('external' );"><?php _e( 'External Service', 'authorizer' ); ?></a>
3359 <a class="nav-tab nav-tab-advanced" href="javascript:choose_tab('advanced' );"><?php _e( 'Advanced', 'authorizer' ); ?></a>
3360 </h2>
3361 <?php else: ?>
3362 <h2 class="nav-tab-wrapper">
3363 <a class="nav-tab nav-tab-access_lists nav-tab-active" href="javascript:choose_tab('access_lists' );"><?php _e( 'Access Lists', 'authorizer' ); ?></a>
3364 <a class="nav-tab nav-tab-access_login" href="javascript:choose_tab('access_login' );"><?php _e( 'Login Access', 'authorizer' ); ?></a>
3365 <a class="nav-tab nav-tab-access_public" href="javascript:choose_tab('access_public' );"><?php _e( 'Public Access', 'authorizer' ); ?></a>
3366 <a class="nav-tab nav-tab-external" href="javascript:choose_tab('external' );"><?php _e( 'External Service', 'authorizer' ); ?></a>
3367 <a class="nav-tab nav-tab-advanced" href="javascript:choose_tab('advanced' );"><?php _e( 'Advanced', 'authorizer' ); ?></a>
3368 </h2>
3369 <?php endif;
3370 }
3371
3372
3373 function print_section_info_access_lists( $args = '' ) {
3374 $admin_mode = $this->get_admin_mode( $args );
3375 ?><div id="section_info_access_lists" class="section_info">
3376 <p><?php _e( 'Manage who has access to this site using these lists.', 'authorizer' ); ?></p>
3377 <ol>
3378 <li><?php _e( "<strong>Pending</strong> users are users who have successfully logged in to the site, but who haven't yet been approved (or blocked) by you.", 'authorizer' ); ?></li>
3379 <li><?php _e( '<strong>Approved</strong> users have access to the site once they successfully log in.', 'authorizer' ); ?></li>
3380 <li><?php _e( '<strong>Blocked</strong> users will receive an error message when they try to visit the site after authenticating.', 'authorizer' ); ?></li>
3381 </ol>
3382 </div>
3383 <table class="form-table">
3384 <tbody>
3385 <tr>
3386 <th scope="row"><?php _e( 'Pending Users', 'authorizer' ); ?> <em>(<?php echo $this->get_user_count_from_list( 'pending', $admin_mode ); ?>)</em></th>
3387 <td><?php $this->print_combo_auth_access_users_pending(); ?></td>
3388 </tr>
3389 <tr>
3390 <th scope="row"><?php _e( 'Approved Users', 'authorizer' ); ?> <em>(<?php echo $this->get_user_count_from_list( 'approved', $admin_mode ); ?>)</em></th>
3391 <td><?php $this->print_combo_auth_access_users_approved(); ?></td>
3392 </tr>
3393 <tr>
3394 <th scope="row"><?php _e( 'Blocked Users', 'authorizer' ); ?> <em>(<?php echo $this->get_user_count_from_list( 'blocked', $admin_mode ); ?>)</em></th>
3395 <td><?php $this->print_combo_auth_access_users_blocked(); ?></td>
3396 </tr>
3397 </tbody>
3398 </table>
3399 <?php
3400 }
3401
3402
3403 function print_combo_auth_access_users_pending( $args = '' ) {
3404 // Get plugin option.
3405 $option = 'access_users_pending';
3406 $auth_settings_option = $this->get_plugin_option( $option );
3407 $auth_settings_option = is_array( $auth_settings_option ) ? $auth_settings_option : array();
3408
3409 // Render wrapper div (for aligning pager to width of content).
3410 ?><div class="wrapper_<?php echo $option; ?>"><?php
3411
3412 // Print option elements.
3413 ?><ul id="list_auth_settings_access_users_pending" style="margin:0;">
3414 <?php if ( count( $auth_settings_option ) > 0 ) : ?>
3415 <?php foreach ( $auth_settings_option as $key => $pending_user ): ?>
3416 <?php if ( empty( $pending_user ) || count( $pending_user ) < 1 ) continue; ?>
3417 <?php $pending_user['is_wp_user'] = false; ?>
3418 <li>
3419 <input type="text" id="auth_settings_<?php echo $option; ?>_<?php echo $key; ?>" value="<?php echo $pending_user['email']; ?>" readonly="true" class="auth-email" />
3420 <select id="auth_settings_<?php echo $option; ?>_<?php echo $key; ?>_role" class="auth-role">
3421 <?php $this->wp_dropdown_permitted_roles( $pending_user['role'] ); ?>
3422 </select>
3423 <a href="javascript:void(0);" class="button-primary" id="approve_user_<?php echo $key; ?>" onclick="auth_add_user( this, 'approved', false ); auth_ignore_user( this, 'pending' );"><span class="glyphicon glyphicon-ok"></span> <?php _e( 'Approve', 'authorizer' ); ?></a>
3424 <a href="javascript:void(0);" class="button-primary" id="block_user_<?php echo $key; ?>" onclick="auth_add_user( this, 'blocked', false ); auth_ignore_user( this, 'pending' );"><span class="glyphicon glyphicon-ban-circle"></span> <?php _e( 'Block', 'authorizer' ); ?></a>
3425 <a href="javascript:void(0);" class="button button-secondary" id="ignore_user_<?php echo $key; ?>" onclick="auth_ignore_user( this, 'pending' );" title="<?php _e( 'Remove user', 'authorizer' ); ?>"><span class="glyphicon glyphicon-remove"></span> <?php _e( 'Ignore', 'authorizer' ); ?></a>
3426 </li>
3427 <?php endforeach; ?>
3428 <?php else: ?>
3429 <li class="auth-empty"><em><?php _e( 'No pending users', 'authorizer' ); ?></em></li>
3430 <?php endif; ?>
3431 </ul>
3432 </div>
3433 <?php
3434 }
3435
3436
3437 function print_combo_auth_access_users_approved( $args = '' ) {
3438 // Get plugin option.
3439 $option = 'access_users_approved';
3440 $admin_mode = $this->get_admin_mode( $args );
3441 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'no override' );
3442 $auth_settings_option = is_array( $auth_settings_option ) ? $auth_settings_option : array();
3443
3444 // Get multisite approved users (will be added to top of list, greyed out).
3445 $auth_override_multisite = $this->get_plugin_option( 'advanced_override_multisite' );
3446 $auth_multisite_settings = $this->get_plugin_options( MULTISITE_ADMIN );
3447 $auth_settings_option_multisite = array();
3448 if (
3449 is_multisite() &&
3450 ! is_network_admin() &&
3451 $auth_override_multisite != '1' &&
3452 array_key_exists( 'multisite_override', $auth_multisite_settings ) &&
3453 $auth_multisite_settings['multisite_override'] === '1'
3454 ) {
3455 $auth_settings_option_multisite = $this->get_plugin_option( $option, MULTISITE_ADMIN, 'allow override' );
3456 $auth_settings_option_multisite = is_array( $auth_settings_option_multisite ) ? $auth_settings_option_multisite : array();
3457 // Add multisite users to the beginning of the main user array.
3458 foreach ( array_reverse( $auth_settings_option_multisite ) as $approved_user ) {
3459 $approved_user['multisite_user'] = true;
3460 array_unshift( $auth_settings_option, $approved_user );
3461 }
3462 }
3463
3464 // Get default role for new user dropdown.
3465 $access_default_role = $this->get_plugin_option( 'access_default_role', SINGLE_ADMIN, 'allow override' );
3466
3467 // Get custom usermeta field to show.
3468 $advanced_usermeta = $this->get_plugin_option( 'advanced_usermeta' );
3469
3470 // Adjust javascript function prefixes if multisite.
3471 $js_function_prefix = $admin_mode === MULTISITE_ADMIN ? 'auth_multisite_' : 'auth_';
3472 $is_multisite_admin_page = $admin_mode === MULTISITE_ADMIN;
3473
3474 // Filter user list to search terms.
3475 if ( isset( $_REQUEST['search'] ) && strlen( $_REQUEST['search'] ) > 0 ) {
3476 $search_term = $_REQUEST['search'];
3477 $auth_settings_option = array_filter( $auth_settings_option, function ( $user ) use ( $search_term ) {
3478 return stripos( $user['email'], $search_term ) !== FALSE ||
3479 stripos( $user['role'], $search_term ) !== FALSE ||
3480 stripos( $user['date_added'], $search_term ) !== FALSE;
3481 } );
3482 }
3483
3484 // Sort user list.
3485 $sort_by = $this->get_plugin_option( 'advanced_users_sort_by', SINGLE_ADMIN, 'allow override' ); // email, role, date_added (registered), created (date approved)
3486 $sort_order = $this->get_plugin_option( 'advanced_users_sort_order', SINGLE_ADMIN, 'allow override' ); // asc or desc
3487 $sort_dimension = array();
3488 if ( in_array( $sort_by, array( 'email', 'role', 'date_added' ) ) ) {
3489 foreach ( $auth_settings_option as $key => $user ) {
3490 if ( $sort_by === 'date_added' ) {
3491 $sort_dimension[$key] = date( 'Ymd', strtotime( $user[$sort_by] ) );
3492 } else {
3493 $sort_dimension[$key] = strtolower( $user[$sort_by] );
3494 }
3495 }
3496 $sort_order = $sort_order == 'asc' ? SORT_ASC : SORT_DESC;
3497 array_multisort( $sort_dimension, $sort_order, $auth_settings_option );
3498 }
3499
3500 // Ensure array keys run from 0..max (keys in database will be the original,
3501 // index, and removing users will not reorder the array keys of other users).
3502 $auth_settings_option = array_values( $auth_settings_option );
3503
3504 // Get pager params.
3505 $total_users = count( $auth_settings_option );
3506 $users_per_page = intval( $this->get_plugin_option( 'advanced_users_per_page', SINGLE_ADMIN, 'allow override' ) );
3507 $current_page = isset( $_REQUEST['paged'] ) ? intval( $_REQUEST['paged'] ) : 1;
3508 $total_pages = ceil( $total_users / $users_per_page );
3509 if ( $total_pages < 1 ) {
3510 $total_pages = 1;
3511 }
3512
3513 // Make sure current_page is between 1 and max pages.
3514 if ( $current_page < 1 ) {
3515 $current_page = 1;
3516 } else if ( $current_page > $total_pages ) {
3517 $current_page = $total_pages;
3518 }
3519
3520 // Render wrapper div (for aligning pager to width of content).
3521 ?><div class="wrapper_<?php echo $option; ?>"><?php
3522
3523 // Render pager.
3524 $this->render_user_pager( $current_page, $users_per_page, $total_users, 'top' );
3525
3526 // Render user list.
3527 ?><ul id="list_auth_settings_access_users_approved" class="<?php echo strlen( $advanced_usermeta ) > 0 ? 'has-usermeta' : ''; ?>"><?php
3528 $offset = ( $current_page - 1 ) * $users_per_page;
3529 $max = min( $offset + $users_per_page, count( $auth_settings_option ) );
3530 for ( $key = $offset; $key < $max; $key++ ) :
3531 $approved_user = $auth_settings_option[$key];
3532 if ( empty( $approved_user ) || count( $approved_user ) < 1 ) :
3533 continue;
3534 endif;
3535 $this->render_user_element( $approved_user, $key, $option, $admin_mode, $advanced_usermeta );
3536 endfor; ?>
3537 </ul><?php
3538
3539 ?><div id="new_auth_settings_<?php echo $option; ?>">
3540 <textarea id="new_approved_user_email" placeholder="<?php _e( 'email address', 'authorizer' ); ?>" class="auth-email new autogrow-short" rows="1"></textarea>
3541 <select id="new_approved_user_role" class="auth-role">
3542 <?php $this->wp_dropdown_permitted_roles( $access_default_role, 'not disabled', $admin_mode ); ?>
3543 </select>
3544 <div class="btn-group">
3545 <a href="javascript:void(0);" class="btn button-primary dropdown-toggle" id="approve_user_new" onclick="<?php echo $js_function_prefix; ?>add_user(this, 'approved' );"><span class="glyphicon glyphicon-ok"></span> <?php _e( 'Approve', 'authorizer' ); ?></a>
3546 <button type="button" class="btn button-primary dropdown-toggle" data-toggle="dropdown">
3547 <span class="caret"></span>
3548 <span class="sr-only"><?php _e( 'Toggle Dropdown', 'authorizer' ); ?></span>
3549 </button>
3550 <ul class="dropdown-menu" role="menu">
3551 <li><a href="javascript:void(0);" onclick="<?php echo $js_function_prefix; ?>add_user( document.getElementById('approve_user_new' ), 'approved', true);"><?php _e( 'Create a local WordPress <br />account instead, and email <br />the user their password.', 'authorizer' ); ?></a></li>
3552 </ul>
3553 </div>
3554 </div>
3555 <?php
3556
3557 // Render pager.
3558 $this->render_user_pager( $current_page, $users_per_page, $total_users, 'bottom' );
3559
3560 ?></div><?php
3561 }
3562
3563
3564 /**
3565 * Renders the html elements for the pager above and below the Approved User list.
3566 * @param integer $current_page Which page we are currently viewing.
3567 * @param integer $users_per_page How many users to show per page.
3568 * @param integer $total_users Total count of users in list.
3569 * @param string $which Where to render the pager ('top' or 'bottom').
3570 * @return null
3571 */
3572 function render_user_pager( $current_page = 1, $users_per_page = 20, $total_users = 0, $which = 'top' ) {
3573 $total_pages = ceil( $total_users / $users_per_page );
3574 if ( $total_pages < 1 ) {
3575 $total_pages = 1;
3576 }
3577
3578 $output = ' <span class="displaying-num">' . sprintf( _n( '%s user', '%s users', $total_users, 'authorizer' ), number_format_i18n( $total_users ) ) . '</span>';
3579
3580 $disable_first = $current_page <= 1;
3581 $disable_prev = $current_page <= 1;
3582 $disable_next = $current_page >= $total_pages;
3583 $disable_last = $current_page >= $total_pages;
3584
3585 $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
3586 $current_url = remove_query_arg( wp_removable_query_args(), $current_url );
3587
3588 $page_links = array();
3589
3590 $total_pages_before = '<span class="paging-input">';
3591 $total_pages_after = '</span></span>';
3592
3593 if ( $disable_first ) {
3594 $page_links[] = '<span class="first-page tablenav-pages-navspan" aria-hidden="true">&laquo;</span>';
3595 } else {
3596 $page_links[] = sprintf( "<a class='first-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
3597 esc_url( remove_query_arg( 'paged', $current_url ) ),
3598 __( 'First page' ),
3599 '&laquo;'
3600 );
3601 }
3602
3603 if ( $disable_prev ) {
3604 $page_links[] = '<span class="prev-page tablenav-pages-navspan" aria-hidden="true">&lsaquo;</span>';
3605 } else {
3606 $page_links[] = sprintf( "<a class='prev-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
3607 esc_url( add_query_arg( 'paged', max( 1, $current_page - 1 ), $current_url ) ),
3608 __( 'Previous page' ),
3609 '&lsaquo;'
3610 );
3611 }
3612
3613 if ( 'bottom' === $which ) {
3614 $html_current_page = '<span class="current-page-text">' . $current_page . '</span>';
3615 $total_pages_before = '<span class="screen-reader-text">' . __( 'Current Page' ) . '</span><span id="table-paging" class="paging-input"><span class="tablenav-paging-text">';
3616 } else {
3617 $html_current_page = sprintf( "%s<input class='current-page' id='current-page-selector' type='text' name='paged' value='%s' size='%d' aria-describedby='table-paging' /><span class='tablenav-paging-text'>",
3618 '<label for="current-page-selector" class="screen-reader-text">' . __( 'Current Page' ) . '</label>',
3619 $current_page,
3620 strlen( $total_pages )
3621 );
3622 }
3623 $html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) );
3624 $page_links[] = $total_pages_before . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . $total_pages_after;
3625
3626 if ( $disable_next ) {
3627 $page_links[] = '<span class="next-page tablenav-pages-navspan" aria-hidden="true">&rsaquo;</span>';
3628 } else {
3629 $page_links[] = sprintf( "<a class='next-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
3630 esc_url( add_query_arg( 'paged', min( $total_pages, $current_page + 1 ), $current_url ) ),
3631 __( 'Next page' ),
3632 '&rsaquo;'
3633 );
3634 }
3635
3636 if ( $disable_last ) {
3637 $page_links[] = '<span class="last-page tablenav-pages-navspan" aria-hidden="true">&raquo;</span>';
3638 } else {
3639 $page_links[] = sprintf( "<a class='last-page' href='%s'><span class='screen-reader-text'>%s</span><span aria-hidden='true'>%s</span></a>",
3640 esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ),
3641 __( 'Last page' ),
3642 '&raquo;'
3643 );
3644 }
3645
3646 $pagination_links_class = 'pagination-links';
3647 $output .= "\n<span class='$pagination_links_class'>" . join( "\n", $page_links ) . '</span>';
3648
3649 $search_form = array();
3650 if ( 'top' === $which ) {
3651 $search_term = isset( $_REQUEST['search'] ) ? $_REQUEST['search'] : '';
3652 $search_form[] = '<div class="search-box">';
3653 $search_form[] = '<label class="screen-reader-text" for="user-search-input">' . __( 'Search Users', 'authorizer' ) . '</label>';
3654 $search_form[] = '<input type="search" size="14" id="user-search-input" name="search" value="' . $search_term . '">';
3655 $search_form[] = '<input type="button" id="search-submit" class="button" value="' . __( 'Search', 'authorizer' ) . '">';
3656 $search_form[] = '</div>';
3657 }
3658 $search_form = join( "\n", $search_form );
3659
3660 $output = "<div class='tablenav-pages'>$output</div>";
3661
3662 ?><div class="tablenav top">
3663 <?php echo $output; ?>
3664 <?php echo $search_form; ?>
3665 </div><?php
3666 }
3667
3668
3669 /**
3670 * Renders the html <li> element for a given user in a list.
3671 * @param array $approved_user User array to render.
3672 * @param int $key Index of user in list of users.
3673 * @param string $option List user is in (e.g., 'access_users_approved').
3674 * @return null
3675 */
3676 function render_user_element( $approved_user, $key, $option, $admin_mode, $advanced_usermeta ) {
3677 $is_local_user = array_key_exists( 'local_user', $approved_user ) && $approved_user['local_user'] === 'true';
3678 $is_multisite_user = array_key_exists( 'multisite_user', $approved_user ) && $approved_user['multisite_user'] === true;
3679 $option_prefix = $is_multisite_user ? 'auth_multisite_settings_' : 'auth_settings_';
3680 $option_id = $option_prefix . $option . '_' . $key;
3681 $approved_wp_user = get_user_by( 'email', $approved_user['email'] );
3682 $is_current_user = $approved_wp_user && $approved_wp_user->ID === get_current_user_id();
3683
3684 // Adjust javascript function prefixes if multisite.
3685 $js_function_prefix = $admin_mode === MULTISITE_ADMIN ? 'auth_multisite_' : 'auth_';
3686 $is_multisite_admin_page = $admin_mode === MULTISITE_ADMIN;
3687
3688 if ( ! $approved_wp_user ) :
3689 $approved_user['is_wp_user'] = false;
3690 else :
3691 $approved_user['is_wp_user'] = true;
3692 $approved_user['email'] = $approved_wp_user->user_email;
3693 $approved_user['role'] = $is_multisite_admin_page || count( $approved_wp_user->roles ) === 0 ? $approved_user['role'] : array_shift( $approved_wp_user->roles );
3694 $approved_user['date_added'] = $approved_wp_user->user_registered;
3695
3696 // Get usermeta field from the WordPress user's real usermeta.
3697 if ( strlen( $advanced_usermeta ) > 0 ) :
3698 if ( strpos( $advanced_usermeta, 'acf___' ) === 0 && class_exists( 'acf' ) ) :
3699 // Get ACF Field value for the user
3700 $approved_user['usermeta'] = get_field( str_replace('acf___', '', $advanced_usermeta ), 'user_' . $approved_wp_user->ID );
3701 else :
3702 // Get regular usermeta value for the user.
3703 $approved_user['usermeta'] = get_user_meta( $approved_wp_user->ID, $advanced_usermeta, true );
3704 endif;
3705 if ( is_array( $approved_user['usermeta'] ) || is_object( $approved_user['usermeta'] ) ) :
3706 $approved_user['usermeta'] = serialize( $approved_user['usermeta'] );
3707 endif;
3708 endif;
3709 endif;
3710 if ( ! array_key_exists( 'usermeta', $approved_user ) ) :
3711 $approved_user['usermeta'] = '';
3712 endif; ?>
3713 <li>
3714 <input
3715 type="text"
3716 id="<?php echo $option_id; ?>"
3717 value="<?php echo $approved_user['email']; ?>"
3718 readonly="true"
3719 class="<?php echo $this->create_class_name( 'email', $is_multisite_user ); ?>"
3720 />
3721 <select
3722 id="<?php echo $option_id; ?>_role"
3723 class="<?php echo $this->create_class_name( 'role', $is_multisite_user ); ?>"
3724 onchange="<?php echo $js_function_prefix; ?>change_role( this );"
3725 <?php if ( $is_multisite_user ) : ?>
3726 disabled="disabled"
3727 <?php endif; ?>
3728 >
3729 <?php $disable_input = $is_current_user ? 'disabled' : null; ?>
3730 <?php $this->wp_dropdown_permitted_roles( $approved_user['role'], $disable_input, $admin_mode ); ?>
3731 </select>
3732 <input
3733 type="text"
3734 id="<?php echo $option_id; ?>_date_added"
3735 value="<?php echo date( 'M Y', strtotime( $approved_user['date_added'] ) ); ?>"
3736 readonly="true"
3737 class="<?php echo $this->create_class_name( 'date-added', $is_multisite_user ); ?>"
3738 />
3739 <?php if ( strlen( $advanced_usermeta ) > 0 ) :
3740 $should_show_usermeta_in_text_field = true; // Fallback renderer for usermeta; try to use a select first.
3741 if ( strpos( $advanced_usermeta, 'acf___' ) === 0 && class_exists( 'acf' ) ) :
3742 $field_object = get_field_object( str_replace('acf___', '', $advanced_usermeta ) );
3743 if ( is_array( $field_object ) && array_key_exists( 'type', $field_object ) && $field_object['type'] === 'select' ) :
3744 $should_show_usermeta_in_text_field = false; ?>
3745 <select
3746 id="<?php echo $option_id; ?>_usermeta"
3747 class="<?php echo $this->create_class_name( 'usermeta', $is_multisite_user ); ?>"
3748 onchange="<?php echo $js_function_prefix; ?>update_usermeta( this );"
3749 >
3750 <option value=""<?php if ( empty( $approved_user['usermeta'] ) ) echo ' selected="selected"'; ?>><?php _e( '-- None --', 'authorizer' ); ?></option>
3751 <?php foreach ( $field_object['choices'] as $key => $label ) : ?>
3752 <option value="<?php echo $key; ?>"<?php if ( $key === $approved_user['usermeta'] || ( isset( $approved_user['usermeta']['meta_value'] ) && $key === $approved_user['usermeta']['meta_value'] ) ) echo ' selected="selected"'; ?>><?php echo $label; ?></option>
3753 <?php endforeach; ?>
3754 </select>
3755 <?php endif; ?>
3756 <?php endif; ?>
3757 <?php if ( $should_show_usermeta_in_text_field ) : ?>
3758 <input
3759 type="text"
3760 id="<?php echo $option_id; ?>_usermeta"
3761 value="<?php echo htmlspecialchars( $approved_user['usermeta'], ENT_COMPAT ); ?>"
3762 class="<?php echo $this->create_class_name( 'usermeta', $is_multisite_user ); ?>"
3763 />
3764 <a class="button button-small button-primary update-usermeta" id="update_usermeta_<?php echo $key; ?>" onclick="<?php echo $js_function_prefix; ?>update_usermeta( this );" title="Update usermeta"><span class="glyphicon glyphicon-floppy-saved"></span></a>
3765 <?php endif; ?>
3766 <?php endif; ?>
3767 <?php if ( ! $is_current_user && ! $is_multisite_user ): ?>
3768 <?php if ( ! $is_multisite_admin_page ) : ?>
3769 <a class="button" id="block_user_<?php echo $key; ?>" onclick="<?php echo $js_function_prefix; ?>add_user( this, 'blocked', false ); <?php echo $js_function_prefix; ?>ignore_user( this, 'approved' );" title="<?php _e( 'Block/Ban user', 'authorizer' ); ?>"><span class="glyphicon glyphicon-ban-circle"></span></a>
3770 <?php endif; ?>
3771 <a class="button" id="ignore_user_<?php echo $key; ?>" onclick="<?php echo $js_function_prefix; ?>ignore_user(this, 'approved' );" title="<?php _e( 'Remove user', 'authorizer' ); ?>"><span class="glyphicon glyphicon-remove"></span></a>
3772 <?php endif; ?>
3773 <?php if ( $is_local_user ) : ?>
3774 &nbsp;<a title="Local WordPress user" class="auth-local-user"><span class="glyphicon glyphicon-user"></span></a>
3775 <?php endif; ?>
3776 <?php if ( $is_multisite_user ) : ?>
3777 &nbsp;<a title="WordPress Multisite user" class="auth-multisite-user"><span class="glyphicon glyphicon-globe"></span></a>
3778 <?php endif; ?>
3779 </li><?php
3780 }
3781
3782
3783 function print_combo_auth_access_users_blocked( $args = '' ) {
3784 // Get plugin option.
3785 $option = 'access_users_blocked';
3786 $auth_settings_option = $this->get_plugin_option( $option );
3787 $auth_settings_option = is_array( $auth_settings_option ) ? $auth_settings_option : array();
3788
3789 // Get default role for new blocked user dropdown.
3790 $access_default_role = $this->get_plugin_option( 'access_default_role', SINGLE_ADMIN, 'allow override' );
3791
3792 // Render wrapper div (for aligning pager to width of content).
3793 ?><div class="wrapper_<?php echo $option; ?>"><?php
3794
3795 // Print option elements.
3796 ?><ul id="list_auth_settings_<?php echo $option; ?>" style="margin:0;">
3797 <?php foreach ( $auth_settings_option as $key => $blocked_user ): ?>
3798 <?php if ( empty( $blocked_user ) || count( $blocked_user ) < 1 ) continue; ?>
3799 <?php if ( $blocked_wp_user = get_user_by( 'email', $blocked_user['email'] ) ): ?>
3800 <?php $blocked_user['email'] = $blocked_wp_user->user_email; ?>
3801 <?php $blocked_user['role'] = array_shift( $blocked_wp_user->roles ); ?>
3802 <?php $blocked_user['date_added'] = $blocked_wp_user->user_registered; ?>
3803 <?php $blocked_user['is_wp_user'] = true; ?>
3804 <?php else: ?>
3805 <?php $blocked_user['is_wp_user'] = false; ?>
3806 <?php endif; ?>
3807 <li>
3808 <input type="text" id="auth_settings_<?php echo $option; ?>_<?php echo $key; ?>" value="<?php echo $blocked_user['email']; ?>" readonly="true" class="auth-email" />
3809 <select id="auth_settings_<?php echo $option; ?>_<?php echo $key; ?>_role" class="auth-role">
3810 <?php $this->wp_dropdown_permitted_roles( $blocked_user['role'] ); ?>
3811 </select>
3812 <input type="text" id="auth_settings_<?php echo $option; ?>_<?php echo $key; ?>_date_added" value="<?php echo date( 'M Y', strtotime( $blocked_user['date_added'] ) ); ?>" readonly="true" class="auth-date-added" />
3813 <a class="button" id="ignore_user_<?php echo $key; ?>" onclick="auth_ignore_user(this, 'blocked' );" title="<?php _e( 'Remove user', 'authorizer' ); ?>"><span class="glyphicon glyphicon-remove"></span></a>
3814 </li>
3815 <?php endforeach; ?>
3816 </ul>
3817 <div id="new_auth_settings_<?php echo $option; ?>">
3818 <input type="text" id="new_blocked_user_email" placeholder="<?php _e( 'email address', 'authorizer' ); ?>" class="auth-email new" />
3819 <select id="new_blocked_user_role" class="auth-role">
3820 <option value="<?php echo $access_default_role; ?>"><?php echo ucfirst( $access_default_role ); ?></option>
3821 </select>
3822 <a href="javascript:void(0);" class="button-primary" id="block_user_new" onclick="auth_add_user(this, 'blocked' );"><span class="glyphicon glyphicon-ban-circle"></span> <?php _e( 'Block', 'authorizer' ); ?></a>
3823 </div>
3824 </div>
3825 <?php
3826 }
3827
3828
3829 function print_section_info_access_login( $args = '' ) {
3830 ?><div id="section_info_access_login" class="section_info">
3831 <?php wp_nonce_field( 'save_auth_settings', 'nonce_save_auth_settings' ); ?>
3832 <p><?php _e( 'Choose who is able to log into this site below.', 'authorizer' ); ?></p>
3833 </div><?php
3834 }
3835
3836
3837 function print_radio_auth_access_who_can_login( $args = '' ) {
3838 // Get plugin option.
3839 $option = 'access_who_can_login';
3840 $admin_mode = $this->get_admin_mode( $args );
3841 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3842
3843 // If this site is configured independently of any multisite overrides, make sure we are not grabbing the multisite value; otherwise, grab the multisite value to show behind the disabled overlay.
3844 if ( is_multisite() && $this->get_plugin_option( 'advanced_override_multisite' ) == '1' ) {
3845 $auth_settings_option = $this->get_plugin_option( $option );
3846 } elseif ( is_multisite() && $admin_mode === SINGLE_ADMIN && $this->get_plugin_option( 'multisite_override', MULTISITE_ADMIN ) === '1' ) {
3847 // Workaround: javascript code hides/shows other settings based
3848 // on the selection in this option. If this option is overridden
3849 // by a multisite option, it should show that value in order to
3850 // correctly display the other appropriate options.
3851 // Side effect: this site option will be overwritten by the
3852 // multisite option on save. Since this is a 2-item radio, we
3853 // determined this was acceptable.
3854 $auth_settings_option = $this->get_plugin_option( $option, MULTISITE_ADMIN );
3855 }
3856
3857 // Print option elements.
3858 ?><input type="radio" id="radio_auth_settings_<?php echo $option; ?>_external_users" name="auth_settings[<?php echo $option; ?>]" value="external_users"<?php checked( 'external_users' == $auth_settings_option ); ?> /><label for="radio_auth_settings_<?php echo $option; ?>_external_users"><?php _e( 'All authenticated users (All external service users and all WordPress users)', 'authorizer' ); ?></label><br />
3859 <input type="radio" id="radio_auth_settings_<?php echo $option; ?>_approved_users" name="auth_settings[<?php echo $option; ?>]" value="approved_users"<?php checked( 'approved_users' == $auth_settings_option ); ?> /><label for="radio_auth_settings_<?php echo $option; ?>_approved_users"><?php _e( 'Only', 'authorizer' ); ?> <a href="javascript:choose_tab('access_lists' );" id="dashboard_link_approved_users"><?php _e( 'approved users', 'authorizer' ); ?></a> <?php _e( '(Approved external users and all WordPress users)', 'authorizer' ); ?></label><br /><?php
3860 }
3861
3862
3863 function print_select_auth_access_role_receive_pending_emails( $args = '' ) {
3864 // Get plugin option.
3865 $option = 'access_role_receive_pending_emails';
3866 $auth_settings_option = $this->get_plugin_option( $option );
3867
3868 // Print option elements.
3869 ?><select id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]">
3870 <option value="---" <?php selected( $auth_settings_option, '---' ); ?>><?php _e( "None (Don't send notification emails)", 'authorizer' ); ?></option>
3871 <?php wp_dropdown_roles( $auth_settings_option ); ?>
3872 </select><?php
3873 }
3874
3875
3876 function print_wysiwyg_auth_access_pending_redirect_to_message( $args = '' ) {
3877 // Get plugin option.
3878 $option = 'access_pending_redirect_to_message';
3879 $auth_settings_option = $this->get_plugin_option( $option );
3880
3881 // Print option elements.
3882 wp_editor(
3883 wpautop( $auth_settings_option ),
3884 "auth_settings_$option",
3885 array(
3886 'media_buttons' => false,
3887 'textarea_name' => "auth_settings[$option]",
3888 'textarea_rows' => 5,
3889 'tinymce' => true,
3890 'teeny' => true,
3891 'quicktags' => false,
3892 )
3893 );
3894 }
3895
3896
3897 function print_wysiwyg_auth_access_blocked_redirect_to_message( $args = '' ) {
3898 // Get plugin option.
3899 $option = 'access_blocked_redirect_to_message';
3900 $auth_settings_option = $this->get_plugin_option( $option );
3901
3902 // Print option elements.
3903 wp_editor(
3904 wpautop( $auth_settings_option ),
3905 "auth_settings_$option",
3906 array(
3907 'media_buttons' => false,
3908 'textarea_name' => "auth_settings[$option]",
3909 'textarea_rows' => 5,
3910 'tinymce' => true,
3911 'teeny' => true,
3912 'quicktags' => false,
3913 )
3914 );
3915 }
3916
3917
3918 function print_checkbox_auth_access_should_email_approved_users( $args = '' ) {
3919 // Get plugin option.
3920 $option = 'access_should_email_approved_users';
3921 $auth_settings_option = $this->get_plugin_option( $option );
3922
3923 // Print option elements.
3924 ?><input type="checkbox" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="1"<?php checked( 1 == $auth_settings_option ); ?> /><label for="auth_settings_<?php echo $option; ?>"><?php _e( 'Send a welcome email when approving a new user', 'authorizer' ); ?></label><?php
3925 }
3926
3927
3928 function print_text_auth_access_email_approved_users_subject( $args = '' ) {
3929 // Get plugin option.
3930 $option = 'access_email_approved_users_subject';
3931 $auth_settings_option = $this->get_plugin_option( $option );
3932
3933 // Print option elements.
3934 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="Welcome to [site_name]!" style="width:320px;" /><br /><small><?php _e( 'You can use the <b>[site_name]</b> shortcode.', 'authorizer' ); ?></small><?php
3935 }
3936
3937
3938 function print_wysiwyg_auth_access_email_approved_users_body( $args = '' ) {
3939 // Get plugin option.
3940 $option = 'access_email_approved_users_body';
3941 $auth_settings_option = $this->get_plugin_option( $option );
3942
3943 // Print option elements.
3944 wp_editor(
3945 wpautop( $auth_settings_option ),
3946 "auth_settings_$option",
3947 array(
3948 'media_buttons' => false,
3949 'textarea_name' => "auth_settings[$option]",
3950 'textarea_rows' => 9,
3951 'tinymce' => true,
3952 'teeny' => true,
3953 'quicktags' => false,
3954 )
3955 );
3956
3957 ?><small><?php printf(
3958 /* TRANSLATORS: 1: Shortcode for site name 2: Shortcode for site URL 3: Shortcode for user email */
3959 __( 'You can use %1$s, %2$s, and %3$s shortcodes.', 'authorizer' ),
3960 '<b>[site_name]</b>',
3961 '<b>[site_url]</b>',
3962 '<b>[user_email]</b>'
3963 ); ?></small><?php
3964
3965 }
3966
3967
3968 function print_section_info_access_public( $args = '' ) {
3969 ?><div id="section_info_access_public" class="section_info">
3970 <p><?php _e( 'Choose your public access options here.', 'authorizer' ); ?></p>
3971 </div><?php
3972 }
3973
3974
3975 function print_radio_auth_access_who_can_view( $args = '' ) {
3976 // Get plugin option.
3977 $option = 'access_who_can_view';
3978 $admin_mode = $this->get_admin_mode( $args );
3979 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3980
3981 // If this site is configured independently of any multisite overrides, make sure we are not grabbing the multisite value; otherwise, grab the multisite value to show behind the disabled overlay.
3982 if ( is_multisite() && $this->get_plugin_option( 'advanced_override_multisite' ) == '1' ) {
3983 $auth_settings_option = $this->get_plugin_option( $option );
3984 } elseif ( is_multisite() && $admin_mode === SINGLE_ADMIN && $this->get_plugin_option( 'multisite_override', MULTISITE_ADMIN ) === '1' ) {
3985 // Workaround: javascript code hides/shows other settings based
3986 // on the selection in this option. If this option is overridden
3987 // by a multisite option, it should show that value in order to
3988 // correctly display the other appropriate options.
3989 // Side effect: this site option will be overwritten by the
3990 // multisite option on save. Since this is a 2-item radio, we
3991 // determined this was acceptable.
3992 $auth_settings_option = $this->get_plugin_option( $option, MULTISITE_ADMIN );
3993 }
3994
3995 // Print option elements.
3996 ?><input type="radio" id="radio_auth_settings_<?php echo $option; ?>_everyone" name="auth_settings[<?php echo $option; ?>]" value="everyone"<?php checked( 'everyone' == $auth_settings_option ); ?> /><label for="radio_auth_settings_<?php echo $option; ?>_everyone"><?php _e( 'Everyone can see the site', 'authorizer' ); ?></label><br />
3997 <input type="radio" id="radio_auth_settings_<?php echo $option; ?>_logged_in_users" name="auth_settings[<?php echo $option; ?>]" value="logged_in_users"<?php checked( 'logged_in_users' == $auth_settings_option ); ?> /><label for="radio_auth_settings_<?php echo $option; ?>_logged_in_users"><?php _e( 'Only logged in users can see the site', 'authorizer' ); ?></label><br /><?php
3998 }
3999
4000
4001 function print_radio_auth_access_redirect( $args = '' ) {
4002 // Get plugin option.
4003 $option = 'access_redirect';
4004 $auth_settings_option = $this->get_plugin_option( $option );
4005
4006 // Print option elements.
4007 ?><input type="radio" id="radio_auth_settings_<?php echo $option; ?>_to_login" name="auth_settings[<?php echo $option; ?>]" value="login"<?php checked( 'login' == $auth_settings_option ); ?> /><label for="radio_auth_settings_<?php echo $option; ?>_to_login"><?php _e( 'Send them to the login screen', 'authorizer' ); ?></label><br />
4008 <input type="radio" id="radio_auth_settings_<?php echo $option; ?>_to_message" name="auth_settings[<?php echo $option; ?>]" value="message"<?php checked( 'message' == $auth_settings_option ); ?> /><label for="radio_auth_settings_<?php echo $option; ?>_to_message"><?php _e( 'Show them the anonymous access message (below)', 'authorizer' ); ?></label><?php
4009 }
4010
4011
4012 function print_radio_auth_access_public_warning( $args = '' ) {
4013 // Get plugin option.
4014 $option = 'access_public_warning';
4015 $auth_settings_option = $this->get_plugin_option( $option );
4016
4017 // Print option elements.
4018 ?><input type="radio" id="radio_auth_settings_<?php echo $option; ?>_no" name="auth_settings[<?php echo $option; ?>]" value="no_warning"<?php checked( 'no_warning' == $auth_settings_option ); ?> /><label for="radio_auth_settings_<?php echo $option; ?>_no"><?php _e( 'Show them the page <strong>without</strong> the anonymous access message', 'authorizer' ); ?></label><br />
4019 <input type="radio" id="radio_auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="warning"<?php checked( 'warning' == $auth_settings_option ); ?> /><label for="radio_auth_settings_<?php echo $option; ?>"><?php _e( 'Show them the page <strong>with</strong> the anonymous access message (marked up as a <a href="http://getbootstrap.com/components/#alerts-dismissible" target="_blank">Bootstrap Dismissible Alert</a>)', 'authorizer' ); ?></label><?php
4020 }
4021
4022
4023 function print_wysiwyg_auth_access_redirect_to_message( $args = '' ) {
4024 // Get plugin option.
4025 $option = 'access_redirect_to_message';
4026 $auth_settings_option = $this->get_plugin_option( $option );
4027
4028 // Print option elements.
4029 wp_editor(
4030 wpautop( $auth_settings_option ),
4031 "auth_settings_$option",
4032 array(
4033 'media_buttons' => false,
4034 'textarea_name' => "auth_settings[$option]",
4035 'textarea_rows' => 5,
4036 'tinymce' => true,
4037 'teeny' => true,
4038 'quicktags' => false,
4039 )
4040 );
4041 }
4042
4043
4044 function print_multiselect_auth_access_public_pages( $args = '' ) {
4045 // Get plugin option.
4046 $option = 'access_public_pages';
4047 $auth_settings_option = $this->get_plugin_option( $option );
4048 $auth_settings_option = is_array( $auth_settings_option ) ? $auth_settings_option : array();
4049
4050 $post_types = array_merge( array( 'page', 'post' ), get_post_types( array( '_builtin' => false ), 'names' ) );
4051 $post_types = is_array( $post_types ) ? $post_types : array();
4052
4053 // Print option elements.
4054 ?><select id="auth_settings_<?php echo $option; ?>" multiple="multiple" name="auth_settings[<?php echo $option; ?>][]">
4055 <optgroup label="<?php _e( 'Home', 'authorizer' ); ?>">
4056 <option value="home" <?php echo in_array( 'home', $auth_settings_option ) ? 'selected="selected"' : ''; ?>><?php _e( 'Home Page', 'authorizer' ); ?></option>
4057 <option value="auth_public_404" <?php echo in_array( 'auth_public_404', $auth_settings_option ) ? 'selected="selected"' : ''; ?>><?php _e( 'Nonexistent (404) Pages', 'authorizer' ); ?></option>
4058 </optgroup>
4059 <?php foreach ( $post_types as $post_type ): ?>
4060 <optgroup label="<?php echo ucfirst( $post_type ); ?>">
4061 <?php $pages = get_posts( array( 'post_type' => $post_type, 'posts_per_page' => -1 ) ); ?>
4062 <?php $pages = is_array( $pages ) ? $pages : array(); ?>
4063 <?php foreach ( $pages as $page ): ?>
4064 <option value="<?php echo $page->ID; ?>" <?php echo in_array( $page->ID, $auth_settings_option ) ? 'selected="selected"' : ''; ?>><?php echo $page->post_title; ?></option>
4065 <?php endforeach; ?>
4066 </optgroup>
4067 <?php endforeach; ?>
4068 <optgroup label="<?php _e( 'Categories', 'authorizer' ); ?>">
4069 <?php
4070 // If sitepress-multilingual-cms plugin is enabled, temporarily disable
4071 // its terms_clauses filter since it conflicts with the category handling.
4072 if ( array_key_exists( 'sitepress', $GLOBALS ) && is_object( $GLOBALS['sitepress'] ) ) {
4073 remove_filter( 'terms_clauses', array( $GLOBALS['sitepress'], 'terms_clauses' ) );
4074 $categories = get_categories( array( 'hide_empty' => false ) );
4075 add_filter( 'terms_clauses', array( $GLOBALS['sitepress'], 'terms_clauses' ) );
4076 } else {
4077 $categories = get_categories( array( 'hide_empty' => false ) );
4078 }
4079 foreach ( $categories as $category ) : ?>
4080 <option value="<?php echo 'cat_' . $category->slug; ?>" <?php echo in_array( 'cat_' . $category->slug, $auth_settings_option ) ? 'selected="selected"' : ''; ?>><?php echo $category->name; ?></option>
4081 <?php endforeach; ?>
4082 </optgroup>
4083 </select><?php
4084 }
4085
4086
4087 function print_section_info_external( $args = '' ) {
4088 ?><div id="section_info_external" class="section_info">
4089 <p><?php _e( 'Enter your external server settings below.', 'authorizer' ); ?></p>
4090 </div><?php
4091 }
4092
4093
4094 function get_admin_mode( $args ) {
4095 if ( is_array( $args ) && array_key_exists( MULTISITE_ADMIN, $args ) && $args[MULTISITE_ADMIN] === true ) {
4096 return MULTISITE_ADMIN;
4097 } else {
4098 return SINGLE_ADMIN;
4099 }
4100 }
4101
4102
4103 function print_select_auth_access_default_role( $args = '' ) {
4104 // Get plugin option.
4105 $option = 'access_default_role';
4106 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4107
4108 // Print option elements.
4109 ?><select id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]">
4110 <?php wp_dropdown_roles( $auth_settings_option ); ?>
4111 </select><?php
4112 }
4113
4114
4115 function print_checkbox_auth_external_google( $args = '' ) {
4116 // Get plugin option.
4117 $option = 'google';
4118 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4119
4120 // Print option elements.
4121 ?><input type="checkbox" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="1"<?php checked( 1 == $auth_settings_option ); ?> /><label for="auth_settings_<?php echo $option; ?>"><?php _e( 'Enable Google Logins', 'authorizer' ); ?></label><?php
4122 }
4123
4124
4125 function print_text_google_clientid( $args = '' ) {
4126 // Get plugin option.
4127 $option = 'google_clientid';
4128 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4129
4130 // Print option elements.
4131 $site_url_parts = parse_url( get_site_url() );
4132 $site_url_host = $site_url_parts['scheme'] . '://' . $site_url_parts['host'] . '/';
4133 ?><?php _e( "If you don't have a Google Client ID and Secret, generate them by following these instructions:", 'authorizer' ); ?>
4134 <ol>
4135 <li><?php _e( 'Click <strong>Create a Project</strong> on the <a href="https://cloud.google.com/console" target="_blank">Google Developers Console</a>. You can name it whatever you want.', 'authorizer' ); ?></li>
4136 <li><?php _e( 'Within the project, navigate to <em>APIs and Auth</em> &gt; <em>Credentials</em>, then click <strong>Create New Client ID</strong> under OAuth. Use these settings:', 'authorizer' ); ?>
4137 <ul>
4138 <li><?php _e( 'Application Type: <strong>Web application</strong>', 'authorizer' ); ?></li>
4139 <li><?php _e( 'Authorized Javascript Origins:', 'authorizer' ); ?> <strong><?php echo rtrim( $site_url_host, '/' ); ?></strong></li>
4140 <li><?php _e( 'Authorized Redirect URI: <em>none</em>', 'authorizer' ); ?></li>
4141 </ul>
4142 </li>
4143 <li><?php _e( 'Copy/paste your new Client ID/Secret pair into the fields below.', 'authorizer' ); ?></li>
4144 <li><?php _e( '<strong>Note</strong>: Navigate to <em>APIs and Auth</em> &gt; <em>Consent screen</em> to change the way the Google consent screen appears after a user has successfully entered their password, but before they are redirected back to WordPress.', 'authorizer' ); ?></li>
4145 <li><?php _e( 'Note: Google may have a more recent version of these instructions in their <a href="https://developers.google.com/identity/sign-in/web/devconsole-project" target="_blank">developer documentation</a>.', 'authorizer' ); ?></li>
4146 </ol>
4147 <input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" style="width:560px;" />
4148 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: 1234567890123-kdjr85yt6vjr6d8g7dhr8g7d6durjf7g.apps.googleusercontent.com', 'authorizer'); ?></label><?php
4149 }
4150
4151
4152 function print_text_google_clientsecret( $args = '' ) {
4153 // Get plugin option.
4154 $option = 'google_clientsecret';
4155 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4156
4157 // Print option elements.
4158 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" style="width:220px;" />
4159 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: sDNgX5_pr_5bly-frKmvp8jT', 'authorizer'); ?></label><?php
4160 }
4161
4162
4163 function print_text_google_hosteddomain( $args = '' ) {
4164 // Get plugin option.
4165 $option = 'google_hosteddomain';
4166 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4167
4168 // Print option elements.
4169 ?><textarea id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" placeholder="" style="width:220px;"><?php echo $auth_settings_option; ?></textarea>
4170 <br /><small><?php _e( 'Restrict Google logins to a specific Google Apps hosted domain (for example, mycollege.edu). Leave blank to allow all Google sign-ins.', 'authorizer' ); ?><br /><?php _e( 'If restricting to multiple domains, add one domain per line.', 'authorizer' ); ?></small>
4171 <?php
4172 }
4173
4174
4175 function print_checkbox_auth_external_cas( $args = '' ) {
4176 // Get plugin option.
4177 $option = 'cas';
4178 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4179
4180 // Make sure php5-curl extension is installed on server.
4181 $curl_installed_message = ! function_exists( 'curl_init' ) ? __( '<a href="http://www.php.net//manual/en/curl.installation.php" target="_blank" style="color: red;">PHP CURL extension</a> is not installed', 'authorizer' ) : '';
4182
4183 // Make sure php_openssl extension is installed on server.
4184 $openssl_installed_message = ! extension_loaded( 'openssl' ) ? __( '<a href="http://stackoverflow.com/questions/23424459/enable-php-openssl-not-working" target="_blank" style="color: red;">PHP openssl extension</a> is not installed', 'authorizer' ) : '';
4185
4186 // Build error message string.
4187 $error_message = '';
4188 if ( strlen( $curl_installed_message ) > 0 || strlen( $openssl_installed_message ) > 0 ) {
4189 $error_message = '<span style="color: red;">(' .
4190 __( 'Warning', 'authorizer' ) . ': ' .
4191 $curl_installed_message .
4192 ( strlen( $curl_installed_message ) > 0 && strlen( $openssl_installed_message ) > 0 ? '; ' : '' ) .
4193 $openssl_installed_message .
4194 ')</span>';
4195 }
4196
4197 // Print option elements.
4198 ?><input type="checkbox" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="1"<?php checked( 1 == $auth_settings_option ); ?> /><label for="auth_settings_<?php echo $option; ?>"><?php _e( 'Enable CAS Logins', 'authorizer' ); ?></label> <?php echo $error_message; ?><?php
4199 }
4200
4201
4202 function print_text_cas_custom_label( $args = '' ) {
4203 // Get plugin option.
4204 $option = 'cas_custom_label';
4205 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4206
4207 // Print option elements.
4208 ?><?php _e( 'The button on the login page will read:', 'authorizer' ); ?><p><a class="button-primary button-large" style="padding: 3px 16px; height: 36px;"><span class="dashicons dashicons-lock" style="margin: 4px 4px 0 0;"></span> <strong><?php _e( 'Sign in with', 'authorizer' ); ?> </strong><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="CAS" style="width: 100px;" /></a></p><?php
4209 }
4210
4211
4212 function print_text_cas_host( $args = '' ) {
4213 // Get plugin option.
4214 $option = 'cas_host';
4215 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4216
4217 // Print option elements.
4218 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" />
4219 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: authn.example.edu', 'authorizer'); ?></label><?php
4220 }
4221
4222
4223 function print_text_cas_port( $args = '' ) {
4224 // Get plugin option.
4225 $option = 'cas_port';
4226 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4227
4228 // Print option elements.
4229 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" style="width:50px;" />
4230 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: 443', 'authorizer'); ?></label><?php
4231 }
4232
4233
4234 function print_text_cas_path( $args = '' ) {
4235 // Get plugin option.
4236 $option = 'cas_path';
4237 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4238
4239 // Print option elements.
4240 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" />
4241 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: /cas', 'authorizer'); ?></label><?php
4242 }
4243
4244
4245 function print_select_cas_version( $args = '' ) {
4246 // Get plugin option.
4247 $option = 'cas_version';
4248 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4249
4250 // Print option elements.
4251 ?><select id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]">
4252 <option value="SAML_VERSION_1_1" <?php selected( $auth_settings_option, 'SAML_VERSION_1_1' ); ?>>SAML_VERSION_1_1</option>
4253 <option value="CAS_VERSION_3_0" <?php selected( $auth_settings_option, 'CAS_VERSION_3_0' ); ?>>CAS_VERSION_3_0</option>
4254 <option value="CAS_VERSION_2_0" <?php selected( $auth_settings_option, 'CAS_VERSION_2_0' ); ?>>CAS_VERSION_2_0</option>
4255 <option value="CAS_VERSION_1_0" <?php selected( $auth_settings_option, 'CAS_VERSION_1_0' ); ?>>CAS_VERSION_1_0</option>
4256 </select><?php
4257 }
4258
4259
4260 function print_text_cas_attr_email( $args = '' ) {
4261 // Get plugin option.
4262 $option = 'cas_attr_email';
4263 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4264
4265 // Print option elements.
4266 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" />
4267 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: mail', 'authorizer'); ?></label>
4268 <br /><small><?php _e( "Note: If your CAS server doesn't return an attribute containing an email, you can specify the @domain portion of the email address here, and the email address will be constructed from it and the username. For example, if user 'bob' logs in and his email address should be bob@example.edu, then enter <strong>@example.edu</strong> in this field.", 'authorizer' ); ?></small><?php
4269 }
4270
4271
4272 function print_text_cas_attr_first_name( $args = '' ) {
4273 // Get plugin option.
4274 $option = 'cas_attr_first_name';
4275 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4276
4277 // Print option elements.
4278 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" />
4279 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: givenName', 'authorizer'); ?></label><?php
4280 }
4281
4282
4283 function print_text_cas_attr_last_name( $args = '' ) {
4284 // Get plugin option.
4285 $option = 'cas_attr_last_name';
4286 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4287
4288 // Print option elements.
4289 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" />
4290 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: sn', 'authorizer'); ?></label><?php
4291 }
4292
4293
4294 function print_checkbox_cas_attr_update_on_login( $args = '' ) {
4295 // Get plugin option.
4296 $option = 'cas_attr_update_on_login';
4297 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4298
4299 // Print option elements.
4300 ?><input type="checkbox" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="1"<?php checked( 1 == $auth_settings_option ); ?> /><label for="auth_settings_<?php echo $option; ?>"><?php _e( 'Update first and last name fields on login (will overwrite any name the user has supplied in their profile)', 'authorizer' ); ?></label><?php
4301 }
4302
4303
4304 function print_checkbox_cas_auto_login( $args = '' ) {
4305 // Get plugin option.
4306 $option = 'cas_auto_login';
4307 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4308
4309 // Print option elements.
4310 ?><input type="checkbox" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="1"<?php checked( 1 == $auth_settings_option ); ?> /><label for="auth_settings_<?php echo $option; ?>"><?php _e( "Immediately redirect to CAS login form if it's the only enabled external service and WordPress logins are hidden", 'authorizer' ); ?></label>
4311 <p><small><?php _e( 'Note: This feature will only work if you have checked "Hide WordPress Logins" in Advanced settings, and if CAS is the only enabled service (i.e., no Google or LDAP). If you have enabled CAS Single Sign-On (SSO), and a user has already logged into CAS elsewhere, enabling this feature will allow automatic logins without any user interaction.', 'authorizer' ); ?></small></p><?php
4312 }
4313
4314
4315 function print_checkbox_auth_external_ldap( $args = '' ) {
4316 // Get plugin option.
4317 $option = 'ldap';
4318 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4319
4320 // Make sure php5-ldap extension is installed on server.
4321 $ldap_installed_message = ! function_exists( 'ldap_connect' ) ? '<span style="color: red;">(' . __( 'Warning: <a href="http://www.php.net/manual/en/ldap.installation.php" target="_blank" style="color: red;">PHP LDAP extension</a> is <strong>not</strong> installed', 'authorizer' ) . ')</span>' : '';
4322
4323 // Print option elements.
4324 ?><input type="checkbox" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="1"<?php checked( 1 == $auth_settings_option ); ?> /><label for="auth_settings_<?php echo $option; ?>"><?php _e( 'Enable LDAP Logins', 'authorizer' ); ?></label> <?php echo $ldap_installed_message; ?><?php
4325 }
4326
4327
4328 function print_text_ldap_host( $args = '' ) {
4329 // Get plugin option.
4330 $option = 'ldap_host';
4331 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4332
4333 // Print option elements.
4334 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" style="width:330px;" />
4335 <br /><small><?php _e( "Specify either a hostname (for example, ldap.example.edu) or a full LDAP URI (for example, ldaps://ldap.example.edu:636).", 'authorizer' ); ?></small><?php
4336 }
4337
4338
4339 function print_text_ldap_port( $args = '' ) {
4340 // Get plugin option.
4341 $option = 'ldap_port';
4342 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4343
4344 // Print option elements.
4345 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" style="width:50px;" />
4346 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: 389', 'authorizer' ); ?></label>
4347 <br /><small><?php _e( "If a full LDAP URI (ldaps://hostname:port) is specified above, this field is ignored.", 'authorizer' ); ?></small><?php
4348 }
4349
4350
4351 function print_checkbox_ldap_tls( $args = '' ) {
4352 // Get plugin option.
4353 $option = 'ldap_tls';
4354 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4355
4356 // Print option elements.
4357 ?><input type="checkbox" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="1"<?php checked( 1 == $auth_settings_option ); ?> /><label for="auth_settings_<?php echo $option; ?>"><?php _e( 'Use TLS', 'authorizer' ); ?></label>
4358 <br /><small><?php _e( "If ldaps is used, this should be unchecked", 'authorizer' ); ?></small><?php
4359 }
4360
4361
4362 function print_text_ldap_search_base( $args = '' ) {
4363 // Get plugin option.
4364 $option = 'ldap_search_base';
4365 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4366
4367 // Print option elements.
4368 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" style="width:330px;" />
4369 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: ou=people,dc=example,dc=edu', 'authorizer'); ?></label><?php
4370 }
4371
4372
4373 function print_text_ldap_uid( $args = '' ) {
4374 // Get plugin option.
4375 $option = 'ldap_uid';
4376 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4377
4378 // Print option elements.
4379 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" style="width:80px;" />
4380 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: uid', 'authorizer' ); ?></label><?php
4381 }
4382
4383
4384 function print_text_ldap_attr_email( $args = '' ) {
4385 // Get plugin option.
4386 $option = 'ldap_attr_email';
4387 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4388
4389 // Print option elements.
4390 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" />
4391 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: mail', 'authorizer' ); ?></label>
4392 <br /><small><?php _e( "Note: If your LDAP server doesn't return an attribute containing an email, you can specify the @domain portion of the email address here, and the email address will be constructed from it and the username. For example, if user 'bob' logs in and his email address should be bob@example.edu, then enter <strong>@example.edu</strong> in this field.", 'authorizer' ); ?></small><?php
4393 }
4394
4395
4396 function print_text_ldap_user( $args = '' ) {
4397 // Get plugin option.
4398 $option = 'ldap_user';
4399 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4400
4401 // Print option elements.
4402 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" style="width:330px;" />
4403 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: cn=directory-user,ou=specials,dc=example,dc=edu', 'authorizer' ); ?></label><?php
4404 }
4405
4406
4407 function print_password_ldap_password( $args = '' ) {
4408 // Get plugin option.
4409 $option = 'ldap_password';
4410 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4411
4412 // Print option elements.
4413 ?><input type="password" id="garbage_to_stop_autofill" name="garbage" value="" autocomplete="off" style="display:none;" />
4414 <input type="password" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $this->decrypt( $auth_settings_option ); ?>" autocomplete="off" /><?php
4415 }
4416
4417
4418 function print_text_ldap_lostpassword_url( $args = '' ) {
4419 // Get plugin option.
4420 $option = 'ldap_lostpassword_url';
4421 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4422
4423 // Print option elements.
4424 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" style="width: 400px;" />
4425 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: https://myschool.example.edu:8888/am-forgot-password', 'authorizer' ); ?></label><?php
4426 }
4427
4428
4429 function print_text_ldap_attr_first_name( $args = '' ) {
4430 // Get plugin option.
4431 $option = 'ldap_attr_first_name';
4432 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4433
4434 // Print option elements.
4435 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" />
4436 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: givenname', 'authorizer' ); ?></label><?php
4437 }
4438
4439
4440 function print_text_ldap_attr_last_name( $args = '' ) {
4441 // Get plugin option.
4442 $option = 'ldap_attr_last_name';
4443 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4444
4445 // Print option elements.
4446 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" />
4447 <br /><label for="auth_settings_<?php echo $option; ?>" class="helper"><?php _e( 'Example: sn', 'authorizer' ); ?></label><?php
4448 }
4449
4450
4451 function print_checkbox_ldap_attr_update_on_login( $args = '' ) {
4452 // Get plugin option.
4453 $option = 'ldap_attr_update_on_login';
4454 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4455
4456 // Print option elements.
4457 ?><input type="checkbox" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="1"<?php checked( 1 == $auth_settings_option ); ?> /><label for="auth_settings_<?php echo $option; ?>"><?php _e( 'Update first and last name fields on login (will overwrite any name the user has supplied in their profile)', 'authorizer' ); ?></label><?php
4458 }
4459
4460
4461 function print_section_info_advanced( $args = '' ) {
4462 ?><div id="section_info_advanced" class="section_info">
4463 <p><?php _e( 'You may optionally specify some advanced settings below.', 'authorizer' ); ?></p>
4464 </div><?php
4465 }
4466
4467
4468 function print_text_auth_advanced_lockouts( $args = '' ) {
4469 // Get plugin option.
4470 $option = 'advanced_lockouts';
4471 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4472
4473 // Print option elements.
4474 ?><?php _e( 'After', 'authorizer' ); ?>
4475 <input type="text" id="auth_settings_<?php echo $option; ?>_attempts_1" name="auth_settings[<?php echo $option; ?>][attempts_1]" value="<?php echo $auth_settings_option['attempts_1']; ?>" placeholder="10" style="width:30px;" />
4476 <?php _e( 'invalid password attempts, delay further attempts on that user for', 'authorizer' ); ?>
4477 <input type="text" id="auth_settings_<?php echo $option; ?>_duration_1" name="auth_settings[<?php echo $option; ?>][duration_1]" value="<?php echo $auth_settings_option['duration_1']; ?>" placeholder="1" style="width:30px;" />
4478 <?php _e( 'minute(s).', 'authorizer' ); ?>
4479 <br />
4480 <?php _e( 'After', 'authorizer' ); ?>
4481 <input type="text" id="auth_settings_<?php echo $option; ?>_attempts_2" name="auth_settings[<?php echo $option; ?>][attempts_2]" value="<?php echo $auth_settings_option['attempts_2']; ?>" placeholder="10" style="width:30px;" />
4482 <?php _e( 'more invalid attempts, increase the delay to', 'authorizer' ); ?>
4483 <input type="text" id="auth_settings_<?php echo $option; ?>_duration_2" name="auth_settings[<?php echo $option; ?>][duration_2]" value="<?php echo $auth_settings_option['duration_2']; ?>" placeholder="10" style="width:30px;" />
4484 <?php _e( 'minutes.', 'authorizer' ); ?>
4485 <br />
4486 <?php _e( 'Reset the delays after', 'authorizer' ); ?>
4487 <input type="text" id="auth_settings_<?php echo $option; ?>_reset_duration" name="auth_settings[<?php echo $option; ?>][reset_duration]" value="<?php echo $auth_settings_option['reset_duration']; ?>" placeholder="240" style="width:40px;" />
4488 <?php _e( 'minutes with no invalid attempts.', 'authorizer' ); ?><?php
4489 }
4490
4491
4492 function print_checkbox_auth_advanced_hide_wp_login( $args = '' ) {
4493 // Get plugin option.
4494 $option = 'advanced_hide_wp_login';
4495 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4496
4497 // Print option elements.
4498 ?><input type="checkbox" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="1"<?php checked( 1 == $auth_settings_option ); ?> /><label for="auth_settings_<?php echo $option; ?>"><?php _e( 'Hide WordPress Logins', 'authorizer' ); ?></label>
4499 <p><small><?php _e( 'Note: You can always access the WordPress logins by adding external=wordpress to the wp-login URL, like so:', 'authorizer' ); ?><br /><a href="<?php echo wp_login_url(); ?>?external=wordpress" target="_blank"><?php echo wp_login_url(); ?>?external=wordpress</a>.</p><?php
4500 }
4501
4502
4503 function print_radio_auth_advanced_branding( $args = '' ) {
4504 // Get plugin option.
4505 $option = 'advanced_branding';
4506 $auth_settings_option = $this->get_plugin_option( $option );
4507
4508 // Print option elements.
4509 ?><input type="radio" id="radio_auth_settings_<?php echo $option; ?>_default" name="auth_settings[<?php echo $option; ?>]" value="default"<?php checked( 'default' == $auth_settings_option ); ?> /><label for="radio_auth_settings_<?php echo $option; ?>_default"><?php _e( 'Default WordPress login screen', 'authorizer' ); ?></label><br />
4510 <?php
4511
4512 /**
4513 * Developers can use the `authorizer_add_branding_option` filter
4514 * to add a radio button for "Custom WordPress login branding"
4515 * under the "Advanced" tab in Authorizer options. Example:
4516 *
4517 * function my_authorizer_add_branding_option( $branding_options ) {
4518 * $new_branding_option = array(
4519 * 'value' => 'your_brand'
4520 * 'description' => 'Custom Your Brand Login Screen',
4521 * 'css_url' => 'http://url/to/your_brand.css',
4522 * 'js_url' => 'http://url/to/your_brand.js',
4523 * );
4524 * array_push( $branding_options, $new_branding_option );
4525 * return $branding_options;
4526 * }
4527 * add_filter( 'authorizer_add_branding_option', 'my_authorizer_add_branding_option' );
4528 */
4529 $branding_options = array();
4530 $branding_options = apply_filters( 'authorizer_add_branding_option', $branding_options );
4531 foreach ( $branding_options as $branding_option ) {
4532 // Make sure the custom brands have the required values
4533 if ( ! ( is_array( $branding_option ) && array_key_exists( 'value', $branding_option ) && array_key_exists( 'description', $branding_option ) ) ) {
4534 continue;
4535 }
4536 ?><input type="radio" id="radio_auth_settings_<?php echo $option; ?>_<?php echo sanitize_title( $branding_option['value'] ); ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $branding_option['value']; ?>"<?php checked( $branding_option['value'] == $auth_settings_option ); ?> /><label for="radio_auth_settings_<?php echo $option; ?>_<?php echo sanitize_title( $branding_option['value'] ); ?>"><?php echo $branding_option['description']; ?></label><br /><?php
4537 }
4538
4539 // Print message about adding custom brands if there are none.
4540 if ( count( $branding_options ) === 0 ) {
4541 ?><p><em><?php _e( '<strong>Note for theme developers</strong>: Add more options here by using the `authorizer_add_branding_option` filter in your theme. You can see an example theme that implements this filter in the plugin directory under sample-theme-add-branding.', 'authorizer' ); ?></em></p><?php
4542 }
4543 }
4544
4545
4546 function print_radio_auth_advanced_admin_menu( $args = '' ) {
4547 // Get plugin option.
4548 $option = 'advanced_admin_menu';
4549 $auth_settings_option = $this->get_plugin_option( $option );
4550
4551 // Print option elements.
4552 ?><input type="radio" id="radio_auth_settings_<?php echo $option; ?>_settings" name="auth_settings[<?php echo $option; ?>]" value="settings"<?php checked( 'settings' == $auth_settings_option ); ?> /><label for="radio_auth_settings_<?php echo $option; ?>_settings"><?php _e( 'Show in Settings menu', 'authorizer' ); ?></label><br />
4553 <input type="radio" id="radio_auth_settings_<?php echo $option; ?>_top" name="auth_settings[<?php echo $option; ?>]" value="top"<?php checked( 'top' == $auth_settings_option ); ?> /><label for="radio_auth_settings_<?php echo $option; ?>_top"><?php _e( 'Show in sidebar (top level)', 'authorizer' ); ?></label><br /><?php
4554
4555 }
4556
4557
4558 function print_select_auth_advanced_usermeta( $args = '' ) {
4559 // Get plugin option.
4560 $option = 'advanced_usermeta';
4561 $auth_settings_option = $this->get_plugin_option( $option );
4562
4563 // Print option elements.
4564 ?><select id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]">
4565 <option value=""><?php _e( '-- None --', 'authorizer' ); ?></option>
4566 <?php if ( class_exists( 'acf' ) ) :
4567 // Get ACF 5 fields. Note: it would be much easier to use `get_field_objects()`
4568 // or `get_field_objects( 'user_' . get_current_user_id() )`, but neither will
4569 // list fields that have never been given values for users (i.e., new ACF
4570 // fields). Therefore we fall back on finding any ACF fields applied to users
4571 // (user_role or user_form location rules in the field group definition).
4572 $fields = array();
4573 $acf_field_group_ids = array();
4574 $acf_field_groups = new WP_Query( array(
4575 'post_type' => 'acf-field-group',
4576 ));
4577 while ( $acf_field_groups->have_posts() ) : $acf_field_groups->the_post();
4578 if ( strpos( get_the_content(), 's:5:"param";s:9:"user_role"' ) !== false || strpos( get_the_content(), 's:5:"param";s:9:"user_form"' ) !== false ) :
4579 array_push( $acf_field_group_ids, get_the_ID() );
4580 endif;
4581 endwhile; wp_reset_postdata();
4582 foreach ( $acf_field_group_ids as $acf_field_group_id ) :
4583 $acf_fields = new WP_Query( array(
4584 'post_type' => 'acf-field',
4585 'post_parent' => $acf_field_group_id,
4586 ));
4587 while ( $acf_fields->have_posts() ) : $acf_fields->the_post();
4588 global $post;
4589 $fields[$post->post_name] = get_field_object( $post->post_name );
4590 endwhile; wp_reset_postdata();
4591 endforeach;
4592 // Get ACF 4 fields.
4593 $acf4_field_groups = new WP_Query( array(
4594 'post_type' => 'acf',
4595 ));
4596 while ( $acf4_field_groups->have_posts() ) : $acf4_field_groups->the_post();
4597 $field_group_rules = get_post_meta( get_the_ID(), 'rule', true );
4598 if ( is_array( $field_group_rules ) && array_key_exists( 'param', $field_group_rules ) && $field_group_rules['param'] === 'ef_user' ) :
4599 $acf4_fields = get_post_custom( get_the_ID() );
4600 foreach ( $acf4_fields as $meta_key => $meta_value ) :
4601 if ( strpos( $meta_key, 'field_' ) === 0 ) :
4602 $meta_value = unserialize( $meta_value[0] );
4603 $fields[$meta_key] = $meta_value;
4604 endif;
4605 endforeach;
4606 endif;
4607 endwhile; wp_reset_postdata(); ?>
4608 <optgroup label="ACF User Fields:">
4609 <?php foreach ( (array)$fields as $field => $field_object ) : ?>
4610 <option value="acf___<?php echo $field_object['key']; ?>"<?php if ( $auth_settings_option === "acf___{$field_object['key']}" ) echo ' selected="selected"'; ?>><?php echo $field_object['label']; ?></option>
4611 <?php endforeach; ?>
4612 </optgroup>
4613 <?php endif; ?>
4614 <optgroup label="<?php _e( 'All Usermeta:', 'authorizer' ); ?>">
4615 <?php foreach ( $this->get_all_usermeta_keys() as $meta_key ) : if ( substr( $meta_key, 0, 3 ) === 'wp_' ) continue; ?>
4616 <option value="<?php echo $meta_key; ?>"<?php if ( $auth_settings_option === $meta_key ) echo ' selected="selected"'; ?>><?php echo $meta_key; ?></option>
4617 <?php endforeach; ?>
4618 </optgroup>
4619 </select><?php
4620 }
4621
4622
4623 function print_text_auth_advanced_users_per_page( $args = '' ) {
4624 // Get plugin option.
4625 $option = 'advanced_users_per_page';
4626 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4627
4628 // Print option elements.
4629 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="" size="4" /><?php
4630 }
4631
4632
4633 function print_select_auth_advanced_users_sort_by( $args = '' ) {
4634 // Get plugin option.
4635 $option = 'advanced_users_sort_by';
4636 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4637
4638 // Print option elements.
4639 ?><select id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]">
4640 <option value="created" <?php selected( $auth_settings_option, 'created' ); ?>><?php _e( 'Date approved', 'authorizer' ); ?></option>
4641 <option value="email" <?php selected( $auth_settings_option, 'email' ); ?>><?php _e( 'Email', 'authorizer' ); ?></option>
4642 <option value="role" <?php selected( $auth_settings_option, 'role' ); ?>><?php _e( 'Role', 'authorizer' ); ?></option>
4643 <option value="date_added" <?php selected( $auth_settings_option, 'date_added' ); ?>><?php _e( 'Date registered', 'authorizer' ); ?></option>
4644 </select><?php
4645 }
4646
4647
4648 function print_select_auth_advanced_users_sort_order( $args = '' ) {
4649 // Get plugin option.
4650 $option = 'advanced_users_sort_order';
4651 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4652
4653 // Print option elements.
4654 ?><select id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]">
4655 <option value="asc" <?php selected( $auth_settings_option, 'asc' ); ?>><?php _e( 'Ascending', 'authorizer' ); ?></option>
4656 <option value="desc" <?php selected( $auth_settings_option, 'desc' ); ?>><?php _e( 'Descending', 'authorizer' ); ?></option>
4657 </select><?php
4658 }
4659
4660
4661 function print_checkbox_auth_advanced_widget_enabled( $args = '' ) {
4662 // Get plugin option.
4663 $option = 'advanced_widget_enabled';
4664 $auth_settings_option = $this->get_plugin_option( $option, $this->get_admin_mode( $args ), 'allow override', 'print overlay' );
4665
4666 // Print option elements.
4667 ?><input type="checkbox" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="1"<?php checked( 1 == $auth_settings_option ); ?> /><label for="auth_settings_<?php echo $option; ?>"><?php _e( 'Show Dashboard Widget', 'authorizer' ); ?></label>
4668 <p><small><?php _e( 'Note: Only users with the create_users capability will be able to see the dashboard widget.', 'authorizer' ) ?></small></p><?php
4669 }
4670
4671
4672 function print_checkbox_auth_advanced_override_multisite( $args = '' ) {
4673 // Get plugin option.
4674 $option = 'advanced_override_multisite';
4675 $auth_settings_option = $this->get_plugin_option( $option );
4676
4677 // Print option elements.
4678 ?><input type="checkbox" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="1"<?php checked( 1 == $auth_settings_option ); ?> /><label for="auth_settings_<?php echo $option; ?>"><?php _e( "Configure this site independently (don't inherit any multisite settings)", 'authorizer' ); ?></label><?php
4679 }
4680
4681
4682
4683 /**
4684 * Add help documentation to the options page.
4685 * Run on action hook chain: load-settings_page_authorizer > admin_head
4686 */
4687 public function admin_head() {
4688 $screen = get_current_screen();
4689
4690 // Add help tab for Access Lists Settings
4691 $help_auth_settings_access_lists_content = '
4692 <p>' . __( "<strong>Pending Users</strong>: Pending users are users who have successfully logged in to the site, but who haven't yet been approved (or blocked) by you.", 'authorizer' ) .'</p>
4693 <p>' . __( "<strong>Approved Users</strong>: Approved users have access to the site once they successfully log in.", 'authorizer' ) . '</p>
4694 <p>' . __( "<strong>Blocked Users</strong>: Blocked users will receive an error message when they try to visit the site after authenticating.", 'authorizer' ) . '</p>
4695 <p>' . __( "Users in the <strong>Pending</strong> list appear automatically after a new user tries to log in from the configured external authentication service. You can add users to the <strong>Approved</strong> or <strong>Blocked</strong> lists by typing them in manually, or by clicking the <em>Approve</em> or <em>Block</em> buttons next to a user in the <strong>Pending</strong> list.", 'authorizer' ) . '</p>
4696 ';
4697 $screen->add_help_tab(
4698 array(
4699 'id' => 'help_auth_settings_access_lists_content',
4700 'title' => __( 'Access Lists', 'authorizer' ),
4701 'content' => $help_auth_settings_access_lists_content,
4702 )
4703 );
4704
4705 // Add help tab for Login Access Settings
4706 $help_auth_settings_access_login_content = '
4707 <p>' . __( "<strong>Who can log in to the site?</strong>: Choose the level of access restriction you'd like to use on your site here. You can leave the site open to anyone with a WordPress account or an account on an external service like Google, CAS, or LDAP, or restrict it to WordPress users and only the external users that you specify via the <em>Access Lists</em>.", 'authorizer' ) . '</p>
4708 <p>' . __( "<strong>Which role should receive email notifications about pending users?</strong>: If you've restricted access to <strong>approved users</strong>, you can determine which WordPress users will receive a notification email everytime a new external user successfully logs in and is added to the pending list. All users of the specified role will receive an email, and the external user will get a message (specified below) telling them their access is pending approval.", 'authorizer' ) . '</p>
4709 <p>' . __( '<strong>What message should pending users see after attempting to log in?</strong>: Here you can specify the exact message a new external user will see once they try to log in to the site for the first time.', 'authorizer' ) . '</p>
4710 ';
4711 $screen->add_help_tab(
4712 array(
4713 'id' => 'help_auth_settings_access_login_content',
4714 'title' => __( 'Login Access', 'authorizer' ),
4715 'content' => $help_auth_settings_access_login_content,
4716 )
4717 );
4718
4719 // Add help tab for Public Access Settings
4720 $help_auth_settings_access_public_content = '
4721 <p>' . __( "<strong>Who can view the site?</strong>: You can restrict the site's visibility by only allowing logged in users to see pages. If you do so, you can customize the specifics about the site's privacy using the settings below.", 'authorizer' ) . '</p>
4722 <p>' . __( "<strong>What pages (if any) should be available to everyone?</strong>: If you'd like to declare certain pages on your site as always public (such as the course syllabus, introduction, or calendar), specify those pages here. These pages will always be available no matter what access restrictions exist.", 'authorizer' ) . '</p>
4723 <p>' . __( "<strong>What happens to people without access when they visit a <em>private</em> page?</strong>: Choose the response anonymous users receive when visiting the site. You can choose between immediately taking them to the <strong>login screen</strong>, or simply showing them a <strong>message</strong>.", 'authorizer' ) . '</p>
4724 <p>' . __( "<strong>What happens to people without access when they visit a <em>public</em> page?</strong>: Choose the response anonymous users receive when visiting a page on the site marked as public. You can choose between showing them the page without any message, or showing them a the page with a message above the content.", 'authorizer' ) . '</p>
4725 <p>' . __( "<strong>What message should people without access see?</strong>: If you chose to show new users a <strong>message</strong> above, type that message here.", 'authorizer' ) . '</p>
4726 ';
4727 $screen->add_help_tab(
4728 array(
4729 'id' => 'help_auth_settings_access_public_content',
4730 'title' => __( 'Public Access', 'authorizer' ),
4731 'content' => $help_auth_settings_access_public_content,
4732 )
4733 );
4734
4735 // Add help tab for External Service (CAS, LDAP) Settings
4736 $help_auth_settings_external_content = '
4737 <p>' . __( "<strong>Type of external service to authenticate against</strong>: Choose which authentication service type you will be using. You'll have to fill out different fields below depending on which service you choose.", 'authorizer' ) . '</p>
4738 <p>' . __( "<strong>Enable Google Logins</strong>: Choose if you want to allow users to log in with their Google Account credentials. You will need to enter your API Client ID and Secret to enable Google Logins.", 'authorizer' ) . '</p>
4739 <p>' . __( "<strong>Enable CAS Logins</strong>: Choose if you want to allow users to log in with via CAS (Central Authentication Service). You will need to enter details about your CAS server (host, port, and path) to enable CAS Logins.", 'authorizer' ) . '</p>
4740 <p>' . __( "<strong>Enable LDAP Logins</strong>: Choose if you want to allow users to log in with their LDAP (Lightweight Directory Access Protocol) credentials. You will need to enter details about your LDAP server (host, port, search base, uid attribute, directory user, directory user password, and whether to use TLS) to enable Google Logins.", 'authorizer' ) . '</p>
4741 <p>' . __( "<strong>Default role for new CAS users</strong>: Specify which role new external users will get by default. Be sure to choose a role with limited permissions!", 'authorizer' ) . '</p>
4742 <p><strong><em>' . __( "If you enable Google logins:", 'authorizer' ) . '</em></strong></p>
4743 <ul>
4744 <li>' . __( "<strong>Google Client ID</strong>: You can generate this ID by creating a new Project in the <a href='https://cloud.google.com/console'>Google Developers Console</a>. A Client ID typically looks something like this: 1234567890123-kdjr85yt6vjr6d8g7dhr8g7d6durjf7g.apps.googleusercontent.com", 'authorizer' ) . '</li>
4745 <li>' . __( "<strong>Google Client Secret</strong>: You can generate this secret by creating a new Project in the <a href='https://cloud.google.com/console'>Google Developers Console</a>. A Client Secret typically looks something like this: sDNgX5_pr_5bly-frKmvp8jT", 'authorizer' ) . '</li>
4746 </ul>
4747 <p><strong><em>' . __( "If you enable CAS logins:", 'authorizer' ) . '</em></strong></p>
4748 <ul>
4749 <li>' . __( "<strong>CAS server hostname</strong>: Enter the hostname of the CAS server you authenticate against (e.g., authn.example.edu).", 'authorizer' ) . '</li>
4750 <li>' . __( "<strong>CAS server port</strong>: Enter the port on the CAS server to connect to (e.g., 443).", 'authorizer' ) . '</li>
4751 <li>' . __( "<strong>CAS server path/context</strong>: Enter the path to the login endpoint on the CAS server (e.g., /cas).", 'authorizer' ) . '</li>
4752 <li>' . __( "<strong>CAS attribute containing first name</strong>: Enter the CAS attribute that has the user's first name. When this user first logs in, their WordPress account will have their first name retrieved from CAS and added to their WordPress profile.", 'authorizer' ) . '</li>
4753 <li>' . __( "<strong>CAS attribute containing last name</strong>: Enter the CAS attribute that has the user's last name. When this user first logs in, their WordPress account will have their last name retrieved from CAS and added to their WordPress profile.", 'authorizer' ) . '</li>
4754 <li>' . __( "<strong>CAS attribute update</strong>: Select whether the first and last names retrieved from CAS should overwrite any value the user has entered in the first and last name fields in their WordPress profile. If this is not set, this only happens the first time they log in.", 'authorizer' ) . '</li>
4755 </ul>
4756 <p><strong><em>' . __( "If you enable LDAP logins:", 'authorizer' ) . '</em></strong></p>
4757 <ul>
4758 <li>' . __( "<strong>LDAP Host</strong>: Enter the URL of the LDAP server you authenticate against.", 'authorizer' ) . '</li>
4759 <li>' . __( "<strong>LDAP Port</strong>: Enter the port number that the LDAP server listens on.", 'authorizer' ) . '</li>
4760 <li>' . __( "<strong>LDAP Search Base</strong>: Enter the LDAP string that represents the search base, e.g., ou=people,dc=example,dc=edu", 'authorizer' ) . '</li>
4761 <li>' . __( "<strong>LDAP attribute containing username</strong>: Enter the name of the LDAP attribute that contains the usernames used by those attempting to log in. The plugin will search on this attribute to find the cn to bind against for login attempts.", 'authorizer' ) . '</li>
4762 <li>' . __( "<strong>LDAP Directory User</strong>: Enter the name of the LDAP user that has permissions to browse the directory.", 'authorizer' ) . '</li>
4763 <li>' . __( "<strong>LDAP Directory User Password</strong>: Enter the password for the LDAP user that has permission to browse the directory.", 'authorizer' ) . '</li>
4764 <li>' . __( "<strong>Use TLS</strong>: Select whether all communication with the LDAP server should be performed over a TLS-secured connection.", 'authorizer' ) . '</li>
4765 <li>' . __( "<strong>Custom lost password URL</strong>: The WordPress login page contains a link to recover a lost password. If you have external users who shouldn't change the password on their WordPress account, point them to the appropriate location to change the password on their external authentication service here.", 'authorizer' ) . '</li>
4766 <li>' . __( "<strong>LDAP attribute containing first name</strong>: Enter the LDAP attribute that has the user's first name. When this user first logs in, their WordPress account will have their first name retrieved from LDAP and added to their WordPress profile.", 'authorizer' ) . '</li>
4767 <li>' . __( "<strong>LDAP attribute containing last name</strong>: Enter the LDAP attribute that has the user's last name. When this user first logs in, their WordPress account will have their last name retrieved from LDAP and added to their WordPress profile.", 'authorizer' ) . '</li>
4768 <li>' . __( "<strong>LDAP attribute update</strong>: Select whether the first and last names retrieved from LDAP should overwrite any value the user has entered in the first and last name fields in their WordPress profile. If this is not set, this only happens the first time they log in.", 'authorizer' ) . '</li>
4769 </ul>
4770 ';
4771 $screen->add_help_tab(
4772 array(
4773 'id' => 'help_auth_settings_external_content',
4774 'title' => __( 'External Service', 'authorizer' ),
4775 'content' => $help_auth_settings_external_content,
4776 )
4777 );
4778
4779 // Add help tab for Advanced Settings
4780 $help_auth_settings_advanced_content = '
4781 <p>' . __( "<strong>Limit invalid login attempts</strong>: Choose how soon (and for how long) to restrict access to individuals (or bots) making repeated invalid login attempts. You may set a shorter delay first, and then a longer delay after repeated invalid attempts; you may also set how much time must pass before the delays will be reset to normal.", 'authorizer' ) . '</p>
4782 <p>' . __( "<strong>Hide WordPress Logins</strong>: If you want to hide the WordPress username and password fields and the Log In button on the wp-login screen, enable this option. Note: You can always access the WordPress logins by adding external=wordpress to the wp-login URL, like so:", 'authorizer' ) . ' <a href="' . wp_login_url() . '?external=wordpress" target="_blank">' . wp_login_url() . '?external=wordpress</a>.</p>
4783 <p>' . __( "<strong>Custom WordPress login branding</strong>: If you'd like to use custom branding on the WordPress login page, select that here. You will need to use the `authorizer_add_branding_option` filter in your theme to add it. You can see an example theme that implements this filter in the plugin directory under sample-theme-add-branding.", 'authorizer' ) . '</p>
4784 ';
4785 $screen->add_help_tab(
4786 array(
4787 'id' => 'help_auth_settings_advanced_content',
4788 'title' => __( 'Advanced', 'authorizer' ),
4789 'content' => $help_auth_settings_advanced_content,
4790 )
4791 );
4792 }
4793
4794
4795
4796 /**
4797 * ***************************
4798 * Multisite: Network Admin Options page
4799 * ***************************
4800 */
4801
4802
4803 /**
4804 * Network Admin menu item
4805 * Hook: network_admin_menu
4806 *
4807 * @param none
4808 * @return void
4809 */
4810 public function network_admin_menu() {
4811 // @see http://codex.wordpress.org/Function_Reference/add_menu_page
4812 add_menu_page(
4813 'Authorizer', // Page title
4814 'Authorizer', // Menu title
4815 'manage_network_options', // Capability
4816 'authorizer', // Menu slug
4817 array( $this, 'create_network_admin_page' ),
4818 'dashicons-groups', // Icon URL
4819 89 // Position
4820 );
4821 }
4822
4823
4824 /**
4825 * Output the HTML for the options page
4826 */
4827 public function create_network_admin_page() {
4828 if ( ! current_user_can( 'manage_network_options' ) ) {
4829 wp_die( __( 'You do not have sufficient permissions to access this page.', 'authorizer' ) );
4830 }
4831 $auth_settings = get_blog_option( $this->current_site_blog_id, 'auth_multisite_settings', array() ); ?>
4832 <div class="wrap">
4833 <form method="post" action="" autocomplete="off">
4834 <h2><?php _e( 'Authorizer Settings', 'authorizer' ); ?></h2>
4835 <p><?php _e( 'Most <strong>Authorizer</strong> settings are set in the individual sites, but you can specify a few options here that apply to <strong>all sites in the network</strong>. These settings will override settings in the individual sites.', 'authorizer' ); ?></p>
4836
4837 <input type="checkbox" id="auth_settings_multisite_override" name="auth_settings[multisite_override]" value="1"<?php checked( 1 == $auth_settings['multisite_override'] ); ?> /><label for="auth_settings_multisite_override"><?php _e( 'Override individual site settings with the settings below', 'authorizer' ); ?></label>
4838
4839 <div id="auth_multisite_settings_disabled_overlay" style="display: none;"></div>
4840
4841 <div class="wrap" id="auth_multisite_settings">
4842 <?php $this->print_section_info_tabs( array( MULTISITE_ADMIN => true ) ); ?>
4843
4844 <?php wp_nonce_field( 'save_auth_settings', 'nonce_save_auth_settings' ); ?>
4845
4846 <?php // Custom access lists (for network, we only really want approved list, not pending or blocked) ?>
4847 <div id="section_info_access_lists" class="section_info">
4848 <p><?php _e( 'Manage who has access to all sites in the network.', 'authorizer' ); ?></p>
4849 </div>
4850 <table class="form-table"><tbody>
4851 <tr>
4852 <th scope="row"><?php _e( 'Who can log in to sites in this network?', 'authorizer' ); ?></th>
4853 <td><?php $this->print_radio_auth_access_who_can_login( array( MULTISITE_ADMIN => true ) ); ?></td>
4854 </tr>
4855 <tr>
4856 <th scope="row"><?php _e( 'Who can view sites in this network?', 'authorizer' ); ?></th>
4857 <td><?php $this->print_radio_auth_access_who_can_view( array( MULTISITE_ADMIN => true ) ); ?></td>
4858 </tr>
4859 <tr>
4860 <th scope="row"><?php _e( 'Approved Users (All Sites)', 'authorizer' ); ?><br /><small><em><?php _e( 'Note: these users will <strong>not</strong> receive welcome emails when approved. Only users approved from individual sites can receive these messages.', 'authorizer' ); ?></em></small></th>
4861 <td><?php $this->print_combo_auth_access_users_approved( array( MULTISITE_ADMIN => true ) ); ?></td>
4862 </tr>
4863 </tbody></table>
4864
4865 <?php $this->print_section_info_external(); ?>
4866 <table class="form-table"><tbody>
4867 <tr>
4868 <th scope="row"><?php _e( 'Default role for new users', 'authorizer' ); ?></th>
4869 <td><?php $this->print_select_auth_access_default_role( array( MULTISITE_ADMIN => true ) ); ?></td>
4870 </tr>
4871 <tr>
4872 <th scope="row"><?php _e( 'Google Logins', 'authorizer' ); ?></th>
4873 <td><?php $this->print_checkbox_auth_external_google( array( MULTISITE_ADMIN => true ) ); ?></td>
4874 </tr>
4875 <tr>
4876 <th scope="row"><?php _e( 'Google Client ID', 'authorizer' ); ?></th>
4877 <td><?php $this->print_text_google_clientid( array( MULTISITE_ADMIN => true ) ); ?></td>
4878 </tr>
4879 <tr>
4880 <th scope="row"><?php _e( 'Google Client Secret', 'authorizer' ); ?></th>
4881 <td><?php $this->print_text_google_clientsecret( array( MULTISITE_ADMIN => true ) ); ?></td>
4882 </tr>
4883 <tr>
4884 <th scope="row"><?php _e( 'Google Hosted Domain', 'authorizer' ); ?></th>
4885 <td><?php $this->print_text_google_hosteddomain( array( MULTISITE_ADMIN => true ) ); ?></td>
4886 </tr>
4887 <tr>
4888 <th scope="row"><?php _e( 'CAS Logins', 'authorizer' ); ?></th>
4889 <td><?php $this->print_checkbox_auth_external_cas( array( MULTISITE_ADMIN => true ) ); ?></td>
4890 </tr>
4891 <tr>
4892 <th scope="row"><?php _e( 'CAS Custom Label', 'authorizer' ); ?></th>
4893 <td><?php $this->print_text_cas_custom_label( array( MULTISITE_ADMIN => true ) ); ?></td>
4894 </tr>
4895 <tr>
4896 <th scope="row"><?php _e( 'CAS server hostname', 'authorizer' ); ?></th>
4897 <td><?php $this->print_text_cas_host( array( MULTISITE_ADMIN => true ) ); ?></td>
4898 </tr>
4899 <tr>
4900 <th scope="row"><?php _e( 'CAS server port', 'authorizer' ); ?></th>
4901 <td><?php $this->print_text_cas_port( array( MULTISITE_ADMIN => true ) ); ?></td>
4902 </tr>
4903 <tr>
4904 <th scope="row"><?php _e( 'CAS server path/context', 'authorizer' ); ?></th>
4905 <td><?php $this->print_text_cas_path( array( MULTISITE_ADMIN => true ) ); ?></td>
4906 </tr>
4907 <tr>
4908 <th scope="row"><?php _e( 'CAS server version', 'authorizer' ); ?></th>
4909 <td><?php $this->print_select_cas_version( array( MULTISITE_ADMIN => true ) ); ?></td>
4910 </tr>
4911 <tr>
4912 <th scope="row"><?php _e( 'CAS attribute containing email', 'authorizer' ); ?></th>
4913 <td><?php $this->print_text_cas_attr_email( array( MULTISITE_ADMIN => true ) ); ?></td>
4914 </tr>
4915 <tr>
4916 <th scope="row"><?php _e( 'CAS attribute containing first name', 'authorizer' ); ?></th>
4917 <td><?php $this->print_text_cas_attr_first_name( array( MULTISITE_ADMIN => true ) ); ?></td>
4918 </tr>
4919 <tr>
4920 <th scope="row"><?php _e( 'CAS attribute containing last name', 'authorizer' ); ?></th>
4921 <td><?php $this->print_text_cas_attr_last_name( array( MULTISITE_ADMIN => true ) ); ?></td>
4922 </tr>
4923 <tr>
4924 <th scope="row"><?php _e( 'CAS attribute update', 'authorizer' ); ?></th>
4925 <td><?php $this->print_checkbox_cas_attr_update_on_login( array( MULTISITE_ADMIN => true ) ); ?></td>
4926 </tr>
4927 <tr>
4928 <th scope="row"><?php _e( 'CAS automatic login', 'authorizer' ); ?></th>
4929 <td><?php $this->print_checkbox_cas_auto_login( array( MULTISITE_ADMIN => true ) ); ?></td>
4930 </tr>
4931 <tr>
4932 <th scope="row"><?php _e( 'LDAP Logins', 'authorizer' ); ?></th>
4933 <td><?php $this->print_checkbox_auth_external_ldap( array( MULTISITE_ADMIN => true ) ); ?></td>
4934 </tr>
4935 <tr>
4936 <th scope="row"><?php _e( 'LDAP Host', 'authorizer' ); ?></th>
4937 <td><?php $this->print_text_ldap_host( array( MULTISITE_ADMIN => true ) ); ?></td>
4938 </tr>
4939 <tr>
4940 <th scope="row"><?php _e( 'LDAP Port', 'authorizer' ); ?></th>
4941 <td><?php $this->print_text_ldap_port( array( MULTISITE_ADMIN => true ) ); ?></td>
4942 </tr>
4943 <tr>
4944 <th scope="row"><?php _e( 'Use TLS', 'authorizer' ); ?></th>
4945 <td><?php $this->print_checkbox_ldap_tls( array( MULTISITE_ADMIN => true ) ); ?></td>
4946 </tr>
4947 <tr>
4948 <th scope="row"><?php _e( 'LDAP Search Base', 'authorizer' ); ?></th>
4949 <td><?php $this->print_text_ldap_search_base( array( MULTISITE_ADMIN => true ) ); ?></td>
4950 </tr>
4951 <tr>
4952 <th scope="row"><?php _e( 'LDAP attribute containing username', 'authorizer' ); ?></th>
4953 <td><?php $this->print_text_ldap_uid( array( MULTISITE_ADMIN => true ) ); ?></td>
4954 </tr>
4955 <tr>
4956 <th scope="row"><?php _e( 'LDAP attribute containing email', 'authorizer' ); ?></th>
4957 <td><?php $this->print_text_ldap_attr_email( array( MULTISITE_ADMIN => true ) ); ?></td>
4958 </tr>
4959 <tr>
4960 <th scope="row"><?php _e( 'LDAP Directory User', 'authorizer' ); ?></th>
4961 <td><?php $this->print_text_ldap_user( array( MULTISITE_ADMIN => true ) ); ?></td>
4962 </tr>
4963 <tr>
4964 <th scope="row"><?php _e( 'LDAP Directory User Password', 'authorizer' ); ?></th>
4965 <td><?php $this->print_password_ldap_password( array( MULTISITE_ADMIN => true ) ); ?></td>
4966 </tr>
4967 <tr>
4968 <th scope="row"><?php _e( 'Custom lost password URL', 'authorizer' ); ?></th>
4969 <td><?php $this->print_text_ldap_lostpassword_url( array( MULTISITE_ADMIN => true ) ); ?></td>
4970 </tr>
4971 <tr>
4972 <th scope="row"><?php _e( 'LDAP attribute containing first name', 'authorizer' ); ?></th>
4973 <td><?php $this->print_text_ldap_attr_first_name( array( MULTISITE_ADMIN => true ) ); ?></td>
4974 </tr>
4975 <tr>
4976 <th scope="row"><?php _e( 'LDAP attribute containing last name', 'authorizer' ); ?></th>
4977 <td><?php $this->print_text_ldap_attr_last_name( array( MULTISITE_ADMIN => true ) ); ?></td>
4978 </tr>
4979 <tr>
4980 <th scope="row"><?php _e( 'LDAP attribute update', 'authorizer' ); ?></th>
4981 <td><?php $this->print_checkbox_ldap_attr_update_on_login( array( MULTISITE_ADMIN => true ) ); ?></td>
4982 </tr>
4983 </tbody></table>
4984
4985 <?php $this->print_section_info_advanced(); ?>
4986 <table class="form-table"><tbody>
4987 <tr>
4988 <th scope="row"><?php _e( 'Limit invalid login attempts', 'authorizer' ); ?></th>
4989 <td><?php $this->print_text_auth_advanced_lockouts( array( MULTISITE_ADMIN => true ) ); ?></td>
4990 </tr>
4991 <tr>
4992 <th scope="row"><?php _e( 'Hide WordPress Logins', 'authorizer' ); ?></th>
4993 <td><?php $this->print_checkbox_auth_advanced_hide_wp_login( array( MULTISITE_ADMIN => true ) ); ?></td>
4994 </tr>
4995 <tr>
4996 <th scope="row"><?php _e( 'Number of users per page', 'authorizer' ); ?></th>
4997 <td><?php $this->print_text_auth_advanced_users_per_page( array( MULTISITE_ADMIN => true ) ); ?></td>
4998 </tr>
4999 <tr>
5000 <th scope="row"><?php _e( 'Approved users sort method', 'authorizer' ); ?></th>
5001 <td><?php $this->print_select_auth_advanced_users_sort_by( array( MULTISITE_ADMIN => true ) ); ?></td>
5002 </tr>
5003 <tr>
5004 <th scope="row"><?php _e( 'Approved users sort order', 'authorizer' ); ?></th>
5005 <td><?php $this->print_select_auth_advanced_users_sort_order( array( MULTISITE_ADMIN => true ) ); ?></td>
5006 </tr>
5007 <tr>
5008 <th scope="row"><?php _e( 'Show Dashboard Widget', 'authorizer' ); ?></th>
5009 <td><?php $this->print_checkbox_auth_advanced_widget_enabled( array( MULTISITE_ADMIN => true ) ); ?></td>
5010 </tr>
5011 </tbody></table>
5012
5013 <br class="clear" />
5014 </div>
5015 <input type="button" name="submit" id="submit" class="button button-primary" value="<?php _e( 'Save Changes', 'authorizer' ); ?>" onclick="save_auth_multisite_settings(this);" />
5016 </form>
5017 </div>
5018 <?php
5019 }
5020
5021
5022 /**
5023 * Save multisite settings (ajax call).
5024 */
5025 function ajax_save_auth_multisite_settings() {
5026 // Fail silently if current user doesn't have permissions.
5027 if ( ! current_user_can( 'manage_network_options' ) ) {
5028 die( '' );
5029 }
5030
5031 // Make sure nonce exists.
5032 if ( empty( $_POST['nonce_save_auth_settings'] ) ) {
5033 die( '' );
5034 }
5035
5036 // Nonce check.
5037 if ( ! wp_verify_nonce( $_POST['nonce_save_auth_settings'], 'save_auth_settings' ) ) {
5038 die( '' );
5039 }
5040
5041 // Assert multisite.
5042 if ( ! is_multisite() ) {
5043 die( '' );
5044 }
5045
5046 // Get multisite settings.
5047 $auth_multisite_settings = get_blog_option( $this->current_site_blog_id, 'auth_multisite_settings', array() );
5048
5049 // Sanitize settings
5050 $auth_multisite_settings = $this->sanitize_options( $_POST );
5051
5052 // Filter options to only the allowed values (multisite options are a subset of all options)
5053 $allowed = array(
5054 'multisite_override',
5055 'access_who_can_login',
5056 'access_who_can_view',
5057 'access_default_role',
5058 'google',
5059 'google_clientid',
5060 'google_clientsecret',
5061 'google_hosteddomain',
5062 'cas',
5063 'cas_custom_label',
5064 'cas_host',
5065 'cas_port',
5066 'cas_path',
5067 'cas_version',
5068 'cas_attr_email',
5069 'cas_attr_first_name',
5070 'cas_attr_last_name',
5071 'cas_attr_update_on_login',
5072 'cas_auto_login',
5073 'ldap',
5074 'ldap_host',
5075 'ldap_port',
5076 'ldap_tls',
5077 'ldap_search_base',
5078 'ldap_uid',
5079 'ldap_attr_email',
5080 'ldap_user',
5081 'ldap_password',
5082 'ldap_lostpassword_url',
5083 'ldap_attr_first_name',
5084 'ldap_attr_last_name',
5085 'ldap_attr_update_on_login',
5086 'advanced_lockouts',
5087 'advanced_hide_wp_login',
5088 'advanced_users_per_page',
5089 'advanced_users_sort_by',
5090 'advanced_users_sort_order',
5091 'advanced_widget_enabled',
5092 );
5093 $auth_multisite_settings = array_intersect_key( $auth_multisite_settings, array_flip( $allowed ) );
5094
5095 // Update multisite settings in database.
5096 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings', $auth_multisite_settings );
5097
5098 // Return 'success' value to AJAX call.
5099 die( 'success' );
5100 }
5101
5102
5103
5104 /**
5105 * ***************************
5106 * Dashboard widget
5107 * ***************************
5108 */
5109
5110
5111
5112 function add_dashboard_widgets() {
5113 $widget_enabled = $this->get_plugin_option( 'advanced_widget_enabled', SINGLE_ADMIN, 'allow override' ) === '1';
5114
5115 // Load authorizer dashboard widget if it's enabled and user has permission.
5116 if ( current_user_can( 'create_users' ) && $widget_enabled ) {
5117 // Add dashboard widget for adding/editing users with access
5118 wp_add_dashboard_widget( 'auth_dashboard_widget', __( 'Authorizer Settings', 'authorizer' ), array( $this, 'add_auth_dashboard_widget' ) );
5119 }
5120 }
5121
5122
5123 function add_auth_dashboard_widget() {
5124 ?><form method="post" id="auth_settings_access_form" action="">
5125 <?php $this->print_section_info_access_login(); ?>
5126 <div>
5127 <h2><?php _e( 'Pending Users', 'authorizer' ); ?></h2>
5128 <?php $this->print_combo_auth_access_users_pending(); ?>
5129 </div>
5130 <div>
5131 <h2><?php _e( 'Approved Users', 'authorizer' ); ?></h2>
5132 <?php $this->print_combo_auth_access_users_approved(); ?>
5133 </div>
5134 <div>
5135 <h2><?php _e( 'Blocked Users', 'authorizer' ); ?></h2>
5136 <?php $this->print_combo_auth_access_users_blocked(); ?>
5137 </div>
5138 <br class="clear" />
5139 </form><?php
5140 }
5141
5142
5143
5144 /**
5145 * ***************************
5146 * AJAX Actions
5147 * ***************************
5148 */
5149
5150
5151
5152 // Re-render the Approved User list (usually triggered if pager params have
5153 // changed, e.g., current page, search term, sort order).
5154 function ajax_refresh_approved_user_list() {
5155 // Fail silently if current user doesn't have permissions.
5156 if ( ! current_user_can( 'create_users' ) ) {
5157 die( '' );
5158 }
5159
5160 // Nonce check.
5161 if ( empty( $_POST['nonce_save_auth_settings'] ) || ! wp_verify_nonce( $_POST['nonce_save_auth_settings'], 'save_auth_settings' ) ) {
5162 die( '' );
5163 }
5164
5165 // Fail if required post data doesn't exist.
5166 if ( ! array_key_exists( 'paged', $_REQUEST ) ) {
5167 die( '' );
5168 }
5169
5170 // Get defaults.
5171 $success = true;
5172 $message = '';
5173 $is_network_admin = isset( $_REQUEST['is_network_admin'] ) && $_REQUEST['is_network_admin'];
5174
5175 // Get user list.
5176 $option = 'access_users_approved';
5177 $admin_mode = SINGLE_ADMIN;
5178 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'no override' );
5179 $auth_settings_option = is_array( $auth_settings_option ) ? $auth_settings_option : array();
5180
5181 // Get multisite approved users (will be added to top of list, greyed out).
5182 $auth_override_multisite = $this->get_plugin_option( 'advanced_override_multisite' );
5183 $auth_multisite_settings = $this->get_plugin_options( MULTISITE_ADMIN );
5184 $auth_settings_option_multisite = array();
5185 if (
5186 is_multisite() &&
5187 ! $is_network_admin &&
5188 $auth_override_multisite != '1' &&
5189 array_key_exists( 'multisite_override', $auth_multisite_settings ) &&
5190 $auth_multisite_settings['multisite_override'] === '1'
5191 ) {
5192 $auth_settings_option_multisite = $this->get_plugin_option( $option, MULTISITE_ADMIN, 'allow override' );
5193 $auth_settings_option_multisite = is_array( $auth_settings_option_multisite ) ? $auth_settings_option_multisite : array();
5194 // Add multisite users to the beginning of the main user array.
5195 foreach ( array_reverse( $auth_settings_option_multisite ) as $approved_user ) {
5196 $approved_user['multisite_user'] = true;
5197 array_unshift( $auth_settings_option, $approved_user );
5198 }
5199 }
5200
5201 // Get custom usermeta field to show.
5202 $advanced_usermeta = $this->get_plugin_option( 'advanced_usermeta' );
5203
5204 // Filter user list to search terms.
5205 if ( isset( $_REQUEST['search'] ) && strlen( $_REQUEST['search'] ) > 0 ) {
5206 $search_term = $_REQUEST['search'];
5207 $auth_settings_option = array_filter( $auth_settings_option, function ( $user ) use ( $search_term ) {
5208 return stripos( $user['email'], $search_term ) !== FALSE ||
5209 stripos( $user['role'], $search_term ) !== FALSE ||
5210 stripos( $user['date_added'], $search_term ) !== FALSE;
5211 } );
5212 }
5213
5214 // Sort user list.
5215 $sort_by = $this->get_plugin_option( 'advanced_users_sort_by', SINGLE_ADMIN, 'allow override' ); // email, role, date_added (registered), created (date approved)
5216 $sort_order = $this->get_plugin_option( 'advanced_users_sort_order', SINGLE_ADMIN, 'allow override' ); // asc or desc
5217 $sort_dimension = array();
5218 if ( in_array( $sort_by, array( 'email', 'role', 'date_added' ) ) ) {
5219 foreach ( $auth_settings_option as $key => $user ) {
5220 if ( $sort_by === 'date_added' ) {
5221 $sort_dimension[$key] = date( 'Ymd', strtotime( $user[$sort_by] ) );
5222 } else {
5223 $sort_dimension[$key] = strtolower( $user[$sort_by] );
5224 }
5225 }
5226 $sort_order = $sort_order == 'asc' ? SORT_ASC : SORT_DESC;
5227 array_multisort( $sort_dimension, $sort_order, $auth_settings_option );
5228 }
5229
5230 // Ensure array keys run from 0..max (keys in database will be the original,
5231 // index, and removing users will not reorder the array keys of other users).
5232 $auth_settings_option = array_values( $auth_settings_option );
5233
5234 // Get pager params.
5235 $total_users = count( $auth_settings_option );
5236 $users_per_page = intval( $this->get_plugin_option( 'advanced_users_per_page', SINGLE_ADMIN, 'allow override' ) );
5237 $current_page = isset( $_REQUEST['paged'] ) ? intval( $_REQUEST['paged'] ) : 1;
5238 $total_pages = ceil( $total_users / $users_per_page );
5239 if ( $total_pages < 1 ) {
5240 $total_pages = 1;
5241 }
5242
5243 // Make sure current_page is between 1 and max pages.
5244 if ( $current_page < 1 ) {
5245 $current_page = 1;
5246 } else if ( $current_page > $total_pages ) {
5247 $current_page = $total_pages;
5248 }
5249
5250 // Render user list.
5251 ob_start();
5252 $offset = ( $current_page - 1 ) * $users_per_page;
5253 $max = min( $offset + $users_per_page, count( $auth_settings_option ) );
5254 for ( $key = $offset; $key < $max; $key++ ) :
5255 $approved_user = $auth_settings_option[$key];
5256 if ( empty( $approved_user ) || count( $approved_user ) < 1 ) :
5257 continue;
5258 endif;
5259 $this->render_user_element( $approved_user, $key, $option, $admin_mode, $advanced_usermeta );
5260 endfor;
5261
5262 // Send response to client.
5263 $response = array(
5264 'success' => $success,
5265 'message' => $message,
5266 'html' => ob_get_clean(),
5267 'total_users_html' => sprintf( _n( '%s user', '%s users', $total_users, 'authorizer' ), number_format_i18n( $total_users ) ),
5268 'total_pages_html' => number_format_i18n( $total_pages ),
5269 'total_pages' => $total_pages,
5270 );
5271 header( 'content-type: application/json' );
5272 echo json_encode( $response );
5273 exit;
5274 }
5275
5276
5277 // Fired on a change event from the optional usermeta field in the
5278 // approved user list. Updates the selected usermeta value, or saves it
5279 // in the user's approved list entry if the user hasn't logged in yet
5280 // and created a WordPress account.
5281 function ajax_update_auth_usermeta() {
5282 // Fail silently if current user doesn't have permissions.
5283 if ( ! current_user_can( 'create_users' ) ) {
5284 die( '' );
5285 }
5286
5287 // Nonce check.
5288 if ( empty( $_POST['nonce_save_auth_settings'] ) || ! wp_verify_nonce( $_POST['nonce_save_auth_settings'], 'save_auth_settings' ) ) {
5289 die( '' );
5290 }
5291
5292 // Fail if required post data doesn't exist.
5293 if ( ! array_key_exists( 'email', $_REQUEST ) || ! array_key_exists( 'usermeta', $_REQUEST ) ) {
5294 die( '' );
5295 }
5296
5297 // Get values to update from post data.
5298 $email = $_REQUEST['email'];
5299 $meta_value = $_REQUEST['usermeta'];
5300 $meta_key = $this->get_plugin_option( 'advanced_usermeta' );
5301
5302 // If user doesn't exist, save usermeta selection to authorizer
5303 // list. This value will get saved to usermeta when the user first
5304 // logs in (i.e., when their WordPress account is created).
5305 if ( ! ( $wp_user = get_user_by( 'email', $email ) ) ) {
5306 // Look through multisite approved users and add a usermeta
5307 // reference for the current blog if the user is found.
5308 $auth_multisite_settings_access_users_approved = is_multisite() ? get_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', array() ) : array();
5309 $should_update_auth_multisite_settings_access_users_approved = false;
5310 foreach ( $auth_multisite_settings_access_users_approved as $index => $approved_user ) {
5311 if ( 0 === strcasecmp( $email, $approved_user['email'] ) ) {
5312 if ( ! is_array( $auth_multisite_settings_access_users_approved[$index]['usermeta'] ) ) {
5313 // Initialize the array of usermeta for each blog this user belongs to.
5314 $auth_multisite_settings_access_users_approved[$index]['usermeta'] = array();
5315 } else {
5316 // There is already usermeta associated with this
5317 // preapproved user; iterate through it and make
5318 // sure it's not for old meta_keys (delete it if
5319 // so). This can happen if someone changes the
5320 // usermeta key in authorizer options, and we don't
5321 // want to hang on to old data.
5322 foreach ( $auth_multisite_settings_access_users_approved[$index]['usermeta'] as $blog_id => $usermeta ) {
5323 if ( array_key_exists( 'meta_key', $usermeta ) && $usermeta['meta_key'] === $meta_key ) {
5324 continue;
5325 } else {
5326 unset( $auth_multisite_settings_access_users_approved[$index]['usermeta'][$blog_id] );
5327 }
5328 }
5329 }
5330 $auth_multisite_settings_access_users_approved[$index]['usermeta'][get_current_blog_id()] = array(
5331 'meta_key' => $meta_key,
5332 'meta_value' => $meta_value,
5333 );
5334 $should_update_auth_multisite_settings_access_users_approved = true;
5335 }
5336 }
5337 if ( $should_update_auth_multisite_settings_access_users_approved ) {
5338 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
5339 }
5340
5341 // Look through the approved users (of the current blog in a
5342 // multisite install, or just of the single site) and add a
5343 // usermeta reference if the user is found.
5344 $auth_settings_access_users_approved = $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN );
5345 $should_update_auth_settings_access_users_approved = false;
5346 foreach ( $auth_settings_access_users_approved as $index => $approved_user ) {
5347 if ( 0 === strcasecmp( $email, $approved_user['email'] ) ) {
5348 $auth_settings_access_users_approved[$index]['usermeta'] = array(
5349 'meta_key' => $meta_key,
5350 'meta_value' => $meta_value,
5351 );
5352 $should_update_auth_settings_access_users_approved = true;
5353 }
5354 }
5355 if ( $should_update_auth_settings_access_users_approved ) {
5356 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
5357 }
5358
5359 } else {
5360 // Update user's usermeta value for usermeta key stored in authorizer options.
5361 if ( strpos( $meta_key, 'acf___' ) === 0 && class_exists( 'acf' ) ) {
5362 // We have an ACF field value, so use the ACF function to update it.
5363 update_field( str_replace('acf___', '', $meta_key ), $meta_value, 'user_' . $wp_user->ID );
5364 } else {
5365 // We have a normal usermeta value, so just update it via the WordPress function.
5366 update_user_meta( $wp_user->ID, $meta_key, $meta_value );
5367 }
5368
5369 }
5370
5371 // Return 'success' value to AJAX call.
5372 die( 'success' );
5373 }
5374
5375
5376 function ajax_update_auth_user() {
5377 // Fail silently if current user doesn't have permissions.
5378 if ( ! current_user_can( 'create_users' ) ) {
5379 die( '' );
5380 }
5381
5382 // Nonce check.
5383 if ( empty( $_POST['nonce_save_auth_settings'] ) || ! wp_verify_nonce( $_POST['nonce_save_auth_settings'], 'save_auth_settings' ) ) {
5384 die( '' );
5385 }
5386
5387 // Fail if requesting a change to an invalid setting.
5388 if ( ! in_array( $_POST['setting'], array( 'access_users_pending', 'access_users_approved', 'access_users_blocked' ) ) ) {
5389 die( '' );
5390 }
5391
5392 // Track any emails that couldn't be added (used when adding users).
5393 $invalid_emails = array();
5394
5395 // Editing a pending list entry.
5396 if ( $_POST['setting'] === 'access_users_pending' ) {
5397 // Initialize posted data if empty.
5398 if ( ! ( array_key_exists( 'access_users_pending', $_POST ) && is_array( $_POST['access_users_pending'] ) ) ) {
5399 $_POST['access_users_pending'] = array();
5400 }
5401
5402 // Deal with each modified user (add or remove).
5403 foreach ( $_POST['access_users_pending'] as $pending_user ) {
5404
5405 if ( $pending_user['edit_action'] === 'add' ) {
5406
5407 // Add new user to pending list and save (skip if it's
5408 // already there--someone else might have just done it).
5409 if ( ! $this->is_email_in_list( $pending_user['email'], 'pending' ) ) {
5410 $auth_settings_access_users_pending = $this->sanitize_user_list(
5411 $this->get_plugin_option( 'access_users_pending', SINGLE_ADMIN )
5412 );
5413 array_push( $auth_settings_access_users_pending, $pending_user );
5414 update_option( 'auth_settings_access_users_pending', $auth_settings_access_users_pending );
5415 }
5416
5417 } elseif ( $pending_user['edit_action'] === 'remove' ) {
5418
5419 // Remove user from pending list and save
5420 if ( $this->is_email_in_list( $pending_user['email'], 'pending' ) ) {
5421 $auth_settings_access_users_pending = $this->sanitize_user_list(
5422 $this->get_plugin_option( 'access_users_pending', SINGLE_ADMIN )
5423 );
5424 foreach ( $auth_settings_access_users_pending as $key => $existing_user ) {
5425 if ( 0 === strcasecmp( $pending_user['email'], $existing_user['email'] ) ) {
5426 unset( $auth_settings_access_users_pending[$key] );
5427 break;
5428 }
5429 }
5430 update_option( 'auth_settings_access_users_pending', $auth_settings_access_users_pending );
5431 }
5432
5433 }
5434 }
5435 }
5436
5437 // Editing an approved list entry.
5438 if ( $_POST['setting'] === 'access_users_approved' ) {
5439 // Initialize posted data if empty.
5440 if ( ! ( array_key_exists( 'access_users_approved', $_POST ) && is_array( $_POST['access_users_approved'] ) ) ) {
5441 $_POST['access_users_approved'] = array();
5442 }
5443
5444 // Deal with each modified user (add, remove, or change_role).
5445 foreach ( $_POST['access_users_approved'] as $approved_user ) {
5446 // Skip blank entries.
5447 if ( strlen( $approved_user['email'] ) < 1 ) {
5448 continue;
5449 }
5450
5451 // New user (create user, or add existing user to current site in multisite).
5452 if ( $approved_user['edit_action'] === 'add' ) {
5453 $new_user = get_user_by( 'email', $approved_user['email'] );
5454 if ( $new_user !== false ) {
5455 // If we're adding an existing multisite user, make sure their
5456 // newly-assigned role is updated on all sites they are already in.
5457 if ( is_multisite() && $approved_user['multisite_user'] !== 'false' ) {
5458 foreach ( get_blogs_of_user( $new_user->ID ) as $blog ) {
5459 add_user_to_blog( $blog->userblog_id, $new_user->ID, $approved_user['role'] );
5460 }
5461 }
5462 // If this user already has an account on another site in the network, add them to this site.
5463 if ( is_multisite() ) {
5464 add_user_to_blog( get_current_blog_id(), $new_user->ID, $approved_user['role'] );
5465 }
5466 } elseif ( $approved_user['local_user'] && $approved_user['local_user'] !== 'false' ) {
5467 // Create a WP account for this new *local* user and email the password.
5468 $plaintext_password = wp_generate_password(); // random password
5469 // If there's already a user with this username (e.g.,
5470 // johndoe/johndoe@gmail.com exists, and we're trying to add
5471 // johndoe/johndoe@example.com), use the full email address
5472 // as the username.
5473 $username = explode( '@', $approved_user['email'] );
5474 $username = $username[0];
5475 if ( get_user_by( 'login', $username ) !== false ) {
5476 $username = $this->lowercase( $approved_user['email'] );
5477 }
5478 if ( $approved_user['multisite_user'] !== 'false' ) {
5479 $result = wpmu_create_user(
5480 strtolower( $username ),
5481 $plaintext_password,
5482 $this->lowercase( $approved_user['email'] )
5483 );
5484 } else {
5485 $result = wp_insert_user(
5486 array(
5487 'user_login' => strtolower( $username ),
5488 'user_pass' => $plaintext_password,
5489 'first_name' => '',
5490 'last_name' => '',
5491 'user_email' => $this->lowercase( $approved_user['email'] ),
5492 'user_registered' => date( 'Y-m-d H:i:s' ),
5493 'role' => $approved_user['role'],
5494 )
5495 );
5496 }
5497 if ( ! is_wp_error( $result ) ) {
5498 // Email login credentials to new user.
5499 wp_new_user_notification( $result, null, 'both' );
5500 }
5501
5502 }
5503
5504 // Email new user welcome message if plugin option is set.
5505 $this->maybe_email_welcome_message( $approved_user['email'] );
5506
5507 // Add new user to approved list and save (skip if it's
5508 // already there--someone else might have just done it).
5509 if ( $approved_user['multisite_user'] !== 'false' ) {
5510 if ( ! $this->is_email_in_list( $approved_user['email'], 'approved', 'multisite' ) ) {
5511 $auth_multisite_settings_access_users_approved = $this->sanitize_user_list(
5512 $this->get_plugin_option( 'access_users_approved', MULTISITE_ADMIN )
5513 );
5514 $approved_user['date_added'] = date( 'M Y' );
5515 array_push( $auth_multisite_settings_access_users_approved, $approved_user );
5516 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
5517 } else {
5518 $invalid_emails[] = $approved_user['email'];
5519 }
5520 } else {
5521 if ( ! $this->is_email_in_list( $approved_user['email'], 'approved' ) ) {
5522 $auth_settings_access_users_approved = $this->sanitize_user_list(
5523 $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN )
5524 );
5525 $approved_user['date_added'] = date( 'M Y' );
5526 array_push( $auth_settings_access_users_approved, $approved_user );
5527 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
5528 } else {
5529 $invalid_emails[] = $approved_user['email'];
5530 }
5531 }
5532
5533 // If we've added a new multisite user, go through all pending/approved/blocked lists
5534 // on individual sites and remove this user from them (to prevent duplicate entries).
5535 if ( $approved_user['multisite_user'] !== 'false' && is_multisite() ) {
5536 $list_names = array( 'access_users_pending', 'access_users_approved', 'access_users_blocked' );
5537 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
5538 foreach ( $sites as $site ) {
5539 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
5540 foreach ( $list_names as $list_name ) {
5541 $user_list = get_blog_option( $blog_id, 'auth_settings_' . $list_name, array() );
5542 $list_changed = false;
5543 foreach ( $user_list as $key => $user ) {
5544 if ( 0 === strcasecmp( $user['email'], $approved_user['email'] ) ) {
5545 unset( $user_list[$key] );
5546 $list_changed = true;
5547 }
5548 }
5549 if ( $list_changed ) {
5550 update_blog_option( $blog_id, 'auth_settings_' . $list_name, $user_list );
5551 }
5552 }
5553 }
5554 }
5555
5556 // Remove user from approved list and save (also remove their role if they have a WordPress account)
5557 } elseif ( $approved_user['edit_action'] === 'remove' ) {
5558 if ( $approved_user['multisite_user'] !== 'false' ) {
5559 if ( $this->is_email_in_list( $approved_user['email'], 'approved', 'multisite' ) ) {
5560 $auth_multisite_settings_access_users_approved = $this->sanitize_user_list(
5561 $this->get_plugin_option( 'access_users_approved', MULTISITE_ADMIN )
5562 );
5563 foreach ( $auth_multisite_settings_access_users_approved as $key => $existing_user ) {
5564 if ( 0 === strcasecmp( $approved_user['email'], $existing_user['email'] ) ) {
5565 // Remove role of the associated WordPress user from all blogs (but don't delete the user).
5566 $user = get_user_by( 'email', $approved_user['email'] );
5567 if ( $user !== false ) {
5568 // Loop through all of the blogs this user is a member of and remove their capabilities.
5569 foreach ( get_blogs_of_user( $user->ID ) as $blog ) {
5570 remove_user_from_blog( $user->ID, $blog->userblog_id, '' );
5571 }
5572 }
5573 // Remove entry from Approved Users list.
5574 unset( $auth_multisite_settings_access_users_approved[$key] );
5575 break;
5576 }
5577 }
5578 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
5579 }
5580 } else {
5581 if ( $this->is_email_in_list( $approved_user['email'], 'approved' ) ) {
5582 $auth_settings_access_users_approved = $this->sanitize_user_list(
5583 $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN )
5584 );
5585 foreach ( $auth_settings_access_users_approved as $key => $existing_user ) {
5586 if ( 0 === strcasecmp( $approved_user['email'], $existing_user['email'] ) ) {
5587 // Remove role of the associated WordPress user (but don't delete the user).
5588 $user = get_user_by( 'email', $approved_user['email'] );
5589 if ( $user !== false ) {
5590 $user->set_role( '' );
5591 }
5592 // Remove entry from Approved Users list.
5593 unset( $auth_settings_access_users_approved[$key] );
5594 break;
5595 }
5596 }
5597 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
5598 }
5599 }
5600
5601 // Update user's role in WordPress
5602 } elseif ( $approved_user['edit_action'] === 'change_role' ) {
5603 $changed_user = get_user_by( 'email', $approved_user['email'] );
5604 if ( $changed_user ) {
5605 if ( is_multisite() && $approved_user['multisite_user'] !== 'false' ) {
5606 foreach ( get_blogs_of_user( $changed_user->ID ) as $blog ) {
5607 add_user_to_blog( $blog->userblog_id, $changed_user->ID, $approved_user['role'] );
5608 }
5609 } else {
5610 $changed_user->set_role( $approved_user['role'] );
5611 }
5612 }
5613
5614 if ( $approved_user['multisite_user'] !== 'false' ) {
5615 if ( $this->is_email_in_list( $approved_user['email'], 'approved', 'multisite' ) ) {
5616 $auth_multisite_settings_access_users_approved = $this->sanitize_user_list(
5617 $this->get_plugin_option( 'access_users_approved', MULTISITE_ADMIN )
5618 );
5619 foreach ( $auth_multisite_settings_access_users_approved as $key => $existing_user ) {
5620 if ( 0 === strcasecmp( $approved_user['email'], $existing_user['email'] ) ) {
5621 $auth_multisite_settings_access_users_approved[$key]['role'] = $approved_user['role'];
5622 break;
5623 }
5624 }
5625 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
5626 }
5627 } else {
5628 // Update user's role in approved list and save.
5629 if ( $this->is_email_in_list( $approved_user['email'], 'approved' ) ) {
5630 $auth_settings_access_users_approved = $this->sanitize_user_list(
5631 $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN )
5632 );
5633 foreach ( $auth_settings_access_users_approved as $key => $existing_user ) {
5634 if ( 0 === strcasecmp( $approved_user['email'], $existing_user['email'] ) ) {
5635 $auth_settings_access_users_approved[$key]['role'] = $approved_user['role'];
5636 break;
5637 }
5638 }
5639 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
5640 }
5641 }
5642
5643 }
5644 }
5645 }
5646
5647 // Editing a blocked list entry.
5648 if ( $_POST['setting'] === 'access_users_blocked' ) {
5649 // Initialize posted data if empty.
5650 if ( ! ( array_key_exists( 'access_users_blocked', $_POST ) && is_array( $_POST['access_users_blocked'] ) ) ) {
5651 $_POST['access_users_blocked'] = array();
5652 }
5653
5654 // Deal with each modified user (add or remove).
5655 foreach ( $_POST['access_users_blocked'] as $blocked_user ) {
5656
5657 if ( $blocked_user['edit_action'] === 'add' ) {
5658
5659 // Add auth_blocked usermeta for the user.
5660 $blocked_wp_user = get_user_by( 'email', $blocked_user['email'] );
5661 if ( $blocked_wp_user !== false ) {
5662 update_user_meta( $blocked_wp_user->ID, 'auth_blocked', 'yes' );
5663 }
5664
5665 // Add new user to blocked list and save (skip if it's
5666 // already there--someone else might have just done it).
5667 if ( ! $this->is_email_in_list( $blocked_user['email'], 'blocked' ) ) {
5668 $auth_settings_access_users_blocked = $this->sanitize_user_list(
5669 $this->get_plugin_option( 'access_users_blocked', SINGLE_ADMIN )
5670 );
5671 $blocked_user['date_added'] = date( 'M Y' );
5672 array_push( $auth_settings_access_users_blocked, $blocked_user );
5673 update_option( 'auth_settings_access_users_blocked', $auth_settings_access_users_blocked );
5674 } else {
5675 $invalid_emails[] = $blocked_user['email'];
5676 }
5677
5678 } elseif ( $blocked_user['edit_action'] === 'remove' ) {
5679
5680 // Remove auth_blocked usermeta for the user.
5681 $unblocked_user = get_user_by( 'email', $blocked_user['email'] );
5682 if ( $unblocked_user !== false ) {
5683 delete_user_meta( $unblocked_user->ID, 'auth_blocked', 'yes' );
5684 }
5685
5686 // Remove user from blocked list and save
5687 if ( $this->is_email_in_list( $blocked_user['email'], 'blocked' ) ) {
5688 $auth_settings_access_users_blocked = $this->sanitize_user_list(
5689 $this->get_plugin_option( 'access_users_blocked', SINGLE_ADMIN )
5690 );
5691 foreach ( $auth_settings_access_users_blocked as $key => $existing_user ) {
5692 if ( 0 === strcasecmp( $blocked_user['email'], $existing_user['email'] ) ) {
5693 unset( $auth_settings_access_users_blocked[$key] );
5694 break;
5695 }
5696 }
5697 update_option( 'auth_settings_access_users_blocked', $auth_settings_access_users_blocked );
5698 }
5699
5700 }
5701 }
5702 }
5703
5704 // Send response to client.
5705 $response = array(
5706 'success' => true,
5707 'invalid_emails' => $invalid_emails,
5708 );
5709 header( 'content-type: application/json' );
5710 echo json_encode( $response );
5711 exit;
5712 }
5713
5714
5715
5716 /**
5717 * ***************************
5718 * Helper functions
5719 * ***************************
5720 */
5721
5722
5723 /**
5724 * Retrieves a specific plugin option from db. Multisite enabled.
5725 *
5726 * @param string $option Option name
5727 * @param string $admin_mode MULTISITE_ADMIN will retrieve the multisite value
5728 * @param string $override_mode 'allow override' will retrieve the multisite value if it exists
5729 * @param string $print_mode 'print overlay' will output overlay that hides this option on the settings page
5730 * @return mixed Option value, or null on failure
5731 */
5732 private function get_plugin_option( $option, $admin_mode = SINGLE_ADMIN, $override_mode = 'no override', $print_mode = 'no overlay' ) {
5733 // Special case for user lists (they are saved seperately to prevent concurrency issues).
5734 if ( in_array( $option, array( 'access_users_pending', 'access_users_approved', 'access_users_blocked' ) ) ) {
5735 $list = $admin_mode === MULTISITE_ADMIN ? array() : get_option( 'auth_settings_' . $option );
5736 if ( is_multisite() && $admin_mode === MULTISITE_ADMIN ) {
5737 $list = get_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_' . $option, array() );
5738 }
5739 return $list;
5740 }
5741
5742 // Get all plugin options.
5743 $auth_settings = $this->get_plugin_options( $admin_mode, $override_mode );
5744
5745 // Set option to null if it wasn't found.
5746 if ( ! array_key_exists( $option, $auth_settings ) ) {
5747 return null;
5748 }
5749
5750 // If requested and appropriate, print the overlay hiding the
5751 // single site option that is overridden by a multisite option.
5752 if (
5753 $admin_mode !== MULTISITE_ADMIN &&
5754 $override_mode === 'allow override' &&
5755 $print_mode === 'print overlay' &&
5756 array_key_exists( 'multisite_override', $auth_settings ) &&
5757 $auth_settings['multisite_override'] === '1' &&
5758 ( ! array_key_exists( 'advanced_override_multisite', $auth_settings ) || $auth_settings['advanced_override_multisite'] != '1' )
5759 ) {
5760 // Get original plugin options (not overridden value). We'll
5761 // show this old value behind the disabled overlay.
5762 //$auth_settings = $this->get_plugin_options( $admin_mode, 'no override' );
5763
5764 $name = "auth_settings[$option]";
5765 $id = "auth_settings_$option"; ?>
5766 <div id="overlay-hide-auth_settings_<?php echo $option; ?>" class="auth_multisite_override_overlay">
5767 <span class="overlay-note">
5768 <?php _e( 'This setting is overridden by a', 'authorizer' ); ?> <a href="<?php echo network_admin_url( 'admin.php?page=authorizer' ); ?>"><?php _e( 'multisite option', 'authorizer' ); ?></a>.
5769 </span>
5770 </div>
5771 <?php
5772 }
5773
5774 // If we're getting an option in a site that has overridden the multisite override, make
5775 // sure we are returning the option value from that site (not the multisite value).
5776 if ( array_key_exists( 'advanced_override_multisite', $auth_settings ) && $auth_settings['advanced_override_multisite'] == '1' ) {
5777 $auth_settings = $this->get_plugin_options( $admin_mode, 'no override' );
5778 }
5779
5780 // Set option to null if it wasn't found.
5781 if ( ! array_key_exists( $option, $auth_settings ) ) {
5782 return null;
5783 }
5784
5785 return $auth_settings[$option];
5786 }
5787
5788 /**
5789 * Retrieves all plugin options from db. Multisite enabled.
5790 *
5791 * @param string $admin_mode MULTISITE_ADMIN will retrieve the multisite value
5792 * @param string $override_mode 'allow override' will retrieve the multisite value if it exists
5793 * @return mixed Option value, or null on failure
5794 */
5795 private function get_plugin_options( $admin_mode = SINGLE_ADMIN, $override_mode = 'no override' ) {
5796 // Grab plugin settings (skip if in MULTISITE_ADMIN mode).
5797 $auth_settings = $admin_mode === MULTISITE_ADMIN ? array() : get_option( 'auth_settings' );
5798
5799 // Initialize to default values if the plugin option doesn't exist.
5800 if ( $auth_settings === FALSE ) {
5801 $auth_settings = $this->set_default_options();
5802 }
5803
5804 // Merge multisite options if we're in a network and the current site hasn't overridden multisite settings.
5805 if ( is_multisite() && ( ! array_key_exists( 'advanced_override_multisite', $auth_settings ) || $auth_settings['advanced_override_multisite'] != '1' ) ) {
5806 // Get multisite options.
5807 $auth_multisite_settings = get_blog_option( $this->current_site_blog_id, 'auth_multisite_settings', array() );
5808
5809 // Return the multisite options if we're viewing the network admin options page.
5810 // Otherwise override options with their multisite equivalents.
5811 if ( $admin_mode === MULTISITE_ADMIN ) {
5812 $auth_settings = $auth_multisite_settings;
5813 } elseif (
5814 $override_mode === 'allow override' &&
5815 array_key_exists( 'multisite_override', $auth_multisite_settings ) &&
5816 $auth_multisite_settings['multisite_override'] === '1'
5817 ) {
5818 // Keep track of the multisite override selection.
5819 $auth_settings['multisite_override'] = $auth_multisite_settings['multisite_override'];
5820
5821 // Note: the options below should be the complete list of
5822 // overridden options. It is *not* the complete list of all
5823 // options (some options don't have a multisite equivalent)
5824
5825 // Note: access_users_approved, access_users_pending, and
5826 // access_users_blocked do not get overridden. However,
5827 // since access_users_approved has a multisite equivalent,
5828 // you must retrieve them both seperately. This is done
5829 // because the two lists should be treated differently.
5830 // $approved_users = $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN );
5831 // $ms_approved_users = $this->get_plugin_option( 'access_users_approved', MULTISITE_ADMIN );
5832
5833 // Override external services (google, cas, or ldap) and associated options
5834 $auth_settings['google'] = $auth_multisite_settings['google'];
5835 $auth_settings['google_clientid'] = $auth_multisite_settings['google_clientid'];
5836 $auth_settings['google_clientsecret'] = $auth_multisite_settings['google_clientsecret'];
5837 $auth_settings['google_hosteddomain'] = $auth_multisite_settings['google_hosteddomain'];
5838 $auth_settings['cas'] = $auth_multisite_settings['cas'];
5839 $auth_settings['cas_custom_label'] = $auth_multisite_settings['cas_custom_label'];
5840 $auth_settings['cas_host'] = $auth_multisite_settings['cas_host'];
5841 $auth_settings['cas_port'] = $auth_multisite_settings['cas_port'];
5842 $auth_settings['cas_path'] = $auth_multisite_settings['cas_path'];
5843 $auth_settings['cas_version'] = $auth_multisite_settings['cas_version'];
5844 $auth_settings['cas_attr_email'] = $auth_multisite_settings['cas_attr_email'];
5845 $auth_settings['cas_attr_first_name'] = $auth_multisite_settings['cas_attr_first_name'];
5846 $auth_settings['cas_attr_last_name'] = $auth_multisite_settings['cas_attr_last_name'];
5847 $auth_settings['cas_attr_update_on_login'] = $auth_multisite_settings['cas_attr_update_on_login'];
5848 $auth_settings['cas_auto_login'] = $auth_multisite_settings['cas_auto_login'];
5849 $auth_settings['ldap'] = $auth_multisite_settings['ldap'];
5850 $auth_settings['ldap_host'] = $auth_multisite_settings['ldap_host'];
5851 $auth_settings['ldap_port'] = $auth_multisite_settings['ldap_port'];
5852 $auth_settings['ldap_tls'] = $auth_multisite_settings['ldap_tls'];
5853 $auth_settings['ldap_search_base'] = $auth_multisite_settings['ldap_search_base'];
5854 $auth_settings['ldap_uid'] = $auth_multisite_settings['ldap_uid'];
5855 $auth_settings['ldap_attr_email'] = $auth_multisite_settings['ldap_attr_email'];
5856 $auth_settings['ldap_user'] = $auth_multisite_settings['ldap_user'];
5857 $auth_settings['ldap_password'] = $auth_multisite_settings['ldap_password'];
5858 $auth_settings['ldap_lostpassword_url'] = $auth_multisite_settings['ldap_lostpassword_url'];
5859 $auth_settings['ldap_attr_first_name'] = $auth_multisite_settings['ldap_attr_first_name'];
5860 $auth_settings['ldap_attr_last_name'] = $auth_multisite_settings['ldap_attr_last_name'];
5861 $auth_settings['ldap_attr_update_on_login'] = $auth_multisite_settings['ldap_attr_update_on_login'];
5862
5863 // Override access_who_can_login and access_who_can_view
5864 $auth_settings['access_who_can_login'] = $auth_multisite_settings['access_who_can_login'];
5865 $auth_settings['access_who_can_view'] = $auth_multisite_settings['access_who_can_view'];
5866
5867 // Override access_default_role
5868 $auth_settings['access_default_role'] = $auth_multisite_settings['access_default_role'];
5869
5870 // Override lockouts
5871 $auth_settings['advanced_lockouts'] = $auth_multisite_settings['advanced_lockouts'];
5872
5873 // Override Hide WordPress login
5874 $auth_settings['advanced_hide_wp_login'] = $auth_multisite_settings['advanced_hide_wp_login'];
5875
5876 // Override Users per page
5877 $auth_settings['advanced_users_per_page'] = $auth_multisite_settings['advanced_users_per_page'];
5878
5879 // Override Sort users by
5880 $auth_settings['advanced_users_sort_by'] = $auth_multisite_settings['advanced_users_sort_by'];
5881
5882 // Override Sort users order
5883 $auth_settings['advanced_users_sort_order'] = $auth_multisite_settings['advanced_users_sort_order'];
5884
5885 // Override Show Dashboard Widget
5886 $auth_settings['advanced_widget_enabled'] = $auth_multisite_settings['advanced_widget_enabled'];
5887 }
5888 }
5889 return $auth_settings;
5890 }
5891
5892
5893 /**
5894 * Remove user from authorizer lists when that user is deleted in WordPress.
5895 * Run on action hook: delete_user
5896 */
5897 function remove_user_from_authorizer_when_deleted( $user_id ) {
5898 $user = get_user_by( 'id', $user_id );
5899 $deleted_email = $user->user_email;
5900
5901 // Remove user from pending/approved lists and save.
5902 $list_names = array( 'access_users_pending', 'access_users_approved' );
5903 foreach ( $list_names as $list_name ) {
5904 $user_list = $this->sanitize_user_list( $this->get_plugin_option( $list_name, SINGLE_ADMIN ) );
5905 $list_changed = false;
5906 foreach ( $user_list as $key => $existing_user ) {
5907 if ( 0 === strcasecmp( $deleted_email, $existing_user['email'] ) ) {
5908 $list_changed = true;
5909 unset( $user_list[$key] );
5910 }
5911 }
5912 if ( $list_changed ) {
5913 update_option( 'auth_settings_' . $list_name, $user_list );
5914 }
5915 }
5916 }
5917
5918
5919 /**
5920 * Remove multisite user from authorizer lists when that user is deleted from Network Users.
5921 * Run on action hook: wpmu_delete_user
5922 */
5923 function remove_network_user_from_authorizer_when_deleted( $user_id ) {
5924 $user = get_user_by( 'id', $user_id );
5925 $deleted_email = $user->user_email;
5926
5927 // Go through multisite approved user list and remove this user.
5928 $auth_multisite_settings_access_users_approved = $this->sanitize_user_list(
5929 $this->get_plugin_option( 'access_users_approved', MULTISITE_ADMIN )
5930 );
5931 $list_changed = false;
5932 foreach ( $auth_multisite_settings_access_users_approved as $key => $existing_user ) {
5933 if ( 0 === strcasecmp( $deleted_email, $existing_user['email'] ) ) {
5934 $list_changed = true;
5935 unset( $auth_multisite_settings_access_users_approved[$key] );
5936 }
5937 }
5938 if ( $list_changed ) {
5939 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
5940 }
5941
5942 // Go through all pending/approved lists on individual sites and remove this user from them.
5943 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
5944 foreach ( $sites as $site ) {
5945 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
5946 $this->remove_network_user_from_site_when_removed( $user_id, $blog_id );
5947 }
5948
5949 }
5950
5951
5952 /**
5953 * Remove multisite user from a specific site's lists when that user is removed from the site.
5954 * Run on action hook: remove_user_from_blog
5955 */
5956 function remove_network_user_from_site_when_removed( $user_id, $blog_id ) {
5957 $user = get_user_by( 'id', $user_id );
5958 $deleted_email = $user->user_email;
5959
5960 $list_names = array( 'access_users_pending', 'access_users_approved' );
5961 foreach ( $list_names as $list_name ) {
5962 $user_list = get_blog_option( $blog_id, 'auth_settings_' . $list_name, array() );
5963 $list_changed = false;
5964 foreach ( $user_list as $key => $existing_user ) {
5965 if ( 0 === strcasecmp( $deleted_email, $existing_user['email'] ) ) {
5966 $list_changed = true;
5967 unset( $user_list[$key] );
5968 }
5969 }
5970 if ( $list_changed ) {
5971 update_blog_option( $blog_id, 'auth_settings_' . $list_name, $user_list );
5972 }
5973 }
5974 }
5975
5976
5977 /**
5978 * Helper: Add multisite user to a specific site's approved list.
5979 */
5980 function add_network_user_to_site( $user_id, $blog_id ) {
5981 // Switch to blog.
5982 switch_to_blog( $blog_id );
5983
5984 // Get user details and role.
5985 $access_default_role = $this->get_plugin_option( 'access_default_role', SINGLE_ADMIN, 'allow override' );
5986 $user = get_user_by( 'id', $user_id );
5987 $user_email = $user->user_email;
5988 $user_role = $user && is_array( $user->roles ) && count( $user->roles ) > 0 ? $user->roles[0] : $access_default_role;
5989
5990 // Add user to approved list if not already there and not in blocked list.
5991 $auth_settings_access_users_approved = $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN );
5992 $auth_settings_access_users_blocked = $this->get_plugin_option( 'access_users_blocked', SINGLE_ADMIN );
5993 if ( ! $this->in_multi_array( $user_email, $auth_settings_access_users_approved ) && ! $this->in_multi_array( $user_email, $auth_settings_access_users_blocked ) ) {
5994 $approved_user = array(
5995 'email' => $this->lowercase( $user_email ),
5996 'role' => $user_role,
5997 'date_added' => date( 'M Y', strtotime( $user->user_registered ) ),
5998 'local_user' => true,
5999 );
6000 array_push( $auth_settings_access_users_approved, $approved_user );
6001 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
6002 }
6003
6004 // Restore original blog.
6005 restore_current_blog();
6006 }
6007
6008
6009 /**
6010 * Multisite:
6011 * When an existing user is invited to the current site (or a new user is created),
6012 * add them to the authorizer approved list. This action fires when the admin
6013 * doesn't select the "Skip Confirmation Email" option.
6014 *
6015 * @action invite_user
6016 *
6017 * @param int $user_id The invited user's ID.
6018 * @param array $role The role of the invited user (or none if a new user creation).
6019 * @param string $newuser_key The key of the invitation.
6020 */
6021 function add_existing_user_to_authorizer_when_created( $user_id, $role = array(), $newuser_key = '' ) {
6022 $user = get_user_by( 'id', $user_id );
6023 $this->add_user_to_authorizer_when_created( $user->user_email, $user->user_registered, $user->roles, $role );
6024 }
6025
6026
6027 /**
6028 * Multisite:
6029 * When an existing user is invited to the current site (or a new user is created),
6030 * add them to the authorizer approved list. This action fires when the admin
6031 * selects the "Skip Confirmation Email" option.
6032 *
6033 * @action added_existing_user
6034 *
6035 * @param int $user_id The invited user's ID.
6036 * @param mixed $result True on success or a WP_Error object if the user doesn't exist.
6037 */
6038 function add_existing_user_to_authorizer_when_created_noconfirmation( $user_id, $result ) {
6039 $user = get_user_by( 'id', $user_id );
6040 $this->add_user_to_authorizer_when_created( $user->user_email, $user->user_registered, $user->roles );
6041 }
6042
6043
6044 /**
6045 * Multisite:
6046 * When a new user is invited to the current site (or a new user is created),
6047 * add them to the authorizer approved list.
6048 *
6049 * @action after_signup_user
6050 *
6051 * @param string $user User's requested login name.
6052 * @param string $user_email User's email address.
6053 * @param string $key User's activation key.
6054 * @param array $meta Additional signup meta, including initially set roles.
6055 */
6056 function add_new_user_to_authorizer_when_created( $user, $user_email, $key, $meta ) {
6057 $user_roles = isset( $meta['new_role'] ) ? array( $meta['new_role'] ) : array();
6058 $this->add_user_to_authorizer_when_created( $user_email, time(), $user_roles );
6059 }
6060
6061
6062 /**
6063 * Single site:
6064 * When a new user is added in single site mode, add them to the authorizer
6065 * approved list.
6066 *
6067 * @action edit_user_created_user
6068 *
6069 * @param int $user_id ID of the newly created user.
6070 * @param string $notify Type of notification that should happen. See wp_send_new_user_notifications()
6071 * for more information on possible values.
6072 */
6073 function add_new_user_to_authorizer_when_created_single_site( $user_id, $notify ) {
6074 $user = get_user_by( 'id', $user_id );
6075 $this->add_user_to_authorizer_when_created( $user->user_email, $user->user_registered, $user->roles );
6076 }
6077
6078
6079 /**
6080 * Helper: When a new user is added/invited to the current site (or a new
6081 * user is created), add them to the authorizer approved list.
6082 */
6083 private function add_user_to_authorizer_when_created( $user_email, $date_registered, $user_roles = array(), $default_role = array() ) {
6084 $auth_multisite_settings_access_users_approved = is_multisite() ? get_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', array() ) : array();
6085 $auth_settings_access_users_pending = $this->get_plugin_option( 'access_users_pending', SINGLE_ADMIN );
6086 $auth_settings_access_users_approved = $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN );
6087 $auth_settings_access_users_blocked = $this->get_plugin_option( 'access_users_blocked', SINGLE_ADMIN );
6088
6089 // Get default role if one isn't specified.
6090 if ( count( $default_role ) < 1 ) {
6091 $default_role = '';
6092 } else {
6093 $default_role = strtolower( $default_role['name'] );
6094 }
6095
6096 $updated = false;
6097
6098 // Skip if user is in blocked list.
6099 if ( $this->in_multi_array( $user_email, $auth_settings_access_users_blocked ) ) {
6100 return;
6101 }
6102 // Remove from pending list if there.
6103 foreach ( $auth_settings_access_users_pending as $key => $pending_user ) {
6104 if ( 0 === strcasecmp( $pending_user['email'], $user_email ) ) {
6105 unset( $auth_settings_access_users_pending[$key] );
6106 $updated = true;
6107 }
6108 }
6109 // Skip if user is in multisite approved list.
6110 if ( $this->in_multi_array( $user_email, $auth_multisite_settings_access_users_approved ) ) {
6111 return;
6112 }
6113 // Add to approved list if not there.
6114 if ( ! $this->in_multi_array( $user_email, $auth_settings_access_users_approved ) ) {
6115 $approved_user = array(
6116 'email' => $this->lowercase( $user_email ),
6117 'role' => is_array( $user_roles ) && count( $user_roles ) > 0 ? $user_roles[0] : $default_role,
6118 'date_added' => date( 'M Y', strtotime( $date_registered ) ),
6119 'local_user' => true,
6120 );
6121 array_push( $auth_settings_access_users_approved, $approved_user );
6122 $updated = true;
6123 }
6124
6125 if ( $updated ) {
6126 update_option( 'auth_settings_access_users_pending', $auth_settings_access_users_pending );
6127 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
6128 }
6129 }
6130
6131
6132 /**
6133 * Multisite:
6134 * When a user is granted super admin status (checkbox on network user edit
6135 * screen), add them to the authorizer network approved list. Also remove
6136 * them from pending/approved list on any individual sites.
6137 *
6138 * @action grant_super_admin
6139 *
6140 * @param int $user_id The user's ID.
6141 */
6142 function grant_super_admin__add_to_network_approved( $user_id ) {
6143 $user = get_user_by( 'id', $user_id );
6144 $user_email = $user->user_email;
6145
6146 // Add user to multisite approved user list (if not already there).
6147 $auth_multisite_settings_access_users_approved = $this->sanitize_user_list(
6148 $this->get_plugin_option( 'access_users_approved', MULTISITE_ADMIN )
6149 );
6150 if ( ! $this->in_multi_array( $user_email, $auth_multisite_settings_access_users_approved ) ) {
6151 $multisite_approved_user = array(
6152 'email' => $this->lowercase( $user_email ),
6153 'role' => count( $user->roles ) > 0 ? $user->roles[0] : 'administrator',
6154 'date_added' => date( 'M Y', strtotime( $user->user_registered ) ),
6155 'local_user' => true,
6156 );
6157 array_push( $auth_multisite_settings_access_users_approved, $multisite_approved_user );
6158 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
6159 }
6160
6161 // Go through all pending/approved lists on individual sites and remove this user from them.
6162 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
6163 foreach ( $sites as $site ) {
6164 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
6165 $this->remove_network_user_from_site_when_removed( $user_id, $blog_id );
6166 }
6167
6168 }
6169
6170 /**
6171 * Multisite:
6172 * When a user's super admin status is revoked (checkbox on network user edit
6173 * screen), remove them from the authorizer network approved list. Also add
6174 * them to approved list on any individual sites they are already a part of.
6175 *
6176 * @action revoke_super_admin
6177 *
6178 * @param int $user_id The user's ID.
6179 */
6180 function revoke_super_admin__remove_from_network_approved( $user_id ) {
6181 $user = get_user_by( 'id', $user_id );
6182 $revoked_email = $user->user_email;
6183
6184 // Go through multisite approved user list and remove this user.
6185 $auth_multisite_settings_access_users_approved = $this->sanitize_user_list(
6186 $this->get_plugin_option( 'access_users_approved', MULTISITE_ADMIN )
6187 );
6188 $list_changed = false;
6189 foreach ( $auth_multisite_settings_access_users_approved as $key => $existing_user ) {
6190 if ( 0 === strcasecmp( $revoked_email, $existing_user['email'] ) ) {
6191 $list_changed = true;
6192 unset( $auth_multisite_settings_access_users_approved[$key] );
6193 }
6194 }
6195 if ( $list_changed ) {
6196 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
6197 }
6198
6199 // Go through this user's current sites and add them to the approved list
6200 // (since they are no longer on the network approved list).
6201 $sites_of_user = get_blogs_of_user( $user_id );
6202 foreach ( $sites_of_user as $site ) {
6203 $blog_id = $site->userblog_id;
6204 $this->add_network_user_to_site( $user_id, $blog_id );
6205 }
6206
6207 }
6208
6209 private function maybe_email_welcome_message( $email ) {
6210 // Get option for whether to email welcome messages.
6211 $should_email_new_approved_users = $this->get_plugin_option( 'access_should_email_approved_users' );
6212
6213 // Do not send welcome email if option not enabled.
6214 if ( $should_email_new_approved_users !== '1' ) {
6215 return false;
6216 }
6217
6218 // Make sure we didn't just email this user (can happen with
6219 // multiple admins saving at the same time, or by clicking
6220 // Approve button too rapidly).
6221 $recently_sent_emails = get_option( 'auth_settings_recently_sent_emails' );
6222 if ( $recently_sent_emails === FALSE ) {
6223 $recently_sent_emails = array();
6224 }
6225 foreach ( $recently_sent_emails as $key => $recently_sent_email ) {
6226 if ( $recently_sent_email['time'] < strtotime( 'now -1 minutes' ) ) {
6227 // Remove emails sent more than 1 minute ago.
6228 unset( $recently_sent_emails[$key] );
6229 } elseif ( $recently_sent_email['email'] === $email ) {
6230 // Sent an email to this user within the last 1 minute, so
6231 // quit without sending.
6232 return false;
6233 }
6234 }
6235 // Add the email we're about to send to the list.
6236 $recently_sent_emails[] = array(
6237 'email' => $email,
6238 'time' => time(),
6239 );
6240 update_option( 'auth_settings_recently_sent_emails', $recently_sent_emails );
6241
6242 // Get welcome email subject and body text
6243 $subject = $this->get_plugin_option( 'access_email_approved_users_subject' );
6244 $body = apply_filters( 'the_content', $this->get_plugin_option( 'access_email_approved_users_body' ) );
6245
6246 // Fail if the subject/body options don't exist or are empty.
6247 if ( is_null( $subject ) || is_null( $body ) || strlen( $subject ) === 0 || strlen( $body ) === 0 ) {
6248 return false;
6249 }
6250
6251 // Replace approved shortcode patterns in subject and body.
6252 $site_name = get_bloginfo( 'name' );
6253 $site_url = get_site_url();
6254 $subject = str_replace( '[site_name]', $site_name, $subject );
6255 $body = str_replace( '[site_name]', $site_name, $body );
6256 $body = str_replace( '[site_url]', $site_url, $body );
6257 $body = str_replace( '[user_email]', $email, $body );
6258 $headers = 'Content-type: text/html' . "\r\n";
6259
6260 // Send email.
6261 wp_mail( $email, $subject, $body, $headers );
6262
6263 // Indicate mail was sent.
6264 return true;
6265 }
6266
6267
6268 /**
6269 * Generate a unique cookie to add to nonces to prevent CSRF.
6270 */
6271 protected $cookie_value = null;
6272 function get_cookie_value() {
6273 if ( ! $this->cookie_value ) {
6274 if ( isset( $_COOKIE['login_unique'] ) ) {
6275 $this->cookie_value = $_COOKIE['login_unique'];
6276 } else {
6277 $this->cookie_value = md5( rand() );
6278 }
6279 }
6280 return $this->cookie_value;
6281 }
6282
6283
6284 /**
6285 * Basic encryption using a public (not secret!) key. Used for general
6286 * database obfuscation of passwords.
6287 * @param $text String to encrypt.
6288 * @param $library Encryption lib to use (openssl).
6289 * @return Encrypted string
6290 */
6291 private static $key = "8QxnrvjdtweisvCBKEY!+0\0\0";
6292 private static $iv = "R_O2D]jPn]1[fhJl!-P1.oe";
6293 function encrypt( $text, $library = 'openssl' ) {
6294 $result = '';
6295
6296 // Use openssl library (better) if it is enabled.
6297 if ( function_exists( 'openssl_encrypt' ) && $library === 'openssl' ) {
6298 $result = base64_encode( openssl_encrypt(
6299 $text,
6300 'AES-256-CBC',
6301 hash( 'sha256', self::$key ),
6302 0,
6303 substr( hash( 'sha256', self::$iv ), 0, 16 )
6304 ) );
6305 // Use mcrypt library (deprecated in PHP 7.1) if php5-mcrypt extension is enabled.
6306 } else if ( function_exists( 'mcrypt_encrypt' ) ) {
6307 $result = base64_encode( mcrypt_encrypt( MCRYPT_RIJNDAEL_256, self::$key, $text, MCRYPT_MODE_ECB, 'abcdefghijklmnopqrstuvwxyz012345' ) );
6308 // Fall back to basic obfuscation.
6309 } else {
6310 for ( $i = 0; $i < strlen( $text ); $i++ ) {
6311 $char = substr( $text, $i, 1 );
6312 $keychar = substr( self::$key, ( $i % strlen( self::$key ) ) - 1, 1 );
6313 $char = chr( ord( $char ) + ord( $keychar ) );
6314 $result .= $char;
6315 }
6316 $result = base64_encode( $result );
6317 }
6318
6319 return $result;
6320 }
6321
6322
6323 /**
6324 * Basic decryption using a public (not secret!) key. Used for general
6325 * database obfuscation of passwords.
6326 * @param $text String to encrypt.
6327 * @param $library Encryption lib to use (openssl).
6328 * @return Decrypted string
6329 */
6330 function decrypt( $secret, $library = 'openssl' ) {
6331 $result = '';
6332
6333 // Use openssl library (better) if it is enabled.
6334 if ( function_exists( 'openssl_decrypt' ) && $library === 'openssl' ) {
6335 $result = openssl_decrypt(
6336 base64_decode( $secret ),
6337 'AES-256-CBC',
6338 hash( 'sha256', self::$key ),
6339 0,
6340 substr( hash( 'sha256', self::$iv ), 0, 16 )
6341 );
6342 // Use mcrypt library (deprecated in PHP 7.1) if php5-mcrypt extension is enabled.
6343 } else if ( function_exists( 'mcrypt_decrypt' ) ) {
6344 $secret = base64_decode( $secret );
6345 $result = rtrim( mcrypt_decrypt( MCRYPT_RIJNDAEL_256, self::$key, $secret, MCRYPT_MODE_ECB, 'abcdefghijklmnopqrstuvwxyz012345' ), "\0$result" );
6346 // Fall back to basic obfuscation.
6347 } else {
6348 $secret = base64_decode( $secret );
6349 for ( $i = 0; $i < strlen( $secret ); $i++ ) {
6350 $char = substr( $secret, $i, 1 );
6351 $keychar = substr( self::$key, ( $i % strlen( self::$key ) ) - 1, 1 );
6352 $char = chr( ord( $char ) - ord( $keychar ) );
6353 $result .= $char;
6354 }
6355 }
6356
6357 return $result;
6358 }
6359
6360
6361 /**
6362 * In a multisite environment, returns true if the current user is logged
6363 * in and a user of the current blog. In single site mode, simply returns
6364 * true if the current user is logged in.
6365 */
6366 function is_user_logged_in_and_blog_user() {
6367 $is_user_logged_in_and_blog_user = false;
6368 if ( is_multisite() ) {
6369 $is_user_logged_in_and_blog_user = is_user_logged_in() && is_user_member_of_blog( get_current_user_id() );
6370 } else {
6371 $is_user_logged_in_and_blog_user = is_user_logged_in();
6372 }
6373 return $is_user_logged_in_and_blog_user;
6374 }
6375
6376
6377 /**
6378 * Helper function to determine whether a given email is in one of
6379 * the lists (pending, approved, blocked). Defaults to the list of
6380 * approved users.
6381 */
6382 function is_email_in_list( $email = '', $list = 'approved', $multisite_mode = 'single' ) {
6383 if ( empty( $email ) )
6384 return false;
6385
6386 switch ( $list ) {
6387 case 'pending':
6388 $auth_settings_access_users_pending = $this->get_plugin_option( 'access_users_pending', SINGLE_ADMIN );
6389 return $this->in_multi_array( $email, $auth_settings_access_users_pending );
6390 break;
6391 case 'blocked':
6392 $auth_settings_access_users_blocked = $this->get_plugin_option( 'access_users_blocked', SINGLE_ADMIN );
6393 return $this->in_multi_array( $email, $auth_settings_access_users_blocked );
6394 break;
6395 case 'approved':
6396 default:
6397 if ( $multisite_mode !== 'single' ) {
6398 // Get multisite users only.
6399 $auth_settings_access_users_approved = $this->get_plugin_option( 'access_users_approved', MULTISITE_ADMIN );
6400 } elseif ( is_multisite() && $this->get_plugin_option( 'advanced_override_multisite' ) == '1' ) {
6401 // This site has overridden any multisite settings, so only get its users.
6402 $auth_settings_access_users_approved = $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN );
6403 } else {
6404 // Get all site users and all multisite users.
6405 $auth_settings_access_users_approved = array_merge(
6406 $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN ),
6407 $this->get_plugin_option( 'access_users_approved', MULTISITE_ADMIN )
6408 );
6409 }
6410 return $this->in_multi_array( $email, $auth_settings_access_users_approved );
6411 break;
6412 }
6413 }
6414
6415
6416 /**
6417 * Helper function to get number of users (including multisite users)
6418 * in a given list (pending, approved, or blocked).
6419 * @param string $list
6420 * @param string $admin_mode SINGLE_ADMIN or MULTISITE_ADMIN determines whether to include multisite users
6421 * @return int number of users in list
6422 */
6423 function get_user_count_from_list( $list, $admin_mode = SINGLE_ADMIN ) {
6424 $auth_settings_access_users = array();
6425
6426 switch ( $list ) {
6427 case 'pending':
6428 $auth_settings_access_users = $this->get_plugin_option( 'access_users_pending', SINGLE_ADMIN );
6429 break;
6430 case 'blocked':
6431 $auth_settings_access_users = $this->get_plugin_option( 'access_users_blocked', SINGLE_ADMIN );
6432 break;
6433 case 'approved':
6434 if ( $admin_mode !== SINGLE_ADMIN ) {
6435 // Get multisite users only.
6436 $auth_settings_access_users = $this->get_plugin_option( 'access_users_approved', MULTISITE_ADMIN );
6437 } elseif ( is_multisite() && $this->get_plugin_option( 'advanced_override_multisite' ) == '1' ) {
6438 // This site has overridden any multisite settings, so only get its users.
6439 $auth_settings_access_users = $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN );
6440 } else {
6441 // Get all site users and all multisite users.
6442 $auth_settings_access_users = array_merge(
6443 $this->get_plugin_option( 'access_users_approved', SINGLE_ADMIN ),
6444 $this->get_plugin_option( 'access_users_approved', MULTISITE_ADMIN )
6445 );
6446 }
6447 }
6448
6449 return count( $auth_settings_access_users );
6450 }
6451
6452
6453 /**
6454 * Helper function to search a multidimensional array for a value.
6455 */
6456 function in_multi_array( $needle = '', $haystack = array(), $strict_mode = 'not strict', $case_sensitivity = 'case insensitive' ) {
6457 if ( ! is_array( $haystack ) ) {
6458 return false;
6459 }
6460 if ( $case_sensitivity === 'case insensitive' ) {
6461 $needle = strtolower( $needle );
6462 }
6463 foreach ( $haystack as $item ) {
6464 if ( $case_sensitivity === 'case insensitive' && ! is_array( $item ) ) {
6465 $item = strtolower( $item );
6466 }
6467 if ( ( $strict_mode === 'strict' ? $item === $needle : $item == $needle ) || ( is_array( $item ) && $this->in_multi_array( $needle, $item, $strict_mode, $case_sensitivity ) ) ) {
6468 return true;
6469 }
6470 }
6471 return false;
6472 }
6473
6474
6475 /**
6476 * Helper function to determine if an URL is accessible.
6477 *
6478 * @param string $url URL that should be publicly reachable
6479 * @return boolean Whether the URL is publicly reachable
6480 */
6481 function url_is_accessible( $url ) {
6482 // Use wp_remote_retrieve_response_code() to retrieve the URL.
6483 $response = wp_remote_get( $url );
6484 $response_code = wp_remote_retrieve_response_code( $response );
6485
6486 // Return true if the document has loaded successfully without any redirection or error
6487 return $response_code >= 200 && $response_code < 400;
6488 }
6489
6490
6491 /**
6492 * Helper function to reconstruct a URL split using parse_url().
6493 * @param array $parts Array returned from parse_url().
6494 * @return string URL.
6495 */
6496 function build_url( $parts = array() ) {
6497 return
6498 ( isset( $parts['scheme'] ) ? "{$parts['scheme']}:" : '' ) .
6499 ( ( isset( $parts['user'] ) || isset( $parts['host'] ) ) ? '//' : '' ) .
6500 ( isset( $parts['user'] ) ? "{$parts['user']}" : '' ) .
6501 ( isset( $parts['pass'] ) ? ":{$parts['pass']}" : '' ) .
6502 ( isset( $parts['user'] ) ? '@' : '' ) .
6503 ( isset( $parts['host'] ) ? "{$parts['host']}" : '' ) .
6504 ( isset( $parts['port'] ) ? ":{$parts['port']}" : '' ) .
6505 ( isset( $parts['path'] ) ? "{$parts['path']}" : '' ) .
6506 ( isset( $parts['query'] ) ? "?{$parts['query']}" : '' ) .
6507 ( isset( $parts['fragment'] ) ? "#{$parts['fragment']}" : '' );
6508 }
6509
6510
6511 // Helper function that builds option tags for a select element for all
6512 // roles the current user has permission to assign.
6513 function wp_dropdown_permitted_roles( $selected_role = 'subscriber', $disable_input = 'not disabled', $admin_mode = SINGLE_ADMIN ) {
6514 $roles = get_editable_roles();
6515 $current_user = wp_get_current_user();
6516
6517 // If we're in network admin, also show any roles that might exist only on
6518 // specific sites in the network (themes can add their own roles).
6519 if ( $admin_mode === MULTISITE_ADMIN ) {
6520 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
6521 foreach ( $sites as $site ) {
6522 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
6523 switch_to_blog( $blog_id );
6524 $roles = array_merge( $roles, get_editable_roles() );
6525 restore_current_blog();
6526 }
6527 $unique_role_names = array();
6528 foreach ( $roles as $role_name => $role_info ) {
6529 if ( array_key_exists( $role_name, $unique_role_names ) ) {
6530 unset( $roles[$role_name] );
6531 } else {
6532 $unique_role_names[$role_name] = true;
6533 }
6534 }
6535 }
6536
6537 // If the currently selected role exists, but is not in the list of roles,
6538 // the current user is not permitted to assign it. Assume they can't edit
6539 // that user's role at all. Return only the one role for the dropdown list.
6540 if ( strlen( $selected_role ) > 0 && ! array_key_exists( $selected_role, $roles ) && ! is_null( get_role( $selected_role ) ) ) {
6541 return;
6542 }
6543
6544 // Print an option element for each permitted role.
6545 foreach ( $roles as $name => $role ) {
6546 $selected = $selected_role === $name ? ' selected="selected"' : '';
6547
6548 // Don't let a user change their own role
6549 $disabled = $selected_role !== $name && $disable_input === 'disabled' ? ' disabled="disabled"' : '';
6550
6551 // But network admins can always change their role.
6552 if ( is_multisite() && current_user_can( 'manage_network' ) ) {
6553 $disabled = '';
6554 }
6555
6556 ?><option value="<?php echo $name; ?>"<?php echo $selected . $disabled; ?>><?php echo $role['name']; ?></option><?php
6557 }
6558
6559 // Print default role (no role).
6560 $selected = strlen( $selected_role ) == 0 || ! array_key_exists( $selected_role, $roles ) ? ' selected="selected"' : '';
6561 $disabled = strlen( $selected_role ) > 0 && $disable_input === 'disabled' ? ' disabled="disabled"' : '';
6562 if ( is_multisite() && current_user_can( 'manage_network' ) ) {
6563 $disabled = '';
6564 }
6565 ?><option value=""<?php echo $selected . $disabled; ?>><?php _e( '&mdash; No role for this site &mdash;', 'authorizer' ); ?></option><?php
6566
6567 }
6568
6569
6570 // Helper function to get a single user info array from one of the
6571 // access control lists (pending, approved, or blocked).
6572 // Returns: false if not found; otherwise
6573 // array( 'email' => '', 'role' => '', 'date_added' => '', ['usermeta' => [''|array()]] );
6574 function get_user_info_from_list( $email, $list ) {
6575 foreach ( $list as $user_info ) {
6576 if ( 0 === strcasecmp( $user_info['email'], $email ) ) {
6577 return $user_info;
6578 }
6579 }
6580 return false;
6581 }
6582
6583 // Helper function to convert a string to lowercase. Prefers to use mb_strtolower,
6584 // but will fall back to strtolower if the former is not available.
6585 // Returns: string in lowercase
6586 function lowercase( $string ) {
6587 return function_exists( "mb_strtolower" ) ? mb_strtolower( $string ) : strtolower( $string );
6588 }
6589
6590
6591 // Helper function to convert seconds to human readable text.
6592 // Source: http://csl.name/php-secs-to-human-text/
6593 function seconds_as_sentence( $secs ) {
6594 $units = array(
6595 "week" => 7 * 24 * 3600,
6596 "day" => 24 * 3600,
6597 "hour" => 3600,
6598 "minute" => 60,
6599 "second" => 1,
6600 );
6601
6602 // specifically handle zero
6603 if ( $secs == 0 ) return "0 seconds";
6604
6605 $s = "";
6606
6607 foreach ( $units as $name => $divisor ) {
6608 if ( $quot = intval( $secs / $divisor ) ) {
6609 $s .= "$quot $name";
6610 $s .= ( abs( $quot ) > 1 ? "s" : "" ) . ", ";
6611 $secs -= $quot * $divisor;
6612 }
6613 }
6614
6615 return substr( $s, 0, -2 );
6616 }
6617
6618 // Helper function to get all available usermeta keys as an array.
6619 function get_all_usermeta_keys() {
6620 global $wpdb;
6621 $usermeta_keys = $wpdb->get_col( "SELECT DISTINCT $wpdb->usermeta.meta_key FROM $wpdb->usermeta" );
6622 return $usermeta_keys;
6623 }
6624
6625
6626 /**
6627 * Load translated strings from *.mo files in /languages.
6628 */
6629 function load_textdomain() {
6630 load_plugin_textdomain(
6631 'authorizer',
6632 false,
6633 plugin_basename( dirname( __FILE__ ) ) . '/languages'
6634 );
6635 }
6636
6637
6638 /**
6639 * Generate CAS authentication URL (wp-login.php URL with reauth=1 removed
6640 * and external=cas added).
6641 */
6642 function modify_current_url_for_cas_login() {
6643 // Construct the URL of the current page (wp-login.php).
6644 $url = 'http' . ( isset( $_SERVER['HTTPS'] ) ? 's' : '' ) . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
6645
6646 // Parse the URL into its components.
6647 $parsed_url = parse_url( $url );
6648
6649 // Fix up the querystring values (remove reauth, make sure external=cas).
6650 $querystring = array();
6651 if ( array_key_exists( 'query', $parsed_url ) ) {
6652 parse_str( $parsed_url['query'], $querystring );
6653 }
6654 unset( $querystring['reauth'] );
6655 $querystring['external'] = 'cas';
6656 $parsed_url['query'] = http_build_query( $querystring );
6657
6658 // Return the URL as a string.
6659 return $this->unparse_url( $parsed_url );
6660 }
6661
6662
6663 /**
6664 * Reconstruct a URL after it has been deconstructed with parse_url().
6665 * @param $parsed_url array() with keys from parse_url().
6666 * @return string URL constructed from the components in $parsed_url.
6667 */
6668 function unparse_url( $parsed_url = array() ) {
6669 $scheme = isset( $parsed_url['scheme'] ) ? $parsed_url['scheme'] . '://' : '';
6670 $host = isset( $parsed_url['host'] ) ? $parsed_url['host'] : '';
6671 $port = isset( $parsed_url['port'] ) ? ':' . $parsed_url['port'] : '';
6672 $user = isset( $parsed_url['user'] ) ? $parsed_url['user'] : '';
6673 $pass = isset( $parsed_url['pass'] ) ? ':' . $parsed_url['pass'] : '';
6674 $pass = $user || $pass ? "$pass@" : '';
6675 $path = isset( $parsed_url['path'] ) ? $parsed_url['path'] : '';
6676 $query = isset( $parsed_url['query'] ) ? '?' . $parsed_url['query'] : '';
6677 $fragment = isset( $parsed_url['fragment'] ) ? '#' . $parsed_url['fragment'] : '';
6678 return "$scheme$user$pass$host$port$path$query$fragment";
6679 }
6680
6681
6682 /**
6683 * Helper function to generate an HTML class name for an option (used in
6684 * Authorizer Settings in the Approved User list).
6685 * @param string $suffix Unique part of class name
6686 * @param boolean $is_multisite_user Whether the class name should indicate it's a multisite user
6687 * @return string Class name, e.g., "auth-email auth-multisite-email"
6688 */
6689 function create_class_name( $suffix = '', $is_multisite_user = false ) {
6690 return $is_multisite_user ? "auth-$suffix auth-multisite-$suffix" : "auth-$suffix";
6691 }
6692
6693 /**
6694 * Plugin Update Routines.
6695 */
6696 function auth_update_check() {
6697 // Get current version.
6698 $needs_updating = false;
6699 if ( is_multisite() ) {
6700 $auth_version = get_blog_option( $this->current_site_blog_id, 'auth_version' );
6701 } else {
6702 $auth_version = get_option( 'auth_version' );
6703 }
6704
6705 // Update: migrate user lists to own options (addresses concurrency
6706 // when saving plugin options, since user lists are changed often
6707 // and we don't want to overwrite changes to the lists when an
6708 // admin saves all of the plugin options.)
6709 // Note: Pending user list is changed whenever a new user tries to
6710 // log in; approved and blocked lists are changed whenever an admin
6711 // changes them from the multisite panel, the dashboard widget, or
6712 // the plugin options page.
6713 $update_if_older_than = 20140709;
6714 if ( $auth_version === false || intval( $auth_version ) < $update_if_older_than ) {
6715 // Copy single site user lists to new options (if they exist).
6716 $auth_settings = get_option( 'auth_settings' );
6717 if ( is_array( $auth_settings ) && array_key_exists( 'access_users_pending', $auth_settings ) ) {
6718 update_option( 'auth_settings_access_users_pending', $auth_settings['access_users_pending'] );
6719 unset( $auth_settings['access_users_pending'] );
6720 update_option( 'auth_settings', $auth_settings );
6721 }
6722 if ( is_array( $auth_settings ) && array_key_exists( 'access_users_approved', $auth_settings ) ) {
6723 update_option( 'auth_settings_access_users_approved', $auth_settings['access_users_approved'] );
6724 unset( $auth_settings['access_users_approved'] );
6725 update_option( 'auth_settings', $auth_settings );
6726 }
6727 if ( is_array( $auth_settings ) && array_key_exists( 'access_users_blocked', $auth_settings ) ) {
6728 update_option( 'auth_settings_access_users_blocked', $auth_settings['access_users_blocked'] );
6729 unset( $auth_settings['access_users_blocked'] );
6730 update_option( 'auth_settings', $auth_settings );
6731 }
6732 // Copy multisite user lists to new options (if they exist).
6733 if ( is_multisite() ) {
6734 $auth_multisite_settings = get_blog_option( $this->current_site_blog_id, 'auth_multisite_settings', array() );
6735 if ( is_array( $auth_multisite_settings ) && array_key_exists( 'access_users_pending', $auth_multisite_settings ) ) {
6736 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_pending', $auth_multisite_settings['access_users_pending'] );
6737 unset( $auth_multisite_settings['access_users_pending'] );
6738 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings', $auth_multisite_settings );
6739 }
6740 if ( is_array( $auth_multisite_settings ) && array_key_exists( 'access_users_approved', $auth_multisite_settings ) ) {
6741 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings['access_users_approved'] );
6742 unset( $auth_multisite_settings['access_users_approved'] );
6743 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings', $auth_multisite_settings );
6744 }
6745 if ( is_array( $auth_multisite_settings ) && array_key_exists( 'access_users_blocked', $auth_multisite_settings ) ) {
6746 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_blocked', $auth_multisite_settings['access_users_blocked'] );
6747 unset( $auth_multisite_settings['access_users_blocked'] );
6748 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings', $auth_multisite_settings );
6749 }
6750 }
6751 // Update version to reflect this change has been made.
6752 $auth_version = $update_if_older_than;
6753 $needs_updating = true;
6754 }
6755
6756 // Update: Set default values for newly added options (forgot to do
6757 // this, so some users are getting debug log notices about undefined
6758 // indexes in $auth_settings).
6759 $update_if_older_than = 20160831;
6760 if ( $auth_version === false || intval( $auth_version ) < $update_if_older_than ) {
6761 // Provide default values for any $auth_settings options that don't exist.
6762 if ( is_multisite() ) {
6763 // Get all blog ids
6764 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
6765 foreach ( $sites as $site ) {
6766 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
6767 switch_to_blog( $blog_id );
6768 // Set meaningful defaults for other sites in the network.
6769 $this->set_default_options();
6770 // Switch back to original blog. See: https://codex.wordpress.org/Function_Reference/restore_current_blog
6771 restore_current_blog();
6772 }
6773 } else {
6774 // Set meaningful defaults for this site.
6775 $this->set_default_options();
6776 }
6777 // Update version to reflect this change has been made.
6778 $auth_version = $update_if_older_than;
6779 $needs_updating = true;
6780 }
6781
6782 // Update: Migrate LDAP passwords encrypted with mcrypt since mcrypt is
6783 // deprecated as of PHP 7.1. Use openssl library instead.
6784 $update_if_older_than = 20170510;
6785 if ( $auth_version === false || intval( $auth_version ) < $update_if_older_than ) {
6786 if ( is_multisite() ) {
6787 // Reencrypt LDAP passwords in each site in the network.
6788 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
6789 foreach ( $sites as $site ) {
6790 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
6791 $auth_settings = get_blog_option( $blog_id, 'auth_settings', array() );
6792 if ( array_key_exists( 'ldap_password', $auth_settings ) && strlen( $auth_settings['ldap_password'] ) > 0 ) {
6793 $plaintext_ldap_password = $this->decrypt( $auth_settings['ldap_password'], 'mcrypt' );
6794 $auth_settings['ldap_password'] = $this->encrypt( $plaintext_ldap_password );
6795 update_blog_option( $blog_id, 'auth_settings', $auth_settings );
6796 }
6797 }
6798 } else {
6799 // Reencrypt LDAP password on this single-site install.
6800 $auth_settings = get_option( 'auth_settings', array() );
6801 if ( array_key_exists( 'ldap_password', $auth_settings ) && strlen( $auth_settings['ldap_password'] ) > 0 ) {
6802 $plaintext_ldap_password = $this->decrypt( $auth_settings['ldap_password'], 'mcrypt' );
6803 $auth_settings['ldap_password'] = $this->encrypt( $plaintext_ldap_password );
6804 update_option( 'auth_settings', $auth_settings );
6805 }
6806 }
6807 // Update version to reflect this change has been made.
6808 $auth_version = $update_if_older_than;
6809 $needs_updating = true;
6810 }
6811
6812 // Update: Migrate LDAP passwords encrypted with mcrypt since mcrypt is
6813 // deprecated as of PHP 7.1. Use openssl library instead.
6814 // Note: Forgot to update the auth_multisite_settings ldap password! Do it here.
6815 $update_if_older_than = 20170511;
6816 if ( $auth_version === false || intval( $auth_version ) < $update_if_older_than ) {
6817 if ( is_multisite() ) {
6818 // Reencrypt LDAP password in network (multisite) options.
6819 $auth_multisite_settings = get_blog_option( $this->current_site_blog_id, 'auth_multisite_settings', array() );
6820 if ( array_key_exists( 'ldap_password', $auth_multisite_settings ) && strlen( $auth_multisite_settings['ldap_password'] ) > 0 ) {
6821 $plaintext_ldap_password = $this->decrypt( $auth_multisite_settings['ldap_password'], 'mcrypt' );
6822 $auth_multisite_settings['ldap_password'] = $this->encrypt( $plaintext_ldap_password );
6823 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings', $auth_multisite_settings );
6824 }
6825 }
6826 // Update version to reflect this change has been made.
6827 $auth_version = $update_if_older_than;
6828 $needs_updating = true;
6829 }
6830
6831 // Update: Remove duplicates from approved list caused by authorizer_automatically_approve_login
6832 // filter not respecting users who are already in the approved list
6833 // (causing them to get re-added each time they logged in).
6834 $update_if_older_than = 20170711;
6835 if ( $auth_version === false || intval( $auth_version ) < $update_if_older_than ) {
6836 // Remove duplicates from approved user lists.
6837 if ( is_multisite() ) {
6838 // Remove duplicates from each site in the multisite
6839 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
6840 foreach ( $sites as $site ) {
6841 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
6842 $auth_settings_access_users_approved = get_blog_option( $blog_id, 'auth_settings_access_users_approved', array() );
6843 if ( is_array( $auth_settings_access_users_approved ) ) {
6844 $should_update = false;
6845 $distinct_emails = array();
6846 foreach ( $auth_settings_access_users_approved as $key => $user ) {
6847 if ( in_array( $user['email'], $distinct_emails ) ) {
6848 $should_update = true;
6849 unset( $auth_settings_access_users_approved[$key] );
6850 } else {
6851 $distinct_emails[] = $user['email'];
6852 }
6853 }
6854 if ( $should_update ) {
6855 update_blog_option( $blog_id, 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
6856 }
6857 }
6858 }
6859 // Remove duplicates from multisite approved user list.
6860 $auth_multisite_settings_access_users_approved = get_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', array() );
6861 if ( is_array( $auth_multisite_settings_access_users_approved ) ) {
6862 $should_update = false;
6863 $distinct_emails = array();
6864 foreach ( $auth_multisite_settings_access_users_approved as $key => $user ) {
6865 if ( in_array( $user['email'], $distinct_emails ) ) {
6866 $should_update = true;
6867 unset( $auth_multisite_settings_access_users_approved[$key] );
6868 } else {
6869 $distinct_emails[] = $user['email'];
6870 }
6871 }
6872 if ( $should_update ) {
6873 update_blog_option( $this->current_site_blog_id, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
6874 }
6875 }
6876 } else {
6877 // Remove duplicates from single site approved user list.
6878 $auth_settings_access_users_approved = get_option( 'auth_settings_access_users_approved' );
6879 if ( is_array( $auth_settings_access_users_approved ) ) {
6880 $should_update = false;
6881 $distinct_emails = array();
6882 foreach ( $auth_settings_access_users_approved as $key => $user ) {
6883 if ( in_array( $user['email'], $distinct_emails ) ) {
6884 $should_update = true;
6885 unset( $auth_settings_access_users_approved[$key] );
6886 } else {
6887 $distinct_emails[] = $user['email'];
6888 }
6889 }
6890 if ( $should_update ) {
6891 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
6892 }
6893 }
6894 }
6895 // Update version to reflect this change has been made.
6896 $auth_version = $update_if_older_than;
6897 $needs_updating = true;
6898 }
6899
6900 // Update: Set default value for newly added option advanced_widget_enabled.
6901 $update_if_older_than = 20171023;
6902 if ( $auth_version === false || intval( $auth_version ) < $update_if_older_than ) {
6903 // Provide default values for any $auth_settings options that don't exist.
6904 if ( is_multisite() ) {
6905 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
6906 foreach ( $sites as $site ) {
6907 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
6908 switch_to_blog( $blog_id );
6909 $this->set_default_options();
6910 restore_current_blog();
6911 }
6912 } else {
6913 $this->set_default_options();
6914 }
6915 // Update version to reflect this change has been made.
6916 $auth_version = $update_if_older_than;
6917 $needs_updating = true;
6918 }
6919
6920 // Update: Set default value for newly added option advanced_users_per_page.
6921 $update_if_older_than = 20171215;
6922 if ( $auth_version === false || intval( $auth_version ) < $update_if_older_than ) {
6923 // Provide default values for any $auth_settings options that don't exist.
6924 if ( is_multisite() ) {
6925 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
6926 foreach ( $sites as $site ) {
6927 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
6928 switch_to_blog( $blog_id );
6929 $this->set_default_options();
6930 restore_current_blog();
6931 }
6932 } else {
6933 $this->set_default_options();
6934 }
6935 // Update version to reflect this change has been made.
6936 $auth_version = $update_if_older_than;
6937 $needs_updating = true;
6938 }
6939
6940 // Update: Set default value for newly added options advanced_users_sort_by and advanced_users_sort_order.
6941 $update_if_older_than = 20171219;
6942 if ( $auth_version === false || intval( $auth_version ) < $update_if_older_than ) {
6943 // Provide default values for any $auth_settings options that don't exist.
6944 if ( is_multisite() ) {
6945 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
6946 foreach ( $sites as $site ) {
6947 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
6948 switch_to_blog( $blog_id );
6949 $this->set_default_options();
6950 restore_current_blog();
6951 }
6952 } else {
6953 $this->set_default_options();
6954 }
6955 // Update version to reflect this change has been made.
6956 $auth_version = $update_if_older_than;
6957 $needs_updating = true;
6958 }
6959
6960 // // Update: TEMPLATE
6961 // $update_if_older_than = YYYYMMDD;
6962 // if ( $auth_version === false || intval( $auth_version ) < $update_if_older_than ) {
6963 // UPDATE CODE HERE
6964 // // Update version to reflect this change has been made.
6965 // $auth_version = $update_if_older_than;
6966 // $needs_updating = true;
6967 // }
6968
6969 // Save new version number if we performed any updates.
6970 if ( $needs_updating ) {
6971 if ( is_multisite() ) {
6972 $sites = function_exists( 'get_sites' ) ? get_sites() : wp_get_sites( array( 'limit' => PHP_INT_MAX ) );
6973 foreach ( $sites as $site ) {
6974 $blog_id = function_exists( 'get_sites' ) ? $site->blog_id : $site['blog_id'];
6975 update_blog_option( $blog_id, 'auth_version', $auth_version );
6976 }
6977 } else {
6978 update_option( 'auth_version', $auth_version );
6979 }
6980 }
6981 }
6982
6983 }
6984 }
6985
6986 // Instantiate the plugin class.
6987 $wp_plugin_authorizer = new WP_Plugin_Authorizer();
6988