PluginProbe
Authorizer / 2.3.3
Authorizer v2.3.3
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.3, at authorizer.php

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