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

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