Skip to content

Commit

Permalink
Merge pull request #101 from smbader/feature/multi-idp
Browse files Browse the repository at this point in the history
Add the ability to configure multiple IdPs
  • Loading branch information
jrchamp authored Oct 11, 2024
2 parents 01aae2d + ceb3853 commit eada385
Show file tree
Hide file tree
Showing 9 changed files with 451 additions and 136 deletions.
3 changes: 3 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": [ "plugin:@wordpress/eslint-plugin/recommended" ]
}
4 changes: 2 additions & 2 deletions .github/workflows/wp-plugin-ci-full.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up PHP
uses: shivammathur/setup-php@v2
Expand All @@ -23,7 +23,7 @@ jobs:
tools: cs2pr

- name: Install Composer dependencies
uses: ramsey/composer-install@v2
uses: ramsey/composer-install@v3

- name: Run PHPCS on all files
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/wp-plugin-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
# Fetch all history so we can diff.
fetch-depth: 0
Expand All @@ -26,7 +26,7 @@ jobs:
tools: cs2pr

- name: Install Composer dependencies
uses: ramsey/composer-install@v2
uses: ramsey/composer-install@v3

- name: Run PHPCS on changed files
run: |
Expand Down
4 changes: 4 additions & 0 deletions assets/css/shibboleth-options.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/* Allow Identity Provider cards to be full width. */
.card {
max-width: none;
}
19 changes: 10 additions & 9 deletions assets/css/shibboleth_login_form.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
padding-bottom: 26px;
}

#loginform #shibboleth-wrap,
#loginform #shibboleth-wrap * {
#loginform .shibboleth-wrap,
#loginform .shibboleth-wrap * {
box-sizing: border-box;
}

#shibboleth-wrap {
.shibboleth-wrap {
position: absolute;
bottom: 20px;
padding: 0 24px;
Expand All @@ -27,7 +27,7 @@
width: 100%;
}

.shibboleth-repositioned #shibboleth-wrap {
.shibboleth-repositioned .shibboleth-wrap {
position: relative;
bottom: auto;
padding: 0;
Expand All @@ -36,7 +36,7 @@
margin-right: 0;
}

.shibboleth-form-display #shibboleth-wrap {
.shibboleth-form-display .shibboleth-wrap {
position: relative;
bottom: auto;
padding: 0;
Expand All @@ -45,23 +45,24 @@
margin-right: 0;
}

#loginform #shibboleth-wrap p {
#loginform .shibboleth-wrap p {
margin-bottom: 16px;
}

#shibboleth-wrap a {
.shibboleth-wrap .shibboleth-button {
display: block;
width: 100%;
text-align: center;
text-decoration: none;
float: none;
}

.shibboleth-form-display #loginform > p,
.shibboleth-form-display #loginform > div {
display: none;
}

.shibboleth-form-display #loginform #shibboleth-wrap {
.shibboleth-form-display #loginform .shibboleth-wrap {
display: block;
}

Expand Down Expand Up @@ -105,6 +106,6 @@
clear: both;
}

.shibboleth-repositioned #shibboleth-wrap .button .dashicons {
.shibboleth-repositioned .shibboleth-wrap .button .dashicons {
font-size: 24px;
}
7 changes: 3 additions & 4 deletions assets/js/shibboleth_login_form.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@

