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

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