PluginProbe
Authorizer / 2.4.0
Authorizer v2.4.0
3.15.3 3.15.2 3.15.1 3.15.0 3.14.3 3.14.4 3.14.2 3.14.1 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.9.0 2.9.1 2.9.10 2.9.11 2.9.12 2.9.13 2.9.2 2.9.3 2.9.6 All 126 releases
authorizer / authorizer.php

authorizer.php in Authorizer 2.4.0, at authorizer.php

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