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