Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to configure multiple IdPs #101

Merged
merged 2 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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