Skip to content

Commit

Permalink
Merge pull request #71 from michaelryanmcneill/2.3-alpha
Browse files Browse the repository at this point in the history
Version 2.3
  • Loading branch information
michaelryanmcneill authored Aug 17, 2020
2 parents 5089e46 + 50f8dbd commit 1de7a25
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 83 deletions.
30 changes: 27 additions & 3 deletions options-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ function shibboleth_options_page() {
if ( ! defined( 'SHIBBOLETH_ATTRIBUTE_ACCESS_METHOD' ) ) {
update_site_option( 'shibboleth_attribute_access_method', $_POST['attribute_access'] );
}
if ( ! defined( 'SHIBBOLETH_ATTRIBUTE_ACCESS_METHOD_FALLBACK' ) ) {
update_site_option( 'shibboleth_attribute_access_method_fallback', $_POST['attribute_access_fallback'] );
}
if ( ! defined( 'SHIBBOLETH_ATTRIBUTE_CUSTOM_ACCESS_METHOD' ) ) {
update_site_option( 'shibboleth_attribute_custom_access_method', $_POST['attribute_custom_access'] );
}
Expand Down Expand Up @@ -201,6 +204,8 @@ function shibboleth_options_page() {
$constant = $constant || $from_constant;
list( $attribute_access, $from_constant ) = shibboleth_getoption( 'shibboleth_attribute_access_method', false, false, true );
$constant = $constant || $from_constant;
list( $attribute_access_fallback, $from_constant ) = shibboleth_getoption( 'shibboleth_attribute_access_method_fallback', false, false, true );
$constant = $constant || $from_constant;
list( $attribute_custom_access, $from_constant ) = shibboleth_getoption( 'shibboleth_attribute_custom_access_method', false, false, true );
$constant = $constant || $from_constant;
list( $spoofkey, $from_constant ) = shibboleth_getoption( 'shibboleth_spoof_key', false, false, true );
Expand Down Expand Up @@ -293,6 +298,16 @@ function shibboleth_options_page() {
. '<br /><b>WARNING:</b> If you incorrectly set this option, you will force <b><i>ALL</i></b> attempts to authenticate with Shibboleth to fail.', 'shibboleth'); ?></p>
</td>
</tr>
<tr id="attribute_access_fallback_row" <?php if( $attribute_access === 'standard' ) echo 'style="display:none;"'; ?>>
<th scope="row"><label for="attribute_access_fallback"><?php _e('Enable Fallback Attribute Access', 'shibboleth'); ?></label></th>
<td>
<input type="checkbox" id="attribute_access_fallback" name="attribute_access_fallback" <?php echo $attribute_access_fallback ? ' checked="checked"' : '' ?> <?php if ( defined( 'SHIBBOLETH_ATTRIBUTE_ACCESS_METHOD_FALLBACK' ) ) { disabled( $attribute_access_fallback, SHIBBOLETH_ATTRIBUTE_ACCESS_METHOD_FALLBACK ); } ?> />
<label for="attribute_access_fallback"><?php _e('Allow the standard environment variables to be used as a fallback for attribute access.', 'shibboleth'); ?></label>

<p><?php _e('If set, this will fallback to standard environment variables when the selected'
. ' attribute access method fails.', 'shibboleth'); ?></p>
</td>
</tr>
<tr>
<th scope="row"><label for="default_login"><?php _e('Default Login Method', 'shibboleth'); ?></label></th>
<td>
Expand Down Expand Up @@ -357,17 +372,26 @@ function AttributeAccessMethod()

if (selectedValue == "custom")
{
document.getElementById("attribute_custom_access_row").style.display = "table-row";
document.getElementById("attribute_custom_access_row").style.display = "table-row";
document.getElementById("attribute_access_fallback_row").style.display = "table-row";
document.getElementById("spoofkey_row").style.display = "none";
}
else if (selectedValue == "http")
{
document.getElementById("attribute_custom_access_row").style.display = "none";
document.getElementById("attribute_custom_access_row").style.display = "none";
document.getElementById("attribute_access_fallback_row").style.display = "table-row";
document.getElementById("spoofkey_row").style.display = "table-row";
}
else if (selectedValue == "standard")
{
document.getElementById("attribute_custom_access_row").style.display = "none";
document.getElementById("attribute_access_fallback_row").style.display = "none";
document.getElementById("spoofkey_row").style.display = "none";
}
else
{
document.getElementById("attribute_custom_access_row").style.display = "none";
document.getElementById("attribute_custom_access_row").style.display = "none";
document.getElementById("attribute_access_fallback_row").style.display = "table-row";
document.getElementById("spoofkey_row").style.display = "none";
}
}
Expand Down
115 changes: 42 additions & 73 deletions options-user.php
Original file line number Diff line number Diff line change
@@ -1,39 +1,41 @@
<?php
// functions for managing Shibboleth user options through the WordPress administration panel

add_action('profile_personal_options', 'shibboleth_profile_personal_options');
add_action('personal_options_update', 'shibboleth_personal_options_update');
add_action('show_user_profile', 'shibboleth_show_user_profile');
add_action('admin_footer-user-edit.php', 'shibboleth_admin_footer_edit_user');

/**
* For WordPress accounts that were created by Shibboleth, limit what profile
* attributes they can modify.
* For WordPress accounts that were created by Shibboleth, limit what administrators and users
* can edit via user-edit.php and profile.php.
*
* @since 1.3
* @since 2.3
*/
function shibboleth_profile_personal_options() {
$user = wp_get_current_user();
function shibboleth_edit_user_options() {
if ( IS_PROFILE_PAGE ) {
$user_id = wp_get_current_user()->ID;
} else {
global $user_id;
}

if (get_user_meta( $user->ID, 'shibboleth_account') ) {
if ( get_user_meta( $user_id, 'shibboleth_account' ) ) {
add_filter( 'show_password_fields', '__return_false' );

add_filter( 'show_password_fields', create_function( '$v', 'return false;' ) );
add_action( 'admin_footer-user-edit.php', 'shibboleth_disable_managed_fields' );

add_action( 'admin_footer-profile.php', 'shibboleth_admin_footer_profile' );
add_action( 'admin_footer-profile.php', 'shibboleth_disable_managed_fields' );
}
}
add_action( 'personal_options', 'shibboleth_edit_user_options' );

/**
* For WordPress accounts that were created by Shibboleth, disable certain fields
* that they are allowed to modify.
* that users/administrators aren't allowed to modify.
*
* @since 1.3
* @since 1.3 (renamed in 2.3 from `shibboleth_admin_footer_profile`)
*/
function shibboleth_admin_footer_profile() {
function shibboleth_disable_managed_fields() {
$managed_fields = shibboleth_get_managed_user_fields();

if ( shibboleth_getoption( 'shibboleth_update_roles' ) ) {
$managed_fields = array_merge( $managed_fields, array('role') );
}
if ( ! empty( $managed_fields ) ) {
$selectors = join( ',', array_map( create_function( '$a', 'return "#$a";' ), $managed_fields ) );
$selectors = join( ',', array_map( function( $a ) { return "#$a"; }, $managed_fields ) );

echo '
<script type="text/javascript">
Expand All @@ -44,59 +46,21 @@ function shibboleth_admin_footer_profile() {
jQuery("form#your-profile").submit(function() {
jQuery("' . $selectors . '").attr("disabled", false);
});
if(jQuery("#email").is(":disabled")){
jQuery("#email-description").hide();
}
});
</script>';
}
}


/**
* For WordPress accounts that were created by Shibboleth, warn the admin of
* Shibboleth managed attributes.
*
* @since 1.3
*/
function shibboleth_admin_footer_edit_user() {
global $user_id;

if ( get_user_meta( $user_id, 'shibboleth_account' ) ) {
$shibboleth_fields = array();

$shibboleth_fields = array_merge( $shibboleth_fields, shibboleth_get_managed_user_fields() );

$update = shibboleth_getoption( 'shibboleth_update_roles' );

if ( $update ) {
$shibboleth_fields = array_merge( $shibboleth_fields, array('role') );
}

if ( ! empty( $shibboleth_fields ) ) {
$selectors = array();

foreach( $shibboleth_fields as $field ) {
$selectors[] = 'label[for=\'' . $field . '\']';
}

echo '
<script type="text/javascript">
jQuery(function() {
jQuery("' . implode( ',', $selectors ) . '").before("<span style=\"color: #F00; font-weight: bold;\">*</span> ");
jQuery("#first_name").parents(".form-table")
.before("<div class=\"updated fade\"><p><span style=\"color: #F00; font-weight: bold;\">*</span> '
. __( 'Starred fields are managed by Shibboleth and should not be changed from WordPress.', 'shibboleth' ) . '</p></div>");
});
</script>';
}
}
}


/**
* Add change password link to the user profile for Shibboleth users.
*
* @since 1.3
* @since 1.3 (renamed in 2.3 from `shibboleth_show_user_profile`)
*/
function shibboleth_show_user_profile() {
function shibboleth_change_password_profile_link() {
$user = wp_get_current_user();
$password_change_url = shibboleth_getoption( 'shibboleth_password_change_url' );

Expand All @@ -112,41 +76,46 @@ function shibboleth_show_user_profile() {
<?php
}
}
add_action( 'show_user_profile', 'shibboleth_change_password_profile_link' );


/**
* Ensure profile data isn't updated by the user. This only applies to accounts that were
* provisioned through Shibboleth, and only for those user fields marked as 'managed'.
* Ensure profile data isn't updated when managed.
*
* @since 1.3
* @since 2.3
* @param int $user_id
*/
function shibboleth_personal_options_update() {
$user = wp_get_current_user();
function shibboleth_prevent_managed_fields_update( $user_id ) {

if ( get_user_meta( $user_id, 'shibboleth_account' ) ) {

$user = get_user_by( 'id', $user_id );

if ( get_user_meta( $user->ID, 'shibboleth_account' ) ) {
$managed = shibboleth_get_managed_user_fields();

if ( in_array( 'first_name', $managed ) ) {
add_filter( 'pre_user_first_name', create_function( '$n', 'return $GLOBALS["current_user"]->first_name;' ) );
$_POST['first_name'] = $user->first_name;
}

if ( in_array( 'last_name', $managed ) ) {
add_filter( 'pre_user_last_name', create_function( '$n', 'return $GLOBALS["current_user"]->last_name;' ) );
$_POST['last_name'] = $user->last_name;
}

if ( in_array( 'nickname', $managed ) ) {
add_filter( 'pre_user_nickname', create_function( '$n', 'return $GLOBALS["current_user"]->nickname;' ) );
$_POST['nickname'] = $user->nickname;
}

if ( in_array( 'display_name', $managed ) ) {
add_filter( 'pre_user_display_name', create_function( '$n', 'return $GLOBALS["current_user"]->display_name;' ) );
$_POST['display_name'] = $user->display_name;
}

if ( in_array( 'email', $managed ) ) {
add_filter( 'pre_user_email', create_function( '$e', 'return $GLOBALS["current_user"]->user_email;' ) );
$_POST['email'] = $user->user_email;
}
}
}
add_action( 'personal_options_update', 'shibboleth_prevent_managed_fields_update' );
add_action( 'edit_user_profile_update', 'shibboleth_prevent_managed_fields_update' );

/**
* Adds a button to user profile pages if administrator has allowed
Expand Down
20 changes: 17 additions & 3 deletions readme.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
=== Shibboleth ===
Contributors: michaelryanmcneill, willnorris, mitchoyoshitaka, jrchamp, dericcrago, bshelton229, Alhrath, dandalpiaz
Tags: shibboleth, authentication, login, saml
Requires at least: 3.3
Tested up to: 5.4.2
Stable tag: 2.2.2
Requires at least: 4.0
Tested up to: 5.5
Requires PHP: 5.6
Stable tag: 2.3

Allows WordPress to externalize user authentication and account creation to a Shibboleth Service Provider.

Expand Down Expand Up @@ -90,6 +91,10 @@ Yes, the plugin allows for all settings to be controlled via constants in `wp-co
- Format: string
- Available options: `'standard'` for the default "Environment Variables" option, `'redirect'` for the "Redirected Environment Variables" option, and `'http'` for the "HTTP Headers" option.
- Example: `define('SHIBBOLETH_ATTRIBUTE_ACCESS_METHOD', 'standard');`
- `SHIBBOLETH_ATTRIBUTE_ACCESS_METHOD_FALLBACK`
- Format: boolean
- Available options: `true` to fallback to the standard "Environment Variables" options when the selected attribute access method does not return results or `false` to not fallback.
- Example: `define('SHIBBOLETH_ATTRIBUTE_ACCESS_METHOD_FALLBACK', true);`
- `SHIBBOLETH_LOGIN_URL`
- Format: string
- Avaliable Options: none
Expand Down Expand Up @@ -176,6 +181,9 @@ Yes, the plugin allows for all settings to be controlled via constants in `wp-co
3. Assign users into WordPress roles based on arbitrary data provided by Shibboleth

== Upgrade Notice ==
= 2.3 =
This update increases the minimum PHP version to 5.6 and the minimum WordPress version to 4.0. The plugin will fail to activate if you are running below those minimum versions.

= 2.2.2 =
This update re-implements a previously reverted <IfModule> conditional for three aliases of the Shibboleth Apache module: `mod_shib`, `mod_shib.c`, and `mod_shib.cpp`. If you run into issues related to this change, please open an issue on [GitHub](https://github.com/michaelryanmcneill/shibboleth/issues).

Expand All @@ -189,6 +197,12 @@ This update brings with it a major change to the way Shibboleth attributes are a
This update brings with it a major change to the way Shibboleth attributes are accessed. For most users, no additional configuration will be necessary. If you are using a specialized server configuration, such as a Shibboleth Service Provider on a reverse proxy or a server configuration that results in environment variables being sent with the prefix REDIRECT_, you should see the changelog for additional details: https://wordpress.org/plugins/shibboleth/#developers

== Changelog ==
= version 2.3 (2020-08-17) =
- Implementing a fallback option for the "Shibboleth Attribute Access Method". For example, if your web server returns redirected environment variables, but occasionally returns standard environment variables, you would want to enable this option.
- Removing deprecated `create_function()` from use.
- Bumped minimum PHP and WordPress versions to 5.6 and 4.0 respectively.
- Greatly improved the handling of managed fields and cleaned up `options-user.php`.

= version 2.2.2 (2020-06-22) =
- Re-implementing <IfModule> conditional for .htaccess to protect against the Shibboleth Apache module not being installed; [thanks to @jrchamp for reporting](https://github.com/michaelryanmcneill/shibboleth/issues/60). This change includes conditionals for `mod_shib`, `mod_shib.c`, and `mod_shib.cpp`. If you run into issues related to this change, please open an issue on [GitHub](https://github.com/michaelryanmcneill/shibboleth/issues).

Expand Down
31 changes: 27 additions & 4 deletions shibboleth.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
Plugin URI: http://wordpress.org/extend/plugins/shibboleth
Description: Easily externalize user authentication to a <a href="http://shibboleth.internet2.edu">Shibboleth</a> Service Provider
Author: Michael McNeill, mitcho (Michael 芳貴 Erlewine), Will Norris
Version: 2.2.2
Version: 2.3
Requires PHP: 5.6
Requires at least: 4.0
License: Apache 2 (http://www.apache.org/licenses/LICENSE-2.0.html)
Text Domain: shibboleth
*/

define( 'SHIBBOLETH_MINIMUM_WP_VERSION', '3.3' );
define( 'SHIBBOLETH_PLUGIN_VERSION', '2.2' );
define( 'SHIBBOLETH_MINIMUM_WP_VERSION', '4.0' );
define( 'SHIBBOLETH_MINIMUM_PHP_VERSION', '5.6');
define( 'SHIBBOLETH_PLUGIN_VERSION', '2.3' );

/**
* Determine if this is a new install or upgrade and, if so, run the
Expand Down Expand Up @@ -79,11 +82,14 @@ function shibboleth_getenv( $var ) {
// Get the specified shibboleth attribute access method; if one isn't specified
// simply use standard environment variables since they're the safest
$method = shibboleth_getoption( 'shibboleth_attribute_access_method', 'standard' );
$fallback = shibboleth_getoption( 'shibboleth_attribute_access_method_fallback' );

switch ( $method ) {
// Use standard by default for security
case 'standard' :
$var_method = '';
// Disable fallback to prevent the same variables from being checked twice.
$fallback = false;
break;
// If specified, use redirect
case 'redirect' :
Expand All @@ -101,6 +107,8 @@ function shibboleth_getenv( $var ) {
// Otherwise, fall back to standard for security
default :
$var_method = '';
// Disable fallback to prevent the same variables from being checked twice.
$fallback = false;
}

// Using the selected attribute access method, check all possible cases
Expand All @@ -115,6 +123,18 @@ function shibboleth_getenv( $var ) {
$var_method . $var_under_upper => TRUE,
);

// If fallback is enabled, we will add the standard environment variables to the end of the array to allow for fallback
if ( $fallback ) {
$fallback_check_vars = array(
$var => TRUE,
$var_under => TRUE,
$var_upper => TRUE,
$var_under_upper => TRUE,
);

$check_vars = array_merge( $check_vars, $fallback_check_vars );
}

foreach ( $check_vars as $check_var => $true ) {
if ( isset( $_SERVER[$check_var] ) && ( $result = $_SERVER[$check_var] ) !== FALSE ) {
return $result;
Expand Down Expand Up @@ -155,7 +175,10 @@ function shibboleth_auto_login() {
function shibboleth_activate_plugin() {
if ( version_compare( $GLOBALS['wp_version'], SHIBBOLETH_MINIMUM_WP_VERSION, '<' ) ) {
deactivate_plugins( plugin_basename( __FILE__ ) );
wp_die( __( 'Shibboleth requires WordPress '. SHIBBOLETH_MINIMUM_WP_VERSION . 'or higher!', 'shibboleth' ) );
wp_die( __( 'Shibboleth requires WordPress '. SHIBBOLETH_MINIMUM_WP_VERSION . ' or higher!', 'shibboleth' ) );
} elseif ( version_compare( PHP_VERSION, SHIBBOLETH_MINIMUM_PHP_VERSION, '<' ) ) {
deactivate_plugins( plugin_basename( __FILE__ ) );
wp_die( __( 'Shibboleth requires PHP '. SHIBBOLETH_MINIMUM_PHP_VERSION . ' or higher!', 'shibboleth' ) );
}

if ( function_exists( 'switch_to_blog' ) ) {
Expand Down

0 comments on commit 1de7a25

Please sign in to comment.