jQuery( document ).ready(
function ( $ ) {
var body = $( 'body' ),
userLogin = $( '#user_login' ),
ssoWrap = $( '#shibboleth-wrap' ),
const body = $( 'body' ),
ssoWrap = $( '.shibboleth-wrap' ),
loginForm = $( '#loginform' ),
overflow = $( '<div class="shibboleth-clear"></div>' );
overflow = $( '<div class="shibboleth-clear"></div>' );

// The overflow div is a poor man's clearfloat. We reposition the remember me
// checkbox and the submit button within that to clear the float on the
Expand Down
180 changes: 140 additions & 40 deletions options-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
*/
function shibboleth_admin_tabs( $current = 'general' ) {
$tabs = array(
'general' => 'General',
'user' => 'User',
'authorization' => 'Authorization',
'logging' => 'Logging',
'general' => __( 'General' ),
'idps' => __( 'Identity Providers', 'shibboleth' ),
'user' => __( 'User' ),
'authorization' => __( 'Authorization', 'shibboleth' ),
'logging' => __( 'Logging', 'shibboleth' ),
);
echo '<nav class="nav-tab-wrapper">';
foreach ( $tabs as $tab => $name ) {
Expand Down Expand Up @@ -118,21 +119,12 @@ function shibboleth_options_general() {
if ( ! defined( 'SHIBBOLETH_SPOOF_KEY' ) && isset( $_POST['spoofkey'] ) ) {
update_site_option( 'shibboleth_spoof_key', sanitize_text_field( wp_unslash( $_POST['spoofkey'] ) ) );
}
if ( ! defined( 'SHIBBOLETH_PASSWORD_CHANGE_URL' ) && isset( $_POST['password_change_url'] ) ) {
update_site_option( 'shibboleth_password_change_url', esc_url_raw( wp_unslash( $_POST['password_change_url'] ) ) );
}
if ( ! defined( 'SHIBBOLETH_PASSWORD_RESET_URL' ) && isset( $_POST['password_reset_url'] ) ) {
update_site_option( 'shibboleth_password_reset_url', esc_url_raw( wp_unslash( $_POST['password_reset_url'] ) ) );
}
if ( ! defined( 'SHIBBOLETH_DEFAULT_TO_SHIB_LOGIN' ) ) {
update_site_option( 'shibboleth_default_to_shib_login', ! empty( $_POST['default_login'] ) );
}
if ( ! defined( 'SHIBBOLETH_AUTO_LOGIN' ) ) {
update_site_option( 'shibboleth_auto_login', ! empty( $_POST['auto_login'] ) );
}
if ( ! defined( 'SHIBBOLETH_BUTTON_TEXT' ) && isset( $_POST['button_text'] ) ) {
update_site_option( 'shibboleth_button_text', sanitize_text_field( wp_unslash( $_POST['button_text'] ) ) );
}
if ( ! defined( 'SHIBBOLETH_DISABLE_LOCAL_AUTH' ) ) {
update_site_option( 'shibboleth_disable_local_auth', ! empty( $_POST['disable_local_auth'] ) );
}
Expand All @@ -145,10 +137,6 @@ function shibboleth_options_general() {
$constant = $constant || $from_constant;
list( $logout_url, $from_constant ) = shibboleth_getoption( 'shibboleth_logout_url', false, false, true );
$constant = $constant || $from_constant;
list( $password_change_url, $from_constant ) = shibboleth_getoption( 'shibboleth_password_change_url', false, false, true );
$constant = $constant || $from_constant;
list( $password_reset_url, $from_constant ) = shibboleth_getoption( 'shibboleth_password_reset_url', false, false, true );
$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 );
Expand All @@ -163,8 +151,6 @@ function shibboleth_options_general() {
$constant = $constant || $from_constant;
list( $disable_local_auth, $from_constant ) = shibboleth_getoption( 'shibboleth_disable_local_auth', false, false, true );
$constant = $constant || $from_constant;
list( $button_text, $from_constant ) = shibboleth_getoption( 'shibboleth_button_text', false, false, true );
$constant = $constant || $from_constant;
?>

<h2><?php esc_html_e( 'General Configuration', 'shibboleth' ); ?></h2>
Expand Down Expand Up @@ -210,20 +196,6 @@ function shibboleth_options_general() {
<a href="https://shibboleth.atlassian.net/wiki/spaces/SHIB2/pages/2577072384/NativeSPLogoutInitiator" target="_blank">Shibboleth SP v2</a>
</td>
</tr>
<tr valign="top">
<th scope="row"><label for="password_change_url"><?php esc_html_e( 'Password Change URL', 'shibboleth' ); ?></label></th>
<td>
<input type="text" id="password_change_url" name="password_change_url" value="<?php echo esc_url( $password_change_url ); ?>" size="50" <?php defined( 'SHIBBOLETH_PASSWORD_CHANGE_URL' ) && disabled( $password_change_url, SHIBBOLETH_PASSWORD_CHANGE_URL ); ?> /><br />
<?php esc_html_e( 'If this option is set, Shibboleth users will see a "change password" link on their profile page directing them to this URL.', 'shibboleth' ); ?>
</td>
</tr>
<tr valign="top">
<th scope="row"><label for="password_reset_url"><?php esc_html_e( 'Password Reset URL', 'shibboleth' ); ?></label></th>
<td>
<input type="text" id="password_reset_url" name="password_reset_url" value="<?php echo esc_url( $password_reset_url ); ?>" size="50" <?php defined( 'SHIBBOLETH_PASSWORD_RESET_URL' ) && disabled( $password_reset_url, SHIBBOLETH_PASSWORD_RESET_URL ); ?> /><br />
<?php echo wp_kses_post( __( 'If this option is set, wp-login.php will send <b><i>ALL</i></b> users here to reset their password.', 'shibboleth' ) ); ?>
</td>
</tr>
<tr valign="top">
<th scope="row"><label for="attribute_access"><?php esc_html_e( 'Attribute Access', 'shibboleth' ); ?></label></th>
<td>
Expand Down Expand Up @@ -355,13 +327,6 @@ function shibboleth_options_general() {
</p>
</td>
</tr>
<tr valign="top">
<th scope="row"><label for="button_text"><?php esc_html_e( 'Button Text', 'shibboleth' ); ?></label></th>
<td>
<input type="text" id="button_text" name="button_text" value="<?php echo esc_attr( $button_text ); ?>" size="50" <?php defined( 'SHIBBOLETH_BUTTON_TEXT' ) && disabled( $button_text, SHIBBOLETH_BUTTON_TEXT ); ?> /><br />
<p><?php echo wp_kses_post( __( 'Set the text of the button that appears on the <code>wp-login.php</code> page.', 'shibboleth' ) ); ?></p>
</td>
</tr>
<?php
/**
* Action shibboleth_options_table
Expand Down Expand Up @@ -409,6 +374,137 @@ function AttributeAccessMethod() {
<?php
}

/**
* Shibboleth - IdP options tab.
*
* @since 2.5.0
*/
function shibboleth_options_idps() {
if ( isset( $_POST['submit'] ) ) {
check_admin_referer( 'shibboleth_update_options' );

$idp_options = shibboleth_getoption( 'shibboleth_idps', array(), true, false );

if ( ! defined( 'SHIBBOLETH_IDPS' ) ) {
if ( isset( $_POST['idps'] ) ) {
// phpcs:disable WordPress.Security.ValidatedSanitizedInput
$idps = wp_unslash( $_POST['idps'] );
// phpcs:enable WordPress.Security.ValidatedSanitizedInput

foreach ( $idps as $current_short_label => $idp ) {
$short_label = sanitize_text_field( $idp['short_label'] );
$current_short_label = sanitize_text_field( $current_short_label );

if ( ! empty( $current_short_label ) ) {
// If the short_label is being updated, then update the IdP for those users to match.
shibboleth_update_idp_users( $short_label, $current_short_label );

unset( $idp_options[ $current_short_label ] );
}

if ( empty( $short_label ) ) {
continue;
}

$idp_options[ $short_label ] = array(
'entity_id' => sanitize_text_field( $idp['entity_id'] ),
'password_change_url' => esc_url_raw( $idp['password_change_url'] ),
'password_reset_url' => esc_url_raw( $idp['password_reset_url'] ),
'button_text' => sanitize_text_field( $idp['button_text'] ),
);
}

update_site_option( 'shibboleth_idps', $idp_options );
}
}

shibboleth_options_updated();
}

$constant = false;
list( $idps, $from_constant ) = shibboleth_getoption( 'shibboleth_idps', array(), false, true );
$constant = $constant || $from_constant;
?>

<h2><?php esc_html_e( 'IdP Configuration', 'shibboleth' ); ?></h2>
<?php if ( $constant ) { ?>
<div class="notice notice-warning">
<p><?php echo wp_kses_post( __( '<strong>Note:</strong> Some options below are defined in the <code>wp-config.php</code> file as constants and cannot be modified from this page.', 'shibboleth' ) ); ?></p>
</div>
<?php
} else {
$idps['__new'] = array(
'entity_id' => '',
'password_change_url' => '',
'password_reset_url' => '',
'button_text' => '',
);
}
?>

<?php
foreach ( $idps as $idp_code => $idp ) {
if ( '__new' === $idp_code ) {
$idp_code_value = '';
} else {
$idp_code_value = $idp_code;
}
?>

<fieldset class="card tool-box">
<legend class="title">
<?php
if ( '' === $idp_code_value ) {
esc_html_e( 'Add new Identity Provider', 'shibboleth' );
} else {
esc_html_e( 'Identity Provider', 'shibboleth' );
echo ' "' . esc_html( $idp_code_value ) . '"';
}
?>
</legend>
<table class="form-table">
<tr>
<th scope="row"><label for="short_label_<?php echo esc_attr( $idp_code ); ?>"><?php esc_html_e( 'Short Label', 'shibboleth' ); ?></label></th>
<td>
<input type="text" id="short_label_<?php echo esc_attr( $idp_code ); ?>" name="idps[<?php echo esc_attr( $idp_code ); ?>][short_label]" value="<?php echo esc_attr( $idp_code_value ); ?>" size="50" <?php disabled( $constant ); ?> /><br />
<?php esc_html_e( 'A short label for the Identity Provider.', 'shibboleth' ); ?>
</td>
</tr>
<tr>
<th scope="row"><label for="entity_id_<?php echo esc_attr( $idp_code ); ?>"><?php esc_html_e( 'Entity ID', 'shibboleth' ); ?></label></th>
<td>
<input type="text" id="entity_id_<?php echo esc_attr( $idp_code ); ?>" name="idps[<?php echo esc_attr( $idp_code ); ?>][entity_id]" value="<?php echo esc_url( $idp['entity_id'] ); ?>" size="50" <?php disabled( $constant ); ?> /><br />
<?php esc_html_e( 'The entityID is the public URI for an Identity Provider.', 'shibboleth' ); ?>
</td>
</tr>
<tr>
<th scope="row"><label for="password_change_url_<?php echo esc_attr( $idp_code ); ?>"><?php esc_html_e( 'Password Change URL', 'shibboleth' ); ?></label></th>
<td>
<input type="text" id="password_change_url_<?php echo esc_attr( $idp_code ); ?>" name="idps[<?php echo esc_attr( $idp_code ); ?>][password_change_url]" value="<?php echo esc_url( $idp['password_change_url'] ); ?>" size="50" <?php disabled( $constant ); ?> /><br />
<?php esc_html_e( 'If this option is set, Shibboleth users will see a "change password" link on their profile page directing them to this URL.', 'shibboleth' ); ?>
</td>
</tr>
<tr>
<th scope="row"><label for="password_reset_url_<?php echo esc_attr( $idp_code ); ?>"><?php esc_html_e( 'Password Reset URL', 'shibboleth' ); ?></label></th>
<td>
<input type="text" id="password_reset_url_<?php echo esc_attr( $idp_code ); ?>" name="idps[<?php echo esc_attr( $idp_code ); ?>][password_reset_url]" value="<?php echo esc_url( $idp['password_reset_url'] ); ?>" size="50" <?php disabled( $constant ); ?> /><br />
<?php echo wp_kses_post( __( 'If this option is set, wp-login.php will send <b><i>ALL</i></b> users here to reset their password.', 'shibboleth' ) ); ?>
</td>
</tr>
<tr>
<th scope="row"><label for="button_text_<?php echo esc_attr( $idp_code ); ?>"><?php esc_html_e( 'Button Text', 'shibboleth' ); ?></label></th>
<td>
<input type="text" id="button_text_<?php echo esc_attr( $idp_code ); ?>" name="idps[<?php echo esc_attr( $idp_code ); ?>][button_text]" value="<?php echo esc_attr( $idp['button_text'] ); ?>" size="50" <?php disabled( $constant ); ?> /><br />
<p><?php echo wp_kses_post( __( 'Set the text of the button that appears on the <code>wp-login.php</code> page.', 'shibboleth' ) ); ?></p>
</td>
</tr>
</table>
</fieldset>

<?php
} // Close IdP foreach
}

/**
* Shibboleth - User options tab.
*
Expand Down Expand Up @@ -901,6 +997,10 @@ function shibboleth_options_page() {
shibboleth_options_general();
break;

case 'idps':
shibboleth_options_idps();
break;

case 'user':
shibboleth_options_user();
break;
Expand Down
Loading

0 comments on commit eada385

Please sign in to comment.