PluginProbe
Authorizer / 2.6.13
Authorizer v2.6.13
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.13, at authorizer.php

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