PluginProbe
Authorizer / 2.6.14
Authorizer v2.6.14
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.14, at authorizer.php

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