PluginProbe
Authorizer / 2.3.10
Authorizer v2.3.10
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.10, at authorizer.php

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