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

authorizer.php in Authorizer 2.3.9, at authorizer.php

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