PluginProbe
Authorizer / 2.3.12
Authorizer v2.3.12
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.3.12, at authorizer.php

4,891 lines 236.9 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/figureone/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.3.12
7 Author: Paul Ryan
8 Author URI: http://www.linkedin.com/in/paulrryan/
9 License: GPL2
10 */
11
12 /*
13 Copyright 2014 Paul Ryan (email: prar@hawaii.edu)
14
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License, version 2, as
17 published by the Free Software Foundation.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29 /*
30 Portions forked from Restricted Site Access plugin: http://wordpress.org/plugins/restricted-site-access/
31 Portions forked from wpCAS plugin: http://wordpress.org/extend/plugins/cas-authentication/
32 Portions forked from Limit Login Attempts: http://wordpress.org/plugins/limit-login-attempts/
33 */
34
35 // Add phpCAS library if it's not included.
36 // @see https://wiki.jasig.org/display/CASC/phpCAS+installation+guide
37 if ( ! defined( 'PHPCAS_VERSION' ) ) {
38 require_once dirname( __FILE__ ) . '/inc/CAS-1.3.3/CAS.php';
39 }
40
41 // Add Google API PHP Client if it's not included.
42 // @see https://github.com/google/google-api-php-client
43 if ( ! class_exists( 'Google_Client' ) ) {
44 set_include_path( get_include_path() . PATH_SEPARATOR . dirname( __FILE__ ) . '/inc/google-api-php-client/src' );
45 require_once dirname( __FILE__ ) . '/inc/google-api-php-client/src/Google/Client.php';
46 }
47
48 if ( ! class_exists( 'WP_Plugin_Authorizer' ) ) {
49 /**
50 * Define class for plugin: Authorizer.
51 *
52 * @category Authentication
53 * @package Authorizer
54 * @author Paul Ryan <prar@hawaii.edu>
55 * @license http://www.gnu.org/licenses/gpl-2.0.html GPL2
56 * @link http://hawaii.edu/coe/dcdc/wordpress/authorizer/doc/
57 */
58 class WP_Plugin_Authorizer {
59
60 /**
61 * Constructor.
62 */
63 public function __construct() {
64 // Installation and uninstallation hooks.
65 register_activation_hook( __FILE__, array( $this, 'activate' ) );
66 register_deactivation_hook( __FILE__, array( $this, 'deactivate' ) );
67
68 // Register filters.
69
70 // Custom wp authentication routine using external service.
71 add_filter( 'authenticate', array( $this, 'custom_authenticate' ), 1, 3 );
72
73 // Custom logout action using external service.
74 add_action( 'wp_logout', array( $this, 'custom_logout' ) );
75
76 // Removing this bypasses Wordpress authentication (so if external auth fails,
77 // no one can log in); with it enabled, it will run if external auth fails.
78 //remove_filter('authenticate', 'wp_authenticate_username_password', 20, 3);
79
80 // Create settings link on Plugins page
81 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'plugin_settings_link' ) );
82 add_filter( 'network_admin_plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'network_admin_plugin_settings_link' ) );
83
84 // Modify login page with a custom password url (if option is set).
85 add_filter( 'lostpassword_url', array( $this, 'custom_lostpassword_url' ) );
86
87 // If we have a custom login error, add the filter to show it.
88 $error = get_option( 'auth_settings_advanced_login_error' );
89 if ( $error && strlen( $error ) > 0 ) {
90 add_filter( 'login_errors', array( $this, 'show_advanced_login_error' ) );
91 }
92
93 // Register actions.
94
95 // Perform plugin updates if newer version installed.
96 add_action( 'plugins_loaded', array( $this, 'auth_update_check' ) );
97
98 // Update the user meta with this user's failed login attempt.
99 add_action( 'wp_login_failed', array( $this, 'update_login_failed_count' ) );
100
101 // Create menu item in Settings
102 add_action( 'admin_menu', array( $this, 'add_plugin_page' ) );
103
104 // Create options page
105 add_action( 'admin_init', array( $this, 'page_init' ) );
106
107 // Update user role in approved list if it's changed in the WordPress edit user page.
108 add_action( 'edit_user_profile_update', array( $this, 'edit_user_profile_update_role' ) );
109
110 // Enqueue javascript and css on the plugin's options page, the
111 // dashboard (for the widget), and the network admin.
112 add_action( 'load-settings_page_authorizer', array( $this, 'load_options_page' ) );
113 add_action( 'admin_head-index.php', array( $this, 'load_options_page' ) );
114 add_action( 'load-toplevel_page_authorizer', array( $this, 'load_options_page' ) );
115
116 // Add custom css and js to wp-login.php
117 add_action( 'login_enqueue_scripts', array( $this, 'login_enqueue_scripts_and_styles' ) );
118 add_action( 'login_footer', array( $this, 'load_login_footer_js' ) );
119
120 // Modify login page with external auth links (if enabled; e.g., google or cas)
121 add_action( 'login_form', array( $this, 'login_form_add_external_service_links' ) );
122
123 // Verify current user has access to page they are visiting
124 add_action( 'parse_request', array( $this, 'restrict_access' ), 20 );
125
126 // ajax save options from dashboard widget
127 add_action( 'wp_ajax_update_auth_user', array( $this, 'ajax_update_auth_user' ) );
128
129 // ajax save options from multisite options page
130 add_action( 'wp_ajax_save_auth_multisite_settings', array( $this, 'ajax_save_auth_multisite_settings' ) );
131
132 // ajax save usermeta from options page
133 add_action( 'wp_ajax_update_auth_usermeta', array( $this, 'ajax_update_auth_usermeta' ) );
134
135 // ajax verify google login
136 add_action( 'wp_ajax_process_google_login', array( $this, 'ajax_process_google_login' ) );
137 add_action( 'wp_ajax_nopriv_process_google_login', array( $this, 'ajax_process_google_login' ) );
138
139 // Add dashboard widget so instructors can add/edit users with access.
140 // Hint: For Multisite Network Admin Dashboard use wp_network_dashboard_setup instead of wp_dashboard_setup.
141 add_action( 'wp_dashboard_setup', array( $this, 'add_dashboard_widgets' ) );
142
143 // If we have a custom admin message, add the action to show it.
144 $notice = get_option( 'auth_settings_advanced_admin_notice' );
145 if ( $notice && strlen( $notice ) > 0 ) {
146 add_action( 'admin_notices', array( $this, 'show_advanced_admin_notice' ) );
147 add_action( 'network_admin_notices', array( $this, 'show_advanced_admin_notice' ) );
148 }
149
150 // Load custom javascript for the main site (e.g., for displaying alerts).
151 add_action( 'wp_enqueue_scripts', array( $this, 'auth_public_scripts' ), 20 );
152
153 // If multisite, add network admin options page (global settings for all sites)
154 if ( is_multisite() ) {
155 add_action( 'network_admin_menu', array( $this, 'network_admin_menu' ) );
156 }
157
158 // Create login cookie (used by google login)
159 if ( ! isset( $_COOKIE['login_unique'] ) ) {
160 setcookie( 'login_unique', $this->get_cookie_value(), time()+1800, '/', defined( COOKIE_DOMAIN ) ? COOKIE_DOMAIN : '' );
161 }
162
163 } // END __construct()
164
165
166 /**
167 * Plugin activation hook.
168 * Will also activate the plugin for all sites/blogs if this is a "Network enable."
169 *
170 * @return void
171 */
172 public function activate() {
173 global $wpdb;
174
175 // If we're in a multisite environment, run the plugin activation for each site when network enabling
176 if ( is_multisite() && isset( $_GET['networkwide'] ) && $_GET['networkwide'] == 1 ) {
177 $old_blog = $wpdb->blogid;
178 // Get all blog ids
179 $blogs = wp_get_sites( array( 'limit' => 999999 ) );
180 foreach ( $blogs as $blog ) {
181 switch_to_blog( $blog['blog_id'] );
182 // Set meaningful defaults for other sites in the network.
183 $this->set_default_options();
184 // Add current WordPress users to the approved list.
185 $this->add_wp_users_to_approved_list();
186 }
187 switch_to_blog( $old_blog );
188 } else {
189 // Set meaningful defaults for this site.
190 $this->set_default_options();
191 // Add current WordPress users to the approved list.
192 $this->add_wp_users_to_approved_list();
193 }
194
195 } // END activate()
196
197 /**
198 * Adds all WordPress users in the current site to the approved list,
199 * unless they are already in the blocked list. Also removes them
200 * from the pending list if they are there.
201 *
202 * Runs in plugin activation hook.
203 *
204 * @return void
205 */
206 private function add_wp_users_to_approved_list() {
207 // Add current WordPress users to the approved list.
208 $auth_multisite_settings_access_users_approved = is_multisite() ? get_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings_access_users_approved', array() ) : array();
209 $auth_settings_access_users_pending = $this->get_plugin_option( 'access_users_pending', 'single admin' );
210 $auth_settings_access_users_approved = $this->get_plugin_option( 'access_users_approved', 'single admin' );
211 $auth_settings_access_users_blocked = $this->get_plugin_option( 'access_users_blocked', 'single admin' );
212 $default_role = $this->get_plugin_option( 'access_default_role', 'single admin', 'allow override' );
213 $updated = false;
214 foreach ( get_users() as $user ) {
215 // Skip if user is in blocked list.
216 if ( $this->in_multi_array( $user->user_email, $auth_settings_access_users_blocked ) ) {
217 continue;
218 }
219 // Skip if user is in multisite approved list.
220 if ( $this->in_multi_array( $user->user_email, $auth_multisite_settings_access_users_approved ) ) {
221 continue;
222 }
223 // Add to approved list if not there.
224 if ( ! $this->in_multi_array( $user->user_email, $auth_settings_access_users_approved ) ) {
225 $approved_user = array(
226 'email' => $user->user_email,
227 'role' => count( $user->roles ) > 0 ? $user->roles[0] : $default_role,
228 'date_added' => date( 'M Y', strtotime( $user->user_registered ) ),
229 'local_user' => true,
230 );
231 array_push( $auth_settings_access_users_approved, $approved_user );
232 $updated = true;
233 }
234 // Remove from pending list if there.
235 foreach ( $auth_settings_access_users_pending as $key => $pending_user ) {
236 if ( $pending_user['email'] == $user->user_email ) {
237 unset( $auth_settings_access_users_pending[$key] );
238 $updated = true;
239 }
240 }
241 }
242 if ( $updated ) {
243 update_option( 'auth_settings_access_users_pending', $auth_settings_access_users_pending );
244 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
245 }
246 }
247
248
249 /**
250 * Plugin deactivation.
251 *
252 * @return void
253 */
254 public function deactivate() {
255 // Do nothing.
256 } // END deactivate()
257
258
259
260 /**
261 * ***************************
262 * External Authentication
263 * ***************************
264 */
265
266
267
268 /**
269 * Authenticate against an external service.
270 *
271 * @param WP_User $user user to authenticate
272 * @param string $username optional username to authenticate.
273 * @param string $password optional password to authenticate.
274 *
275 * @return WP_User or WP_Error
276 */
277 public function custom_authenticate( $user, $username, $password ) {
278 // Pass through if already authenticated.
279 if ( is_a( $user, 'WP_User' ) ) {
280 return $user;
281 } else {
282 $user = null;
283 }
284
285 // If username and password are blank, this isn't a log in attempt
286 $is_login_attempt = strlen( $username ) > 0 && strlen( $password ) > 0;
287
288 // Check to make sure that $username is not locked out due to too
289 // many invalid login attempts. If it is, tell the user how much
290 // time remains until they can try again.
291 $unauthenticated_user = $is_login_attempt ? get_user_by( 'login', $username ) : false;
292 $unauthenticated_user_is_blocked = false;
293 if ( $is_login_attempt && $unauthenticated_user !== false ) {
294 $last_attempt = get_user_meta( $unauthenticated_user->ID, 'auth_settings_advanced_lockouts_time_last_failed', true );
295 $num_attempts = get_user_meta( $unauthenticated_user->ID, 'auth_settings_advanced_lockouts_failed_attempts', true );
296 // Also check the auth_blocked user_meta flag (users in blocked list will get this flag)
297 $unauthenticated_user_is_blocked = get_user_meta( $unauthenticated_user->ID, 'auth_blocked', true ) === 'yes';
298 } else {
299 $last_attempt = get_option( 'auth_settings_advanced_lockouts_time_last_failed' );
300 $num_attempts = get_option( 'auth_settings_advanced_lockouts_failed_attempts' );
301 }
302
303 // Inactive users should be treated like deleted users (we just
304 // do this to preserve any content they created, but here we should
305 // pretend they don't exist).
306 if ( $unauthenticated_user_is_blocked ) {
307 remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
308 return new WP_Error( 'empty_password', __( '<strong>ERROR</strong>: Incorrect username or password.' ) );
309 }
310
311 // Grab plugin settings.
312 $auth_settings = $this->get_plugin_options( 'single admin', 'allow override' );
313
314 // Make sure $last_attempt (time) and $num_attempts are positive integers.
315 // Note: this addresses resetting them if either is unset from above.
316 $last_attempt = abs( intval( $last_attempt ) );
317 $num_attempts = abs( intval( $num_attempts ) );
318
319 // Create semantic lockout variables.
320 $lockouts = $auth_settings['advanced_lockouts'];
321 $time_since_last_fail = time() - $last_attempt;
322 $reset_duration = $lockouts['reset_duration'] * 60; // minutes to seconds
323 $num_attempts_long_lockout = $lockouts['attempts_1'] + $lockouts['attempts_2'];
324 $num_attempts_short_lockout = $lockouts['attempts_1'];
325 $seconds_remaining_long_lockout = $lockouts['duration_2'] * 60 - $time_since_last_fail;
326 $seconds_remaining_short_lockout = $lockouts['duration_1'] * 60 - $time_since_last_fail;
327
328 // Check if we need to institute a lockout delay
329 if ( $is_login_attempt && $time_since_last_fail > $reset_duration ) {
330 // Enough time has passed since the last invalid attempt and
331 // now that we can reset the failed attempt count, and let this
332 // login attempt go through.
333 $num_attempts = 0; // This does nothing, but include it for semantic meaning.
334 } elseif ( $is_login_attempt && $num_attempts > $num_attempts_long_lockout && $seconds_remaining_long_lockout > 0 ) {
335 // Stronger lockout (1st/2nd round of invalid attempts reached)
336 // Note: set the error code to 'empty_password' so it doesn't
337 // trigger the wp_login_failed hook, which would continue to
338 // increment the failed attempt count.
339 remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
340 return new WP_Error( 'empty_password', sprintf( __( '<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>?' ), $username, $seconds_remaining_long_lockout, $this->seconds_as_sentence( $seconds_remaining_long_lockout ), wp_lostpassword_url() ) );
341 } elseif ( $is_login_attempt && $num_attempts > $num_attempts_short_lockout && $seconds_remaining_short_lockout > 0 ) {
342 // Normal lockout (1st round of invalid attempts reached)
343 // Note: set the error code to 'empty_password' so it doesn't
344 // trigger the wp_login_failed hook, which would continue to
345 // increment the failed attempt count.
346 remove_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
347 return new WP_Error( 'empty_password', sprintf( __( '<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>?' ), $username, $seconds_remaining_short_lockout, $this->seconds_as_sentence( $seconds_remaining_short_lockout ), wp_lostpassword_url() ) );
348 }
349
350 // Start external authentication.
351 $externally_authenticated_emails = array();
352 $authenticated_by = '';
353
354 // Try Google authentication if it's enabled and we don't have a
355 // successful login yet.
356 if ( $auth_settings['google'] === '1' ) {
357 $result = $this->custom_authenticate_google( $auth_settings );
358 if ( ! is_wp_error( $result ) ) {
359 if ( is_array( $result['email'] ) ) {
360 $externally_authenticated_emails = $result['email'];
361 } else {
362 $externally_authenticated_emails[] = $result['email'];
363 }
364 $authenticated_by = $result['authenticated_by'];
365 }
366 }
367
368 // Try CAS authentication if it's enabled and we don't have a
369 // successful login yet.
370 if ( $auth_settings['cas'] === '1' && count( $externally_authenticated_emails ) === 0 ) {
371 $result = $this->custom_authenticate_cas( $auth_settings );
372 if ( ! is_wp_error( $result ) ) {
373 if ( is_array( $result['email'] ) ) {
374 $externally_authenticated_emails = $result['email'];
375 } else {
376 $externally_authenticated_emails[] = $result['email'];
377 }
378 $authenticated_by = $result['authenticated_by'];
379 }
380 }
381
382 // Try LDAP authentication if it's enabled and we don't have an
383 // authenticated user yet.
384 if ( $auth_settings['ldap'] === '1' && count( $externally_authenticated_emails ) === 0 ) {
385 $result = $this->custom_authenticate_ldap( $auth_settings, $username, $password );
386 if ( ! is_wp_error( $result ) ) {
387 if ( is_array( $result['email'] ) ) {
388 $externally_authenticated_emails = $result['email'];
389 } else {
390 $externally_authenticated_emails[] = $result['email'];
391 }
392 $authenticated_by = $result['authenticated_by'];
393 }
394 }
395
396 // Skip to WordPress authentication if we don't have an externally
397 // authenticated user.
398 if ( count( array_filter( $externally_authenticated_emails ) ) < 1 ) {
399 return null;
400 }
401
402 // Remove duplicate and blank emails, if any.
403 $externally_authenticated_emails = array_filter( array_unique( $externally_authenticated_emails ) );
404
405 // If we've made it this far, we should have an externally
406 // authenticated user. The following should be set:
407 // $externally_authenticated_emails
408 // $authenticated_by
409
410 // Get the external user's WordPress account by email address.
411 foreach ( $externally_authenticated_emails as $externally_authenticated_email ) {
412 $user = get_user_by( 'email', $externally_authenticated_email );
413
414 // If we've already found a WordPress user associated with one
415 // of the supplied email addresses, don't keep examining other
416 // email addresses associated with the externally authenticated user.
417 if ( $user !== FALSE ) {
418 break;
419 }
420 }
421
422 // Check this external user's access against the access lists
423 // (pending, approved, blocked)
424 $result = $this->check_user_access( $user, $externally_authenticated_emails, $result );
425
426 // Fail with message if there was an error creating/adding the user.
427 if ( is_wp_error( $result ) || $result === 0 ) {
428 return $result;
429 }
430
431 // If we created a new user in check_user_access(), log that user in.
432 if ( get_class( $result ) === 'WP_User' ) {
433 $user = $result;
434 }
435
436 // We'll track how this user was authenticated in user meta.
437 if ( $user ) {
438 update_user_meta( $user->ID, 'authenticated_by', $authenticated_by );
439 }
440
441 // If we haven't exited yet, we have a valid/approved user, so authenticate them.
442 return $user;
443 } // END custom_authenticate()
444
445
446 /**
447 * This function will fail with a wp_die() message to the user if they
448 * don't have access.
449 *
450 * @param WP_User $user User to check
451 * @param [type] $user_emails Array of user's plaintext emails (in case current user doesn't have a WP account)
452 * @param [type] $user_data Array of keys for email(s), username, first_name, last_name, and authenticated_by
453 * @return WP_Error if there was an error on user creation / adding user to blog
454 * wp_die() if user does not have access
455 * null if user has access (success)
456 * WP_User if user has access and a new account was created for them
457 */
458 private function check_user_access( $user, $user_emails, $user_data = array() ) {
459 // Grab plugin settings.
460 $auth_settings = $this->get_plugin_options( 'single admin', 'allow override' );
461 $auth_settings_access_users_pending = $this->sanitize_user_list(
462 $this->get_plugin_option( 'access_users_pending', 'single admin' )
463 );
464 $auth_settings_access_users_approved = $this->sanitize_user_list(
465 array_merge(
466 $this->get_plugin_option( 'access_users_approved', 'single admin' ),
467 $this->get_plugin_option( 'access_users_approved', 'multisite admin' )
468 )
469 );
470
471 // Check our externally authenticated user against the block list.
472 // If they are blocked, set the relevant user meta field, and show
473 // them an error screen.
474 foreach ( $user_emails as $user_email ) {
475 if ( $this->is_email_in_list( $user_email, 'blocked' ) ) {
476 // If the blocked external user has a WordPress account, change
477 // its password and mark it as blocked.
478 if ( $user ) {
479 // Mark user as blocked (enforce block in this->authenticate()).
480 update_user_meta( $user->ID, 'auth_blocked', 'yes' );
481 }
482
483 // Notify user about blocked status and return without authenticating them.
484 $redirect_to = ! empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : home_url();
485 $page_title = get_bloginfo( 'name' ) . ' - Access Restricted';
486 $error_message = apply_filters( 'the_content', $auth_settings['access_blocked_redirect_to_message'] );
487 $error_message .= '<hr /><p style="text-align: center;"><a class="button" href="' . wp_logout_url( $redirect_to ) . '">Back</a></p>';
488 update_option( 'auth_settings_advanced_login_error', $error_message );
489 wp_die( $error_message, $page_title );
490 }
491 }
492
493 // If this externally authenticated user isn't in the approved list
494 // and login access is set to "All authenticated users," add them
495 // to the approved list (they'll get an account created below if
496 // they don't have one yet).
497 $last_email = end( $user_emails );
498 reset( $user_emails );
499 foreach ( $user_emails as $user_email ) {
500 $is_newly_approved_user = false;
501 if ( ! $this->is_email_in_list( $user_email, 'approved' ) && $auth_settings['access_who_can_login'] === 'external_users' ) {
502 $is_newly_approved_user = true;
503
504 // If this user happens to be in the pending list (rare),
505 // remove them from pending before adding them to approved.
506 if ( $this->is_email_in_list( $user_email, 'pending' ) ) {
507 foreach ( $auth_settings_access_users_pending as $key => $pending_user ) {
508 if ( $pending_user['email'] === $user_email ) {
509 unset( $auth_settings_access_users_pending[ $key ] );
510 update_option( 'auth_settings_access_users_pending', $auth_settings_access_users_pending );
511 break;
512 }
513 }
514 }
515
516 // Add this user to the approved list.
517 $approved_role = $user && is_array( $user->roles ) && count( $user->roles ) > 0 ? $user->roles[0] : $auth_settings['access_default_role'];
518 $approved_user = array(
519 'email' => $user_email,
520 'role' => $approved_role,
521 'date_added' => date( "Y-m-d H:i:s" ),
522 );
523 array_push( $auth_settings_access_users_approved, $approved_user );
524 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
525 }
526
527 // Check our externally authenticated user against the approved
528 // list. If they are approved, log them in (and create their account
529 // if necessary)
530 if ( $is_newly_approved_user || $this->is_email_in_list( $user_email, 'approved' ) ) {
531 $user_info = $is_newly_approved_user ? $approved_user : $this->get_user_info_from_list( $user_email, $auth_settings_access_users_approved );
532
533 // If the approved external user does not have a WordPress account, create it
534 if ( ! $user ) {
535 // If there's already a user with this username (e.g.,
536 // johndoe/johndoe@gmail.com exists, and we're trying to add
537 // johndoe/johndoe@example.com), use the full email address
538 // as the username.
539 if ( array_key_exists( 'username', $user_data ) ) {
540 $username = $user_data['username'];
541 } else {
542 $username = explode( '@', $user_info['email'] );
543 $username = $username[0];
544 }
545 if ( get_user_by( 'login', $username ) !== false ) {
546 $username = $approved_user['email'];
547 }
548 $result = wp_insert_user(
549 array(
550 'user_login' => strtolower( $username ),
551 'user_pass' => wp_generate_password(), // random password
552 'first_name' => array_key_exists( 'first_name', $user_data ) ? $user_data['first_name'] : '',
553 'last_name' => array_key_exists( 'last_name', $user_data ) ? $user_data['last_name'] : '',
554 'user_email' => strtolower( $user_info['email'] ),
555 'user_registered' => date( 'Y-m-d H:i:s' ),
556 'role' => $user_info['role'],
557 )
558 );
559
560 // Fail with message if error.
561 if ( is_wp_error( $result ) || $result === 0 ) {
562 return $result;
563 }
564
565 // Authenticate as new user
566 $user = new WP_User( $result );
567
568 // Check if this new user has any preassigned usermeta
569 // values in their approved list entry, and apply them to
570 // their new WordPress account.
571 if ( array_key_exists( 'usermeta', $user_info ) && is_array( $user_info['usermeta'] ) ) {
572 $meta_key = $this->get_plugin_option( 'advanced_usermeta' );
573
574 if ( array_key_exists( 'meta_key', $user_info['usermeta'] ) && array_key_exists( 'meta_value', $user_info['usermeta'] ) ) {
575 // Only update the usermeta if the stored value matches
576 // the option set in authorizer settings (if they don't
577 // match it's probably old data).
578 if ( $meta_key === $user_info['usermeta']['meta_key'] ) {
579 // Update user's usermeta value for usermeta key stored in authorizer options.
580 if ( strpos( $meta_key, 'acf___' ) === 0 && class_exists( 'acf' ) ) {
581 // We have an ACF field value, so use the ACF function to update it.
582 update_field( str_replace('acf___', '', $meta_key ), $user_info['usermeta']['meta_value'], 'user_' . $user->ID );
583 } else {
584 // We have a normal usermeta value, so just update it via the WordPress function.
585 update_user_meta( $user->ID, $meta_key, $user_info['usermeta']['meta_value'] );
586 }
587 }
588 } elseif ( is_multisite() && count( $user_info['usermeta'] ) > 0 ) {
589 // Update usermeta for each multisite blog defined for this user.
590 foreach ( $user_info['usermeta'] as $blog_id => $usermeta ) {
591 if ( array_key_exists( 'meta_key', $usermeta ) && array_key_exists( 'meta_value', $usermeta ) ) {
592 // 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).
593 if ( ! is_user_member_of_blog( $user->ID, $blog_id ) ) {
594 add_user_to_blog( $blog_id, $user->ID, $user_info['role'] );
595 }
596 switch_to_blog( $blog_id );
597 // Update user's usermeta value for usermeta key stored in authorizer options.
598 if ( strpos( $meta_key, 'acf___' ) === 0 && class_exists( 'acf' ) ) {
599 // We have an ACF field value, so use the ACF function to update it.
600 update_field( str_replace('acf___', '', $meta_key ), $usermeta['meta_value'], 'user_' . $user->ID );
601 } else {
602 // We have a normal usermeta value, so just update it via the WordPress function.
603 update_user_meta( $user->ID, $meta_key, $usermeta['meta_value'] );
604 }
605 restore_current_blog();
606 }
607 }
608 }
609 }
610 } else {
611 // Update first/last names of WordPress user from external
612 // service if that option is set.
613 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 ) ) {
614 if ( array_key_exists( 'first_name', $user_data ) && strlen( $user_data['first_name'] ) > 0 ) {
615 wp_update_user( array(
616 'ID' => $user->ID,
617 'first_name' => $user_data['first_name'],
618 ));
619 }
620 if ( array_key_exists( 'last_name', $user_data ) && strlen( $user_data['last_name'] ) > 0 ) {
621 wp_update_user( array(
622 'ID' => $user->ID,
623 'last_name' => $user_data['last_name'],
624 ));
625 }
626 }
627 }
628
629 // If this is multisite, add new user to current blog.
630 if ( is_multisite() && ! is_user_member_of_blog( $user->ID ) ) {
631 $result = add_user_to_blog( get_current_blog_id(), $user->ID, $user_info['role'] );
632
633 // Fail with message if error.
634 if ( is_wp_error( $result ) ) {
635 return $result;
636 }
637 }
638
639 // Ensure user has the same role as their entry in the approved list.
640 // (This is just a precaution, the role should already be set when
641 // saving admin options in the sanitizing function.)
642 if ( $user_info && ! array_key_exists( $user_info['role'], $user->roles ) ) {
643 $user->set_role( $user_info['role'] );
644 }
645
646 return $user;
647
648 } elseif ( $user && in_array( 'administrator', $user->roles ) ) {
649 // User has a WordPress account, but is not in the blocked or approved
650 // list. If they are an administrator, let them in.
651 return;
652
653 // Note: only do this for the last email address we are checking (we need
654 // to iterate through them all to make sure one of them isn't approved).
655 } elseif ( $user_email === $last_email ) {
656 // User isn't an admin, is not blocked, and is not approved.
657 // Add them to the pending list and notify them and their instructor.
658 if ( strlen( $user_email ) > 0 && ! $this->is_email_in_list( $user_email, 'pending' ) ) {
659 $pending_user = array();
660 $pending_user['email'] = $user_email;
661 $pending_user['role'] = $auth_settings['access_default_role'];
662 $pending_user['date_added'] = '';
663 array_push( $auth_settings_access_users_pending, $pending_user );
664 update_option( 'auth_settings_access_users_pending', $auth_settings_access_users_pending );
665
666 // Create strings used in the email notification.
667 $site_name = get_bloginfo( 'name' );
668 $site_url = get_bloginfo( 'url' );
669 $authorizer_options_url = $auth_settings['advanced_admin_menu'] === 'settings' ? admin_url( 'options-general.php?page=authorizer' ) : admin_url( '?page=authorizer' );
670
671 // Notify instructor about new pending user if that option is set.
672 foreach ( get_users( array( 'role' => $auth_settings['access_role_receive_pending_emails'] ) ) as $user_recipient ) {
673 wp_mail(
674 $user_recipient->user_email,
675 "Action required: Pending user {$pending_user['email']} at $site_name",
676 "A new user has tried to access the $site_name site you manage at:\n$site_url\n\n" .
677 "Please log in to approve or deny their request:\n$authorizer_options_url\n"
678 );
679 }
680 }
681
682 // Notify user about pending status and return without authenticating them.
683 $redirect_to = ! empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : home_url();
684 $page_title = get_bloginfo( 'name' ) . ' - Access Pending';
685 $error_message = apply_filters( 'the_content', $auth_settings['access_pending_redirect_to_message'] );
686 $error_message .= '<hr /><p style="text-align: center;"><a class="button" href="' . wp_logout_url( $redirect_to ) . '">Back</a></p>';
687 update_option( 'auth_settings_advanced_login_error', $error_message );
688 wp_die( $error_message, $page_title );
689 }
690 }
691
692 // Sanity check: if we made it here without returning, something has gone wrong.
693 return new WP_Error( 'invalid_login', 'Invalid login attempted.' );
694
695 } // END check_user_access()
696
697
698 /**
699 * Verify the Google login and set a session token.
700 *
701 * Flow: "Sign in with Google" button clicked; JS Google library
702 * called; JS function signInCallback() fired with results from Google;
703 * signInCallback() posts code and nonce (via AJAX) to this function;
704 * This function checks the token using the Google PHP library, and
705 * saves it to a session variable if it's authentic; control passes
706 * back to signInCallback(), which will reload the current page
707 * (wp-login.php) on success; wp-login.php reloads; custom_authenticate
708 * hooked into authenticate action fires again, and
709 * custom_authenticate_google() runs to verify the token; once verified
710 * custom_authenticate proceeds as normal with the google email address
711 * as a successfully authenticated external user.
712 *
713 * @return void, but die with the value to return to the success() function in AJAX call signInCallback()
714 */
715 function ajax_process_google_login() {
716 $nonce = array_key_exists( 'nonce', $_POST ) ? $_POST['nonce'] : '';
717 $code = array_key_exists( 'code', $_POST ) ? $_POST['code'] : null;
718
719 // Nonce check.
720 if ( ! wp_verify_nonce( $nonce, 'google_csrf_nonce' ) ) {
721 return '';
722 }
723
724 // Grab plugin settings.
725 $auth_settings = $this->get_plugin_options( 'single admin', 'allow override' );
726
727 // Build the Google Client.
728 $client = new Google_Client();
729 $client->setApplicationName( 'WordPress' );
730 $client->setClientId( $auth_settings['google_clientid'] );
731 $client->setClientSecret( $auth_settings['google_clientsecret'] );
732 $client->setRedirectUri( 'postmessage' );
733
734 // Get one time use token (if it doesn't exist, we'll create one below)
735 session_start();
736 $token = array_key_exists( 'token', $_SESSION ) ? json_decode( $_SESSION['token'] ) : null;
737
738 if ( empty( $token ) ) {
739 // Exchange the OAuth 2.0 authorization code for user credentials.
740 $client->authenticate( $code );
741 $token = json_decode( $client->getAccessToken() );
742
743 // Store the token in the session for later use.
744 $_SESSION['token'] = json_encode( $token );
745
746 $response = "Successfully authenticated.";
747 } else {
748 $client->setAccessToken( json_encode( $token ) );
749
750 $response = 'Already authenticated.';
751 }
752
753 die( $response );
754 } // END ajax_process_google_login()
755
756
757 /**
758 * Validate this user's credentials against Google.
759 *
760 * @param array $auth_settings Plugin settings
761 * @return [mixed] Array containing email, authenticated_by,
762 * first_name, last_name, and username
763 * strings for the successfully authenticated
764 * user, or WP_Error() object on failure.
765 */
766 private function custom_authenticate_google( $auth_settings ) {
767 // Get one time use token
768 session_start();
769 $token = array_key_exists( 'token', $_SESSION ) ? json_decode( $_SESSION['token'] ) : null;
770
771 // No token, so this is not a succesful Google login.
772 if ( is_null( $token ) ) {
773 return new WP_Error( 'no_google_login', 'No Google credentials provided.' );
774 }
775
776 // Build the Google Client.
777 $client = new Google_Client();
778 $client->setApplicationName( 'WordPress' );
779 $client->setClientId( $auth_settings['google_clientid'] );
780 $client->setClientSecret( $auth_settings['google_clientsecret'] );
781 $client->setRedirectUri( 'postmessage' );
782
783 // Verify this is a successful Google authentication
784 $ticket = $client->verifyIdToken( $token->id_token, $auth_settings['google_clientid'] );
785
786 // Invalid ticket, so this in not a successful Google login.
787 if ( ! $ticket ) {
788 return new WP_Error( 'invalid_google_login', 'Invalid Google credentials provided.' );
789 }
790
791 // Get email address
792 $attributes = $ticket->getAttributes();
793 $email = $attributes['payload']['email'];
794 $username = current( explode( '@', $email ) );
795
796 return array(
797 'email' => $email,
798 'username' => $username,
799 'first_name' => '',
800 'last_name' => '',
801 'authenticated_by' => 'google',
802 );
803 } // END custom_authenticate_google()
804
805
806 /**
807 * Validate this user's credentials against CAS.
808 *
809 * @param array $auth_settings Plugin settings
810 * @return [mixed] Array containing 'email' and 'authenticated_by'
811 * strings for the successfully authenticated
812 * user, or WP_Error() object on failure.
813 */
814 private function custom_authenticate_cas( $auth_settings ) {
815 // Move on if CAS hasn't been requested here.
816 if ( empty( $_GET['external'] ) || $_GET['external'] !== 'cas' ) {
817 return new WP_Error( 'cas_not_available', 'CAS is not enabled.' );
818 }
819
820 // Set the CAS client configuration
821 phpCAS::client( SAML_VERSION_1_1, $auth_settings['cas_host'], intval( $auth_settings['cas_port'] ), $auth_settings['cas_path'] );
822
823 // Update server certificate bundle if it doesn't exist or is older
824 // than 3 months, then use it to ensure CAS server is legitimate.
825 $cacert_path = plugin_dir_path( __FILE__ ) . 'inc/cacert.pem';
826 $time_90_days = 90 * 24 * 60 * 60; // days * hours * minutes * seconds
827 $time_90_days_ago = time() - $time_90_days;
828 if ( ! file_exists( $cacert_path ) || filemtime( $cacert_path ) < $time_90_days_ago ) {
829 $cacert_contents = file_get_contents( 'http://curl.haxx.se/ca/cacert.pem' );
830 if ( $cacert_contents !== false ) {
831 file_put_contents( $cacert_path, $cacert_contents );
832 } else {
833 return new WP_Error( 'cannot_update_cacert', 'Unable to update outdated server certificates from http://curl.haxx.se/ca/cacert.pem.' );
834 }
835 }
836 phpCAS::setCasServerCACert( $cacert_path );
837
838 // Authenticate against CAS
839 try {
840 if ( ! phpCAS::isAuthenticated() && ! phpCAS::checkAuthentication() ) {
841 phpCAS::forceAuthentication();
842 die();
843 }
844 } catch ( CAS_AuthenticationException $e ) {
845 error_log( 'CAS server returned an Authentication Exception. Details:' );
846 error_log( print_r( $e, true ) );
847 wp_die( 'CAS server returned an Authentication Exception. Details:' . print_r( $e, true ), 'Authentication Exception' );
848 }
849
850 // Get the TLD from the CAS host for use in matching email addresses
851 // For example: example.edu is the TLD for authn.example.edu, so user
852 // 'bob' will have the following email address: bob@example.edu.
853 $tld = preg_match( '/[^.]*\.[^.]*$/', $auth_settings['cas_host'], $matches ) === 1 ? $matches[0] : '';
854
855 // Get username that successfully authenticated against the external service (CAS).
856 $externally_authenticated_email = strtolower( phpCAS::getUser() ) . '@' . $tld;
857
858 // Retrieve the user attributes (e.g., email address, first name, last name) from the CAS server.
859 $cas_attributes = phpCAS::getAttributes();
860
861 // If a CAS attribute has been specified as containing the email address, use that instead.
862 // Email attribute can be a string or an array of strings.
863 if (
864 array_key_exists( 'cas_attr_email', $auth_settings ) &&
865 strlen( $auth_settings['cas_attr_email'] ) > 0 &&
866 array_key_exists( $auth_settings['cas_attr_email'], $cas_attributes ) && (
867 (
868 is_array( $cas_attributes[$auth_settings['cas_attr_email']] ) &&
869 count( $cas_attributes[$auth_settings['cas_attr_email']] ) > 0
870 ) || (
871 is_string( $cas_attributes[$auth_settings['cas_attr_email']] ) &&
872 strlen( $cas_attributes[$auth_settings['cas_attr_email']] ) > 0
873 )
874 )
875 ) {
876 $externally_authenticated_email = $cas_attributes[$auth_settings['cas_attr_email']];
877 }
878
879 // Get username (as specified by the CAS server).
880 $username = phpCAS::getUser();
881
882 // Get user first name and last name.
883 $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']] : '';
884 $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']] : '';
885
886 return array(
887 'email' => $externally_authenticated_email,
888 'username' => $username,
889 'first_name' => $first_name,
890 'last_name' => $last_name,
891 'authenticated_by' => 'cas',
892 );
893 } // END custom_authenticate_cas()
894
895
896 /**
897 * Validate this user's credentials against LDAP.
898 *
899 * @param array $auth_settings Plugin settings
900 * @param string $username Attempted username from authenticate action
901 * @param string $password Attempted password from authenticate action
902 * @return [mixed] Array containing 'email' and 'authenticated_by'
903 * strings for the successfully authenticated
904 * user, or WP_Error() object on failure.
905 */
906 private function custom_authenticate_ldap( $auth_settings, $username, $password ) {
907 // Get the TLD from the LDAP host for use in matching email addresses
908 // For example: example.edu is the TLD for ldap.example.edu, so user
909 // 'bob' will have the following email address: bob@example.edu.
910 $tld = preg_match( '/[^.]*\.[^.]*$/', $auth_settings['ldap_host'], $matches ) === 1 ? $matches[0] : '';
911
912 // remove top level domain if it exists in the username (i.e., if user entered their email)
913 $username = str_replace( '@' . $tld, '', $username );
914
915 // Fail with error message if username or password is blank.
916 if ( empty( $username ) ) {
917 return null;
918 }
919 if ( empty( $password ) ) {
920 return new WP_Error( 'empty_password', 'You must provide a password.' );
921 }
922
923 // Make sure php5-ldap extension is installed on server.
924 if ( ! function_exists( 'ldap_connect' ) ) {
925 // Note: this error message won't get shown to the user because
926 // authenticate will fall back to WP auth when this fails.
927 return new WP_Error( 'ldap_not_installed', 'LDAP logins are disabled because this server does not support them.' );
928 }
929
930 // Authenticate against LDAP using options provided in plugin settings.
931 $result = false;
932 $ldap_user_dn = '';
933 $first_name = '';
934 $last_name = '';
935 $email = '';
936
937 // Establish LDAP connection.
938 $ldap = ldap_connect( $auth_settings['ldap_host'], $auth_settings['ldap_port'] );
939 ldap_set_option( $ldap, LDAP_OPT_PROTOCOL_VERSION, 3 );
940 if ( $auth_settings['ldap_tls'] == 1 ) {
941 ldap_start_tls( $ldap );
942 }
943
944 // Set bind credentials; attempt an anonymous bind if not provided.
945 $bind_rdn = NULL;
946 $bind_password = NULL;
947 if ( strlen( $auth_settings['ldap_user'] ) > 0 ) {
948 $bind_rdn = $auth_settings['ldap_user'];
949 $bind_password = $this->decrypt( base64_decode( $auth_settings['ldap_password'] ) );
950 }
951
952 // Attempt LDAP bind.
953 $result = @ldap_bind( $ldap, $bind_rdn, $bind_password );
954 if ( ! $result ) {
955 // Can't connect to LDAP, so fall back to WordPress authentication.
956 return new WP_Error( 'ldap_error', 'Could not authenticate using LDAP.' );
957 }
958 // Look up the bind DN (and first/last name) of the user trying to
959 // log in by performing an LDAP search for the login username in
960 // the field specified in the LDAP settings. This setup is common.
961 $ldap_attributes_to_retrieve = array( 'dn' );
962 if ( array_key_exists( 'ldap_attr_first_name', $auth_settings ) && strlen( $auth_settings['ldap_attr_first_name'] ) > 0 ) {
963 array_push( $ldap_attributes_to_retrieve, $auth_settings['ldap_attr_first_name'] );
964 }
965 if ( array_key_exists( 'ldap_attr_last_name', $auth_settings ) && strlen( $auth_settings['ldap_attr_last_name'] ) > 0 ) {
966 array_push( $ldap_attributes_to_retrieve, $auth_settings['ldap_attr_last_name'] );
967 }
968 if ( array_key_exists( 'ldap_attr_email', $auth_settings ) && strlen( $auth_settings['ldap_attr_email'] ) > 0 ) {
969 array_push( $ldap_attributes_to_retrieve, $auth_settings['ldap_attr_email'] );
970 }
971 $ldap_search = ldap_search(
972 $ldap,
973 $auth_settings['ldap_search_base'],
974 "(" . $auth_settings['ldap_uid'] . "=" . $username . ")",
975 $ldap_attributes_to_retrieve
976 );
977 $ldap_entries = ldap_get_entries( $ldap, $ldap_search );
978
979 // If we didn't find any users in ldap, exit with error (rely on default wordpress authentication)
980 if ( $ldap_entries['count'] < 1 ) {
981 return new WP_Error( 'no_ldap', 'No LDAP user found.' );
982 }
983
984 // Get the bind dn and first/last names; if there are multiple results returned, just get the last one.
985 for ( $i = 0; $i < $ldap_entries['count']; $i++ ) {
986 $ldap_user_dn = $ldap_entries[$i]['dn'];
987
988 // Get user first name and last name.
989 if ( array_key_exists( 'ldap_attr_first_name', $auth_settings ) && strlen( $auth_settings['ldap_attr_first_name'] ) > 0 && array_key_exists( $auth_settings['ldap_attr_first_name'], $ldap_entries[$i] ) && $ldap_entries[$i][$auth_settings['ldap_attr_first_name']]['count'] > 0 && strlen( $ldap_entries[$i][$auth_settings['ldap_attr_first_name']][0] ) > 0 ) {
990 $first_name = $ldap_entries[$i][$auth_settings['ldap_attr_first_name']][0];
991 }
992 if ( array_key_exists( 'ldap_attr_last_name', $auth_settings ) && strlen( $auth_settings['ldap_attr_last_name'] ) > 0 && array_key_exists( $auth_settings['ldap_attr_last_name'], $ldap_entries[$i] ) && $ldap_entries[$i][$auth_settings['ldap_attr_last_name']]['count'] > 0 && strlen( $ldap_entries[$i][$auth_settings['ldap_attr_last_name']][0] ) > 0 ) {
993 $last_name = $ldap_entries[$i][$auth_settings['ldap_attr_last_name']][0];
994 }
995 // Get user email if it is specified in another field.
996 if ( array_key_exists( 'ldap_attr_email', $auth_settings ) && strlen( $auth_settings['ldap_attr_email'] ) > 0 && array_key_exists( $auth_settings['ldap_attr_email'], $ldap_entries[$i] ) && $ldap_entries[$i][$auth_settings['ldap_attr_email']]['count'] > 0 && strlen( $ldap_entries[$i][$auth_settings['ldap_attr_email']][0] ) > 0 ) {
997 $email = $ldap_entries[$i][$auth_settings['ldap_attr_email']][0];
998 }
999 }
1000
1001 $result = @ldap_bind( $ldap, $ldap_user_dn, $password );
1002 if ( ! $result ) {
1003 // We have a real ldap user, but an invalid password. Pass
1004 // through to wp authentication after failing LDAP (since
1005 // this could be a local account that happens to be the
1006 // same name as an LDAP user).
1007 return new WP_Error( 'using_wp_authentication', 'Moving on to WordPress authentication...' );
1008 }
1009
1010 // User successfully authenticated against LDAP, so set the relevant variables.
1011 $externally_authenticated_email = $username . '@' . $tld;
1012
1013 // If an LDAP attribute has been specified as containing the email address, use that instead.
1014 if ( strlen( $email ) > 0 ) {
1015 $externally_authenticated_email = $email;
1016 }
1017
1018 return array(
1019 'email' => $externally_authenticated_email,
1020 'username' => $username,
1021 'first_name' => $first_name,
1022 'last_name' => $last_name,
1023 'authenticated_by' => 'ldap',
1024 );
1025 } // END custom_authenticate_ldap()
1026
1027
1028 /**
1029 * Log out of the attached external service.
1030 *
1031 * @return void
1032 */
1033 public function custom_logout() {
1034 // Grab plugin settings.
1035 $auth_settings = $this->get_plugin_options( 'single admin', 'allow override' );
1036
1037 // Reset option containing old error messages.
1038 delete_option( 'auth_settings_advanced_login_error' );
1039
1040 if ( session_id() == '' ) {
1041 session_start();
1042 }
1043
1044 $current_user_authenticated_by = get_user_meta( get_current_user_id(), 'authenticated_by', true );
1045
1046 // If logged in to CAS, Log out of CAS.
1047 if ( $current_user_authenticated_by === 'cas' && $auth_settings['cas'] === '1' ) {
1048 if ( ! array_key_exists( 'PHPCAS_CLIENT', $GLOBALS ) || ! array_key_exists( 'phpCAS', $_SESSION ) ) {
1049 // Set the CAS client configuration if it hasn't been set already.
1050 phpCAS::client( SAML_VERSION_1_1, $auth_settings['cas_host'], intval( $auth_settings['cas_port'] ), $auth_settings['cas_path'] );
1051 // Restrict logout request origin to the CAS server only (prevent DDOS).
1052 phpCAS::handleLogoutRequests( true, array( $auth_settings['cas_host'] ) );
1053 }
1054 if ( phpCAS::isAuthenticated() ) {
1055 phpCAS::logoutWithRedirectService( get_option( 'siteurl' ) );
1056 }
1057 }
1058
1059 // If session token set, log out of Google.
1060 if ( $current_user_authenticated_by === 'google' && array_key_exists( 'token', $_SESSION ) ) {
1061 $token = json_decode( $_SESSION['token'] )->access_token;
1062
1063 // Build the Google Client.
1064 $client = new Google_Client();
1065 $client->setApplicationName( 'WordPress' );
1066 $client->setClientId( $auth_settings['google_clientid'] );
1067 $client->setClientSecret( $auth_settings['google_clientsecret'] );
1068 $client->setRedirectUri( 'postmessage' );
1069
1070 // Revoke the token
1071 $client->revokeToken( $token );
1072
1073 // Remove the credentials from the user's session.
1074 $_SESSION['token'] = '';
1075 }
1076
1077 } // END custom_logout()
1078
1079
1080
1081 /**
1082 * ***************************
1083 * Access Restriction
1084 * ***************************
1085 */
1086
1087
1088
1089 /**
1090 * Restrict access to WordPress site based on settings (everyone, logged_in_users).
1091 * Hook: parse_request http://codex.wordpress.org/Plugin_API/Action_Reference/parse_request
1092 *
1093 * @param array $wp WordPress object.
1094 *
1095 * @return void
1096 */
1097 public function restrict_access( $wp ) {
1098 remove_action( 'parse_request', array( $this, 'restrict_access' ), 20 ); // only need it the first time
1099
1100 // Grab plugin settings.
1101 $auth_settings = $this->get_plugin_options( 'single admin', 'allow override' );
1102
1103 // Grab current user.
1104 $current_user = wp_get_current_user();
1105
1106 $has_access = (
1107 // Always allow access if WordPress is installing
1108 ( defined( 'WP_INSTALLING' ) && isset( $_GET['key'] ) ) ||
1109 // Always allow access to admins
1110 ( current_user_can( 'create_users' ) ) ||
1111 // Allow access if option is set to 'everyone'
1112 ( $auth_settings['access_who_can_view'] == 'everyone' ) ||
1113 // Allow access to approved external users and logged in users if option is set to 'logged_in_users'
1114 ( $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' ) )
1115 );
1116
1117 /**
1118 * Developers can use the `authorizer_has_access` filter
1119 * to override restricted access on certain pages. Note that the
1120 * restriction checks happens before WordPress executes any queries, so
1121 * use the global `$wp` variable to investigate what the visitor is
1122 * trying to load.
1123 *
1124 * For example, to unblock an RSS feed, place the following PHP code in
1125 * the theme's functions.php file or in a simple plug-in:
1126 *
1127 * function my_rsa_feed_access_override( $has_access ) {
1128 * global $wp;
1129 * // check query variables to see if this is the feed
1130 * if ( ! empty( $wp->query_vars['feed'] ) )
1131 * $has_access = true;
1132 * return $has_access;
1133 * }
1134 * add_filter( 'authorizer_has_access', 'my_rsa_feed_access_override' );
1135 */
1136 if ( apply_filters( 'authorizer_has_access', $has_access, $wp ) === true ) {
1137 // Turn off the public notice about browsing anonymously
1138 update_option( 'auth_settings_advanced_public_notice', false );
1139
1140 // We've determined that the current user has access, so simply return to grant access.
1141 return $wp;
1142 }
1143
1144 // We've determined that the current user doesn't have access, so we deal with them now.
1145
1146 // Fringe case: In a multisite, a user of a different blog can
1147 // successfully log in, but they aren't on the 'approved' whitelist
1148 // for this blog. Flag these users, and redirect them to their
1149 // profile page with a message (so we don't get into a redirect
1150 // loop on the wp-login.php page).
1151 if ( is_multisite() && is_user_logged_in() && ! $has_access ) {
1152 $current_user = wp_get_current_user();
1153
1154 // Check user access; block if not, add them to pending list if open, let them through otherwise.
1155 $result = $this->check_user_access( $current_user, array( $current_user->user_email ) );
1156 }
1157
1158 // Check to see if the requested page is public. If so, show it.
1159 $current_page_name = property_exists( $wp, 'query_vars' ) && array_key_exists( 'name', $wp->query_vars ) && strlen( $wp->query_vars['name'] ) > 0 ? $wp->query_vars['name'] : '';
1160 if ( ! $current_page_name ) {
1161 // Different WordPress versions store the page slug in different places; look for it elsewhere.
1162 if ( property_exists( $wp, 'query_vars' ) && array_key_exists( 'pagename', $wp->query_vars ) && strlen( $wp->query_vars['pagename'] ) > 0 ) {
1163 $current_page_name = $wp->query_vars['pagename'];
1164 }
1165 }
1166 $current_page_id = empty( $wp->request ) ? 'home' : $this->get_id_from_pagename( $current_page_name );
1167 if ( ! is_array( $auth_settings['access_public_pages'] ) ) {
1168 $auth_settings['access_public_pages'] = array();
1169 }
1170 if ( in_array( $current_page_id, $auth_settings['access_public_pages'] ) ) {
1171 if ( $auth_settings['access_public_warning'] === 'no_warning' ) {
1172 update_option( 'auth_settings_advanced_public_notice', false );
1173 } else {
1174 update_option( 'auth_settings_advanced_public_notice', true );
1175 }
1176 return $wp;
1177 }
1178
1179 // Check to see if any category assigned to the requested page is public. If so, show it.
1180 $current_page_categories = wp_get_post_categories( $current_page_id, array( 'fields' => 'slugs' ) );
1181 foreach( $current_page_categories as $current_page_category ) {
1182 if ( in_array( 'cat_' . $current_page_category, $auth_settings['access_public_pages'] ) ) {
1183 if ( $auth_settings['access_public_warning'] === 'no_warning' ) {
1184 update_option( 'auth_settings_advanced_public_notice', false );
1185 } else {
1186 update_option( 'auth_settings_advanced_public_notice', true );
1187 }
1188 return $wp;
1189 }
1190 }
1191
1192 $current_path = empty( $_SERVER['REQUEST_URI'] ) ? home_url() : $_SERVER['REQUEST_URI'];
1193 if ( $auth_settings['access_redirect'] === 'message' ) {
1194 $page_title = get_bloginfo( 'name' ) . ' - Access Restricted';
1195 $error_message = apply_filters( 'the_content', $auth_settings['access_redirect_to_message'] );
1196 $error_message .= '<hr /><p style="text-align:center;margin-bottom:-15px;"><a class="button" href="' . wp_login_url( $current_path ) . '">Log In</a></p>';
1197 wp_die( $error_message, $page_title );
1198 } else { // if ( $auth_settings['access_redirect'] === 'login' ) {
1199 wp_redirect( wp_login_url( $current_path ), 302 );
1200 exit;
1201 }
1202
1203 // Sanity check: we should never get here
1204 wp_die( '<p>Access denied.</p>', 'Site Access Restricted' );
1205 } // END restrict_access()
1206
1207
1208
1209 /**
1210 * ***************************
1211 * Login page (wp-login.php)
1212 * ***************************
1213 */
1214
1215
1216
1217 /**
1218 * Add custom error message to login screen.
1219 * Filter: login_errors
1220 */
1221 function show_advanced_login_error( $errors ) {
1222 $error = get_option( 'auth_settings_advanced_login_error' );
1223 delete_option( 'auth_settings_advanced_login_error' );
1224
1225 //$errors .= ' ' . $error . "<br />\n";
1226 $errors = ' ' . $error . "<br />\n";
1227 return $errors;
1228 } // END show_advance_login_error()
1229
1230
1231 /**
1232 * Load external resources for the public-facing site.
1233 */
1234 function auth_public_scripts() {
1235 // Load (and localize) public scripts
1236 $current_path = empty( $_SERVER['REQUEST_URI'] ) ? home_url() : $_SERVER['REQUEST_URI'];
1237 wp_enqueue_script( 'auth_public_scripts', plugins_url( '/js/authorizer-public.js', __FILE__ ), array(), '2.3.2' );
1238 $auth_localized = array(
1239 'wp_login_url' => wp_login_url( $current_path ),
1240 'public_warning' => get_option( 'auth_settings_advanced_public_notice' )
1241 );
1242 wp_localize_script( 'auth_public_scripts', 'auth', $auth_localized );
1243 //update_option( 'auth_settings_advanced_public_notice', false);
1244
1245 // Load public css
1246 wp_register_style( 'authorizer-public-css', plugins_url( 'css/authorizer-public.css', __FILE__ ), array(), '2.3.2' );
1247 wp_enqueue_style( 'authorizer-public-css' );
1248 } // END auth_public_scripts()
1249
1250
1251 /**
1252 * Enqueue JS scripts and CSS styles appearing on wp-login.php.
1253 *
1254 * @return void
1255 */
1256 function login_enqueue_scripts_and_styles() {
1257 // Grab plugin settings.
1258 $auth_settings = $this->get_plugin_options( 'single admin', 'allow override' );
1259
1260 // Enqueue scripts appearing on wp-login.php.
1261 wp_enqueue_script( 'auth_login_scripts', plugins_url( '/js/authorizer-login.js', __FILE__ ), array( 'jquery' ), '2.3.2' );
1262
1263 // Enqueue styles appearing on wp-login.php.
1264 wp_register_style( 'authorizer-login-css', plugins_url( '/css/authorizer-login.css', __FILE__ ), array(), '2.3.2' );
1265 wp_enqueue_style( 'authorizer-login-css' );
1266
1267 /**
1268 * Developers can use the `authorizer_add_branding_option` filter
1269 * to add a radio button for "Custom WordPress login branding"
1270 * under the "Advanced" tab in Authorizer options. Example:
1271 *
1272 * function my_authorizer_add_branding_option( $branding_options ) {
1273 * $new_branding_option = array(
1274 * 'value' => 'your_brand'
1275 * 'description' => 'Custom Your Brand Login Screen',
1276 * 'css_url' => 'http://url/to/your_brand.css',
1277 * 'js_url' => 'http://url/to/your_brand.js',
1278 * );
1279 * array_push( $branding_options, $new_branding_option );
1280 * return $branding_options;
1281 * }
1282 * add_filter( 'authorizer_add_branding_option', 'my_authorizer_add_branding_option' );
1283 */
1284 $branding_options = array();
1285 $branding_options = apply_filters( 'authorizer_add_branding_option', $branding_options );
1286 foreach ( $branding_options as $branding_option ) {
1287 // Make sure the custom brands have the required values
1288 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 ) ) ) {
1289 continue;
1290 }
1291 if ( $auth_settings['advanced_branding'] === $branding_option['value'] ) {
1292 wp_enqueue_script( 'auth_login_custom_scripts-' . sanitize_title( $branding_option['value'] ), $branding_option['js_url'], array( 'jquery' ), '2.3.2' );
1293 wp_register_style( 'authorizer-login-custom-css-' . sanitize_title( $branding_option['value'] ), $branding_option['css_url'], array(), '2.3.2' );
1294 wp_enqueue_style( 'authorizer-login-custom-css-' . sanitize_title( $branding_option['value'] ) );
1295 }
1296 }
1297
1298 // If we're using Google logins, load those resources.
1299 if ( $auth_settings['google'] === '1' ) {
1300 wp_enqueue_script( 'authorizer-login-custom-google', plugins_url( '/js/authorizer-login-custom_google.js', __FILE__ ), array( 'jquery' ), '2.3.2' ); ?>
1301 <meta name="google-signin-clientid" content="<?php echo $auth_settings['google_clientid']; ?>" />
1302 <meta name="google-signin-scope" content="email" />
1303 <meta name="google-signin-cookiepolicy" content="single_host_origin" />
1304 <?php
1305 }
1306 } // END login_enqueue_scripts_and_styles()
1307
1308
1309 /**
1310 * Load external resources in the footer of the wp-login.php page.
1311 * Run on action hook: login_footer
1312 */
1313 function load_login_footer_js() {
1314 // Grab plugin settings.
1315 $auth_settings = $this->get_plugin_options( 'single admin', 'allow override' ); ?>
1316 <?php if ( $auth_settings['google'] === '1' ): ?>
1317 <script type="text/javascript">
1318 // Reload login page if reauth querystring param exists,
1319 // since reauth interrupts external logins (e.g., google).
1320 if ( location.search.indexOf( 'reauth=1' ) >= 0 ) {
1321 location.href = location.href.replace( 'reauth=1', '' );
1322 }
1323
1324 function signInCallback( authResult ) {
1325 var $ = jQuery;
1326 if ( authResult['status'] && authResult['status']['signed_in'] ) {
1327 // Hide the sign-in button now that the user is authorized, for example:
1328 $( '#googleplus_button' ).attr( 'style', 'display: none' );
1329
1330 // Send the code to the server
1331 var ajaxurl = '<?php echo admin_url( "admin-ajax.php" ); ?>';
1332 $.post(ajaxurl, {
1333 action: 'process_google_login',
1334 'code': authResult['code'],
1335 'nonce': $('#nonce_google_auth-<?php echo $this->get_cookie_value(); ?>').val(),
1336 }, function( response ) {
1337 // Handle or verify the server response if necessary.
1338 //console.log( response );
1339
1340 // Reload wp-login.php to continue the authentication process.
1341 location.reload();
1342 });
1343 } else {
1344 // Update the app to reflect a signed out user
1345 // Possible error values:
1346 // "user_signed_out" - User is signed-out
1347 // "access_denied" - User denied access to your app
1348 // "immediate_failed" - Could not automatically log in the user
1349 //console.log('Sign-in state: ' + authResult['error']);
1350 }
1351 }
1352 </script>
1353 <?php endif;
1354 } // END load_login_footer_js()
1355
1356
1357 /**
1358 * Create links for any external authentication services that are enabled.
1359 */
1360 function login_form_add_external_service_links() {
1361 // Grab plugin settings.
1362 $auth_settings = $this->get_plugin_options( 'single admin', 'allow override' );
1363
1364 $auth_url_cas = '';
1365 if ( $auth_settings['cas'] === '1' ) {
1366 $auth_url_cas = 'http' . ( isset( $_SERVER['HTTPS'] ) ? 's' : '' ) . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
1367 // Remove force reauth param if it exists so this
1368 // authentication attempt doesn't get stopped by WordPress.
1369 if ( strpos( $auth_url_cas, 'reauth=1' ) !== false ) {
1370 if ( strpos( $auth_url_cas, '&reauth=1' ) !== false ) {
1371 // There are parames before reauth, so just remove reauth
1372 $auth_url_cas = str_replace( '&reauth=1', '', $auth_url_cas );
1373 } elseif ( strpos( $auth_url_cas, '?reauth=1&' ) !== false ) {
1374 // Reauth is first param with others behind it, so remove it and next delimiter.
1375 $auth_url_cas = str_replace( 'reauth=1&', '', $auth_url_cas );
1376 } else {
1377 // Reauth is first and only param, so remove it and '?'
1378 $auth_url_cas = str_replace( '?reauth=1', '', $auth_url_cas );
1379 }
1380
1381 }
1382 // Add special param indicating this is CAS authentication attempt.
1383 if ( strpos( $auth_url_cas, 'external=cas' ) === false ) {
1384 $auth_url_cas .= strpos( $auth_url_cas, '?' ) !== false ? '&external=cas' : '?external=cas';
1385 }
1386 } ?>
1387 <div id="auth-external-service-login">
1388 <?php if ( $auth_settings['google'] === '1' ): ?>
1389 <p><a id="googleplus_button" class="button button-primary button-external button-google"><span class="dashicons dashicons-googleplus"></span><span class="label">Sign in with Google</span></a></p>
1390 <?php wp_nonce_field( 'google_csrf_nonce', 'nonce_google_auth-' . $this->get_cookie_value() ); ?>
1391 <?php endif; ?>
1392
1393 <?php if ( $auth_settings['cas'] === '1' ): ?>
1394 <p><a class="button button-primary button-external button-cas" href="<?php echo $auth_url_cas; ?>"><span class="dashicons dashicons-lock"></span><span class="label">Sign in with <?php echo $auth_settings['cas_custom_label']; ?></span></a></p>
1395 <?php endif; ?>
1396
1397 <?php if ( $auth_settings['advanced_hide_wp_login'] === '1' && strpos( $_SERVER['QUERY_STRING'], 'external=wordpress' ) === false ): ?>
1398 <style type="text/css">
1399 #loginform {
1400 padding-bottom: 8px;
1401 }
1402 #loginform p>label, #loginform p.forgetmenot, #loginform p.submit, p#nav {
1403 display: none;
1404 }
1405 </style>
1406 <?php elseif ( $auth_settings['cas'] === '1' || $auth_settings['google'] === '1' ): ?>
1407 <h3> &mdash; or &mdash; </h3>
1408 <?php endif; ?>
1409 </div>
1410 <?php
1411
1412 } // END login_form_add_external_service_links()
1413
1414
1415 /**
1416 * Implements hook: do_action( 'wp_login_failed', $username );
1417 * Update the user meta for the user that just failed logging in.
1418 * Keep track of time of last failed attempt and number of failed attempts.
1419 */
1420 function update_login_failed_count( $username ) {
1421 // Grab plugin settings.
1422 $auth_settings = $this->get_plugin_options( 'single admin', 'allow override' );
1423
1424 // Get user trying to log in.
1425 // If this isn't a real user, update the global failed attempt
1426 // variables. We'll use these global variables to institute the
1427 // lockouts on nonexistent accounts. We do this so an attacker
1428 // won't be able to determine which accounts are real by which
1429 // accounts get locked out on multiple invalid attempts.
1430 $user = get_user_by( 'login', $username );
1431
1432 if ( $user !== FALSE ) {
1433 $last_attempt = get_user_meta( $user->ID, 'auth_settings_advanced_lockouts_time_last_failed', true );
1434 $num_attempts = get_user_meta( $user->ID, 'auth_settings_advanced_lockouts_failed_attempts', true );
1435 } else {
1436 $last_attempt = get_option( 'auth_settings_advanced_lockouts_time_last_failed' );
1437 $num_attempts = get_option( 'auth_settings_advanced_lockouts_failed_attempts' );
1438 }
1439
1440 // Make sure $last_attempt (time) and $num_attempts are positive integers.
1441 // Note: this addresses resetting them if either is unset from above.
1442 $last_attempt = abs( intval( $last_attempt ) );
1443 $num_attempts = abs( intval( $num_attempts ) );
1444
1445 // Reset the failed attempt count if the time since the last
1446 // failed attempt is greater than the reset duration.
1447 $time_since_last_fail = time() - $last_attempt;
1448 $reset_duration = $auth_settings['advanced_lockouts']['reset_duration'] * 60; // minutes to seconds
1449 if ( $time_since_last_fail > $reset_duration ) {
1450 $num_attempts = 0;
1451 }
1452
1453 // Set last failed time to now and increment last failed count.
1454 if ( $user !== FALSE ) {
1455 update_user_meta( $user->ID, 'auth_settings_advanced_lockouts_time_last_failed', time() );
1456 update_user_meta( $user->ID, 'auth_settings_advanced_lockouts_failed_attempts', $num_attempts + 1 );
1457 } else {
1458 update_option( 'auth_settings_advanced_lockouts_time_last_failed', time() );
1459 update_option( 'auth_settings_advanced_lockouts_failed_attempts', $num_attempts + 1 );
1460 }
1461 } // END update_login_failed_count()
1462
1463 /**
1464 * Overwrite the URL for the lost password link on the login form.
1465 * If we're authenticating against an external service, standard
1466 * WordPress password resets won't work.
1467 */
1468 function custom_lostpassword_url( $lostpassword_url ) {
1469 // Grab plugin settings.
1470 $auth_settings = $this->get_plugin_options( 'single admin', 'allow override' );
1471
1472 if (
1473 array_key_exists( 'ldap_lostpassword_url', $auth_settings ) &&
1474 filter_var( $auth_settings['ldap_lostpassword_url'], FILTER_VALIDATE_URL )
1475 ) {
1476 $lostpassword_url = $auth_settings['ldap_lostpassword_url'];
1477 }
1478 return $lostpassword_url;
1479 } // END custom_lostpassword_url()
1480
1481
1482
1483 /**
1484 * ***************************
1485 * Options page
1486 * ***************************
1487 */
1488
1489
1490
1491 /**
1492 * Add a link to this plugin's settings page from the WordPress Plugins page.
1493 * Called from "plugin_action_links" filter in __construct() above.
1494 *
1495 * @param array $links array of links in the admin sidebar
1496 *
1497 * @return array of links to show in the admin sidebar.
1498 */
1499 public function plugin_settings_link( $links ) {
1500 $admin_menu = $this->get_plugin_option( 'advanced_admin_menu' );
1501 $settings_url = $admin_menu === 'settings' ? admin_url( 'options-general.php?page=authorizer' ) : admin_url( 'admin.php?page=authorizer' );
1502 array_unshift( $links, '<a href="' . $settings_url . '">Settings</a>' );
1503 return $links;
1504 } // END plugin_settings_link()
1505
1506
1507
1508 /**
1509 * Add a link to this plugin's network settings page from the WordPress Plugins page.
1510 * Called from "network_admin_plugin_action_links" filter in __construct() above.
1511 *
1512 * @param array $links array of links in the network admin sidebar
1513 *
1514 * @return array of links to show in the network admin sidebar.
1515 */
1516 public function network_admin_plugin_settings_link( $links ) {
1517 $settings_link = '<a href="admin.php?page=authorizer">Network Settings</a>';
1518 array_unshift( $links, $settings_link );
1519 return $links;
1520 } // END network_admin_plugin_settings_link()
1521
1522
1523
1524 /**
1525 * Create the options page under Dashboard > Settings
1526 * Run on action hook: admin_menu
1527 */
1528 public function add_plugin_page() {
1529 $admin_menu = $this->get_plugin_option( 'advanced_admin_menu' );
1530 if ( $admin_menu === 'settings' ) {
1531 // @see http://codex.wordpress.org/Function_Reference/add_options_page
1532 add_options_page(
1533 'Authorizer', // Page title
1534 'Authorizer', // Menu title
1535 'create_users', // Capability
1536 'authorizer', // Menu slug
1537 array( $this, 'create_admin_page' ) // function
1538 );
1539 } else {
1540 // @see http://codex.wordpress.org/Function_Reference/add_menu_page
1541 add_menu_page(
1542 'Authorizer', // Page title
1543 'Authorizer', // Menu title
1544 'create_users', // Capability
1545 'authorizer', // Menu slug
1546 array( $this, 'create_admin_page' ), // callback
1547 'dashicons-groups', // icon
1548 '99.0018465' // position (decimal is to make overlap with other plugins less likely)
1549 );
1550 }
1551 } // END add_plugin_page()
1552
1553
1554 /**
1555 * Output the HTML for the options page
1556 */
1557 public function create_admin_page() { ?>
1558 <div class="wrap">
1559 <h2>Authorizer Settings</h2>
1560 <form method="post" action="options.php" autocomplete="off"><?php
1561 // This prints out all hidden settings fields
1562 // @see http://codex.wordpress.org/Function_Reference/settings_fields
1563 settings_fields( 'auth_settings_group' );
1564 // This prints out all the sections
1565 // @see http://codex.wordpress.org/Function_Reference/do_settings_sections
1566 do_settings_sections( 'authorizer' );
1567 submit_button(); ?>
1568 </form>
1569 </div><?php
1570 } // END create_admin_page()
1571
1572
1573
1574 /**
1575 * Load external resources on this plugin's options page.
1576 * Run on action hooks: load-settings_page_authorizer, load-toplevel_page_authorizer, admin_head-index.php
1577 */
1578 public function load_options_page() {
1579 wp_enqueue_script(
1580 'authorizer',
1581 plugins_url( 'js/authorizer.js', __FILE__ ),
1582 array( 'jquery-effects-shake' ), '2.3.2', true
1583 );
1584 $js_auth_config = array( 'baseurl' => get_bloginfo( 'url' ) );
1585 wp_localize_script( 'authorizer', 'auth_config', $js_auth_config );
1586
1587 wp_enqueue_script(
1588 'jquery.multi-select',
1589 plugins_url( 'inc/jquery.multi-select/js/jquery.multi-select.js', __FILE__ ),
1590 array( 'jquery' ), '1.8', true
1591 );
1592
1593 wp_register_style( 'authorizer-css', plugins_url( 'css/authorizer.css', __FILE__ ), array(), '2.3.2' );
1594 wp_enqueue_style( 'authorizer-css' );
1595
1596 wp_register_style( 'jquery-multi-select-css', plugins_url( 'inc/jquery.multi-select/css/multi-select.css', __FILE__ ), array(), '1.8' );
1597 wp_enqueue_style( 'jquery-multi-select-css' );
1598
1599 add_action( 'admin_notices', array( $this, 'admin_notices' ) ); // Add any notices to the top of the options page.
1600 add_action( 'admin_head', array( $this, 'admin_head' ) ); // Add help documentation to the options page.
1601 } // END load_options_page()
1602
1603
1604
1605 /**
1606 * Show custom admin notice.
1607 * Filter: admin_notice
1608 */
1609 function show_advanced_admin_notice() {
1610 $notice = get_option( 'auth_settings_advanced_admin_notice' );
1611 delete_option( 'auth_settings_advanced_admin_notice' );
1612
1613 if ( $notice && strlen( $notice ) > 0 ) { ?>
1614 <div class="error">
1615 <p><?php _e( $notice ); ?></p>
1616 </div><?php
1617 }
1618 } // END show_advanced_admin_notice()
1619
1620
1621 /**
1622 * Add notices to the top of the options page.
1623 * Run on action hook chain: load-settings_page_authorizer > admin_notices
1624 * Description: Check for invalid settings combinations and show a warning message, e.g.:
1625 * if ( cas url inaccessible ) : ?>
1626 * <div class='updated settings-error'><p>Can't reach CAS server.</p></div>
1627 * <?php endif;
1628 */
1629 public function admin_notices() {
1630 // Grab plugin settings.
1631 $auth_settings = $this->get_plugin_options( 'single admin', 'allow override' );
1632
1633 if ( $auth_settings['cas'] === '1' ) :
1634 // Check if provided CAS URL is accessible.
1635 $protocol = $auth_settings['cas_port'] == '80' ? 'http' : 'https';
1636 if ( ! $this->url_is_accessible( $protocol . '://' . $auth_settings['cas_host'] . $auth_settings['cas_path'] ) ) :
1637 $authorizer_options_url = $auth_settings['advanced_admin_menu'] === 'settings' ? admin_url( 'options-general.php?page=authorizer' ) : admin_url( '?page=authorizer' );
1638 ?><div class='notice notice-warning is-dismissible'>
1639 <p>Can't reach CAS server. Please provide <a href='<?php echo $authorizer_options_url; ?>&tab=external'>accurate CAS settings</a> if you intend to use it.</p>
1640 </div><?php
1641 endif;
1642 endif;
1643 } // END admin_notices()
1644
1645
1646 /**
1647 * Create sections and options
1648 * Run on action hook: admin_init
1649 */
1650 public function page_init() {
1651 // Create one setting that holds all the options (array)
1652 // @see http://codex.wordpress.org/Function_Reference/register_setting
1653 // @see http://codex.wordpress.org/Function_Reference/add_settings_section
1654 // @see http://codex.wordpress.org/Function_Reference/add_settings_field
1655 register_setting(
1656 'auth_settings_group', // Option group
1657 'auth_settings', // Option name
1658 array( $this, 'sanitize_options' ) // Sanitize callback
1659 );
1660
1661 add_settings_section(
1662 'auth_settings_tabs', // HTML element ID
1663 '', // HTML element Title
1664 array( $this, 'print_section_info_tabs' ), // Callback (echos section content)
1665 'authorizer' // Page this section is shown on (slug)
1666 );
1667
1668 // Create Access Lists section
1669 add_settings_section(
1670 'auth_settings_lists', // HTML element ID
1671 '', // HTML element Title
1672 array( $this, 'print_section_info_access_lists' ), // Callback (echos section content)
1673 'authorizer' // Page this section is shown on (slug)
1674 );
1675
1676 // Create Login Access section
1677 add_settings_section(
1678 'auth_settings_access_login', // HTML element ID
1679 '', // HTML element Title
1680 array( $this, 'print_section_info_access_login' ), // Callback (echos section content)
1681 'authorizer' // Page this section is shown on (slug)
1682 );
1683 add_settings_field(
1684 'auth_settings_access_who_can_login', // HTML element ID
1685 'Who can log into the site?', // HTML element Title
1686 array( $this, 'print_radio_auth_access_who_can_login' ), // Callback (echos form element)
1687 'authorizer', // Page this setting is shown on (slug)
1688 'auth_settings_access_login' // Section this setting is shown on
1689 );
1690 add_settings_field(
1691 'auth_settings_access_role_receive_pending_emails', // HTML element ID
1692 'Which role should receive email notifications about pending users?', // HTML element Title
1693 array( $this, 'print_select_auth_access_role_receive_pending_emails' ), // Callback (echos form element)
1694 'authorizer', // Page this setting is shown on (slug)
1695 'auth_settings_access_login' // Section this setting is shown on
1696 );
1697 add_settings_field(
1698 'auth_settings_access_pending_redirect_to_message', // HTML element ID
1699 'What message should pending users see after attempting to log in?', // HTML element Title
1700 array( $this, 'print_wysiwyg_auth_access_pending_redirect_to_message' ), // Callback (echos form element)
1701 'authorizer', // Page this setting is shown on (slug)
1702 'auth_settings_access_login' // Section this setting is shown on
1703 );
1704 add_settings_field(
1705 'auth_settings_access_blocked_redirect_to_message', // HTML element ID
1706 'What message should blocked users see after attempting to log in?', // HTML element Title
1707 array( $this, 'print_wysiwyg_auth_access_blocked_redirect_to_message' ), // Callback (echos form element)
1708 'authorizer', // Page this setting is shown on (slug)
1709 'auth_settings_access_login' // Section this setting is shown on
1710 );
1711 add_settings_field(
1712 'auth_settings_access_should_email_approved_users', // HTML element ID
1713 'Send welcome email to new approved users?', // HTML element Title
1714 array( $this, 'print_checkbox_auth_access_should_email_approved_users' ), // Callback (echos form element)
1715 'authorizer', // Page this setting is shown on (slug)
1716 'auth_settings_access_login' // Section this setting is shown on
1717 );
1718 add_settings_field(
1719 'auth_settings_access_email_approved_users_subject', // HTML element ID
1720 'Welcome email subject', // HTML element Title
1721 array( $this, 'print_text_auth_access_email_approved_users_subject' ), // Callback (echos form element)
1722 'authorizer', // Page this setting is shown on (slug)
1723 'auth_settings_access_login' // Section this setting is shown on
1724 );
1725 add_settings_field(
1726 'auth_settings_access_email_approved_users_body', // HTML element ID
1727 'Welcome email body', // HTML element Title
1728 array( $this, 'print_wysiwyg_auth_access_email_approved_users_body' ), // Callback (echos form element)
1729 'authorizer', // Page this setting is shown on (slug)
1730 'auth_settings_access_login' // Section this setting is shown on
1731 );
1732
1733
1734 // Create Public Access section
1735 add_settings_section(
1736 'auth_settings_access_public', // HTML element ID
1737 '', // HTML element Title
1738 array( $this, 'print_section_info_access_public' ), // Callback (echos section content)
1739 'authorizer' // Page this section is shown on (slug)
1740 );
1741 add_settings_field(
1742 'auth_settings_access_who_can_view', // HTML element ID
1743 'Who can view the site?', // HTML element Title
1744 array( $this, 'print_radio_auth_access_who_can_view' ), // Callback (echos form element)
1745 'authorizer', // Page this setting is shown on (slug)
1746 'auth_settings_access_public' // Section this setting is shown on
1747 );
1748 add_settings_field(
1749 'auth_settings_access_public_pages', // HTML element ID
1750 'What pages (if any) should be available to everyone?', // HTML element Title
1751 array( $this, 'print_multiselect_auth_access_public_pages' ), // Callback (echos form element)
1752 'authorizer', // Page this setting is shown on (slug)
1753 'auth_settings_access_public' // Section this setting is shown on
1754 );
1755 add_settings_field(
1756 'auth_settings_access_redirect', // HTML element ID
1757 'What happens to people without access when they visit a private page?', // HTML element Title
1758 array( $this, 'print_radio_auth_access_redirect' ), // Callback (echos form element)
1759 'authorizer', // Page this setting is shown on (slug)
1760 'auth_settings_access_public' // Section this setting is shown on
1761 );
1762 add_settings_field(
1763 'auth_settings_access_public_warning', // HTML element ID
1764 'What happens to people without access when they visit a public page?', // HTML element Title
1765 array( $this, 'print_radio_auth_access_public_warning' ), // Callback (echos form element)
1766 'authorizer', // Page this setting is shown on (slug)
1767 'auth_settings_access_public' // Section this setting is shown on
1768 );
1769 add_settings_field(
1770 'auth_settings_access_redirect_to_message', // HTML element ID
1771 'What message should people without access see?', // HTML element Title
1772 array( $this, 'print_wysiwyg_auth_access_redirect_to_message' ), // Callback (echos form element)
1773 'authorizer', // Page this setting is shown on (slug)
1774 'auth_settings_access_public' // Section this setting is shown on
1775 );
1776
1777 // Create External Service Settings section
1778 add_settings_section(
1779 'auth_settings_external', // HTML element ID
1780 '', // HTML element Title
1781 array( $this, 'print_section_info_external' ), // Callback (echos section content)
1782 'authorizer' // Page this section is shown on (slug)
1783 );
1784 add_settings_field(
1785 'auth_settings_access_default_role', // HTML element ID
1786 'Default role for new users', // HTML element Title
1787 array( $this, 'print_select_auth_access_default_role' ), // Callback (echos form element)
1788 'authorizer', // Page this setting is shown on (slug)
1789 'auth_settings_external' // Section this setting is shown on
1790 );
1791 add_settings_field(
1792 'auth_settings_external_google', // HTML element ID
1793 'Google Logins', // HTML element Title
1794 array( $this, 'print_checkbox_auth_external_google' ), // Callback (echos form element)
1795 'authorizer', // Page this setting is shown on (slug)
1796 'auth_settings_external' // Section this setting is shown on
1797 );
1798 add_settings_field(
1799 'auth_settings_google_clientid', // HTML element ID
1800 'Google Client ID', // HTML element Title
1801 array( $this, 'print_text_google_clientid' ), // Callback (echos form element)
1802 'authorizer', // Page this setting is shown on (slug)
1803 'auth_settings_external' // Section this setting is shown on
1804 );
1805 add_settings_field(
1806 'auth_settings_google_clientsecret', // HTML element ID
1807 'Google Client Secret', // HTML element Title
1808 array( $this, 'print_text_google_clientsecret' ), // Callback (echos form element)
1809 'authorizer', // Page this setting is shown on (slug)
1810 'auth_settings_external' // Section this setting is shown on
1811 );
1812 add_settings_field(
1813 'auth_settings_external_cas', // HTML element ID
1814 'CAS Logins', // HTML element Title
1815 array( $this, 'print_checkbox_auth_external_cas' ), // Callback (echos form element)
1816 'authorizer', // Page this setting is shown on (slug)
1817 'auth_settings_external' // Section this setting is shown on
1818 );
1819 add_settings_field(
1820 'auth_settings_cas_custom_label', // HTML element ID
1821 'CAS custom label', // HTML element Title
1822 array( $this, 'print_text_cas_custom_label' ), // Callback (echos form element)
1823 'authorizer', // Page this setting is shown on (slug)
1824 'auth_settings_external' // Section this setting is shown on
1825 );
1826 add_settings_field(
1827 'auth_settings_cas_host', // HTML element ID
1828 'CAS server hostname', // HTML element Title
1829 array( $this, 'print_text_cas_host' ), // Callback (echos form element)
1830 'authorizer', // Page this setting is shown on (slug)
1831 'auth_settings_external' // Section this setting is shown on
1832 );
1833 add_settings_field(
1834 'auth_settings_cas_port', // HTML element ID
1835 'CAS server port', // HTML element Title
1836 array( $this, 'print_text_cas_port' ), // Callback (echos form element)
1837 'authorizer', // Page this setting is shown on (slug)
1838 'auth_settings_external' // Section this setting is shown on
1839 );
1840 add_settings_field(
1841 'auth_settings_cas_path', // HTML element ID
1842 'CAS server path/context', // HTML element Title
1843 array( $this, 'print_text_cas_path' ), // Callback (echos form element)
1844 'authorizer', // Page this setting is shown on (slug)
1845 'auth_settings_external' // Section this setting is shown on
1846 );
1847 add_settings_field(
1848 'auth_settings_cas_attr_email', // HTML element ID
1849 'CAS attribute containing email address', // HTML element Title
1850 array( $this, 'print_text_cas_attr_email' ), // Callback (echos form element)
1851 'authorizer', // Page this setting is shown on (slug)
1852 'auth_settings_external' // Section this setting is shown on
1853 );
1854 add_settings_field(
1855 'auth_settings_cas_attr_first_name', // HTML element ID
1856 'CAS attribute containing first name', // HTML element Title
1857 array( $this, 'print_text_cas_attr_first_name' ), // Callback (echos form element)
1858 'authorizer', // Page this setting is shown on (slug)
1859 'auth_settings_external' // Section this setting is shown on
1860 );
1861 add_settings_field(
1862 'auth_settings_cas_attr_last_name', // HTML element ID
1863 'CAS attribute containing last name', // HTML element Title
1864 array( $this, 'print_text_cas_attr_last_name' ), // Callback (echos form element)
1865 'authorizer', // Page this setting is shown on (slug)
1866 'auth_settings_external' // Section this setting is shown on
1867 );
1868 add_settings_field(
1869 'auth_settings_cas_attr_update_on_login', // HTML element ID
1870 'CAS attribute update', // HTML element Title
1871 array( $this, 'print_checkbox_cas_attr_update_on_login' ), // Callback (echos form element)
1872 'authorizer', // Page this setting is shown on (slug)
1873 'auth_settings_external' // Section this setting is shown on
1874 );
1875 add_settings_field(
1876 'auth_settings_external_ldap', // HTML element ID
1877 'LDAP Logins', // HTML element Title
1878 array( $this, 'print_checkbox_auth_external_ldap' ), // Callback (echos form element)
1879 'authorizer', // Page this setting is shown on (slug)
1880 'auth_settings_external' // Section this setting is shown on
1881 );
1882 add_settings_field(
1883 'auth_settings_ldap_host', // HTML element ID
1884 'LDAP Host', // HTML element Title
1885 array( $this, 'print_text_ldap_host' ), // Callback (echos form element)
1886 'authorizer', // Page this setting is shown on (slug)
1887 'auth_settings_external' // Section this setting is shown on
1888 );
1889 add_settings_field(
1890 'auth_settings_ldap_port', // HTML element ID
1891 'LDAP Port', // HTML element Title
1892 array( $this, 'print_text_ldap_port' ), // Callback (echos form element)
1893 'authorizer', // Page this setting is shown on (slug)
1894 'auth_settings_external' // Section this setting is shown on
1895 );
1896 add_settings_field(
1897 'auth_settings_ldap_search_base', // HTML element ID
1898 'LDAP Search Base', // HTML element Title
1899 array( $this, 'print_text_ldap_search_base' ), // Callback (echos form element)
1900 'authorizer', // Page this setting is shown on (slug)
1901 'auth_settings_external' // Section this setting is shown on
1902 );
1903 add_settings_field(
1904 'auth_settings_ldap_uid', // HTML element ID
1905 'LDAP attribute containing username', // HTML element Title
1906 array( $this, 'print_text_ldap_uid' ), // Callback (echos form element)
1907 'authorizer', // Page this setting is shown on (slug)
1908 'auth_settings_external' // Section this setting is shown on
1909 );
1910 add_settings_field(
1911 'auth_settings_ldap_attr_email', // HTML element ID
1912 'LDAP attribute containing email address', // HTML element Title
1913 array( $this, 'print_text_ldap_attr_email' ), // Callback (echos form element)
1914 'authorizer', // Page this setting is shown on (slug)
1915 'auth_settings_external' // Section this setting is shown on
1916 );
1917 add_settings_field(
1918 'auth_settings_ldap_user', // HTML element ID
1919 'LDAP Directory User', // HTML element Title
1920 array( $this, 'print_text_ldap_user' ), // Callback (echos form element)
1921 'authorizer', // Page this setting is shown on (slug)
1922 'auth_settings_external' // Section this setting is shown on
1923 );
1924 add_settings_field(
1925 'auth_settings_ldap_password', // HTML element ID
1926 'LDAP Directory User Password', // HTML element Title
1927 array( $this, 'print_password_ldap_password' ), // Callback (echos form element)
1928 'authorizer', // Page this setting is shown on (slug)
1929 'auth_settings_external' // Section this setting is shown on
1930 );
1931 add_settings_field(
1932 'auth_settings_ldap_tls', // HTML element ID
1933 'Secure Connection (TLS)', // HTML element Title
1934 array( $this, 'print_checkbox_ldap_tls' ), // Callback (echos form element)
1935 'authorizer', // Page this setting is shown on (slug)
1936 'auth_settings_external' // Section this setting is shown on
1937 );
1938 add_settings_field(
1939 'auth_settings_ldap_lostpassword_url', // HTML element ID
1940 'Custom lost password URL', // HTML element Title
1941 array( $this, 'print_text_ldap_lostpassword_url' ), // Callback (echos form element)
1942 'authorizer', // Page this setting is shown on (slug)
1943 'auth_settings_external' // Section this setting is shown on
1944 );
1945 add_settings_field(
1946 'auth_settings_ldap_attr_first_name', // HTML element ID
1947 'LDAP attribute containing first name', // HTML element Title
1948 array( $this, 'print_text_ldap_attr_first_name' ), // Callback (echos form element)
1949 'authorizer', // Page this setting is shown on (slug)
1950 'auth_settings_external' // Section this setting is shown on
1951 );
1952 add_settings_field(
1953 'auth_settings_ldap_attr_last_name', // HTML element ID
1954 'LDAP attribute containing last name', // HTML element Title
1955 array( $this, 'print_text_ldap_attr_last_name' ), // Callback (echos form element)
1956 'authorizer', // Page this setting is shown on (slug)
1957 'auth_settings_external' // Section this setting is shown on
1958 );
1959 add_settings_field(
1960 'auth_settings_ldap_attr_update_on_login', // HTML element ID
1961 'LDAP attribute update', // HTML element Title
1962 array( $this, 'print_checkbox_ldap_attr_update_on_login' ), // Callback (echos form element)
1963 'authorizer', // Page this setting is shown on (slug)
1964 'auth_settings_external' // Section this setting is shown on
1965 );
1966
1967 // Create Advanced Settings section
1968 add_settings_section(
1969 'auth_settings_advanced', // HTML element ID
1970 '', // HTML element Title
1971 array( $this, 'print_section_info_advanced' ), // Callback (echos section content)
1972 'authorizer' // Page this section is shown on (slug)
1973 );
1974 add_settings_field(
1975 'auth_settings_advanced_lockouts', // HTML element ID
1976 'Limit invalid login attempts', // HTML element Title
1977 array( $this, 'print_text_auth_advanced_lockouts' ), // Callback (echos form element)
1978 'authorizer', // Page this setting is shown on (slug)
1979 'auth_settings_advanced' // Section this setting is shown on
1980 );
1981 add_settings_field(
1982 'auth_settings_advanced_hide_wp_login', // HTML element ID
1983 'Hide WordPress Login', // HTML element Title
1984 array( $this, 'print_checkbox_auth_advanced_hide_wp_login' ), // Callback (echos form element)
1985 'authorizer', // Page this setting is shown on (slug)
1986 'auth_settings_advanced' // Section this setting is shown on
1987 );
1988 add_settings_field(
1989 'auth_settings_advanced_branding', // HTML element ID
1990 'Custom WordPress login branding', // HTML element Title
1991 array( $this, 'print_radio_auth_advanced_branding' ), // Callback (echos form element)
1992 'authorizer', // Page this setting is shown on (slug)
1993 'auth_settings_advanced' // Section this setting is shown on
1994 );
1995 add_settings_field(
1996 'auth_settings_advanced_admin_menu', // HTML element ID
1997 'Authorizer admin menu item location', // HTML element Title
1998 array( $this, 'print_radio_auth_advanced_admin_menu' ), // Callback (echos form element)
1999 'authorizer', // Page this setting is shown on (slug)
2000 'auth_settings_advanced' // Section this setting is shown on
2001 );
2002 add_settings_field(
2003 'auth_settings_advanced_usermeta', // HTML element ID
2004 'Show custom usermeta in user list', // HTML element Title
2005 array( $this, 'print_select_auth_advanced_usermeta' ), // Callback (echos form element)
2006 'authorizer', // Page this setting is shown on (slug)
2007 'auth_settings_advanced' // Section this setting is shown on
2008 );
2009 // On multisite installs, add an option to override all multisite settings on individual sites.
2010 if ( is_multisite() ) {
2011 add_settings_field(
2012 'auth_settings_advanced_override_multisite', // HTML element ID
2013 'Override multisite options', // HTML element Title
2014 array( $this, 'print_checkbox_auth_advanced_override_multisite' ), // Callback (echos form element)
2015 'authorizer', // Page this setting is shown on (slug)
2016 'auth_settings_advanced' // Section this setting is shown on
2017 );
2018 }
2019 } // END page_init()
2020
2021
2022 /**
2023 * Set meaningful defaults for the plugin options.
2024 * Note: This function is called on plugin activation.
2025 */
2026 function set_default_options() {
2027 global $wp_roles;
2028
2029 $auth_settings = get_option( 'auth_settings' );
2030 if ( $auth_settings === FALSE ) {
2031 $auth_settings = array();
2032 }
2033
2034 // Access Lists Defaults.
2035 $auth_settings_access_users_pending = get_option( 'auth_settings_access_users_pending' );
2036 if ( $auth_settings_access_users_pending === FALSE ) {
2037 $auth_settings_access_users_pending = array();
2038 }
2039 $auth_settings_access_users_approved = get_option( 'auth_settings_access_users_approved' );
2040 if ( $auth_settings_access_users_approved === FALSE ) {
2041 $auth_settings_access_users_approved = array();
2042 }
2043 $auth_settings_access_users_blocked = get_option( 'auth_settings_access_users_blocked' );
2044 if ( $auth_settings_access_users_blocked === FALSE ) {
2045 $auth_settings_access_users_blocked = array();
2046 }
2047
2048 // Login Access Defaults.
2049 if ( ! array_key_exists( 'access_who_can_login', $auth_settings ) ) {
2050 $auth_settings['access_who_can_login'] = 'approved_users';
2051 }
2052 if ( ! array_key_exists( 'access_role_receive_pending_emails', $auth_settings ) ) {
2053 $auth_settings['access_role_receive_pending_emails'] = '---';
2054 }
2055 if ( ! array_key_exists( 'access_pending_redirect_to_message', $auth_settings ) ) {
2056 $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.</p>';
2057 }
2058 if ( ! array_key_exists( 'access_blocked_redirect_to_message', $auth_settings ) ) {
2059 $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.</p>';
2060 }
2061 if ( ! array_key_exists( 'access_should_email_approved_users', $auth_settings ) ) {
2062 $auth_settings['access_should_email_approved_users'] = '';
2063 }
2064 if ( ! array_key_exists( 'access_email_approved_users_subject', $auth_settings ) ) {
2065 $auth_settings['access_email_approved_users_subject'] = 'Welcome to [site_name]!';
2066 }
2067 if ( ! array_key_exists( 'access_email_approved_users_body', $auth_settings ) ) {
2068 $auth_settings['access_email_approved_users_body'] =
2069 'Hello [user_email],' . PHP_EOL .
2070 'Welcome to [site_name]! You now have access to all content on the site. Please visit us here:' . PHP_EOL .
2071 '[site_url]';
2072 }
2073
2074 // Public Access to Private Page Defaults.
2075 if ( ! array_key_exists( 'access_who_can_view', $auth_settings ) ) {
2076 $auth_settings['access_who_can_view'] = 'everyone';
2077 }
2078 if ( ! array_key_exists( 'access_public_pages', $auth_settings ) ) {
2079 $auth_settings['access_public_pages'] = array();
2080 }
2081 if ( ! array_key_exists( 'access_redirect', $auth_settings ) ) {
2082 $auth_settings['access_redirect'] = 'login';
2083 }
2084 if ( ! array_key_exists( 'access_public_warning', $auth_settings ) ) {
2085 $auth_settings['access_public_warning'] = 'no_warning';
2086 }
2087 if ( ! array_key_exists( 'access_redirect_to_message', $auth_settings ) ) {
2088 $auth_settings['access_redirect_to_message'] = '<p><strong>Notice</strong>: You are browsing this site anonymously, and only have access to a portion of its content.</p>';
2089 }
2090
2091
2092 // External Service Defaults.
2093 if ( ! array_key_exists( 'access_default_role', $auth_settings ) ) {
2094 // Set default role to 'student' if that role exists, 'subscriber' otherwise.
2095 $all_roles = $wp_roles->roles;
2096 $editable_roles = apply_filters( 'editable_roles', $all_roles );
2097 if ( array_key_exists( 'student', $editable_roles ) ) {
2098 $auth_settings['access_default_role'] = 'student';
2099 } else {
2100 $auth_settings['access_default_role'] = 'subscriber';
2101 }
2102 }
2103
2104 if ( ! array_key_exists( 'google', $auth_settings ) ) {
2105 $auth_settings['google'] = '';
2106 }
2107 if ( ! array_key_exists( 'cas', $auth_settings ) ) {
2108 $auth_settings['cas'] = '';
2109 }
2110 if ( ! array_key_exists( 'ldap', $auth_settings ) ) {
2111 $auth_settings['ldap'] = '';
2112 }
2113
2114 if ( ! array_key_exists( 'google_clientid', $auth_settings ) ) {
2115 $auth_settings['google_clientid'] = '';
2116 }
2117 if ( ! array_key_exists( 'google_clientsecret', $auth_settings ) ) {
2118 $auth_settings['google_clientsecret'] = '';
2119 }
2120
2121 if ( ! array_key_exists( 'cas_custom_label', $auth_settings ) ) {
2122 $auth_settings['cas_custom_label'] = 'CAS';
2123 }
2124 if ( ! array_key_exists( 'cas_host', $auth_settings ) ) {
2125 $auth_settings['cas_host'] = '';
2126 }
2127 if ( ! array_key_exists( 'cas_port', $auth_settings ) ) {
2128 $auth_settings['cas_port'] = '';
2129 }
2130 if ( ! array_key_exists( 'cas_path', $auth_settings ) ) {
2131 $auth_settings['cas_path'] = '';
2132 }
2133 if ( ! array_key_exists( 'cas_attr_email', $auth_settings ) ) {
2134 $auth_settings['cas_attr_email'] = '';
2135 }
2136 if ( ! array_key_exists( 'cas_attr_first_name', $auth_settings ) ) {
2137 $auth_settings['cas_attr_first_name'] = '';
2138 }
2139 if ( ! array_key_exists( 'cas_attr_last_name', $auth_settings ) ) {
2140 $auth_settings['cas_attr_last_name'] = '';
2141 }
2142 if ( ! array_key_exists( 'cas_attr_update_on_login', $auth_settings ) ) {
2143 $auth_settings['cas_attr_update_on_login'] = '';
2144 }
2145
2146 if ( ! array_key_exists( 'ldap_host', $auth_settings ) ) {
2147 $auth_settings['ldap_host'] = '';
2148 }
2149 if ( ! array_key_exists( 'ldap_port', $auth_settings ) ) {
2150 $auth_settings['ldap_port'] = '';
2151 }
2152 if ( ! array_key_exists( 'ldap_search_base', $auth_settings ) ) {
2153 $auth_settings['ldap_search_base'] = '';
2154 }
2155 if ( ! array_key_exists( 'ldap_uid', $auth_settings ) ) {
2156 $auth_settings['ldap_uid'] = '';
2157 }
2158 if ( ! array_key_exists( 'ldap_attr_email', $auth_settings ) ) {
2159 $auth_settings['ldap_attr_email'] = '';
2160 }
2161 if ( ! array_key_exists( 'ldap_user', $auth_settings ) ) {
2162 $auth_settings['ldap_user'] = '';
2163 }
2164 if ( ! array_key_exists( 'ldap_password', $auth_settings ) ) {
2165 $auth_settings['ldap_password'] = '';
2166 }
2167 if ( ! array_key_exists( 'ldap_tls', $auth_settings ) ) {
2168 $auth_settings['ldap_tls'] = '1';
2169 }
2170 if ( ! array_key_exists( 'ldap_lostpassword_url', $auth_settings ) ) {
2171 $auth_settings['ldap_lostpassword_url'] = '';
2172 }
2173 if ( ! array_key_exists( 'ldap_attr_first_name', $auth_settings ) ) {
2174 $auth_settings['ldap_attr_first_name'] = '';
2175 }
2176 if ( ! array_key_exists( 'ldap_attr_last_name', $auth_settings ) ) {
2177 $auth_settings['ldap_attr_last_name'] = '';
2178 }
2179 if ( ! array_key_exists( 'ldap_attr_update_on_login', $auth_settings ) ) {
2180 $auth_settings['ldap_attr_update_on_login'] = '';
2181 }
2182
2183 // Advanced defaults.
2184 if ( ! array_key_exists( 'advanced_lockouts', $auth_settings ) ) {
2185 $auth_settings['advanced_lockouts'] = array(
2186 'attempts_1' => 10,
2187 'duration_1' => 1,
2188 'attempts_2' => 10,
2189 'duration_2' => 10,
2190 'reset_duration' => 120,
2191 );
2192 }
2193 if ( ! array_key_exists( 'advanced_hide_wp_login', $auth_settings ) ) {
2194 $auth_settings['advanced_hide_wp_login'] = '';
2195 }
2196 if ( ! array_key_exists( 'advanced_branding', $auth_settings ) ) {
2197 $auth_settings['advanced_branding'] = 'default';
2198 }
2199 if ( ! array_key_exists( 'advanced_admin_menu', $auth_settings ) ) {
2200 $auth_settings['advanced_admin_menu'] = 'top';
2201 }
2202 if ( ! array_key_exists( 'advanced_usermeta', $auth_settings ) ) {
2203 $auth_settings['advanced_usermeta'] = '';
2204 }
2205 if ( ! array_key_exists( 'advanced_override_multisite', $auth_settings ) ) {
2206 $auth_settings['advanced_override_multisite'] = '';
2207 }
2208
2209 // Save default options to database.
2210 update_option( 'auth_settings', $auth_settings );
2211 update_option( 'auth_settings_access_users_pending', $auth_settings_access_users_pending );
2212 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
2213 update_option( 'auth_settings_access_users_blocked', $auth_settings_access_users_blocked );
2214
2215 // Multisite defaults.
2216 if ( is_multisite() ) {
2217 $auth_multisite_settings = get_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings', array() );
2218
2219 if ( $auth_multisite_settings === FALSE ) {
2220 $auth_multisite_settings = array();
2221 }
2222 // Global switch for enabling multisite options.
2223 if ( ! array_key_exists( 'multisite_override', $auth_multisite_settings ) ) {
2224 $auth_multisite_settings['multisite_override'] = '';
2225 }
2226 // Access Lists Defaults.
2227 $auth_multisite_settings_access_users_approved = get_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings_access_users_approved' );
2228 if ( $auth_multisite_settings_access_users_approved === FALSE ) {
2229 $auth_multisite_settings_access_users_approved = array();
2230 }
2231 // Login Access Defaults.
2232 if ( ! array_key_exists( 'access_who_can_login', $auth_multisite_settings ) ) {
2233 $auth_multisite_settings['access_who_can_login'] = 'approved_users';
2234 }
2235 // View Access Defaults.
2236 if ( ! array_key_exists( 'access_who_can_view', $auth_multisite_settings ) ) {
2237 $auth_multisite_settings['access_who_can_view'] = 'everyone';
2238 }
2239 // External Service Defaults.
2240 if ( ! array_key_exists( 'access_default_role', $auth_multisite_settings ) ) {
2241 // Set default role to 'student' if that role exists, 'subscriber' otherwise.
2242 $all_roles = $wp_roles->roles;
2243 $editable_roles = apply_filters( 'editable_roles', $all_roles );
2244 if ( array_key_exists( 'student', $editable_roles ) ) {
2245 $auth_multisite_settings['access_default_role'] = 'student';
2246 } else {
2247 $auth_multisite_settings['access_default_role'] = 'subscriber';
2248 }
2249 }
2250 if ( ! array_key_exists( 'google', $auth_multisite_settings ) ) {
2251 $auth_multisite_settings['google'] = '';
2252 }
2253 if ( ! array_key_exists( 'cas', $auth_multisite_settings ) ) {
2254 $auth_multisite_settings['cas'] = '';
2255 }
2256 if ( ! array_key_exists( 'ldap', $auth_multisite_settings ) ) {
2257 $auth_multisite_settings['ldap'] = '';
2258 }
2259 if ( ! array_key_exists( 'google_clientid', $auth_multisite_settings ) ) {
2260 $auth_multisite_settings['google_clientid'] = '';
2261 }
2262 if ( ! array_key_exists( 'google_clientsecret', $auth_multisite_settings ) ) {
2263 $auth_multisite_settings['google_clientsecret'] = '';
2264 }
2265 if ( ! array_key_exists( 'cas_custom_label', $auth_multisite_settings ) ) {
2266 $auth_multisite_settings['cas_custom_label'] = 'CAS';
2267 }
2268 if ( ! array_key_exists( 'cas_host', $auth_multisite_settings ) ) {
2269 $auth_multisite_settings['cas_host'] = '';
2270 }
2271 if ( ! array_key_exists( 'cas_port', $auth_multisite_settings ) ) {
2272 $auth_multisite_settings['cas_port'] = '';
2273 }
2274 if ( ! array_key_exists( 'cas_path', $auth_multisite_settings ) ) {
2275 $auth_multisite_settings['cas_path'] = '';
2276 }
2277 if ( ! array_key_exists( 'cas_attr_email', $auth_multisite_settings ) ) {
2278 $auth_multisite_settings['cas_attr_email'] = '';
2279 }
2280 if ( ! array_key_exists( 'cas_attr_first_name', $auth_multisite_settings ) ) {
2281 $auth_multisite_settings['cas_attr_first_name'] = '';
2282 }
2283 if ( ! array_key_exists( 'cas_attr_last_name', $auth_multisite_settings ) ) {
2284 $auth_multisite_settings['cas_attr_last_name'] = '';
2285 }
2286 if ( ! array_key_exists( 'cas_attr_update_on_login', $auth_multisite_settings ) ) {
2287 $auth_multisite_settings['cas_attr_update_on_login'] = '';
2288 }
2289 if ( ! array_key_exists( 'ldap_host', $auth_multisite_settings ) ) {
2290 $auth_multisite_settings['ldap_host'] = '';
2291 }
2292 if ( ! array_key_exists( 'ldap_port', $auth_multisite_settings ) ) {
2293 $auth_multisite_settings['ldap_port'] = '';
2294 }
2295 if ( ! array_key_exists( 'ldap_search_base', $auth_multisite_settings ) ) {
2296 $auth_multisite_settings['ldap_search_base'] = '';
2297 }
2298 if ( ! array_key_exists( 'ldap_uid', $auth_multisite_settings ) ) {
2299 $auth_multisite_settings['ldap_uid'] = '';
2300 }
2301 if ( ! array_key_exists( 'ldap_attr_email', $auth_multisite_settings ) ) {
2302 $auth_multisite_settings['ldap_attr_email'] = '';
2303 }
2304 if ( ! array_key_exists( 'ldap_user', $auth_multisite_settings ) ) {
2305 $auth_multisite_settings['ldap_user'] = '';
2306 }
2307 if ( ! array_key_exists( 'ldap_password', $auth_multisite_settings ) ) {
2308 $auth_multisite_settings['ldap_password'] = '';
2309 }
2310 if ( ! array_key_exists( 'ldap_tls', $auth_multisite_settings ) ) {
2311 $auth_multisite_settings['ldap_tls'] = '1';
2312 }
2313 if ( ! array_key_exists( 'ldap_lostpassword_url', $auth_multisite_settings ) ) {
2314 $auth_multisite_settings['ldap_lostpassword_url'] = '';
2315 }
2316 if ( ! array_key_exists( 'ldap_attr_first_name', $auth_multisite_settings ) ) {
2317 $auth_multisite_settings['ldap_attr_first_name'] = '';
2318 }
2319 if ( ! array_key_exists( 'ldap_attr_last_name', $auth_multisite_settings ) ) {
2320 $auth_multisite_settings['ldap_attr_last_name'] = '';
2321 }
2322 if ( ! array_key_exists( 'ldap_attr_update_on_login', $auth_multisite_settings ) ) {
2323 $auth_multisite_settings['ldap_attr_update_on_login'] = '';
2324 }
2325 // Advanced defaults.
2326 if ( ! array_key_exists( 'advanced_lockouts', $auth_multisite_settings ) ) {
2327 $auth_multisite_settings['advanced_lockouts'] = array(
2328 'attempts_1' => 10,
2329 'duration_1' => 1,
2330 'attempts_2' => 10,
2331 'duration_2' => 10,
2332 'reset_duration' => 120,
2333 );
2334 }
2335 if ( ! array_key_exists( 'advanced_hide_wp_login', $auth_multisite_settings ) ) {
2336 $auth_multisite_settings['advanced_hide_wp_login'] = '';
2337 }
2338 // Save default network options to database.
2339 update_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings', $auth_multisite_settings );
2340 update_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
2341 }
2342 } // END set_default_options()
2343
2344
2345 /**
2346 * List sanitizer.
2347 * $side_effect = 'none' or 'update roles' to make sure WP user roles match
2348 * $multisite_mode = 'single' or 'multisite' to indicate which user roles to change (this site or all sites)
2349 */
2350 function sanitize_user_list( $list, $side_effect = 'none', $multisite_mode = 'single' ) {
2351 // If it's not a list, make it so.
2352 if ( ! is_array( $list ) ) {
2353 $list = array();
2354 }
2355 foreach ( $list as $key => $user_info ) {
2356 if ( strlen( $user_info['email'] ) < 1 ) {
2357 // Make sure there are no empty entries in the list
2358 unset( $list[$key] );
2359 } elseif ( $side_effect === 'update roles' ) {
2360 // Make sure the WordPress user accounts have the same role
2361 // as that indicated in the list.
2362 $wp_user = get_user_by( 'email', $user_info['email'] );
2363 if ( $wp_user ) {
2364 if ( is_multisite() && $multisite_mode === 'multisite' ) {
2365 foreach ( get_blogs_of_user( $wp_user->ID ) as $blog ) {
2366 add_user_to_blog( $blog->userblog_id, $wp_user->ID, $user_info['role'] );
2367 }
2368 } else {
2369 $wp_user->set_role( $user_info['role'] );
2370 }
2371 }
2372 }
2373 }
2374 return $list;
2375 }
2376
2377 /**
2378 * Settings sanitizer callback
2379 */
2380 function sanitize_options( $auth_settings, $multisite_mode = 'single' ) {
2381 // Default to "Approved Users" login access restriction.
2382 if ( ! in_array( $auth_settings['access_who_can_login'], array( 'external_users', 'approved_users' ) ) ) {
2383 $auth_settings['access_who_can_login'] = 'approved_users';
2384 }
2385
2386 // Default to "Everyone" view access restriction.
2387 if ( ! in_array( $auth_settings['access_who_can_view'], array( 'everyone', 'logged_in_users' ) ) ) {
2388 $auth_settings['access_who_can_view'] = 'everyone';
2389 }
2390
2391 // Default to WordPress login access redirect.
2392 if ( ! in_array( $auth_settings['access_redirect'], array( 'login', 'page', 'message' ) ) ) {
2393 $auth_settings['access_redirect'] = 'login';
2394 }
2395
2396 // Default to warning message for anonymous users on public pages.
2397 if ( ! in_array( $auth_settings['access_public_warning'], array( 'no_warning', 'warning' ) ) ) {
2398 $auth_settings['access_public_warning'] = 'no_warning';
2399 }
2400
2401 // Sanitize Enable Google Logins (checkbox: value can only be '1' or empty string)
2402 if ( array_key_exists( 'google', $auth_settings ) && strlen( $auth_settings['google'] ) > 0 ) {
2403 $auth_settings['google'] = '1';
2404 }
2405
2406 // Sanitize Enable CAS Logins (checkbox: value can only be '1' or empty string)
2407 if ( array_key_exists( 'cas', $auth_settings ) && strlen( $auth_settings['cas'] ) > 0 ) {
2408 $auth_settings['cas'] = '1';
2409 }
2410
2411 // Sanitize Enable LDAP Logins (checkbox: value can only be '1' or empty string)
2412 if ( array_key_exists( 'ldap', $auth_settings ) && strlen( $auth_settings['ldap'] ) > 0 ) {
2413 $auth_settings['ldap'] = '1';
2414 }
2415
2416 // Sanitize CAS Host setting
2417 $auth_settings['cas_host'] = filter_var( $auth_settings['cas_host'], FILTER_SANITIZE_URL );
2418
2419 // Sanitize CAS Port (int)
2420 $auth_settings['cas_port'] = filter_var( $auth_settings['cas_port'], FILTER_SANITIZE_NUMBER_INT );
2421
2422 // Sanitize CAS attribute update (checkbox: value can only be '1' or empty string)
2423 if ( array_key_exists( 'cas_attr_update_on_login', $auth_settings ) && strlen( $auth_settings['cas_attr_update_on_login'] ) > 0 ) {
2424 $auth_settings['cas_attr_update_on_login'] = '1';
2425 }
2426
2427 // Sanitize LDAP Host setting
2428 $auth_settings['ldap_host'] = filter_var( $auth_settings['ldap_host'], FILTER_SANITIZE_URL );
2429
2430 // Sanitize LDAP Port (int)
2431 $auth_settings['ldap_port'] = filter_var( $auth_settings['ldap_port'], FILTER_SANITIZE_NUMBER_INT );
2432
2433 // Sanitize LDAP attributes (basically make sure they don't have any parentheses)
2434 $auth_settings['ldap_uid'] = filter_var( $auth_settings['ldap_uid'], FILTER_SANITIZE_EMAIL );
2435
2436 // Sanitize LDAP TLS (checkbox: value can only be '1' or empty string)
2437 if ( array_key_exists( 'ldap_tls', $auth_settings ) && strlen( $auth_settings['ldap_tls'] ) > 0 ) {
2438 $auth_settings['ldap_tls'] = '1';
2439 }
2440
2441 // Sanitize LDAP Lost Password URL
2442 $auth_settings['ldap_lostpassword_url'] = filter_var( $auth_settings['ldap_lostpassword_url'], FILTER_SANITIZE_URL );
2443
2444 // Obfuscate LDAP directory user password
2445 if ( strlen( $auth_settings['ldap_password'] ) > 0 ) {
2446 // encrypt the directory user password for some minor obfuscation in the database.
2447 $auth_settings['ldap_password'] = base64_encode( $this->encrypt( $auth_settings['ldap_password'] ) );
2448 }
2449
2450 // Sanitize LDAP attribute update (checkbox: value can only be '1' or empty string)
2451 if ( array_key_exists( 'ldap_attr_update_on_login', $auth_settings ) && strlen( $auth_settings['ldap_attr_update_on_login'] ) > 0 ) {
2452 $auth_settings['ldap_attr_update_on_login'] = '1';
2453 }
2454
2455 // Make sure public pages is an empty array if it's empty
2456 if ( ! is_array( $auth_settings['access_public_pages'] ) ) {
2457 $auth_settings['access_public_pages'] = array();
2458 }
2459
2460 // Make sure all lockout options are integers (attempts_1,
2461 // duration_1, attempts_2, duration_2, reset_duration).
2462 foreach ( $auth_settings['advanced_lockouts'] as $key => $value ) {
2463 $auth_settings['advanced_lockouts'][$key] = filter_var( $value, FILTER_SANITIZE_NUMBER_INT );
2464 }
2465
2466 // Sanitize Hide WordPress logins (checkbox: value can only be '1' or empty string)
2467 if ( array_key_exists( 'advanced_hide_wp_login', $auth_settings ) && strlen( $auth_settings['advanced_hide_wp_login'] ) > 0 ) {
2468 $auth_settings['advanced_hide_wp_login'] = '1';
2469 }
2470
2471 return $auth_settings;
2472 } // END sanitize_options()
2473
2474
2475 /**
2476 * Keep authorizer approved users' roles in sync with WordPress roles
2477 * if someone changes the role via the WordPress Edit User options page.
2478 *
2479 * @action edit_user_profile_update
2480 * @ref https://codex.wordpress.org/Plugin_API/Action_Reference/edit_user_profile_update
2481 * @param int $user_id The user ID of the user being edited
2482 */
2483 function edit_user_profile_update_role( $user_id ) {
2484 if ( ! current_user_can( 'edit_user', $user_id ) ) {
2485 return;
2486 }
2487
2488 // If user is in approved list, update his/her associated role.
2489 $wp_user = get_user_by( 'id', $user_id );
2490 if ( $this->is_email_in_list( $wp_user->get( 'user_email' ), 'approved' ) ) {
2491 $auth_settings_access_users_approved = $this->sanitize_user_list(
2492 $this->get_plugin_option( 'access_users_approved', 'single admin' )
2493 );
2494 // Find approved user and update their role.
2495 foreach ( $auth_settings_access_users_approved as $key => $user ) {
2496 if ( $user['email'] === $wp_user->get( 'user_email' ) ) {
2497 $auth_settings_access_users_approved[$key]['role'] = $_REQUEST['role'];
2498 }
2499 }
2500
2501 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
2502 }
2503 }
2504
2505 /**
2506 * Settings print callbacks
2507 */
2508 function print_section_info_tabs( $args = '' ) {
2509 if ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ): ?>
2510 <h2 class="nav-tab-wrapper">
2511 <a class="nav-tab nav-tab-access_lists nav-tab-active" href="javascript:choose_tab('access_lists');">Access Lists</a>
2512 <a class="nav-tab nav-tab-external" href="javascript:choose_tab('external');">External Service</a>
2513 <a class="nav-tab nav-tab-advanced" href="javascript:choose_tab('advanced');">Advanced</a>
2514 </h2>
2515 <?php else: ?>
2516 <h2 class="nav-tab-wrapper">
2517 <a class="nav-tab nav-tab-access_lists nav-tab-active" href="javascript:choose_tab('access_lists');">Access Lists</a>
2518 <a class="nav-tab nav-tab-access_login" href="javascript:choose_tab('access_login');">Login Access</a>
2519 <a class="nav-tab nav-tab-access_public" href="javascript:choose_tab('access_public');">Public Access</a>
2520 <a class="nav-tab nav-tab-external" href="javascript:choose_tab('external');">External Service</a>
2521 <a class="nav-tab nav-tab-advanced" href="javascript:choose_tab('advanced');">Advanced</a>
2522 </h2>
2523 <?php endif;
2524 } // END print_section_info_tabs()
2525
2526
2527 function print_section_info_access_lists( $args = '' ) {
2528 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
2529 ?><div id="section_info_access_lists" class="section_info">
2530 <p>Manage who has access to this site using these lists.</p>
2531 <ol>
2532 <li><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.</li>
2533 <li><strong>Approved</strong> users have access to the site once they successfully log in.</li>
2534 <li><strong>Blocked</strong> users will receive an error message when they try to visit the site after authenticating.</li>
2535 </ol>
2536 </div>
2537 <table class="form-table">
2538 <tbody>
2539 <tr>
2540 <th scope="row">Pending Users <em>(<?php echo $this->get_user_count_from_list( 'pending', $admin_mode ); ?>)</em></th>
2541 <td><?php $this->print_combo_auth_access_users_pending(); ?></td>
2542 </tr>
2543 <tr>
2544 <th scope="row">Approved Users <em>(<?php echo $this->get_user_count_from_list( 'approved', $admin_mode ); ?>)</em></th>
2545 <td><?php $this->print_combo_auth_access_users_approved(); ?></td>
2546 </tr>
2547 <tr>
2548 <th scope="row">Blocked Users <em>(<?php echo $this->get_user_count_from_list( 'blocked', $admin_mode ); ?>)</em></th>
2549 <td><?php $this->print_combo_auth_access_users_blocked(); ?></td>
2550 </tr>
2551 </tbody>
2552 </table>
2553 <?php
2554 } // END print_section_info_access_lists()
2555
2556 function print_combo_auth_access_users_pending( $args = '' ) {
2557 // Get plugin option.
2558 $option = 'access_users_pending';
2559 $auth_settings_option = $this->get_plugin_option( $option );
2560 $auth_settings_option = is_array( $auth_settings_option ) ? $auth_settings_option : array();
2561
2562 // Print option elements.
2563 ?><ul id="list_auth_settings_access_users_pending" style="margin:0;">
2564 <?php if ( count( $auth_settings_option ) > 0 ) : ?>
2565 <?php foreach ( $auth_settings_option as $key => $pending_user ): ?>
2566 <?php if ( empty( $pending_user ) || count( $pending_user ) < 1 ) continue; ?>
2567 <?php $pending_user['is_wp_user'] = false; ?>
2568 <li>
2569 <input type="text" id="auth_settings_<?php echo $option; ?>_<?php echo $key; ?>" value="<?php echo $pending_user['email']; ?>" readonly="true" class="auth-email" />
2570 <select id="auth_settings_<?php echo $option; ?>_<?php echo $key; ?>_role" class="auth-role">
2571 <?php $this->wp_dropdown_permitted_roles( $pending_user['role'] ); ?>
2572 </select>
2573 <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> Approve</a>
2574 <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> Block</a>
2575 <a href="javascript:void(0);" class="button button-secondary" id="ignore_user_<?php echo $key; ?>" onclick="auth_ignore_user( this, 'pending' );" title="Remove user"><span class="glyphicon glyphicon-remove"></span> Ignore</a>
2576 </li>
2577 <?php endforeach; ?>
2578 <?php else: ?>
2579 <li class="auth-empty"><em>No pending users</em></li>
2580 <?php endif; ?>
2581 </ul>
2582 <?php
2583 } // END print_combo_auth_access_users_pending()
2584
2585 function print_combo_auth_access_users_approved( $args = '' ) {
2586 // Get plugin option.
2587 $option = 'access_users_approved';
2588 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
2589 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'no override' );
2590 $auth_settings_option = is_array( $auth_settings_option ) ? $auth_settings_option : array();
2591
2592 // Get multisite approved users (add them to top of list, greyed out).
2593 $auth_override_multisite = $this->get_plugin_option( 'advanced_override_multisite' );
2594 $auth_multisite_settings = $this->get_plugin_options( 'multisite admin' );
2595 $option_multisite = 'access_users_approved';
2596 $auth_settings_option_multisite = array();
2597 if (
2598 is_multisite() &&
2599 $auth_override_multisite != '1' &&
2600 array_key_exists( 'multisite_override', $auth_multisite_settings ) &&
2601 $auth_multisite_settings['multisite_override'] === '1'
2602 ) {
2603 $auth_settings_option_multisite = $this->get_plugin_option( $option, 'multisite admin', 'allow override' );
2604 $auth_settings_option_multisite = is_array( $auth_settings_option_multisite ) ? $auth_settings_option_multisite : array();
2605 }
2606
2607 // Get default role for new user dropdown.
2608 $access_default_role = $this->get_plugin_option( 'access_default_role', 'single admin', 'allow override' );
2609
2610 // Get custom usermeta field to show.
2611 $advanced_usermeta = $this->get_plugin_option( 'advanced_usermeta' );
2612
2613 // Adjust javascript function prefixes if multisite.
2614 $js_function_prefix = $admin_mode === 'multisite admin' ? 'auth_multisite_' : 'auth_';
2615 $multisite_admin_page = $admin_mode === 'multisite admin';
2616
2617 ?><ul id="list_auth_settings_access_users_approved" style="margin:0;">
2618 <?php if ( ! $multisite_admin_page ) :
2619 foreach ( $auth_settings_option_multisite as $key => $approved_user ) :
2620 if ( empty( $approved_user ) || count( $approved_user ) < 1 ) :
2621 continue;
2622 endif;
2623 $approved_wp_user = get_user_by( 'email', $approved_user['email'] );
2624 if ( $approved_wp_user ) :
2625 $approved_user['email'] = $approved_wp_user->user_email;
2626 $approved_user['role'] = $multisite_admin_page || count( $approved_wp_user->roles ) === 0 ? $approved_user['role'] : array_shift( $approved_wp_user->roles );
2627 $approved_user['date_added'] = $approved_wp_user->user_registered;
2628 // Get usermeta field from the WordPress user's real usermeta.
2629 if ( strlen( $advanced_usermeta ) > 0 ) :
2630 if ( strpos( $advanced_usermeta, 'acf___' ) === 0 && class_exists( 'acf' ) ) :
2631 // Get ACF Field value for the user
2632 $approved_user['usermeta'] = get_field( str_replace('acf___', '', $advanced_usermeta ), 'user_' . $approved_wp_user->ID );
2633 else :
2634 // Get regular usermeta value for the user.
2635 $approved_user['usermeta'] = get_user_meta( $approved_wp_user->ID, $advanced_usermeta, true );
2636 endif;
2637
2638 if ( is_array( $approved_user['usermeta'] ) || is_object( $approved_user['usermeta'] ) ) :
2639 $approved_user['usermeta'] = serialize( $approved_user['usermeta'] );
2640 endif;
2641 endif;
2642 endif;
2643 if ( ! array_key_exists( 'usermeta', $approved_user ) ) :
2644 $approved_user['usermeta'] = '';
2645 endif; ?>
2646 <li>
2647 <input type="text" id="auth_multisite_settings_<?php echo $option; ?>_<?php echo $key; ?>" value="<?php echo $approved_user['email']; ?>" readonly="true" class="auth-email auth-multisite-email" />
2648 <select id="auth_multisite_settings_<?php echo $option; ?>_<?php echo $key; ?>_role" class="auth-role auth-multisite-role" disabled="disabled">
2649 <?php $this->wp_dropdown_permitted_roles( $approved_user['role'] ); ?>
2650 </select>
2651 <input type="text" id="auth_multisite_settings_<?php echo $option; ?>_<?php echo $key; ?>_date_added" value="<?php echo date( 'M Y', strtotime( $approved_user['date_added'] ) ); ?>" readonly="true" class="auth-date-added auth-multisite-date-added" disabled="disabled" />
2652 <?php if ( strlen( $advanced_usermeta ) > 0 ) :
2653 $should_show_usermeta_in_text_field = true; // Fallback renderer for usermeta; try to use a select first.
2654 if ( strpos( $advanced_usermeta, 'acf___' ) === 0 && class_exists( 'acf' ) ) :
2655 $field_object = get_field_object( str_replace('acf___', '', $advanced_usermeta ) );
2656 if ( is_array( $field_object ) && array_key_exists( 'type', $field_object ) && $field_object['type'] === 'select' ) :
2657 $should_show_usermeta_in_text_field = false; ?>
2658 <select id="auth_settings_<?php echo $option; ?>_<?php echo $key; ?>_usermeta" class="auth-usermeta auth-multisite-usermeta" onchange="<?php echo $js_function_prefix; ?>update_usermeta( this );">
2659 <option value=""<?php if ( empty( $approved_user['usermeta'] ) ) echo ' selected="selected"'; ?>>-- None --</option>
2660 <?php foreach ( $field_object['choices'] as $key => $label ) : ?>
2661 <option value="<?php echo $key; ?>"<?php if ( $key === $approved_user['usermeta'] || ( is_array( $approved_user['usermeta'] ) && array_key_exists( get_current_blog_id(), $approved_user['usermeta'] ) && $key === $approved_user['usermeta'][get_current_blog_id()]['meta_value'] ) ) echo ' selected="selected"'; ?>><?php echo $label; ?></option>
2662 <?php endforeach; ?>
2663 </select>
2664 <?php endif; ?>
2665 <?php endif; ?>
2666 <?php if ( $should_show_usermeta_in_text_field ) : ?>
2667 <input type="text" id="auth_multisite_settings_<?php echo $option; ?>_<?php echo $key; ?>_usermeta" value="<?php echo htmlspecialchars( $approved_user['usermeta'], ENT_COMPAT ); ?>" class="auth-usermeta auth-multisite-usermeta" />
2668 <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>
2669 <?php endif; ?>
2670 <?php endif; ?>
2671 &nbsp;&nbsp;<a title="WordPress Multisite user" class="auth-multisite-user"><span class="glyphicon glyphicon-globe"></span></a>
2672 </li>
2673 <?php endforeach;
2674 endif;
2675 foreach ( $auth_settings_option as $key => $approved_user ):
2676 $is_current_user = false;
2677 $local_user_icon = array_key_exists( 'local_user', $approved_user ) && $approved_user['local_user'] === 'true' ? '&nbsp;<a title="Local WordPress user" class="auth-local-user"><span class="glyphicon glyphicon-user"></span></a>' : '';
2678 if ( empty( $approved_user ) || count( $approved_user ) < 1 ) :
2679 continue;
2680 endif;
2681 $approved_wp_user = get_user_by( 'email', $approved_user['email'] );
2682 if ( $approved_wp_user ) :
2683 $approved_user['email'] = $approved_wp_user->user_email;
2684 $approved_user['role'] = $multisite_admin_page || count( $approved_wp_user->roles ) === 0 ? $approved_user['role'] : array_shift( $approved_wp_user->roles );
2685 $approved_user['date_added'] = $approved_wp_user->user_registered;
2686 $approved_user['is_wp_user'] = true;
2687 $is_current_user = $approved_wp_user->ID === get_current_user_id();
2688 // Get usermeta field from the WordPress user's real usermeta.
2689 if ( strlen( $advanced_usermeta ) > 0 ) :
2690 if ( strpos( $advanced_usermeta, 'acf___' ) === 0 && class_exists( 'acf' ) ) :
2691 // Get ACF Field value for the user
2692 $approved_user['usermeta'] = get_field( str_replace('acf___', '', $advanced_usermeta ), 'user_' . $approved_wp_user->ID );
2693 else :
2694 // Get regular usermeta value for the user.
2695 $approved_user['usermeta'] = get_user_meta( $approved_wp_user->ID, $advanced_usermeta, true );
2696 endif;
2697
2698 if ( is_array( $approved_user['usermeta'] ) || is_object( $approved_user['usermeta'] ) ) :
2699 $approved_user['usermeta'] = serialize( $approved_user['usermeta'] );
2700 endif;
2701 endif;
2702 else :
2703 $approved_user['is_wp_user'] = false;
2704 endif;
2705 if ( ! array_key_exists( 'usermeta', $approved_user ) ) :
2706 $approved_user['usermeta'] = '';
2707 endif; ?>
2708 <li>
2709 <input type="text" id="auth_settings_<?php echo $option; ?>_<?php echo $key; ?>" value="<?php echo $approved_user['email']; ?>" readonly="true" class="auth-email" />
2710 <select id="auth_settings_<?php echo $option; ?>_<?php echo $key; ?>_role" class="auth-role" onchange="<?php echo $js_function_prefix; ?>change_role( this );">
2711 <?php $disable_input = $is_current_user ? 'disabled' : null; ?>
2712 <?php $this->wp_dropdown_permitted_roles( $approved_user['role'], $disable_input ); ?>
2713 </select>
2714 <input type="text" id="auth_settings_<?php echo $option; ?>_<?php echo $key; ?>_date_added" value="<?php echo date( 'M Y', strtotime( $approved_user['date_added'] ) ); ?>" readonly="true" class="auth-date-added" />
2715 <?php if ( strlen( $advanced_usermeta ) > 0 ) :
2716 $should_show_usermeta_in_text_field = true; // Fallback renderer for usermeta; try to use a select first.
2717 if ( strpos( $advanced_usermeta, 'acf___' ) === 0 && class_exists( 'acf' ) ) :
2718 $field_object = get_field_object( str_replace('acf___', '', $advanced_usermeta ) );
2719 if ( is_array( $field_object ) && array_key_exists( 'type', $field_object ) && $field_object['type'] === 'select' ) :
2720 $should_show_usermeta_in_text_field = false; ?>
2721 <select id="auth_settings_<?php echo $option; ?>_<?php echo $key; ?>_usermeta" class="auth-usermeta" onchange="<?php echo $js_function_prefix; ?>update_usermeta( this );" >
2722 <option value=""<?php if ( empty( $approved_user['usermeta'] ) ) echo ' selected="selected"'; ?>>-- None --</option>
2723 <?php foreach ( $field_object['choices'] as $key => $label ) : ?>
2724 <option value="<?php echo $key; ?>"<?php if ( $key === $approved_user['usermeta'] || ( is_array( $approved_user['usermeta'] ) && $key === $approved_user['usermeta']['meta_value'] ) ) echo ' selected="selected"'; ?>><?php echo $label; ?></option>
2725 <?php endforeach; ?>
2726 </select>
2727 <?php endif; ?>
2728 <?php endif; ?>
2729 <?php if ( $should_show_usermeta_in_text_field ) : ?>
2730 <input type="text" id="auth_settings_<?php echo $option; ?>_<?php echo $key; ?>_usermeta" value="<?php echo htmlspecialchars( $approved_user['usermeta'], ENT_COMPAT ); ?>" class="auth-usermeta" />
2731 <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>
2732 <?php endif; ?>
2733 <?php endif; ?>
2734 <?php if ( ! $is_current_user ): ?>
2735 <?php if ( ! $multisite_admin_page ) : ?>
2736 <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="Block/Ban user"><span class="glyphicon glyphicon-ban-circle"></span></a>
2737 <?php endif; ?>
2738 <a class="button" id="ignore_user_<?php echo $key; ?>" onclick="<?php echo $js_function_prefix; ?>ignore_user(this, 'approved');" title="Remove user"><span class="glyphicon glyphicon-remove"></span></a>
2739 <?php endif; ?>
2740 <?php echo $local_user_icon; ?>
2741 </li>
2742 <?php endforeach; ?>
2743 </ul>
2744 <div id="new_auth_settings_<?php echo $option; ?>">
2745 <input type="text" id="new_approved_user_email" placeholder="email address" class="auth-email new" />
2746 <select id="new_approved_user_role" class="auth-role">
2747 <?php $this->wp_dropdown_permitted_roles( $access_default_role ); ?>
2748 </select>
2749 <div class="btn-group">
2750 <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> Approve</a>
2751 <button type="button" class="btn button-primary dropdown-toggle" data-toggle="dropdown">
2752 <span class="caret"></span>
2753 <span class="sr-only">Toggle Dropdown</span>
2754 </button>
2755 <ul class="dropdown-menu" role="menu">
2756 <li><a href="javascript:void(0);" onclick="<?php echo $js_function_prefix; ?>add_user( document.getElementById('approve_user_new'), 'approved', true);">Create a local WordPress <br />account instead, and email <br />the user their password.</a></li>
2757 </ul>
2758 </div>
2759 </div>
2760 <?php
2761 } // END print_combo_auth_access_users_approved()
2762
2763 function print_combo_auth_access_users_blocked( $args = '' ) {
2764 // Get plugin option.
2765 $option = 'access_users_blocked';
2766 $auth_settings_option = $this->get_plugin_option( $option );
2767 $auth_settings_option = is_array( $auth_settings_option ) ? $auth_settings_option : array();
2768
2769 // Get default role for new blocked user dropdown.
2770 $access_default_role = $this->get_plugin_option( 'access_default_role', 'single admin', 'allow override' );
2771
2772 // Print option elements.
2773 ?><ul id="list_auth_settings_<?php echo $option; ?>" style="margin:0;">
2774 <?php foreach ( $auth_settings_option as $key => $blocked_user ): ?>
2775 <?php if ( empty( $blocked_user ) || count( $blocked_user ) < 1 ) continue; ?>
2776 <?php if ( $blocked_wp_user = get_user_by( 'email', $blocked_user['email'] ) ): ?>
2777 <?php $blocked_user['email'] = $blocked_wp_user->user_email; ?>
2778 <?php $blocked_user['role'] = array_shift( $blocked_wp_user->roles ); ?>
2779 <?php $blocked_user['date_added'] = $blocked_wp_user->user_registered; ?>
2780 <?php $blocked_user['is_wp_user'] = true; ?>
2781 <?php else: ?>
2782 <?php $blocked_user['is_wp_user'] = false; ?>
2783 <?php endif; ?>
2784 <li>
2785 <input type="text" id="auth_settings_<?php echo $option; ?>_<?php echo $key; ?>" value="<?php echo $blocked_user['email']; ?>" readonly="true" class="auth-email" />
2786 <select id="auth_settings_<?php echo $option; ?>_<?php echo $key; ?>_role" class="auth-role">
2787 <?php $this->wp_dropdown_permitted_roles( $blocked_user['role'] ); ?>
2788 </select>
2789 <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" />
2790 <a class="button" id="ignore_user_<?php echo $key; ?>" onclick="auth_ignore_user(this, 'blocked');" title="Remove user"><span class="glyphicon glyphicon-remove"></span></a>
2791 </li>
2792 <?php endforeach; ?>
2793 </ul>
2794 <div id="new_auth_settings_<?php echo $option; ?>">
2795 <input type="text" id="new_blocked_user_email" placeholder="email address" class="auth-email new" />
2796 <select id="new_blocked_user_role" class="auth-role">
2797 <option value="<?php echo $access_default_role; ?>"><?php echo ucfirst( $access_default_role ); ?></option>
2798 </select>
2799 <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> Block</a>
2800 </div>
2801 <?php
2802 } // END print_combo_auth_access_users_blocked()
2803
2804
2805 function print_section_info_access_login( $args = '' ) {
2806 ?><div id="section_info_access_login" class="section_info">
2807 <?php wp_nonce_field( 'save_auth_settings', 'nonce_save_auth_settings' ); ?>
2808 <p>Choose who is able to log into this site below.</p>
2809 </div><?php
2810 } // END print_section_info_access_login()
2811
2812 function print_radio_auth_access_who_can_login( $args = '' ) {
2813 // Get plugin option.
2814 $option = 'access_who_can_login';
2815 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
2816 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
2817
2818 // 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.
2819 if ( is_multisite() && $this->get_plugin_option( 'advanced_override_multisite' ) == '1' ) {
2820 $auth_settings_option = $this->get_plugin_option( $option );
2821 } else if ( is_multisite() && $admin_mode === 'single admin' && $this->get_plugin_option( 'multisite_override', 'multisite admin' ) === '1' ) {
2822 // Workaround: javascript code hides/shows other settings based
2823 // on the selection in this option. If this option is overridden
2824 // by a multisite option, it should show that value in order to
2825 // correctly display the other appropriate options.
2826 // Side effect: this site option will be overwritten by the
2827 // multisite option on save. Since this is a 2-item radio, we
2828 // determined this was acceptable.
2829 $auth_settings_option = $this->get_plugin_option( $option, 'multisite admin' );
2830 }
2831
2832 // Print option elements.
2833 ?><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">All authenticated users (All external service users and all WordPress users)</label><br />
2834 <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">Only <a href="javascript:choose_tab('access_lists');" id="dashboard_link_approved_users">approved users</a> (Approved external users and all WordPress users)</label><br /><?php
2835 } // END print_radio_auth_access_who_can_login()
2836
2837 function print_select_auth_access_role_receive_pending_emails( $args = '' ) {
2838 // Get plugin option.
2839 $option = 'access_role_receive_pending_emails';
2840 $auth_settings_option = $this->get_plugin_option( $option );
2841
2842 // Print option elements.
2843 ?><select id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]">
2844 <option value="---" <?php selected( $auth_settings_option, '---' ); ?>>None (Don't send notification emails)</option>
2845 <?php wp_dropdown_roles( $auth_settings_option ); ?>
2846 </select><?php
2847 } // END print_select_auth_access_role_receive_pending_emails()
2848
2849 function print_wysiwyg_auth_access_pending_redirect_to_message( $args = '' ) {
2850 // Get plugin option.
2851 $option = 'access_pending_redirect_to_message';
2852 $auth_settings_option = $this->get_plugin_option( $option );
2853
2854 // Print option elements.
2855 wp_editor(
2856 wpautop( $auth_settings_option ),
2857 "auth_settings_$option",
2858 array(
2859 'media_buttons' => false,
2860 'textarea_name' => "auth_settings[$option]",
2861 'textarea_rows' => 5,
2862 'tinymce' => true,
2863 'teeny' => true,
2864 'quicktags' => false,
2865 )
2866 );
2867 } // END print_wysiwyg_auth_access_pending_redirect_to_message()
2868
2869 function print_wysiwyg_auth_access_blocked_redirect_to_message( $args = '' ) {
2870 // Get plugin option.
2871 $option = 'access_blocked_redirect_to_message';
2872 $auth_settings_option = $this->get_plugin_option( $option );
2873
2874 // Print option elements.
2875 wp_editor(
2876 wpautop( $auth_settings_option ),
2877 "auth_settings_$option",
2878 array(
2879 'media_buttons' => false,
2880 'textarea_name' => "auth_settings[$option]",
2881 'textarea_rows' => 5,
2882 'tinymce' => true,
2883 'teeny' => true,
2884 'quicktags' => false,
2885 )
2886 );
2887 } // END print_wysiwyg_auth_access_blocked_redirect_to_message()
2888
2889 function print_checkbox_auth_access_should_email_approved_users( $args = '' ) {
2890 // Get plugin option.
2891 $option = 'access_should_email_approved_users';
2892 $auth_settings_option = $this->get_plugin_option( $option );
2893
2894 // Print option elements.
2895 ?><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; ?>">Send a welcome email when approving a new user</label><?php
2896 } // END print_checkbox_auth_external_ldap()
2897
2898 function print_text_auth_access_email_approved_users_subject( $args = '' ) {
2899 // Get plugin option.
2900 $option = 'access_email_approved_users_subject';
2901 $auth_settings_option = $this->get_plugin_option( $option );
2902
2903 // Print option elements.
2904 ?><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>You can use the <b>[site_name]</b> shortcode.</small><?php
2905 } // END print_text_auth_access_email_approved_users_subject()
2906
2907 function print_wysiwyg_auth_access_email_approved_users_body( $args = '' ) {
2908 // Get plugin option.
2909 $option = 'access_email_approved_users_body';
2910 $auth_settings_option = $this->get_plugin_option( $option );
2911
2912 // Print option elements.
2913 wp_editor(
2914 wpautop( $auth_settings_option ),
2915 "auth_settings_$option",
2916 array(
2917 'media_buttons' => false,
2918 'textarea_name' => "auth_settings[$option]",
2919 'textarea_rows' => 9,
2920 'tinymce' => true,
2921 'teeny' => true,
2922 'quicktags' => false,
2923 )
2924 );
2925
2926 ?><small>You can use <b>[site_name]</b>, <b>[site_url]</b>, and <b>[user_email]</b> shortcodes.</small><?php
2927
2928 } // END print_wysiwyg_auth_access_email_approved_users_body()
2929
2930
2931 function print_section_info_access_public( $args = '' ) {
2932 ?><div id="section_info_access_public" class="section_info">
2933 <p>Choose your public access options here.</p>
2934 </div><?php
2935 } // END print_section_info_access_public()
2936
2937 function print_radio_auth_access_who_can_view( $args = '' ) {
2938 // Get plugin option.
2939 $option = 'access_who_can_view';
2940 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
2941 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
2942
2943 // 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.
2944 if ( is_multisite() && $this->get_plugin_option( 'advanced_override_multisite' ) == '1' ) {
2945 $auth_settings_option = $this->get_plugin_option( $option );
2946 } else if ( is_multisite() && $admin_mode === 'single admin' && $this->get_plugin_option( 'multisite_override', 'multisite admin' ) === '1' ) {
2947 // Workaround: javascript code hides/shows other settings based
2948 // on the selection in this option. If this option is overridden
2949 // by a multisite option, it should show that value in order to
2950 // correctly display the other appropriate options.
2951 // Side effect: this site option will be overwritten by the
2952 // multisite option on save. Since this is a 2-item radio, we
2953 // determined this was acceptable.
2954 $auth_settings_option = $this->get_plugin_option( $option, 'multisite admin' );
2955 }
2956
2957 // Print option elements.
2958 ?><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">Everyone can see the site</label><br />
2959 <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">Only logged in users can see the site</label><br /><?php
2960 } // END print_radio_auth_access_who_can_view()
2961
2962 function print_radio_auth_access_redirect( $args = '' ) {
2963 // Get plugin option.
2964 $option = 'access_redirect';
2965 $auth_settings_option = $this->get_plugin_option( $option );
2966
2967 // Print option elements.
2968 ?><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">Send them to the login screen</label><br />
2969 <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">Show them the anonymous access message (below)</label><?php
2970 } // END print_radio_auth_access_redirect()
2971
2972 function print_radio_auth_access_public_warning( $args = '' ) {
2973 // Get plugin option.
2974 $option = 'access_public_warning';
2975 $auth_settings_option = $this->get_plugin_option( $option );
2976
2977 // Print option elements.
2978 ?><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">Show them the page <strong>without</strong> the anonymous access message</label><br />
2979 <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; ?>">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>)</label><?php
2980 } // END print_radio_auth_access_public_warning()
2981
2982 function print_wysiwyg_auth_access_redirect_to_message( $args = '' ) {
2983 // Get plugin option.
2984 $option = 'access_redirect_to_message';
2985 $auth_settings_option = $this->get_plugin_option( $option );
2986
2987 // Print option elements.
2988 wp_editor(
2989 wpautop( $auth_settings_option ),
2990 "auth_settings_$option",
2991 array(
2992 'media_buttons' => false,
2993 'textarea_name' => "auth_settings[$option]",
2994 'textarea_rows' => 5,
2995 'tinymce' => true,
2996 'teeny' => true,
2997 'quicktags' => false,
2998 )
2999 );
3000 } // END print_wysiwyg_auth_access_redirect_to_message()
3001
3002 function print_multiselect_auth_access_public_pages( $args = '' ) {
3003 // Get plugin option.
3004 $option = 'access_public_pages';
3005 $auth_settings_option = $this->get_plugin_option( $option );
3006 $auth_settings_option = is_array( $auth_settings_option ) ? $auth_settings_option : array();
3007
3008 $post_types = array_merge( array( 'page', 'post' ), get_post_types( array( '_builtin' => false ), 'names' ) );
3009 $post_types = is_array( $post_types ) ? $post_types : array();
3010
3011 // Print option elements.
3012 ?><select id="auth_settings_<?php echo $option; ?>" multiple="multiple" name="auth_settings[<?php echo $option; ?>][]">
3013 <optgroup label="Home">
3014 <option value="home" <?php echo in_array( 'home', $auth_settings_option ) ? 'selected="selected"' : ''; ?>>Home Page</option>
3015 </optgroup>
3016 <?php foreach ( $post_types as $post_type ): ?>
3017 <optgroup label="<?php echo ucfirst( $post_type ); ?>">
3018 <?php $pages = get_posts( array( 'post_type' => $post_type, 'posts_per_page' => -1 ) ); ?>
3019 <?php $pages = is_array( $pages ) ? $pages : array(); ?>
3020 <?php foreach ( $pages as $page ): ?>
3021 <option value="<?php echo $page->ID; ?>" <?php echo in_array( $page->ID, $auth_settings_option ) ? 'selected="selected"' : ''; ?>><?php echo $page->post_title; ?></option>
3022 <?php endforeach; ?>
3023 </optgroup>
3024 <?php endforeach; ?>
3025 <optgroup label="Categories">
3026 <?php foreach ( get_categories() as $category ) : ?>
3027 <option value="<?php echo 'cat_' . $category->slug; ?>" <?php echo in_array( 'cat_' . $category->slug, $auth_settings_option ) ? 'selected="selected"' : ''; ?>><?php echo $category->name; ?></option>
3028 <?php endforeach; ?>
3029 </optgroup>
3030 </select><?php
3031 } // END print_multiselect_auth_access_public_pages()
3032
3033
3034 function print_section_info_external( $args = '' ) {
3035 ?><div id="section_info_external" class="section_info">
3036 <p>Enter your external server settings below.</p>
3037 </div><?php
3038 } // END print_section_info_external()
3039
3040 function print_select_auth_access_default_role( $args = '' ) {
3041 // Get plugin option.
3042 $option = 'access_default_role';
3043 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3044 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3045
3046 // Print option elements.
3047 ?><select id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]">
3048 <?php wp_dropdown_roles( $auth_settings_option ); ?>
3049 </select><?php
3050 } // END print_select_auth_access_default_role()
3051
3052 function print_checkbox_auth_external_google( $args = '' ) {
3053 // Get plugin option.
3054 $option = 'google';
3055 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3056 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3057
3058 // Make sure php5-curl extension is installed on server.
3059 $curl_installed_message = ! function_exists( 'curl_init' ) ? '<span style="color: red;">(Warning: <a href="http://www.php.net//manual/en/curl.installation.php" target="_blank" style="color: red;">PHP CURL extension</a> is <strong>not</strong> installed)</span>' : '';
3060
3061 // Print option elements.
3062 ?><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; ?>">Enable Google Logins</label> <?php echo $curl_installed_message; ?><?php
3063 } // END print_checkbox_auth_external_google()
3064
3065 function print_text_google_clientid( $args = '' ) {
3066 // Get plugin option.
3067 $option = 'google_clientid';
3068 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3069 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3070
3071 // Print option elements.
3072 $site_url_parts = parse_url( get_site_url() );
3073 $site_url_host = $site_url_parts['scheme'] . '://' . $site_url_parts['host'] . '/';
3074 ?>If you don't have a Google Client ID and Secret, generate them by following these instructions:
3075 <ol>
3076 <li>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.</li>
3077 <li>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:
3078 <ul>
3079 <li>Application Type: <strong>Web application</strong></li>
3080 <li>Authorized Javascript Origins: <strong><?php echo $site_url_host; ?></strong></li>
3081 <li>Authorized Redirect URI: <em>none</em></li>
3082 </ul>
3083 </li>
3084 <li>Copy/paste your new Client ID/Secret pair into the fields below.</li>
3085 <li><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.</li>
3086 </ol>
3087 <input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="1234567890123-kdjr85yt6vjr6d8g7dhr8g7d6durjf7g.apps.googleusercontent.com" style="width:560px;" /><?php
3088 } // END print_text_google_clientid()
3089
3090 function print_text_google_clientsecret( $args = '' ) {
3091 // Get plugin option.
3092 $option = 'google_clientsecret';
3093 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3094 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3095
3096 // Print option elements.
3097 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="sDNgX5_pr_5bly-frKmvp8jT" style="width:220px;" /><?php
3098 } // END print_text_google_clientsecret()
3099
3100 function print_checkbox_auth_external_cas( $args = '' ) {
3101 // Get plugin option.
3102 $option = 'cas';
3103 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3104 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3105
3106 // Make sure php5-curl extension is installed on server.
3107 $curl_installed_message = ! function_exists( 'curl_init' ) ? '<span style="color: red;">(Warning: <a href="http://www.php.net//manual/en/curl.installation.php" target="_blank" style="color: red;">PHP CURL extension</a> is <strong>not</strong> installed)</span>' : '';
3108
3109 // Print option elements.
3110 ?><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; ?>">Enable CAS Logins</label> <?php echo $curl_installed_message; ?><?php
3111 } // END print_checkbox_auth_external_cas()
3112
3113 function print_text_cas_custom_label( $args = '' ) {
3114 // Get plugin option.
3115 $option = 'cas_custom_label';
3116 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3117 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3118
3119 // Print option elements.
3120 ?>The button on the login page will read:<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>Sign in with </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
3121 } // END print_text_cas_custom_label()
3122
3123 function print_text_cas_host( $args = '' ) {
3124 // Get plugin option.
3125 $option = 'cas_host';
3126 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3127 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3128
3129 // Print option elements.
3130 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="authn.example.edu" /><?php
3131 } // END print_text_cas_host()
3132
3133 function print_text_cas_port( $args = '' ) {
3134 // Get plugin option.
3135 $option = 'cas_port';
3136 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3137 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3138
3139 // Print option elements.
3140 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="443" style="width:50px;" /><?php
3141 } // END print_text_cas_port()
3142
3143 function print_text_cas_path( $args = '' ) {
3144 // Get plugin option.
3145 $option = 'cas_path';
3146 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3147 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3148
3149 // Print option elements.
3150 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="/cas" /><?php
3151 } // END print_text_cas_path()
3152
3153 function print_text_cas_attr_email( $args = '' ) {
3154 // Get plugin option.
3155 $option = 'cas_attr_email';
3156 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3157 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3158
3159 // Print option elements.
3160 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="mail" /><?php
3161 } // END print_text_cas_attr_email()
3162
3163 function print_text_cas_attr_first_name( $args = '' ) {
3164 // Get plugin option.
3165 $option = 'cas_attr_first_name';
3166 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3167 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3168
3169 // Print option elements.
3170 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="givenName" /><?php
3171 } // END print_text_cas_attr_first_name()
3172
3173 function print_text_cas_attr_last_name( $args = '' ) {
3174 // Get plugin option.
3175 $option = 'cas_attr_last_name';
3176 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3177 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3178
3179 // Print option elements.
3180 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="sn" /><?php
3181 } // END print_text_cas_attr_last_name()
3182
3183 function print_checkbox_cas_attr_update_on_login( $args = '' ) {
3184 // Get plugin option.
3185 $option = 'cas_attr_update_on_login';
3186 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3187 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3188
3189 // Print option elements.
3190 ?><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; ?>">Update first and last name fields on login (will overwrite any name the user has supplied in their profile)</label><?php
3191 } // END print_checkbox_cas_attr_update_on_login()
3192
3193
3194 function print_checkbox_auth_external_ldap( $args = '' ) {
3195 // Get plugin option.
3196 $option = 'ldap';
3197 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3198 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3199
3200 // Make sure php5-ldap extension is installed on server.
3201 $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)</span>' : '';
3202
3203 // Print option elements.
3204 ?><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; ?>">Enable LDAP Logins</label> <?php echo $ldap_installed_message; ?><?php
3205 } // END print_checkbox_auth_external_ldap()
3206
3207 function print_text_ldap_host( $args = '' ) {
3208 // Get plugin option.
3209 $option = 'ldap_host';
3210 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3211 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3212
3213 // Print option elements.
3214 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="ldap.example.edu" /><?php
3215 } // END print_text_ldap_host()
3216
3217 function print_text_ldap_port( $args = '' ) {
3218 // Get plugin option.
3219 $option = 'ldap_port';
3220 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3221 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3222
3223 // Print option elements.
3224 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="389" style="width:50px;" /><?php
3225 } // END print_text_ldap_port()
3226
3227 function print_text_ldap_search_base( $args = '' ) {
3228 // Get plugin option.
3229 $option = 'ldap_search_base';
3230 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3231 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3232
3233 // Print option elements.
3234 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="ou=people,dc=example,dc=edu" style="width:225px;" /><?php
3235 } // END print_text_ldap_search_base()
3236
3237 function print_text_ldap_uid( $args = '' ) {
3238 // Get plugin option.
3239 $option = 'ldap_uid';
3240 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3241 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3242
3243 // Print option elements.
3244 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="uid" style="width:80px;" /><?php
3245 } // END print_text_ldap_uid()
3246
3247 function print_text_ldap_attr_email( $args = '' ) {
3248 // Get plugin option.
3249 $option = 'ldap_attr_email';
3250 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3251 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3252
3253 // Print option elements.
3254 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="mail" /><?php
3255 } // END print_text_ldap_attr_email()
3256
3257 function print_text_ldap_user( $args = '' ) {
3258 // Get plugin option.
3259 $option = 'ldap_user';
3260 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3261 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3262
3263 // Print option elements.
3264 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="cn=directory-user,ou=specials,dc=example,dc=edu" style="width:330px;" /><?php
3265 } // END print_text_ldap_user()
3266
3267 function print_password_ldap_password( $args = '' ) {
3268 // Get plugin option.
3269 $option = 'ldap_password';
3270 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3271 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3272
3273 // Print option elements.
3274 ?><input type="password" id="garbage_to_stop_autofill" name="garbage" value="" autocomplete="off" style="display:none;" />
3275 <input type="password" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $this->decrypt( base64_decode( $auth_settings_option ) ); ?>" autocomplete="off" /><?php
3276 } // END print_password_ldap_password()
3277
3278 function print_checkbox_ldap_tls( $args = '' ) {
3279 // Get plugin option.
3280 $option = 'ldap_tls';
3281 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3282 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3283
3284 // Print option elements.
3285 ?><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; ?>">Use TLS</label><?php
3286 } // END print_checkbox_ldap_tls
3287
3288 function print_text_ldap_lostpassword_url( $args = '' ) {
3289 // Get plugin option.
3290 $option = 'ldap_lostpassword_url';
3291 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3292 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3293
3294 // Print option elements.
3295 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="https://myschool.example.edu:8888/am-forgot-password" style="width: 400px;" /><?php
3296 } // END print_text_ldap_lostpassword_url()
3297
3298 function print_text_ldap_attr_first_name( $args = '' ) {
3299 // Get plugin option.
3300 $option = 'ldap_attr_first_name';
3301 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3302 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3303
3304 // Print option elements.
3305 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="givenname" /><?php
3306 } // END print_text_ldap_attr_first_name()
3307
3308 function print_text_ldap_attr_last_name( $args = '' ) {
3309 // Get plugin option.
3310 $option = 'ldap_attr_last_name';
3311 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3312 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3313
3314 // Print option elements.
3315 ?><input type="text" id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]" value="<?php echo $auth_settings_option; ?>" placeholder="sn" /><?php
3316 } // END print_text_ldap_attr_last_name()
3317
3318 function print_checkbox_ldap_attr_update_on_login( $args = '' ) {
3319 // Get plugin option.
3320 $option = 'ldap_attr_update_on_login';
3321 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3322 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3323
3324 // Print option elements.
3325 ?><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; ?>">Update first and last name fields on login (will overwrite any name the user has supplied in their profile)</label><?php
3326 } // END print_checkbox_ldap_attr_update_on_login()
3327
3328
3329 function print_section_info_advanced( $args = '' ) {
3330 ?><div id="section_info_advanced" class="section_info">
3331 <p>You may optionally specify some advanced settings below.</p>
3332 </div><?php
3333 } // END print_section_info_advanced()
3334
3335 function print_text_auth_advanced_lockouts( $args = '' ) {
3336 // Get plugin option.
3337 $option = 'advanced_lockouts';
3338 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3339 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3340
3341 // Print option elements.
3342 ?>After
3343 <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;" />
3344 invalid password attempts, delay further attempts on that user for
3345 <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;" />
3346 minute(s).
3347 <br />
3348 After
3349 <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;" />
3350 more invalid attempts, increase the delay to
3351 <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;" />
3352 minutes.
3353 <br />
3354 Reset the delays after
3355 <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;" />
3356 minutes with no invalid attempts.<?php
3357 } // END print_text_auth_advanced_lockouts()
3358
3359 function print_checkbox_auth_advanced_hide_wp_login( $args = '' ) {
3360 // Get plugin option.
3361 $option = 'advanced_hide_wp_login';
3362 $admin_mode = ( is_array( $args ) && array_key_exists( 'multisite_admin', $args ) && $args['multisite_admin'] === true ) ? 'multisite admin' : 'single admin';
3363 $auth_settings_option = $this->get_plugin_option( $option, $admin_mode, 'allow override', 'print overlay' );
3364
3365 // Print option elements.
3366 ?><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; ?>">Hide WordPress Logins</label>
3367 <p><small>Note: You can always access the WordPress logins by adding external=wordpress to the wp-login URL, like so:<br /><a href="<?php echo wp_login_url(); ?>?external=wordpress" target="_blank"><?php echo wp_login_url(); ?>?external=wordpress</a>.</p><?php
3368 } // END print_checkbox_auth_advanced_hide_wp_login()
3369
3370 function print_radio_auth_advanced_branding( $args = '' ) {
3371 // Get plugin option.
3372 $option = 'advanced_branding';
3373 $auth_settings_option = $this->get_plugin_option( $option );
3374
3375 // Print option elements.
3376 ?><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">Default WordPress login screen</label><br />
3377 <?php
3378
3379 /**
3380 * Developers can use the `authorizer_add_branding_option` filter
3381 * to add a radio button for "Custom WordPress login branding"
3382 * under the "Advanced" tab in Authorizer options. Example:
3383 *
3384 * function my_authorizer_add_branding_option( $branding_options ) {
3385 * $new_branding_option = array(
3386 * 'value' => 'your_brand'
3387 * 'description' => 'Custom Your Brand Login Screen',
3388 * 'css_url' => 'http://url/to/your_brand.css',
3389 * 'js_url' => 'http://url/to/your_brand.js',
3390 * );
3391 * array_push( $branding_options, $new_branding_option );
3392 * return $branding_options;
3393 * }
3394 * add_filter( 'authorizer_add_branding_option', 'my_authorizer_add_branding_option' );
3395 */
3396 $branding_options = array();
3397 $branding_options = apply_filters( 'authorizer_add_branding_option', $branding_options );
3398 foreach ( $branding_options as $branding_option ) {
3399 // Make sure the custom brands have the required values
3400 if ( ! ( is_array( $branding_option ) && array_key_exists( 'value', $branding_option ) && array_key_exists( 'description', $branding_option ) ) ) {
3401 continue;
3402 }
3403 ?><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
3404 }
3405
3406 // Print message about adding custom brands if there are none.
3407 if ( count( $branding_options ) === 0 ) {
3408 ?><p><em><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.</em></p><?php
3409 }
3410 } // END print_radio_auth_advanced_branding()
3411
3412 function print_radio_auth_advanced_admin_menu( $args = '' ) {
3413 // Get plugin option.
3414 $option = 'advanced_admin_menu';
3415 $auth_settings_option = $this->get_plugin_option( $option );
3416
3417 // Print option elements.
3418 ?><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">Show in Settings menu</label><br />
3419 <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">Show in sidebar (top level)</label><br /><?php
3420
3421 } // END print_radio_auth_advanced_admin_menu()
3422
3423 function print_select_auth_advanced_usermeta( $args = '' ) {
3424 // Get plugin option.
3425 $option = 'advanced_usermeta';
3426 $auth_settings_option = $this->get_plugin_option( $option );
3427
3428 // Print option elements.
3429 ?><select id="auth_settings_<?php echo $option; ?>" name="auth_settings[<?php echo $option; ?>]">
3430 <option value="">-- None --</option>
3431 <?php if ( class_exists( 'acf' ) ) :
3432 // Get ACF 5 fields. Note: it would be much easier to use `get_field_objects()`
3433 // or `get_field_objects( 'user_' . get_current_user_id() )`, but neither will
3434 // list fields that have never been given values for users (i.e., new ACF
3435 // fields). Therefore we fall back on finding any ACF fields applied to users
3436 // (user_role or user_form location rules in the field group definition).
3437 $fields = array();
3438 $acf_field_group_ids = array();
3439 $acf_field_groups = new WP_Query( array(
3440 'post_type' => 'acf-field-group',
3441 ));
3442 while ( $acf_field_groups->have_posts() ) : $acf_field_groups->the_post();
3443 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 ) :
3444 array_push( $acf_field_group_ids, get_the_ID() );
3445 endif;
3446 endwhile; wp_reset_postdata();
3447 foreach ( $acf_field_group_ids as $acf_field_group_id ) :
3448 $acf_fields = new WP_Query( array(
3449 'post_type' => 'acf-field',
3450 'post_parent' => $acf_field_group_id,
3451 ));
3452 while ( $acf_fields->have_posts() ) : $acf_fields->the_post();
3453 global $post;
3454 $fields[$post->post_name] = get_field_object( $post->post_name );
3455 endwhile; wp_reset_postdata();
3456 endforeach;
3457 // Get ACF 4 fields.
3458 $acf4_field_groups = new WP_Query( array(
3459 'post_type' => 'acf',
3460 ));
3461 while ( $acf4_field_groups->have_posts() ) : $acf4_field_groups->the_post();
3462 $field_group_rules = get_post_meta( get_the_ID(), 'rule', true );
3463 if ( is_array( $field_group_rules ) && array_key_exists( 'param', $field_group_rules ) && $field_group_rules['param'] === 'ef_user' ) :
3464 $acf4_fields = get_post_custom( get_the_ID() );
3465 foreach ( $acf4_fields as $meta_key => $meta_value ) :
3466 if ( strpos( $meta_key, 'field_' ) === 0 ) :
3467 $meta_value = unserialize( $meta_value[0] );
3468 $fields[$meta_key] = $meta_value;
3469 endif;
3470 endforeach;
3471 endif;
3472 endwhile; wp_reset_postdata(); ?>
3473 <optgroup label="ACF User Fields:">
3474 <?php foreach ( (array)$fields as $field => $field_object ) : ?>
3475 <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>
3476 <?php endforeach; ?>
3477 </optgroup>
3478 <?php endif; ?>
3479 <optgroup label="All Usermeta:">
3480 <?php foreach ( $this->get_all_usermeta_keys() as $meta_key ) : if ( substr( $meta_key, 0, 3 ) === 'wp_' ) continue; ?>
3481 <option value="<?php echo $meta_key; ?>"<?php if ( $auth_settings_option === $meta_key ) echo ' selected="selected"'; ?>><?php echo $meta_key; ?></option>
3482 <?php endforeach; ?>
3483 </optgroup>
3484 </select><?php
3485 } // END print_select_auth_advanced_usermeta()
3486
3487 function print_checkbox_auth_advanced_override_multisite( $args = '' ) {
3488 // Get plugin option.
3489 $option = 'advanced_override_multisite';
3490 $auth_settings_option = $this->get_plugin_option( $option );
3491
3492 // Print option elements.
3493 ?><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; ?>">Configure this site independently (don't inherit any multisite settings)</label><?php
3494 } // END print_checkbox_auth_advanced_override_multisite()
3495
3496
3497
3498 /**
3499 * Add help documentation to the options page.
3500 * Run on action hook chain: load-settings_page_authorizer > admin_head
3501 */
3502 public function admin_head() {
3503 $screen = get_current_screen();
3504
3505 // Add help tab for Access Lists Settings
3506 $help_auth_settings_access_lists_content = '
3507 <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.</p>
3508 <p><strong>Approved Users</strong>: Approved users have access to the site once they successfully log in.</p>
3509 <p><strong>Blocked Users</strong>: Blocked users will receive an error message when they try to visit the site after authenticating.</p>
3510 <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.</p>
3511 ';
3512 $screen->add_help_tab(
3513 array(
3514 'id' => 'help_auth_settings_access_lists_content',
3515 'title' => 'Access Lists',
3516 'content' => $help_auth_settings_access_lists_content,
3517 )
3518 );
3519
3520 // Add help tab for Login Access Settings
3521 $help_auth_settings_access_login_content = '
3522 <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>.</p>
3523 <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.</p>
3524 <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.</p>
3525 ';
3526 $screen->add_help_tab(
3527 array(
3528 'id' => 'help_auth_settings_access_login_content',
3529 'title' => 'Login Access',
3530 'content' => $help_auth_settings_access_login_content,
3531 )
3532 );
3533
3534 // Add help tab for Public Access Settings
3535 $help_auth_settings_access_public_content = '
3536 <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.</p>
3537 <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.</p>
3538 <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>.</p>
3539 <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.</p>
3540 <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.</p>
3541 ';
3542 $screen->add_help_tab(
3543 array(
3544 'id' => 'help_auth_settings_access_public_content',
3545 'title' => 'Public Access',
3546 'content' => $help_auth_settings_access_public_content,
3547 )
3548 );
3549
3550 // Add help tab for External Service (CAS, LDAP) Settings
3551 $help_auth_settings_external_content = '
3552 <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.</p>
3553 <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.</p>
3554 <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.</p>
3555 <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.</p>
3556 <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!</p>
3557 <p><strong><em>If you enable Google logins:</em></strong></p>
3558 <ul>
3559 <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</li>
3560 <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</li>
3561 </ul>
3562 <p><strong><em>If you enable CAS logins:</em></strong></p>
3563 <ul>
3564 <li><strong>CAS server hostname</strong>: Enter the hostname of the CAS server you authenticate against (e.g., authn.example.edu).</li>
3565 <li><strong>CAS server port</strong>: Enter the port on the CAS server to connect to (e.g., 443).</li>
3566 <li><strong>CAS server path/context</strong>: Enter the path to the login endpoint on the CAS server (e.g., /cas).</li>
3567 <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.</li>
3568 <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.</li>
3569 <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.</li>
3570 </ul>
3571 <p><strong><em>If you enable LDAP logins:</em></strong></p>
3572 <ul>
3573 <li><strong>LDAP Host</strong>: Enter the URL of the LDAP server you authenticate against.</li>
3574 <li><strong>LDAP Port</strong>: Enter the port number that the LDAP server listens on.</li>
3575 <li><strong>LDAP Search Base</strong>: Enter the LDAP string that represents the search base, e.g., ou=people,dc=example,dc=edu</li>
3576 <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.</li>
3577 <li><strong>LDAP Directory User</strong>: Enter the name of the LDAP user that has permissions to browse the directory.</li>
3578 <li><strong>LDAP Directory User Password</strong>: Enter the password for the LDAP user that has permission to browse the directory.</li>
3579 <li><strong>Secure Connection (TLS)</strong>: Select whether all communication with the LDAP server should be performed over a TLS-secured connection.</li>
3580 <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.</li>
3581 <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.</li>
3582 <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.</li>
3583 <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.</li>
3584 </ul>';
3585 $screen->add_help_tab(
3586 array(
3587 'id' => 'help_auth_settings_external_content',
3588 'title' => 'External Service',
3589 'content' => $help_auth_settings_external_content,
3590 )
3591 );
3592
3593 // Add help tab for Advanced Settings
3594 $help_auth_settings_advanced_content = '
3595 <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.</p>
3596 <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: <a href="' . wp_login_url() . '?external=wordpress" target="_blank">' . wp_login_url() . '?external=wordpress</a>.</p>
3597 <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.</p>
3598 ';
3599 $screen->add_help_tab(
3600 array(
3601 'id' => 'help_auth_settings_advanced_content',
3602 'title' => 'Advanced',
3603 'content' => $help_auth_settings_advanced_content,
3604 )
3605 );
3606 } // END admin_head()
3607
3608
3609
3610 /**
3611 * ***************************
3612 * Multisite: Network Admin Options page
3613 * ***************************
3614 */
3615
3616
3617 /**
3618 * Network Admin menu item
3619 * Hook: network_admin_menu
3620 *
3621 * @param none
3622 * @return void
3623 */
3624 public function network_admin_menu() {
3625 // @see http://codex.wordpress.org/Function_Reference/add_menu_page
3626 add_menu_page(
3627 'Authorizer', // Page title
3628 'Authorizer', // Menu title
3629 'manage_network_options', // Capability
3630 'authorizer', // Menu slug
3631 array( $this, 'create_network_admin_page' ),
3632 'dashicons-groups', // Icon URL
3633 89 // Position
3634 );
3635 } // END network_admin_menu()
3636
3637 /**
3638 * Output the HTML for the options page
3639 */
3640 public function create_network_admin_page() {
3641 if ( ! current_user_can( 'manage_network_options' ) ) {
3642 wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
3643 }
3644 $auth_settings = get_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings', array() ); ?>
3645 <div class="wrap">
3646 <form method="post" action="" autocomplete="off">
3647 <h2>Authorizer Settings</h2>
3648 <p>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.</p>
3649
3650 <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">Override individual site settings with the settings below</label>
3651
3652 <div id="auth_multisite_settings_disabled_overlay" style="display: none;"></div>
3653
3654 <div class="wrap" id="auth_multisite_settings">
3655 <?php $this->print_section_info_tabs( array( 'multisite_admin' => true ) ); ?>
3656
3657 <?php wp_nonce_field( 'save_auth_settings', 'nonce_save_auth_settings' ); ?>
3658
3659 <?php // Custom access lists (for network, we only really want approved list, not pending or blocked) ?>
3660 <div id="section_info_access_lists" class="section_info">
3661 <p>Manage who has access to all sites in the network.</p>
3662 </div>
3663 <table class="form-table"><tbody>
3664 <tr>
3665 <th scope="row">Who can log in to sites in this network?</th>
3666 <td><?php $this->print_radio_auth_access_who_can_login( array( 'multisite_admin' => true ) ); ?></td>
3667 </tr>
3668 <tr>
3669 <th scope="row">Who can view sites in this network?</th>
3670 <td><?php $this->print_radio_auth_access_who_can_view( array( 'multisite_admin' => true ) ); ?></td>
3671 </tr>
3672 <tr>
3673 <th scope="row">Approved Users (All Sites)<br /><small><em>Note: these users will <strong>not</strong> receive welcome emails when approved. Only users approved from individual sites can receive these messages.</em></small></th>
3674 <td><?php $this->print_combo_auth_access_users_approved( array( 'multisite_admin' => true ) ); ?></td>
3675 </tr>
3676 </tbody></table>
3677
3678 <?php $this->print_section_info_external(); ?>
3679 <table class="form-table"><tbody>
3680 <tr>
3681 <th scope="row">Default role for new users</th>
3682 <td><?php $this->print_select_auth_access_default_role( array( 'multisite_admin' => true ) ); ?></td>
3683 </tr>
3684 <tr>
3685 <th scope="row">Google Logins</th>
3686 <td><?php $this->print_checkbox_auth_external_google( array( 'multisite_admin' => true ) ); ?></td>
3687 </tr>
3688 <tr>
3689 <th scope="row">Google Client ID</th>
3690 <td><?php $this->print_text_google_clientid( array( 'multisite_admin' => true ) ); ?></td>
3691 </tr>
3692 <tr>
3693 <th scope="row">Google Client Secret</th>
3694 <td><?php $this->print_text_google_clientsecret( array( 'multisite_admin' => true ) ); ?></td>
3695 </tr>
3696 <tr>
3697 <th scope="row">CAS Logins</th>
3698 <td><?php $this->print_checkbox_auth_external_cas( array( 'multisite_admin' => true ) ); ?></td>
3699 </tr>
3700 <tr>
3701 <th scope="row">CAS Custom Label</th>
3702 <td><?php $this->print_text_cas_custom_label( array( 'multisite_admin' => true ) ); ?></td>
3703 </tr>
3704 <tr>
3705 <th scope="row">CAS server hostname</th>
3706 <td><?php $this->print_text_cas_host( array( 'multisite_admin' => true ) ); ?></td>
3707 </tr>
3708 <tr>
3709 <th scope="row">CAS server port</th>
3710 <td><?php $this->print_text_cas_port( array( 'multisite_admin' => true ) ); ?></td>
3711 </tr>
3712 <tr>
3713 <th scope="row">CAS server path/context</th>
3714 <td><?php $this->print_text_cas_path( array( 'multisite_admin' => true ) ); ?></td>
3715 </tr>
3716 <tr>
3717 <th scope="row">CAS attribute containing email</th>
3718 <td><?php $this->print_text_cas_attr_email( array( 'multisite_admin' => true ) ); ?></td>
3719 </tr>
3720 <tr>
3721 <th scope="row">CAS attribute containing first name</th>
3722 <td><?php $this->print_text_cas_attr_first_name( array( 'multisite_admin' => true ) ); ?></td>
3723 </tr>
3724 <tr>
3725 <th scope="row">CAS attribute containing last name</th>
3726 <td><?php $this->print_text_cas_attr_last_name( array( 'multisite_admin' => true ) ); ?></td>
3727 </tr>
3728 <tr>
3729 <th scope="row">CAS attribute update</th>
3730 <td><?php $this->print_checkbox_cas_attr_update_on_login( array( 'multisite_admin' => true ) ); ?></td>
3731 </tr>
3732 <tr>
3733 <th scope="row">LDAP Logins</th>
3734 <td><?php $this->print_checkbox_auth_external_ldap( array( 'multisite_admin' => true ) ); ?></td>
3735 </tr>
3736 <tr>
3737 <th scope="row">LDAP Host</th>
3738 <td><?php $this->print_text_ldap_host( array( 'multisite_admin' => true ) ); ?></td>
3739 </tr>
3740 <tr>
3741 <th scope="row">LDAP Port</th>
3742 <td><?php $this->print_text_ldap_port( array( 'multisite_admin' => true ) ); ?></td>
3743 </tr>
3744 <tr>
3745 <th scope="row">LDAP Search Base</th>
3746 <td><?php $this->print_text_ldap_search_base( array( 'multisite_admin' => true ) ); ?></td>
3747 </tr>
3748 <tr>
3749 <th scope="row">LDAP attribute containing username</th>
3750 <td><?php $this->print_text_ldap_uid( array( 'multisite_admin' => true ) ); ?></td>
3751 </tr>
3752 <tr>
3753 <th scope="row">LDAP attribute containing email</th>
3754 <td><?php $this->print_text_ldap_attr_email( array( 'multisite_admin' => true ) ); ?></td>
3755 </tr>
3756 <tr>
3757 <th scope="row">LDAP Directory User</th>
3758 <td><?php $this->print_text_ldap_user( array( 'multisite_admin' => true ) ); ?></td>
3759 </tr>
3760 <tr>
3761 <th scope="row">LDAP Directory User Password</th>
3762 <td><?php $this->print_password_ldap_password( array( 'multisite_admin' => true ) ); ?></td>
3763 </tr>
3764 <tr>
3765 <th scope="row">Secure Connection (TLS)</th>
3766 <td><?php $this->print_checkbox_ldap_tls( array( 'multisite_admin' => true ) ); ?></td>
3767 </tr>
3768 <tr>
3769 <th scope="row">Custom lost password URL</th>
3770 <td><?php $this->print_text_ldap_lostpassword_url( array( 'multisite_admin' => true ) ); ?></td>
3771 </tr>
3772 <tr>
3773 <th scope="row">LDAP attribute containing first name</th>
3774 <td><?php $this->print_text_ldap_attr_first_name( array( 'multisite_admin' => true ) ); ?></td>
3775 </tr>
3776 <tr>
3777 <th scope="row">LDAP attribute containing last name</th>
3778 <td><?php $this->print_text_ldap_attr_last_name( array( 'multisite_admin' => true ) ); ?></td>
3779 </tr>
3780 <tr>
3781 <th scope="row">LDAP attribute update</th>
3782 <td><?php $this->print_checkbox_ldap_attr_update_on_login( array( 'multisite_admin' => true ) ); ?></td>
3783 </tr>
3784 </tbody></table>
3785
3786 <?php $this->print_section_info_advanced(); ?>
3787 <table class="form-table"><tbody>
3788 <tr>
3789 <th scope="row">Limit invalid login attempts</th>
3790 <td><?php $this->print_text_auth_advanced_lockouts( array( 'multisite_admin' => true ) ); ?></td>
3791 </tr>
3792 <tr>
3793 <th scope="row">Hide WordPress Logins</th>
3794 <td><?php $this->print_checkbox_auth_advanced_hide_wp_login( array( 'multisite_admin' => true ) ); ?></td>
3795 </tr>
3796 </tbody></table>
3797
3798 <br class="clear" />
3799 </div>
3800 <input type="button" name="submit" id="submit" class="button button-primary" value="Save Changes" onclick="save_auth_multisite_settings(this);" />
3801 </form>
3802 </div>
3803 <?php
3804 } // END create_network_admin_page()
3805
3806 /**
3807 * Save multisite settings (ajax call).
3808 */
3809 function ajax_save_auth_multisite_settings() {
3810 // Fail silently if current user doesn't have permissions.
3811 if ( ! current_user_can( 'manage_network_options' ) ) {
3812 die( '' );
3813 }
3814
3815 // Make sure nonce exists.
3816 if ( empty( $_POST['nonce_save_auth_settings'] ) ) {
3817 die( '' );
3818 }
3819
3820 // Nonce check.
3821 if ( ! wp_verify_nonce( $_POST['nonce_save_auth_settings'], 'save_auth_settings' ) ) {
3822 die( '' );
3823 }
3824
3825 // Assert multisite.
3826 if ( ! is_multisite() ) {
3827 die( '' );
3828 }
3829
3830 // Get multisite settings.
3831 $auth_multisite_settings = get_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings', array() );
3832
3833 // Sanitize settings
3834 $auth_multisite_settings = $this->sanitize_options( $_POST, 'multisite' );
3835
3836 // Filter options to only the allowed values (multisite options are a subset of all options)
3837 $allowed = array(
3838 'multisite_override',
3839 'access_who_can_login',
3840 'access_who_can_view',
3841 'access_default_role',
3842 'google',
3843 'google_clientid',
3844 'google_clientsecret',
3845 'cas',
3846 'cas_custom_label',
3847 'cas_host',
3848 'cas_port',
3849 'cas_path',
3850 'cas_attr_email',
3851 'cas_attr_first_name',
3852 'cas_attr_last_name',
3853 'cas_attr_update_on_login',
3854 'ldap',
3855 'ldap_host',
3856 'ldap_port',
3857 'ldap_search_base',
3858 'ldap_uid',
3859 'ldap_attr_email',
3860 'ldap_user',
3861 'ldap_password',
3862 'ldap_tls',
3863 'ldap_lostpassword_url',
3864 'ldap_attr_first_name',
3865 'ldap_attr_last_name',
3866 'ldap_attr_update_on_login',
3867 'advanced_lockouts',
3868 'advanced_hide_wp_login',
3869 );
3870 $auth_multisite_settings = array_intersect_key( $auth_multisite_settings, array_flip( $allowed ) );
3871
3872 // Update multisite settings in database.
3873 update_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings', $auth_multisite_settings );
3874
3875 // Return 'success' value to AJAX call.
3876 die( 'success' );
3877 } // END ajax_save_auth_multisite_settings()
3878
3879
3880
3881 /**
3882 * ***************************
3883 * Dashboard widget
3884 * ***************************
3885 */
3886
3887
3888
3889 function add_dashboard_widgets() {
3890 // Only users who can edit can see the authorizer dashboard widget
3891 if ( current_user_can( 'create_users' ) ) {
3892 // Add dashboard widget for adding/editing users with access
3893 wp_add_dashboard_widget( 'auth_dashboard_widget', 'Authorizer Settings', array( $this, 'add_auth_dashboard_widget' ) );
3894 }
3895 } // END add_dashboard_widgets()
3896
3897
3898 function add_auth_dashboard_widget() {
3899 ?><form method="post" id="auth_settings_access_form" action="">
3900 <?php $this->print_section_info_access_login(); ?>
3901 <div>
3902 <h2>Pending Users</h2>
3903 <?php $this->print_combo_auth_access_users_pending(); ?>
3904 </div>
3905 <div>
3906 <h2>Approved Users</h2>
3907 <?php $this->print_combo_auth_access_users_approved(); ?>
3908 </div>
3909 <div>
3910 <h2>Blocked Users</h2>
3911 <?php $this->print_combo_auth_access_users_blocked(); ?>
3912 </div>
3913 <br class="clear" />
3914 </form><?php
3915 } // END add_auth_dashboard_widget()
3916
3917
3918 // Fired on a change event from the optional usermeta field in the
3919 // approved user list. Updates the selected usermeta value, or saves it
3920 // in the user's approved list entry if the user hasn't logged in yet
3921 // and created a WordPress account.
3922 function ajax_update_auth_usermeta() {
3923
3924 // Fail silently if current user doesn't have permissions.
3925 if ( ! current_user_can( 'create_users' ) ) {
3926 die( '' );
3927 }
3928
3929 // Nonce check.
3930 if ( empty( $_POST['nonce_save_auth_settings'] ) || ! wp_verify_nonce( $_POST['nonce_save_auth_settings'], 'save_auth_settings' ) ) {
3931 die( '' );
3932 }
3933
3934 // Fail if required post data doesn't exist.
3935 if ( ! array_key_exists( 'email', $_REQUEST ) || ! array_key_exists( 'usermeta', $_REQUEST ) ) {
3936 die( '' );
3937 }
3938
3939 // Get values to update from post data.
3940 $email = $_REQUEST['email'];
3941 $meta_value = $_REQUEST['usermeta'];
3942 $meta_key = $this->get_plugin_option( 'advanced_usermeta' );
3943
3944 // If user doesn't exist, save usermeta selection to authorizer
3945 // list. This value will get saved to usermeta when the user first
3946 // logs in (i.e., when their WordPress account is created).
3947 if ( ! ( $wp_user = get_user_by( 'email', $email ) ) ) {
3948 // Look through multisite approved users and add a usermeta
3949 // reference for the current blog if the user is found.
3950 $auth_multisite_settings_access_users_approved = is_multisite() ? get_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings_access_users_approved', array() ) : array();
3951 $should_update_auth_multisite_settings_access_users_approved = false;
3952 foreach ( $auth_multisite_settings_access_users_approved as $index => $approved_user ) {
3953 if ( $email === $approved_user['email'] ) {
3954 if ( ! is_array( $auth_multisite_settings_access_users_approved[$index]['usermeta'] ) ) {
3955 // Initialize the array of usermeta for each blog this user belongs to.
3956 $auth_multisite_settings_access_users_approved[$index]['usermeta'] = array();
3957 } else {
3958 // There is already usermeta associated with this
3959 // preapproved user; iterate through it and make
3960 // sure it's not for old meta_keys (delete it if
3961 // so). This can happen if someone changes the
3962 // usermeta key in authorizer options, and we don't
3963 // want to hang on to old data.
3964 foreach ( $auth_multisite_settings_access_users_approved[$index]['usermeta'] as $blog_id => $usermeta ) {
3965 if ( array_key_exists( 'meta_key', $usermeta ) && $usermeta['meta_key'] === $meta_key ) {
3966 continue;
3967 } else {
3968 unset( $auth_multisite_settings_access_users_approved[$index]['usermeta'][$blog_id] );
3969 }
3970 }
3971 }
3972 $auth_multisite_settings_access_users_approved[$index]['usermeta'][get_current_blog_id()] = array(
3973 'meta_key' => $meta_key,
3974 'meta_value' => $meta_value,
3975 );
3976 $should_update_auth_multisite_settings_access_users_approved = true;
3977 }
3978 }
3979 if ( $should_update_auth_multisite_settings_access_users_approved ) {
3980 update_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
3981 }
3982
3983 // Look through the approved users (of the current blog in a
3984 // multisite install, or just of the single site) and add a
3985 // usermeta reference if the user is found.
3986 $auth_settings_access_users_approved = $this->get_plugin_option( 'access_users_approved', 'single admin' );
3987 $should_update_auth_settings_access_users_approved = false;
3988 foreach ( $auth_settings_access_users_approved as $index => $approved_user ) {
3989 if ( $email === $approved_user['email'] ) {
3990 $auth_settings_access_users_approved[$index]['usermeta'] = array(
3991 'meta_key' => $meta_key,
3992 'meta_value' => $meta_value,
3993 );
3994 $should_update_auth_settings_access_users_approved = true;
3995 }
3996 }
3997 if ( $should_update_auth_settings_access_users_approved ) {
3998 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
3999 }
4000
4001 } else {
4002 // Update user's usermeta value for usermeta key stored in authorizer options.
4003 if ( strpos( $meta_key, 'acf___' ) === 0 && class_exists( 'acf' ) ) {
4004 // We have an ACF field value, so use the ACF function to update it.
4005 update_field( str_replace('acf___', '', $meta_key ), $meta_value, 'user_' . $wp_user->ID );
4006 } else {
4007 // We have a normal usermeta value, so just update it via the WordPress function.
4008 update_user_meta( $wp_user->ID, $meta_key, $meta_value );
4009 }
4010
4011 }
4012
4013 // Return 'success' value to AJAX call.
4014 die( 'success' );
4015 } // END ajax_update_auth_usermeta()
4016
4017
4018 function ajax_update_auth_user() {
4019
4020 // Fail silently if current user doesn't have permissions.
4021 if ( ! current_user_can( 'create_users' ) ) {
4022 die( '' );
4023 }
4024
4025 // Nonce check.
4026 if ( empty( $_POST['nonce_save_auth_settings'] ) || ! wp_verify_nonce( $_POST['nonce_save_auth_settings'], 'save_auth_settings' ) ) {
4027 die( '' );
4028 }
4029
4030 // Fail if requesting a change to an invalid setting.
4031 if ( ! in_array( $_POST['setting'], array( 'access_users_pending', 'access_users_approved', 'access_users_blocked' ) ) ) {
4032 die( '' );
4033 }
4034
4035 // Editing a pending list entry.
4036 if ( $_POST['setting'] === 'access_users_pending' ) {
4037 // Initialize posted data if empty.
4038 if ( ! ( array_key_exists( 'access_users_pending', $_POST ) && is_array( $_POST['access_users_pending'] ) ) ) {
4039 $_POST['access_users_pending'] = array();
4040 }
4041
4042 // Deal with each modified user (add or remove).
4043 foreach ( $_POST['access_users_pending'] as $pending_user ) {
4044
4045 if ( $pending_user['edit_action'] === 'add' ) {
4046
4047 // Add new user to pending list and save (skip if it's
4048 // already there--someone else might have just done it).
4049 if ( ! $this->is_email_in_list( $pending_user['email'], 'pending' ) ) {
4050 $auth_settings_access_users_pending = $this->sanitize_user_list(
4051 $this->get_plugin_option( 'access_users_pending', 'single admin' )
4052 );
4053 array_push( $auth_settings_access_users_pending, $pending_user );
4054 update_option( 'auth_settings_access_users_pending', $auth_settings_access_users_pending );
4055 }
4056
4057 } elseif ( $pending_user['edit_action'] === 'remove' ) {
4058
4059 // Remove user from pending list and save
4060 if ( $this->is_email_in_list( $pending_user['email'], 'pending' ) ) {
4061 $auth_settings_access_users_pending = $this->sanitize_user_list(
4062 $this->get_plugin_option( 'access_users_pending', 'single admin' )
4063 );
4064 foreach ( $auth_settings_access_users_pending as $key => $existing_user ) {
4065 if ( $pending_user['email'] == $existing_user['email'] ) {
4066 unset( $auth_settings_access_users_pending[$key] );
4067 break;
4068 }
4069 }
4070 update_option( 'auth_settings_access_users_pending', $auth_settings_access_users_pending );
4071 }
4072
4073 }
4074 }
4075 }
4076
4077 // Editing an approved list entry.
4078 if ( $_POST['setting'] === 'access_users_approved' ) {
4079 // Initialize posted data if empty.
4080 if ( ! ( array_key_exists( 'access_users_approved', $_POST ) && is_array( $_POST['access_users_approved'] ) ) ) {
4081 $_POST['access_users_approved'] = array();
4082 }
4083
4084 // Deal with each modified user (add, remove, or change_role).
4085 foreach ( $_POST['access_users_approved'] as $approved_user ) {
4086 if ( $approved_user['edit_action'] === 'add' ) {
4087
4088 // New user (create user, or add existing user to current site in multisite).
4089 $new_user = get_user_by( 'email', $approved_user['email'] );
4090 if ( $new_user !== false ) {
4091 if ( is_multisite() ) {
4092 add_user_to_blog( get_current_blog_id(), $new_user->ID, $approved_user['role'] );
4093 }
4094 } elseif ( $approved_user['local_user'] === 'true' ) {
4095 // Create a WP account for this new *local* user and email the password.
4096 $plaintext_password = wp_generate_password(); // random password
4097 // If there's already a user with this username (e.g.,
4098 // johndoe/johndoe@gmail.com exists, and we're trying to add
4099 // johndoe/johndoe@example.com), use the full email address
4100 // as the username.
4101 $username = explode( '@', $approved_user['email'] );
4102 $username = $username[0];
4103 if ( get_user_by( 'login', $username ) !== false ) {
4104 $username = $approved_user['email'];
4105 }
4106 if ( $approved_user['multisite_user'] !== 'false' ) {
4107 $result = wpmu_create_user(
4108 strtolower( $username ),
4109 $plaintext_password,
4110 strtolower( $approved_user['email'] )
4111 );
4112 } else {
4113 $result = wp_insert_user(
4114 array(
4115 'user_login' => strtolower( $username ),
4116 'user_pass' => $plaintext_password,
4117 'first_name' => '',
4118 'last_name' => '',
4119 'user_email' => strtolower( $approved_user['email'] ),
4120 'user_registered' => date( 'Y-m-d H:i:s' ),
4121 'role' => $approved_user['role'],
4122 )
4123 );
4124 }
4125 if ( ! is_wp_error( $result ) ) {
4126 // Email password to new user
4127 wp_new_user_notification( $result, $plaintext_password );
4128 }
4129
4130 }
4131
4132 // Email new user welcome message if plugin option is set.
4133 $this->maybe_email_welcome_message( $approved_user['email'] );
4134
4135 // Add new user to approved list and save (skip if it's
4136 // already there--someone else might have just done it).
4137 if ( $approved_user['multisite_user'] !== 'false' ) {
4138 if ( ! $this->is_email_in_list( $approved_user['email'], 'approved', 'multisite' ) ) {
4139 $auth_multisite_settings_access_users_approved = $this->sanitize_user_list(
4140 $this->get_plugin_option( 'access_users_approved', 'multisite admin' )
4141 );
4142 $approved_user['date_added'] = date( 'M Y' );
4143 array_push( $auth_multisite_settings_access_users_approved, $approved_user );
4144 update_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
4145 }
4146 } else {
4147 if ( ! $this->is_email_in_list( $approved_user['email'], 'approved' ) ) {
4148 $auth_settings_access_users_approved = $this->sanitize_user_list(
4149 $this->get_plugin_option( 'access_users_approved', 'single admin' )
4150 );
4151 $approved_user['date_added'] = date( 'M Y' );
4152 array_push( $auth_settings_access_users_approved, $approved_user );
4153 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
4154 }
4155 }
4156
4157 // If we've added a new multisite user, go through all pending/approved/blocked lists
4158 // on individual sites and remove this user from them (to prevent duplicate entries).
4159 if ( $approved_user['multisite_user'] !== 'false' && is_multisite() ) {
4160 $list_names = array( 'access_users_pending', 'access_users_approved', 'access_users_blocked' );
4161 foreach ( wp_get_sites( array( 'limit' => 999999 ) ) as $site ) {
4162 foreach ( $list_names as $list_name ) {
4163 $user_list = get_blog_option( $site['blog_id'], 'auth_settings_' . $list_name, array() );
4164 $list_changed = false;
4165 foreach ( $user_list as $key => $user ) {
4166 if ( $user['email'] == $approved_user['email'] ) {
4167 unset( $user_list[$key] );
4168 $list_changed = true;
4169 }
4170 }
4171 if ( $list_changed ) {
4172 update_blog_option( $site['blog_id'], 'auth_settings_' . $list_name, $user_list );
4173 }
4174 }
4175 }
4176 }
4177
4178 } elseif ( $approved_user['edit_action'] === 'remove' ) {
4179
4180 // Remove user from approved list and save
4181 if ( $approved_user['multisite_user'] !== 'false' ) {
4182 if ( $this->is_email_in_list( $approved_user['email'], 'approved', 'multisite' ) ) {
4183 $auth_multisite_settings_access_users_approved = $this->sanitize_user_list(
4184 $this->get_plugin_option( 'access_users_approved', 'multisite admin' )
4185 );
4186 foreach ( $auth_multisite_settings_access_users_approved as $key => $existing_user ) {
4187 if ( $approved_user['email'] == $existing_user['email'] ) {
4188 unset( $auth_multisite_settings_access_users_approved[$key] );
4189 break;
4190 }
4191 }
4192 update_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
4193 }
4194 } else {
4195 if ( $this->is_email_in_list( $approved_user['email'], 'approved' ) ) {
4196 $auth_settings_access_users_approved = $this->sanitize_user_list(
4197 $this->get_plugin_option( 'access_users_approved', 'single admin' )
4198 );
4199 foreach ( $auth_settings_access_users_approved as $key => $existing_user ) {
4200 if ( $approved_user['email'] == $existing_user['email'] ) {
4201 unset( $auth_settings_access_users_approved[$key] );
4202 break;
4203 }
4204 }
4205 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
4206 }
4207 }
4208
4209 } elseif ( $approved_user['edit_action'] === 'change_role' ) {
4210
4211 // Update user's role in WordPress
4212 $changed_user = get_user_by( 'email', $approved_user['email'] );
4213 if ( $changed_user ) {
4214 if ( is_multisite() && $approved_user['multisite_user'] !== 'false' ) {
4215 foreach ( get_blogs_of_user( $changed_user->ID ) as $blog ) {
4216 add_user_to_blog( $blog->userblog_id, $changed_user->ID, $approved_user['role'] );
4217 }
4218 } else {
4219 $changed_user->set_role( $approved_user['role'] );
4220 }
4221 }
4222
4223 if ( $approved_user['multisite_user'] !== 'false' ) {
4224 if ( $this->is_email_in_list( $approved_user['email'], 'approved', 'multisite' ) ) {
4225 $auth_multisite_settings_access_users_approved = $this->sanitize_user_list(
4226 $this->get_plugin_option( 'access_users_approved', 'multisite admin' )
4227 );
4228 foreach ( $auth_multisite_settings_access_users_approved as $key => $existing_user ) {
4229 if ( $approved_user['email'] == $existing_user['email'] ) {
4230 $auth_multisite_settings_access_users_approved[$key]['role'] = $approved_user['role'];
4231 break;
4232 }
4233 }
4234 update_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings_access_users_approved );
4235 }
4236 } else {
4237 // Update user's role in approved list and save.
4238 if ( $this->is_email_in_list( $approved_user['email'], 'approved' ) ) {
4239 $auth_settings_access_users_approved = $this->sanitize_user_list(
4240 $this->get_plugin_option( 'access_users_approved', 'single admin' )
4241 );
4242 foreach ( $auth_settings_access_users_approved as $key => $existing_user ) {
4243 if ( $approved_user['email'] == $existing_user['email'] ) {
4244 $auth_settings_access_users_approved[$key]['role'] = $approved_user['role'];
4245 break;
4246 }
4247 }
4248 update_option( 'auth_settings_access_users_approved', $auth_settings_access_users_approved );
4249 }
4250 }
4251
4252 }
4253 }
4254 }
4255
4256 // Editing a blocked list entry.
4257 if ( $_POST['setting'] === 'access_users_blocked' ) {
4258 // Initialize posted data if empty.
4259 if ( ! ( array_key_exists( 'access_users_blocked', $_POST ) && is_array( $_POST['access_users_blocked'] ) ) ) {
4260 $_POST['access_users_blocked'] = array();
4261 }
4262
4263 // Deal with each modified user (add or remove).
4264 foreach ( $_POST['access_users_blocked'] as $blocked_user ) {
4265
4266 if ( $blocked_user['edit_action'] === 'add' ) {
4267
4268 // Add new user to blocked list and save (skip if it's
4269 // already there--someone else might have just done it).
4270 if ( ! $this->is_email_in_list( $blocked_user['email'], 'blocked' ) ) {
4271 $auth_settings_access_users_blocked = $this->sanitize_user_list(
4272 $this->get_plugin_option( 'access_users_blocked', 'single admin' )
4273 );
4274 $blocked_user['date_added'] = date( 'M Y' );
4275 array_push( $auth_settings_access_users_blocked, $blocked_user );
4276 update_option( 'auth_settings_access_users_blocked', $auth_settings_access_users_blocked );
4277 }
4278
4279 } elseif ( $blocked_user['edit_action'] === 'remove' ) {
4280
4281 // Remove auth_blocked usermeta for the user.
4282 $unblocked_user = get_user_by( 'email', $blocked_user['email'] );
4283 if ( $unblocked_user !== false ) {
4284 delete_user_meta( $unblocked_user->ID, 'auth_blocked', 'yes' );
4285 }
4286
4287 // Remove user from blocked list and save
4288 if ( $this->is_email_in_list( $blocked_user['email'], 'blocked' ) ) {
4289 $auth_settings_access_users_blocked = $this->sanitize_user_list(
4290 $this->get_plugin_option( 'access_users_blocked', 'single admin' )
4291 );
4292 foreach ( $auth_settings_access_users_blocked as $key => $existing_user ) {
4293 if ( $blocked_user['email'] == $existing_user['email'] ) {
4294 unset( $auth_settings_access_users_blocked[$key] );
4295 break;
4296 }
4297 }
4298 update_option( 'auth_settings_access_users_blocked', $auth_settings_access_users_blocked );
4299 }
4300
4301 }
4302 }
4303 }
4304
4305 // Return 'success' value to AJAX call.
4306 die( 'success' );
4307 } // END update_auth_user()
4308
4309
4310
4311 /**
4312 * ***************************
4313 * Helper functions
4314 * ***************************
4315 */
4316
4317
4318 /**
4319 * Retrieves a specific plugin option from db. Multisite enabled.
4320 *
4321 * @param string $option Option name
4322 * @param string $admin_mode 'multisite admin' will retrieve the multisite value
4323 * @param string $override_mode 'allow override' will retrieve the multisite value if it exists
4324 * @param string $print_mode 'print overlay' will output overlay that hides this option on the settings page
4325 * @return mixed Option value, or null on failure
4326 */
4327 private function get_plugin_option( $option, $admin_mode = 'single admin', $override_mode = 'no override', $print_mode = 'no overlay' ) {
4328
4329 // Special case for user lists (they are saved seperately to prevent concurrency issues).
4330 if ( in_array( $option, array( 'access_users_pending', 'access_users_approved', 'access_users_blocked' ) ) ) {
4331 $list = $admin_mode === 'multisite admin' ? array() : get_option( 'auth_settings_' . $option );
4332 if ( is_multisite() && $admin_mode === 'multisite admin' ) {
4333 $list = get_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings_' . $option, array() );
4334 }
4335 return $list;
4336 }
4337
4338 // Get all plugin options.
4339 $auth_settings = $this->get_plugin_options( $admin_mode, $override_mode );
4340
4341 // Set option to null if it wasn't found.
4342 if ( ! array_key_exists( $option, $auth_settings ) ) {
4343 return null;
4344 }
4345
4346 // If requested and appropriate, print the overlay hiding the
4347 // single site option that is overridden by a multisite option.
4348 if (
4349 $admin_mode !== 'multisite admin' &&
4350 $override_mode === 'allow override' &&
4351 $print_mode === 'print overlay' &&
4352 array_key_exists( 'multisite_override', $auth_settings ) &&
4353 $auth_settings['multisite_override'] === '1' &&
4354 ( ! array_key_exists( 'advanced_override_multisite', $auth_settings ) || $auth_settings['advanced_override_multisite'] != '1' )
4355 ) {
4356 // Get original plugin options (not overridden value). We'll
4357 // show this old value behind the disabled overlay.
4358 $auth_settings = $this->get_plugin_options( $admin_mode, 'no override' );
4359
4360 $name = "auth_settings[$option]";
4361 $id = "auth_settings_$option"; ?>
4362 <div id="overlay-hide-auth_settings_<?php echo $option; ?>" class="auth_multisite_override_overlay">
4363 <span class="overlay-note">
4364 This setting is overridden by a <a href="<?php echo network_admin_url( 'admin.php?page=authorizer&tab=external' ); ?>">multisite option</a>.
4365 </span>
4366 </div>
4367 <?php
4368 }
4369
4370 // If we're getting an option in a site that has overridden the multisite override, make
4371 // sure we are returning the option value from that site (not the multisite value).
4372 if ( array_key_exists( 'advanced_override_multisite', $auth_settings ) && $auth_settings['advanced_override_multisite'] == '1' ) {
4373 $auth_settings = $this->get_plugin_options( $admin_mode, 'no override' );
4374 }
4375
4376 return $auth_settings[$option];
4377 }
4378
4379 /**
4380 * Retrieves all plugin options from db. Multisite enabled.
4381 *
4382 * @param string $admin_mode 'multisite admin' will retrieve the multisite value
4383 * @param string $override_mode 'allow override' will retrieve the multisite value if it exists
4384 * @return mixed Option value, or null on failure
4385 */
4386 private function get_plugin_options( $admin_mode = 'single admin', $override_mode = 'no override' ) {
4387 // Grab plugin settings (skip if in multisite admin mode).
4388 $auth_settings = $admin_mode === 'multisite admin' ? array() : get_option( 'auth_settings' );
4389
4390 // Initialize to empty array if the plugin option doesn't exist.
4391 if ( $auth_settings === FALSE ) {
4392 $auth_settings = array();
4393 }
4394
4395 // Merge multisite options if we're in a network and the current site hasn't overridden multisite settings.
4396 if ( is_multisite() && ( ! array_key_exists( 'advanced_override_multisite', $auth_settings ) || $auth_settings['advanced_override_multisite'] != '1' ) ) {
4397 // Get multisite options.
4398 $auth_multisite_settings = get_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings', array() );
4399
4400 // Return the multisite options if we're viewing the network admin options page.
4401 // Otherwise override options with their multisite equivalents.
4402 if ( $admin_mode === 'multisite admin' ) {
4403 $auth_settings = $auth_multisite_settings;
4404 } elseif (
4405 $override_mode === 'allow override' &&
4406 array_key_exists( 'multisite_override', $auth_multisite_settings ) &&
4407 $auth_multisite_settings['multisite_override'] === '1'
4408 ) {
4409 // Keep track of the multisite override selection.
4410 $auth_settings['multisite_override'] = $auth_multisite_settings['multisite_override'];
4411
4412 // Note: the options below should be the complete list of
4413 // overridden options. It is *not* the complete list of all
4414 // options (some options don't have a multisite equivalent)
4415
4416 // Note: access_users_approved, access_users_pending, and
4417 // access_users_blocked do not get overridden. However,
4418 // since access_users_approved has a multisite equivalent,
4419 // you must retrieve them both seperately. This is done
4420 // because the two lists should be treated differently.
4421 // $approved_users = $this->get_plugin_option( 'access_users_approved', 'single admin' );
4422 // $ms_approved_users = $this->get_plugin_option( 'access_users_approved', 'multisite admin' );
4423
4424 // Override external services (google, cas, or ldap) and associated options
4425 $auth_settings['google'] = $auth_multisite_settings['google'];
4426 $auth_settings['google_clientid'] = $auth_multisite_settings['google_clientid'];
4427 $auth_settings['google_clientsecret'] = $auth_multisite_settings['google_clientsecret'];
4428 $auth_settings['cas'] = $auth_multisite_settings['cas'];
4429 $auth_settings['cas_custom_label'] = $auth_multisite_settings['cas_custom_label'];
4430 $auth_settings['cas_host'] = $auth_multisite_settings['cas_host'];
4431 $auth_settings['cas_port'] = $auth_multisite_settings['cas_port'];
4432 $auth_settings['cas_path'] = $auth_multisite_settings['cas_path'];
4433 $auth_settings['cas_attr_email'] = $auth_multisite_settings['cas_attr_email'];
4434 $auth_settings['cas_attr_first_name'] = $auth_multisite_settings['cas_attr_first_name'];
4435 $auth_settings['cas_attr_last_name'] = $auth_multisite_settings['cas_attr_last_name'];
4436 $auth_settings['cas_attr_update_on_login'] = $auth_multisite_settings['cas_attr_update_on_login'];
4437 $auth_settings['ldap'] = $auth_multisite_settings['ldap'];
4438 $auth_settings['ldap_host'] = $auth_multisite_settings['ldap_host'];
4439 $auth_settings['ldap_port'] = $auth_multisite_settings['ldap_port'];
4440 $auth_settings['ldap_search_base'] = $auth_multisite_settings['ldap_search_base'];
4441 $auth_settings['ldap_uid'] = $auth_multisite_settings['ldap_uid'];
4442 $auth_settings['ldap_attr_email'] = $auth_multisite_settings['ldap_attr_email'];
4443 $auth_settings['ldap_user'] = $auth_multisite_settings['ldap_user'];
4444 $auth_settings['ldap_password'] = $auth_multisite_settings['ldap_password'];
4445 $auth_settings['ldap_tls'] = $auth_multisite_settings['ldap_tls'];
4446 $auth_settings['ldap_lostpassword_url'] = $auth_multisite_settings['ldap_lostpassword_url'];
4447 $auth_settings['ldap_attr_first_name'] = $auth_multisite_settings['ldap_attr_first_name'];
4448 $auth_settings['ldap_attr_last_name'] = $auth_multisite_settings['ldap_attr_last_name'];
4449 $auth_settings['ldap_attr_update_on_login'] = $auth_multisite_settings['ldap_attr_update_on_login'];
4450
4451 // Override access_who_can_login and access_who_can_view
4452 $auth_settings['access_who_can_login'] = $auth_multisite_settings['access_who_can_login'];
4453 $auth_settings['access_who_can_view'] = $auth_multisite_settings['access_who_can_view'];
4454
4455 // Override access_default_role
4456 $auth_settings['access_default_role'] = $auth_multisite_settings['access_default_role'];
4457
4458 // Override lockouts
4459 $auth_settings['advanced_lockouts'] = $auth_multisite_settings['advanced_lockouts'];
4460
4461 // Override Hide WordPress login
4462 $auth_settings['advanced_hide_wp_login'] = $auth_multisite_settings['advanced_hide_wp_login'];
4463 }
4464 }
4465 return $auth_settings;
4466 }
4467
4468
4469 private function maybe_email_welcome_message( $email ) {
4470 // Get option for whether to email welcome messages.
4471 $should_email_new_approved_users = $this->get_plugin_option( 'access_should_email_approved_users' );
4472
4473 // Do not send welcome email if option not enabled.
4474 if ( $should_email_new_approved_users !== '1' ) {
4475 return false;
4476 }
4477
4478 // Make sure we didn't just email this user (can happen with
4479 // multiple admins saving at the same time, or by clicking
4480 // Approve button too rapidly).
4481 $recently_sent_emails = get_option( 'auth_settings_recently_sent_emails' );
4482 if ( $recently_sent_emails === FALSE ) {
4483 $recently_sent_emails = array();
4484 }
4485 foreach ( $recently_sent_emails as $key => $recently_sent_email ) {
4486 if ( $recently_sent_email['time'] < strtotime( 'now -1 minutes' ) ) {
4487 // Remove emails sent more than 1 minute ago.
4488 unset( $recently_sent_emails[$key] );
4489 } elseif ( $recently_sent_email['email'] === $email ) {
4490 // Sent an email to this user within the last 1 minute, so
4491 // quit without sending.
4492 return false;
4493 }
4494 }
4495 // Add the email we're about to send to the list.
4496 $recently_sent_emails[] = array(
4497 'email' => $email,
4498 'time' => time(),
4499 );
4500 update_option( 'auth_settings_recently_sent_emails', $recently_sent_emails );
4501
4502 // Get welcome email subject and body text
4503 $subject = $this->get_plugin_option( 'access_email_approved_users_subject' );
4504 $body = apply_filters( 'the_content', $this->get_plugin_option( 'access_email_approved_users_body' ) );
4505
4506 // Fail if the subject/body options don't exist or are empty.
4507 if ( is_null( $subject ) || is_null( $body ) || strlen( $subject ) === 0 || strlen( $body ) === 0 ) {
4508 return false;
4509 }
4510
4511 // Replace approved shortcode patterns in subject and body.
4512 $site_name = get_bloginfo( 'name' );
4513 $site_url = get_site_url();
4514 $subject = str_replace( '[site_name]', $site_name, $subject );
4515 $body = str_replace( '[site_name]', $site_name, $body );
4516 $body = str_replace( '[site_url]', $site_url, $body );
4517 $body = str_replace( '[user_email]', $email, $body );
4518 $headers = 'Content-type: text/html' . "\r\n";
4519
4520 // Send email.
4521 wp_mail( $email, $subject, $body, $headers );
4522
4523 // Indicate mail was sent.
4524 return true;
4525 }
4526
4527 /**
4528 * Generate a unique cookie to add to nonces to prevent CSRF.
4529 */
4530 protected $cookie_value = null;
4531 function get_cookie_value() {
4532 if ( ! $this->cookie_value ) {
4533 if ( isset( $_COOKIE['login_unique'] ) ) {
4534 $this->cookie_value = $_COOKIE['login_unique'];
4535 } else {
4536 $this->cookie_value = md5( rand() );
4537 }
4538 }
4539 return $this->cookie_value;
4540 } // END get_cookie_value()
4541
4542 /**
4543 * Basic encryption using a public (not secret!) key. Used for general
4544 * database obfuscation of passwords.
4545 */
4546 private static $key = '8QxnrvjdtweisvCBKEY!+0';
4547 function encrypt( $text ) {
4548 $result = '';
4549
4550 // Use mcrypt library (better) if php5-mcrypt extension is enabled.
4551 if ( function_exists( 'mcrypt_encrypt' ) ) {
4552 $result = mcrypt_encrypt( MCRYPT_RIJNDAEL_256, self::$key, $text, MCRYPT_MODE_ECB, 'abcdefghijklmnopqrstuvwxyz012345' );
4553 } else {
4554 for ( $i = 0; $i < strlen( $text ); $i++ ) {
4555 $char = substr( $text, $i, 1 );
4556 $keychar = substr( self::$key, ( $i % strlen( self::$key ) ) - 1, 1 );
4557 $char = chr( ord( $char ) + ord( $keychar ) );
4558 $result .= $char;
4559 }
4560 $result = base64_encode( $result );
4561 }
4562
4563 return $result;
4564 } // END encrypt()
4565
4566 function decrypt( $secret ) {
4567 $result = '';
4568
4569 // Use mcrypt library (better) if php5-mcrypt extension is enabled.
4570 if ( function_exists( 'mcrypt_decrypt' ) ) {
4571 $result = rtrim( mcrypt_decrypt( MCRYPT_RIJNDAEL_256, self::$key, $secret, MCRYPT_MODE_ECB, 'abcdefghijklmnopqrstuvwxyz012345' ), "\0$result" );
4572 } else {
4573 $secret = base64_decode( $secret );
4574 for ( $i = 0; $i < strlen( $secret ); $i++ ) {
4575 $char = substr( $secret, $i, 1 );
4576 $keychar = substr( self::$key, ( $i % strlen( self::$key ) ) - 1, 1 );
4577 $char = chr( ord( $char ) - ord( $keychar ) );
4578 $result .= $char;
4579 }
4580 }
4581
4582 return $result;
4583 } // END decrypt()
4584
4585 /**
4586 * In a multisite environment, returns true if the current user is logged
4587 * in and a user of the current blog. In single site mode, simply returns
4588 * true if the current user is logged in.
4589 */
4590 function is_user_logged_in_and_blog_user() {
4591 $is_user_logged_in_and_blog_user = false;
4592 if ( is_multisite() ) {
4593 $is_user_logged_in_and_blog_user = is_user_logged_in() && is_user_member_of_blog( get_current_user_id() );
4594 } else {
4595 $is_user_logged_in_and_blog_user = is_user_logged_in();
4596 }
4597 return $is_user_logged_in_and_blog_user;
4598 } // END is_user_logged_in_and_blog_user()
4599
4600 /**
4601 * Helper function to determine whether a given email is in one of
4602 * the lists (pending, approved, blocked). Defaults to the list of
4603 * approved users.
4604 */
4605 function is_email_in_list( $email = '', $list = 'approved', $multisite_mode = 'single' ) {
4606 if ( empty( $email ) )
4607 return false;
4608
4609 switch ( $list ) {
4610 case 'pending':
4611 $auth_settings_access_users_pending = $this->get_plugin_option( 'access_users_pending', 'single admin' );
4612 return $this->in_multi_array( $email, $auth_settings_access_users_pending );
4613 break;
4614 case 'blocked':
4615 $auth_settings_access_users_blocked = $this->get_plugin_option( 'access_users_blocked', 'single admin' );
4616 return $this->in_multi_array( $email, $auth_settings_access_users_blocked );
4617 break;
4618 case 'approved':
4619 default:
4620 if ( $multisite_mode !== 'single' ) {
4621 // Get multisite users only.
4622 $auth_settings_access_users_approved = $this->get_plugin_option( 'access_users_approved', 'multisite admin' );
4623 } else if ( is_multisite() && $this->get_plugin_option( 'advanced_override_multisite' ) == '1' ) {
4624 // This site has overridden any multisite settings, so only get its users.
4625 $auth_settings_access_users_approved = $this->get_plugin_option( 'access_users_approved', 'single admin' );
4626 } else {
4627 // Get all site users and all multisite users.
4628 $auth_settings_access_users_approved = array_merge(
4629 $this->get_plugin_option( 'access_users_approved', 'single admin' ),
4630 $this->get_plugin_option( 'access_users_approved', 'multisite admin' )
4631 );
4632 }
4633 return $this->in_multi_array( $email, $auth_settings_access_users_approved );
4634 break;
4635 }
4636 } // END is_email_in_list
4637
4638 /**
4639 * Helper function to get number of users (including multisite users)
4640 * in a given list (pending, approved, or blocked).
4641 * @param string $list
4642 * @param string $admin_mode 'single admin' or 'multisite admin' determines whether to include multisite users
4643 * @return int number of users in list
4644 */
4645 function get_user_count_from_list( $list, $admin_mode = 'single admin' ) {
4646 $auth_settings_access_users = array();
4647
4648 switch ( $list ) {
4649 case 'pending':
4650 $auth_settings_access_users = $this->get_plugin_option( 'access_users_pending', 'single admin' );
4651 break;
4652 case 'blocked':
4653 $auth_settings_access_users = $this->get_plugin_option( 'access_users_blocked', 'single admin' );
4654 break;
4655 case 'approved':
4656 if ( $admin_mode !== 'single admin' ) {
4657 // Get multisite users only.
4658 $auth_settings_access_users = $this->get_plugin_option( 'access_users_approved', 'multisite admin' );
4659 } else if ( is_multisite() && $this->get_plugin_option( 'advanced_override_multisite' ) == '1' ) {
4660 // This site has overridden any multisite settings, so only get its users.
4661 $auth_settings_access_users = $this->get_plugin_option( 'access_users_approved', 'single admin' );
4662 } else {
4663 // Get all site users and all multisite users.
4664 $auth_settings_access_users = array_merge(
4665 $this->get_plugin_option( 'access_users_approved', 'single admin' ),
4666 $this->get_plugin_option( 'access_users_approved', 'multisite admin' )
4667 );
4668 }
4669 }
4670
4671 return count( $auth_settings_access_users );
4672 }
4673
4674 /**
4675 * Helper function to search a multidimensional array for a value.
4676 */
4677 function in_multi_array( $needle = '', $haystack = array(), $strict_mode = 'not strict', $case_sensitivity = 'case insensitive' ) {
4678 if ( ! is_array( $haystack ) ) {
4679 return false;
4680 }
4681 if ( $case_sensitivity === 'case insensitive' ) {
4682 $needle = strtolower( $needle );
4683 }
4684 foreach ( $haystack as $item ) {
4685 if ( $case_sensitivity === 'case insensitive' && ! is_array( $item ) ) {
4686 $item = strtolower( $item );
4687 }
4688 if ( ( $strict_mode === 'strict' ? $item === $needle : $item == $needle ) || ( is_array( $item ) && $this->in_multi_array( $needle, $item, $strict_mode, $case_sensitivity ) ) ) {
4689 return true;
4690 }
4691 }
4692 return false;
4693 } // END in_multi_array()
4694
4695 /**
4696 * Helper function to get a WordPress page ID from the pagename.
4697 *
4698 * @param string $pagename Page Slug
4699 * @return int Page/Post ID
4700 */
4701 function get_id_from_pagename( $pagename = '' ) {
4702 global $wpdb;
4703 $page_id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_name = '" . sanitize_title_for_query( $pagename ) . "'" );
4704 return $page_id;
4705 } // END get_id_from_pagename()
4706
4707 /**
4708 * Helper function to determine if an URL is accessible.
4709 *
4710 * @param string $url URL that should be publicly reachable
4711 * @return boolean Whether the URL is publicly reachable
4712 */
4713 function url_is_accessible( $url ) {
4714 // Make sure php5-curl extension is installed on server.
4715 if ( ! function_exists( 'curl_init' ) ) {
4716 // Note: This will silently fail, saying url is not accessible.
4717 // Warn user elsewhere that they should install curl.
4718 return false;
4719 }
4720
4721 // Use curl to retrieve the URL.
4722 $handle = curl_init( $url );
4723 curl_setopt( $handle, CURLOPT_RETURNTRANSFER, TRUE );
4724 curl_setopt( $handle, CURLOPT_SSL_VERIFYPEER, FALSE );
4725 $response = curl_exec( $handle );
4726 $http_code = curl_getinfo( $handle, CURLINFO_HTTP_CODE );
4727 curl_close( $handle );
4728
4729 // Return true if the document has loaded successfully without any redirection or error
4730 return $http_code >= 200 && $http_code < 400;
4731 } // END url_is_accessible()
4732
4733 // Helper function that builds option tags for a select element for all
4734 // roles the current user has permission to assign.
4735 function wp_dropdown_permitted_roles( $selected_role = 'subscriber', $disable_input = 'not disabled' ) {
4736 $roles = get_editable_roles();
4737 $current_user = wp_get_current_user();
4738
4739 // Make sure we have a selected role (default to subscriber).
4740 if ( strlen( $selected_role ) < 1 ) {
4741 $selected_role = 'subscriber';
4742 }
4743
4744 // If the currently selected role is not in the list of roles, it
4745 // either doesn't exist or the current user is not permitted to
4746 // assign it.
4747 if ( ! array_key_exists( $selected_role, $roles ) ) {
4748 ?><option value="<?php echo $selected_role; ?>"><?php echo ucfirst( $selected_role ); ?></option><?php
4749
4750 // If the role exists, that means the user isn't permitted to
4751 // assign it, so assume they can't edit that user's role at
4752 // all. Return only the one role for the dropdown list.
4753 if ( ! is_null( get_role( $selected_role ) ) ) {
4754 return;
4755 }
4756 }
4757
4758 // Print an option element for each permitted role.
4759 foreach ( $roles as $name => $role ) {
4760 $selected = $selected_role === $name ? ' selected="selected"' : '';
4761
4762 // Don't let a user change their own role
4763 $disabled = $selected_role !== $name && $disable_input === 'disabled' ? ' disabled="disabled"' : '';
4764
4765 // But network admins can always change their role.
4766 if ( is_multisite() && current_user_can( 'manage_network' ) ) {
4767 $disabled = '';
4768 }
4769
4770 ?><option value="<?php echo $name; ?>"<?php echo $selected . $disabled; ?>><?php echo $role['name']; ?></option><?php
4771 }
4772 } // END wp_dropdown_permitted_roles()
4773
4774 // Helper function to get a single user info array from one of the
4775 // access control lists (pending, approved, or blocked).
4776 // Returns: false if not found; otherwise
4777 // array( 'email' => '', 'role' => '', 'date_added' => '', ['usermeta' => [''|array()]] );
4778 function get_user_info_from_list( $email, $list ) {
4779 foreach ( $list as $user_info ) {
4780 if ( $user_info['email'] === $email ) {
4781 return $user_info;
4782 }
4783 }
4784 return false;
4785 } // END get_user_info_from_list()
4786
4787 // Helper function to convert seconds to human readable text.
4788 // Source: http://csl.name/php-secs-to-human-text/
4789 function seconds_as_sentence( $secs ) {
4790 $units = array(
4791 "week" => 7 * 24 * 3600,
4792 "day" => 24 * 3600,
4793 "hour" => 3600,
4794 "minute" => 60,
4795 "second" => 1,
4796 );
4797
4798 // specifically handle zero
4799 if ( $secs == 0 ) return "0 seconds";
4800
4801 $s = "";
4802
4803 foreach ( $units as $name => $divisor ) {
4804 if ( $quot = intval( $secs / $divisor ) ) {
4805 $s .= "$quot $name";
4806 $s .= ( abs( $quot ) > 1 ? "s" : "" ) . ", ";
4807 $secs -= $quot * $divisor;
4808 }
4809 }
4810
4811 return substr( $s, 0, -2 );
4812 } // END seconds_as_sentence()
4813
4814 // Helper function to get all available usermeta keys as an array.
4815 function get_all_usermeta_keys() {
4816 global $wpdb;
4817 $usermeta_keys = $wpdb->get_col( "SELECT DISTINCT $wpdb->usermeta.meta_key FROM $wpdb->usermeta" );
4818 return $usermeta_keys;
4819 }
4820
4821
4822 /**
4823 * Plugin Update Routines.
4824 */
4825 function auth_update_check() {
4826 // Update: migrate user lists to own options (addresses concurrency
4827 // when saving plugin options, since user lists are changed often
4828 // and we don't want to overwrite changes to the lists when an
4829 // admin saves all of the plugin options.)
4830 // Note: Pending user list is changed whenever a new user tries to
4831 // log in; approved and blocked lists are changed whenever an admin
4832 // changes them from the multisite panel, the dashboard widget, or
4833 // the plugin options page.
4834 $update_if_older_than = 20140709;
4835 $auth_version = get_option( 'auth_version' );
4836 if ( $auth_version === false || intval( $auth_version ) < $update_if_older_than ) {
4837 // Copy single site user lists to new options (if they exist).
4838 $auth_settings = get_option( 'auth_settings' );
4839 if ( is_array( $auth_settings ) && array_key_exists( 'access_users_pending', $auth_settings ) ) {
4840 update_option( 'auth_settings_access_users_pending', $auth_settings['access_users_pending'] );
4841 unset( $auth_settings['access_users_pending'] );
4842 update_option( 'auth_settings', $auth_settings );
4843 }
4844 if ( is_array( $auth_settings ) && array_key_exists( 'access_users_approved', $auth_settings ) ) {
4845 update_option( 'auth_settings_access_users_approved', $auth_settings['access_users_approved'] );
4846 unset( $auth_settings['access_users_approved'] );
4847 update_option( 'auth_settings', $auth_settings );
4848 }
4849 if ( is_array( $auth_settings ) && array_key_exists( 'access_users_blocked', $auth_settings ) ) {
4850 update_option( 'auth_settings_access_users_blocked', $auth_settings['access_users_blocked'] );
4851 unset( $auth_settings['access_users_blocked'] );
4852 update_option( 'auth_settings', $auth_settings );
4853 }
4854 // Copy multisite user lists to new options (if they exist).
4855 if ( is_multisite() ) {
4856 $auth_multisite_settings = get_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings', array() );
4857 if ( is_array( $auth_multisite_settings ) && array_key_exists( 'access_users_pending', $auth_multisite_settings ) ) {
4858 update_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings_access_users_pending', $auth_multisite_settings['access_users_pending'] );
4859 unset( $auth_multisite_settings['access_users_pending'] );
4860 update_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings', $auth_multisite_settings );
4861 }
4862 if ( is_array( $auth_multisite_settings ) && array_key_exists( 'access_users_approved', $auth_multisite_settings ) ) {
4863 update_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings_access_users_approved', $auth_multisite_settings['access_users_approved'] );
4864 unset( $auth_multisite_settings['access_users_approved'] );
4865 update_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings', $auth_multisite_settings );
4866 }
4867 if ( is_array( $auth_multisite_settings ) && array_key_exists( 'access_users_blocked', $auth_multisite_settings ) ) {
4868 update_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings_access_users_blocked', $auth_multisite_settings['access_users_blocked'] );
4869 unset( $auth_multisite_settings['access_users_blocked'] );
4870 update_blog_option( BLOG_ID_CURRENT_SITE, 'auth_multisite_settings', $auth_multisite_settings );
4871 }
4872 }
4873 // Update version to reflect this change has been made.
4874 update_option( 'auth_version', $update_if_older_than );
4875 }
4876
4877 // // Update: TEMPLATE
4878 // $update_if_older_than = YYYYMMDD;
4879 // $auth_version = get_option( 'auth_version' );
4880 // if ( $auth_version === false || intval( $auth_version ) < $update_if_older_than ) {
4881 // UPDATE CODE HERE
4882 // update_option( 'auth_version', $update_if_older_than );
4883 // }
4884 }
4885
4886 } // END class WP_Plugin_Authorizer
4887 }
4888
4889 // Instantiate the plugin class.
4890 $wp_plugin_authorizer = new WP_Plugin_Authorizer();
4891