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

Avoid undesired session_start() when using SimpleSAMLphp #196

Merged
merged 4 commits into from
May 27, 2020
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
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
**Tags:** authentication, SAML
**Requires at least:** 4.4
**Tested up to:** 5.4
**Stable tag:** 1.0.0
**Stable tag:** 1.0.2
**License:** GPLv2 or later
**License URI:** http://www.gnu.org/licenses/gpl-2.0.html

Expand Down Expand Up @@ -277,6 +277,9 @@ There is no third step. Because SimpleSAMLphp loads WordPress, which has WP Nati

## Changelog ##

### 1.0.2 (May 27, 2020) ###
* Avoid undesired `session_start()` when using SimpleSAMLphp [[#196](https://github.com/pantheon-systems/wp-saml-auth/pull/196)].

### 1.0.1 (May 26, 2020) ###
* Allows redirecting back to `wp-login.php` while avoiding redirect loop [[#192](https://github.com/pantheon-systems/wp-saml-auth/pull/192)].

Expand Down
98 changes: 61 additions & 37 deletions inc/class-wp-saml-auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,29 +61,24 @@ public static function get_option( $option_name ) {
* @return mixed
*/
public function get_provider() {
if ( is_null( $this->provider ) ) {
$this->set_provider();
}
return $this->provider;
}

/**
* Initialize the controller logic on the 'init' hook
* Determines the provider class to use and loads an instance of it, stores it to ->provider
*
* @return void
*/
public function action_init() {

protected function set_provider() {
$connection_type = self::get_option( 'connection_type' );
if ( 'internal' === $connection_type ) {
if ( file_exists( WP_SAML_AUTH_AUTOLOADER ) ) {
require_once WP_SAML_AUTH_AUTOLOADER;
}
if ( ! class_exists( 'OneLogin\Saml2\Auth' ) ) {
add_action(
'admin_notices',
function() {
if ( current_user_can( 'manage_options' ) ) {
// Translators: Links to the WP SAML Auth plugin.
echo '<div class="message error"><p>' . wp_kses_post( sprintf( __( "WP SAML Auth wasn't able to find the <code>OneLogin\Saml2\Auth</code> class. Please verify your Composer autoloader, or <a href='%s'>visit the plugin page</a> for more information.", 'wp-saml-auth' ), 'https://wordpress.org/plugins/wp-saml-auth/' ) ) . '</p></div>';
}
}
);
return;
}
$auth_config = self::get_option( 'internal_config' );
Expand All @@ -97,28 +92,22 @@ function() {
$this->simplesamlphp_class = 'SimpleSAML\Auth\Simple';
}
if ( ! class_exists( $this->simplesamlphp_class ) ) {
add_action(
'admin_notices',
function() {
if ( ! empty( $_GET['page'] )
&& 'wp-saml-auth-settings' === $_GET['page'] ) {
return;
}
if ( current_user_can( 'manage_options' ) ) {
// Translators: Links to the WP SAML Auth plugin.
echo '<div class="message error"><p>' . wp_kses_post( sprintf( __( "WP SAML Auth wasn't able to find the <code>%1\$s</code> class. Please check the <code>simplesamlphp_autoload</code> configuration option, or <a href='%2\$s'>visit the plugin page</a> for more information.", 'wp-saml-auth' ), $this->simplesamlphp_class, 'https://wordpress.org/plugins/wp-saml-auth/' ) ) . '</p></div>';
}
}
);
return;
}
$this->provider = new $this->simplesamlphp_class( self::get_option( 'auth_source' ) );
}
}

/**
* Initialize the controller logic on the 'init' hook
*/
public function action_init() {
add_action( 'login_head', array( $this, 'action_login_head' ) );
add_action( 'login_message', array( $this, 'action_login_message' ) );
add_action( 'wp_logout', array( $this, 'action_wp_logout' ) );
add_filter( 'login_body_class', array( $this, 'filter_login_body_class' ) );
add_filter( 'authenticate', array( $this, 'filter_authenticate' ), 21, 3 ); // after wp_authenticate_username_password runs.
add_action( 'admin_notices', array( $this, 'action_admin_notices' ) );

}

Expand Down Expand Up @@ -184,13 +173,14 @@ public function action_login_message( $message ) {
* Log the user out of the SAML instance when they log out of WordPress
*/
public function action_wp_logout() {
$provider = $this->get_provider();
if ( 'internal' === self::get_option( 'connection_type' ) ) {
$internal_config = self::get_option( 'internal_config' );
if ( empty( $internal_config['idp']['singleLogoutService']['url'] ) ) {
return;
}
}
$this->provider->logout( add_query_arg( 'loggedout', true, wp_login_url() ) );
$provider->logout( add_query_arg( 'loggedout', true, wp_login_url() ) );
}

/**
Expand Down Expand Up @@ -235,15 +225,15 @@ public function filter_authenticate( $user, $username, $password ) {
* Do the SAML authentication dance
*/
public function do_saml_authentication() {

if ( is_a( $this->provider, 'OneLogin\Saml2\Auth' ) ) {
$provider = $this->get_provider();
if ( is_a( $provider, 'OneLogin\Saml2\Auth' ) ) {
if ( ! empty( $_POST['SAMLResponse'] ) ) {
$this->provider->processResponse();
if ( ! $this->provider->isAuthenticated() ) {
$provider->processResponse();
if ( ! $provider->isAuthenticated() ) {
// Translators: Includes error reason from OneLogin.
return new WP_Error( 'wp_saml_auth_unauthenticated', sprintf( __( 'User is not authenticated with SAML IdP. Reason: %s', 'wp-saml-auth' ), $this->provider->getLastErrorReason() ) );
return new WP_Error( 'wp_saml_auth_unauthenticated', sprintf( __( 'User is not authenticated with SAML IdP. Reason: %s', 'wp-saml-auth' ), $provider->getLastErrorReason() ) );
}
$attributes = $this->provider->getAttributes();
$attributes = $provider->getAttributes();
$redirect_to = filter_input( INPUT_POST, 'RelayState', FILTER_SANITIZE_URL );
$permit_wp_login = self::get_option( 'permit_wp_login' );
if ( $redirect_to ) {
Expand All @@ -264,9 +254,9 @@ function() use ( $redirect_to ) {
} else {
$redirect_to = filter_input( INPUT_GET, 'redirect_to', FILTER_SANITIZE_URL );
$redirect_to = $redirect_to ? $redirect_to : $_SERVER['REQUEST_URI'];
$this->provider->login( $redirect_to );
$provider->login( $redirect_to );
}
} elseif ( is_a( $this->provider, $this->simplesamlphp_class ) ) {
} elseif ( is_a( $provider, $this->simplesamlphp_class ) ) {
$redirect_to = filter_input( INPUT_GET, 'redirect_to', FILTER_SANITIZE_URL );
if ( $redirect_to ) {
$redirect_to = add_query_arg(
Expand All @@ -287,12 +277,12 @@ function() use ( $redirect_to ) {
$redirect_to = add_query_arg( array( 'action' => 'wp-saml-auth' ), $redirect_to );
}
}
$this->provider->requireAuth(
$provider->requireAuth(
array(
'ReturnTo' => $redirect_to,
)
);
$attributes = $this->provider->getAttributes();
$attributes = $provider->getAttributes();
} else {
return new WP_Error( 'wp_saml_auth_invalid_provider', __( 'Invalid provider specified for SAML authentication', 'wp-saml-auth' ) );
}
Expand All @@ -303,7 +293,7 @@ function() use ( $redirect_to ) {
* @param array $attributes All attributes received from the SAML response.
* @param object $provider Provider instance currently in use.
*/
$attributes = apply_filters( 'wp_saml_auth_attributes', $attributes, $this->provider );
$attributes = apply_filters( 'wp_saml_auth_attributes', $attributes, $provider );

/**
* Runs before the SAML authentication dance proceeds
Expand Down Expand Up @@ -375,4 +365,38 @@ function() use ( $redirect_to ) {
return $user;
}

/**
* Displays notices in the admin if certain configuration properties aren't correct.
*/
public function action_admin_notices() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
if ( ! empty( $_GET['page'] )
&& 'wp-saml-auth-settings' === $_GET['page'] ) {
return;
}
$connection_type = self::get_option( 'connection_type' );
if ( 'internal' === $connection_type ) {
if ( file_exists( WP_SAML_AUTH_AUTOLOADER ) ) {
require_once WP_SAML_AUTH_AUTOLOADER;
}
if ( ! class_exists( 'OneLogin\Saml2\Auth' ) ) {
// Translators: Links to the WP SAML Auth plugin.
echo '<div class="message error"><p>' . wp_kses_post( sprintf( __( "WP SAML Auth wasn't able to find the <code>OneLogin\Saml2\Auth</code> class. Please verify your Composer autoloader, or <a href='%s'>visit the plugin page</a> for more information.", 'wp-saml-auth' ), 'https://wordpress.org/plugins/wp-saml-auth/' ) ) . '</p></div>';
}
} else {
$simplesamlphp_path = self::get_option( 'simplesamlphp_autoload' );
if ( file_exists( $simplesamlphp_path ) ) {
require_once $simplesamlphp_path;
}
if ( class_exists( 'SimpleSAML\Auth\Simple' ) ) {
$this->simplesamlphp_class = 'SimpleSAML\Auth\Simple';
}
if ( ! class_exists( $this->simplesamlphp_class ) ) {
echo '<div class="message error"><p>' . wp_kses_post( sprintf( __( "WP SAML Auth wasn't able to find the <code>%1\$s</code> class. Please check the <code>simplesamlphp_autoload</code> configuration option, or <a href='%2\$s'>visit the plugin page</a> for more information.", 'wp-saml-auth' ), $this->simplesamlphp_class, 'https://wordpress.org/plugins/wp-saml-auth/' ) ) . '</p></div>';
}
}
}

}
39 changes: 19 additions & 20 deletions languages/wp-saml-auth.pot
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
# This file is distributed under the same license as the WP SAML Auth plugin.
msgid ""
msgstr ""
"Project-Id-Version: WP SAML Auth 1.0.1\n"
"Project-Id-Version: WP SAML Auth 1.0.2\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-saml-auth\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2020-05-26T12:03:20+00:00\n"
"POT-Creation-Date: 2020-05-27T13:00:23+00:00\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"X-Generator: WP-CLI 2.4.0\n"
"X-Domain: wp-saml-auth\n"
Expand Down Expand Up @@ -182,46 +182,45 @@ msgstr ""
msgid "N/A"
msgstr ""

#. Translators: Links to the WP SAML Auth plugin.
#: inc/class-wp-saml-auth.php:83
msgid "WP SAML Auth wasn't able to find the <code>OneLogin\\Saml2\\Auth</code> class. Please verify your Composer autoloader, or <a href='%s'>visit the plugin page</a> for more information."
msgstr ""

#. Translators: Links to the WP SAML Auth plugin.
#: inc/class-wp-saml-auth.php:109
msgid "WP SAML Auth wasn't able to find the <code>%1$s</code> class. Please check the <code>simplesamlphp_autoload</code> configuration option, or <a href='%2$s'>visit the plugin page</a> for more information."
msgstr ""

#: inc/class-wp-saml-auth.php:158
#: inc/class-wp-saml-auth.php:147
msgid "Use one-click authentication:"
msgstr ""

#: inc/class-wp-saml-auth.php:159
#: inc/class-wp-saml-auth.php:148
msgid "Sign In"
msgstr ""

#: inc/class-wp-saml-auth.php:160
#: inc/class-wp-saml-auth.php:149
msgid "Or, sign in with WordPress:"
msgstr ""

#. Translators: Includes error reason from OneLogin.
#: inc/class-wp-saml-auth.php:244
#: inc/class-wp-saml-auth.php:234
msgid "User is not authenticated with SAML IdP. Reason: %s"
msgstr ""

#: inc/class-wp-saml-auth.php:297
#: inc/class-wp-saml-auth.php:287
msgid "Invalid provider specified for SAML authentication"
msgstr ""

#: inc/class-wp-saml-auth.php:322
#: inc/class-wp-saml-auth.php:312
msgid "No attributes were present in SAML response. Attributes are used to create and fetch users. Please contact your administrator"
msgstr ""

#. Translators: Communicates how the user is fetched based on the SAML response.
#: inc/class-wp-saml-auth.php:329
#: inc/class-wp-saml-auth.php:319
msgid "\"%1$s\" attribute is expected, but missing, in SAML response. Attribute is used to fetch existing user by \"%2$s\". Please contact your administrator."
msgstr ""

#: inc/class-wp-saml-auth.php:344
#: inc/class-wp-saml-auth.php:334
msgid "No WordPress user exists for your account. Please contact your administrator."
msgstr ""

#. Translators: Links to the WP SAML Auth plugin.
#: inc/class-wp-saml-auth.php:386
msgid "WP SAML Auth wasn't able to find the <code>OneLogin\\Saml2\\Auth</code> class. Please verify your Composer autoloader, or <a href='%s'>visit the plugin page</a> for more information."
msgstr ""

#: inc/class-wp-saml-auth.php:397
msgid "WP SAML Auth wasn't able to find the <code>%1$s</code> class. Please check the <code>simplesamlphp_autoload</code> configuration option, or <a href='%2$s'>visit the plugin page</a> for more information."
msgstr ""
5 changes: 4 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Contributors: getpantheon, danielbachhuber, Outlandish Josh
Tags: authentication, SAML
Requires at least: 4.4
Tested up to: 5.4
Stable tag: 1.0.0
Stable tag: 1.0.2
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html

Expand Down Expand Up @@ -277,6 +277,9 @@ There is no third step. Because SimpleSAMLphp loads WordPress, which has WP Nati

== Changelog ==

= 1.0.2 (May 27, 2020) =
* Avoid undesired `session_start()` when using SimpleSAMLphp [[#196](https://github.com/pantheon-systems/wp-saml-auth/pull/196)].

= 1.0.1 (May 26, 2020) =
* Allows redirecting back to `wp-login.php` while avoiding redirect loop [[#192](https://github.com/pantheon-systems/wp-saml-auth/pull/192)].

Expand Down
2 changes: 1 addition & 1 deletion wp-saml-auth.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
/**
* Plugin Name: WP SAML Auth
* Version: 1.0.1
* Version: 1.0.2
* Description: SAML authentication for WordPress, using SimpleSAMLphp.
* Author: Pantheon
* Author URI: https://pantheon.io
Expand Down