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

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