PluginProbe
Authorizer / 2.6.15
Authorizer v2.6.15
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.15, at authorizer.php

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