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