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

authorizer.php in Authorizer 2.5.1, at authorizer.php

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