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

Update #2

Merged
merged 22 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
726b0c5
Update composer dependencies
figureone Sep 23, 2024
7f108a1
Add missing hook: authorizer_oauth2_azure_authenticated_email
figureone Sep 23, 2024
46782ac
Enlarge Oauth2 URL settings fields
figureone Sep 23, 2024
c2dd3fd
Move Oauth2 auto login option to top
figureone Sep 23, 2024
7c44dd9
Add OAuth2 (generic) options for syncing first and last names from ex…
figureone Sep 24, 2024
5cb329b
Remove debug lines
figureone Sep 24, 2024
20f9bcd
Add missing translatable string
figureone Sep 24, 2024
824b6c6
Whitespace
figureone Sep 25, 2024
c4dfc40
Fix fatal error in previous commit
figureone Sep 25, 2024
70fe4ce
Add username and email attribute overrides to OAuth2 generic options
figureone Sep 25, 2024
6955cd5
Accept array of emails in `authorizer_oauth2_generic_authenticated_em…
figureone Sep 25, 2024
bdef1bd
Add $user param to `authorizer_custom_role` hook
figureone Sep 25, 2024
68c2369
Prevent password managers from suggestion completions in OAuth2 (gene…
figureone Sep 25, 2024
475a1f7
Update French translation (#164)
julienlusson Sep 25, 2024
9fe6e31
Force Google logins to use FedCM
figureone Sep 25, 2024
b6fdb8a
French translation update (#166)
julienlusson Sep 25, 2024
63aa6d5
Version 3.10.0
figureone Sep 25, 2024
c8852d1
Revert to 3.9.1 for bug testing
figureone Sep 25, 2024
57d3ff1
Hotfix for CAS logins broken if new settings not saved
figureone Sep 25, 2024
27579b6
Version 3.10.1
figureone Sep 25, 2024
49c11f3
Fix redirect error on CAS logins
figureone Sep 26, 2024
c2fc1fb
Version 3.10.2
figureone Sep 26, 2024
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
Prev Previous commit
Next Next commit
Add OAuth2 (generic) options for syncing first and last names from ex…
…ternal service
  • Loading branch information
figureone committed Sep 24, 2024
commit 7c44dd9272b3e43db0741a361ea818f97be79d7c
12 changes: 12 additions & 0 deletions js/authorizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,9 @@
var auth_settings_external_oauth2_url_authorize = $( '#auth_settings_oauth2_url_authorize' ).closest( 'tr' );
var auth_settings_external_oauth2_url_token = $( '#auth_settings_oauth2_url_token' ).closest( 'tr' );
var auth_settings_external_oauth2_url_resource = $( '#auth_settings_oauth2_url_resource' ).closest( 'tr' );
var auth_settings_external_oauth2_attr_first_name = $( '#auth_settings_oauth2_attr_first_name' ).closest( 'tr' );
var auth_settings_external_oauth2_attr_last_name = $( '#auth_settings_oauth2_attr_last_name' ).closest( 'tr' );
var auth_settings_external_oauth2_attr_update_on_login = $( '#auth_settings_oauth2_attr_update_on_login' ).closest( 'tr' );
var auth_settings_external_oauth2_auto_login = $( '#auth_settings_oauth2_auto_login' ).closest( 'tr' );
var auth_settings_external_google_clientid = $( '#auth_settings_google_clientid' ).closest( 'tr' );
var auth_settings_external_google_clientsecret = $( '#auth_settings_google_clientsecret' ).closest( 'tr' );
Expand Down Expand Up @@ -482,6 +485,9 @@
animateOption( 'hide_immediately', auth_settings_external_oauth2_url_authorize );
animateOption( 'hide_immediately', auth_settings_external_oauth2_url_token );
animateOption( 'hide_immediately', auth_settings_external_oauth2_url_resource );
animateOption( 'hide_immediately', auth_settings_external_oauth2_attr_first_name );
animateOption( 'hide_immediately', auth_settings_external_oauth2_attr_last_name );
animateOption( 'hide_immediately', auth_settings_external_oauth2_attr_update_on_login );
}

// Hide OAuth2 Tenant ID if azure isn't chosen.
Expand Down Expand Up @@ -579,6 +585,9 @@
animateOption( action, auth_settings_external_oauth2_url_authorize );
animateOption( action, auth_settings_external_oauth2_url_token );
animateOption( action, auth_settings_external_oauth2_url_resource );
animateOption( action, auth_settings_external_oauth2_attr_first_name );
animateOption( action, auth_settings_external_oauth2_attr_last_name );
animateOption( action, auth_settings_external_oauth2_attr_update_on_login );
action = 'azure' === $( this ).val() ? 'show' : 'hide';
animateOption( action, auth_settings_external_oauth2_tenant_id );
});
Expand Down Expand Up @@ -1142,6 +1151,9 @@
params.oauth2_url_authorize = $( '#auth_settings_oauth2_url_authorize' ).val();
params.oauth2_url_token = $( '#auth_settings_oauth2_url_token' ).val();
params.oauth2_url_resource = $( '#auth_settings_oauth2_url_resource' ).val();
params.oauth2_attr_first_name = $( '#auth_settings_oauth2_attr_first_name' ).val();
params.oauth2_attr_last_name = $( '#auth_settings_oauth2_attr_last_name' ).val();
params.oauth2_attr_update_on_login = $( '#auth_settings_oauth2_attr_update_on_login' ).val();
params.oauth2_auto_login = $( '#auth_settings_oauth2_auto_login' ).is( ':checked' ) ? '1' : '';

params.google = $( '#auth_settings_google' ).is( ':checked' ) ? '1' : '';
Expand Down
34 changes: 34 additions & 0 deletions src/authorizer/class-admin-page.php
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,27 @@ public function page_init() {
'authorizer',
'auth_settings_external'
);
add_settings_field(
'auth_settings_oauth2_attr_first_name',
__( 'Attribute containing first name', 'authorizer' ),
array( OAuth2::get_instance(), 'print_text_oauth2_attr_first_name' ),
'authorizer',
'auth_settings_external'
);
add_settings_field(
'auth_settings_oauth2_attr_last_name',
__( 'Attribute containing last name', 'authorizer' ),
array( OAuth2::get_instance(), 'print_text_oauth2_attr_last_name' ),
'authorizer',
'auth_settings_external'
);
add_settings_field(
'auth_settings_oauth2_attr_update_on_login',
__( 'Name attribute update', 'authorizer' ),
array( Oauth2::get_instance(), 'print_select_oauth2_attr_update_on_login' ),
'authorizer',
'auth_settings_external'
);

add_settings_field(
'auth_settings_external_google',
Expand Down Expand Up @@ -980,6 +1001,19 @@ public function create_network_admin_page() {
<td><?php $oauth2->print_text_oauth2_url_resource( array( 'context' => Helper::NETWORK_CONTEXT ) ); ?></td>
</tr>
<tr>
<tr>
<th scope="row"><?php esc_html_e( 'Attribute containing first name', 'authorizer' ); ?></th>
<td><?php $oauth2->print_text_oauth2_attr_first_name( array( 'context' => Helper::NETWORK_CONTEXT ) ); ?></td>
</tr>
<tr>
<tr>
<th scope="row"><?php esc_html_e( 'Attribute containing last name', 'authorizer' ); ?></th>
<td><?php $oauth2->print_text_oauth2_attr_last_name( array( 'context' => Helper::NETWORK_CONTEXT ) ); ?></td>
</tr>
<tr>
<th scope="row"><?php esc_html_e( 'Name attribute update', 'authorizer' ); ?></th>
<td><?php $oauth2->print_select_oauth2_attr_update_on_login( array( 'context' => Helper::NETWORK_CONTEXT ) ); ?></td>
</tr>

<tr class="border-top">
<th scope="row"><?php esc_html_e( 'Google Logins', 'authorizer' ); ?></th>
Expand Down
3 changes: 3 additions & 0 deletions src/authorizer/class-ajax-endpoints.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ public function ajax_save_auth_multisite_settings() {
'oauth2_url_authorize',
'oauth2_url_token',
'oauth2_url_resource',
'oauth2_attr_first_name',
'oauth2_attr_last_name',
'oauth2_attr_update_on_login',
'oauth2_auto_login',
'google',
'google_clientid',
Expand Down
28 changes: 26 additions & 2 deletions src/authorizer/class-authentication.php
Original file line number Diff line number Diff line change
Expand Up @@ -677,11 +677,35 @@ function ( $entry ) {
}
}

// Get user first name (handle string or array results from CAS attribute).
$first_name = '';
$oauth2_attr_first_name = $auth_settings['oauth2_attr_first_name'] ?? '';
er($auth_settings['oauth2_attr_first_name']);
if ( ! empty( $oauth2_attr_first_name ) && ! empty( $attributes[ $oauth2_attr_first_name ] ) ) {
er($attributes[ $oauth2_attr_first_name ]);
if ( is_string( $attributes[ $oauth2_attr_first_name ] ) ) {
$first_name = $attributes[ $oauth2_attr_first_name ];
} elseif ( is_array( $attributes[ $oauth2_attr_first_name ] ) ) {
$first_name = trim( implode( ' ', $attributes[ $oauth2_attr_first_name ] ) );
}
}

// Get user last name (handle string or array results from CAS attribute).
$last_name = '';
$oauth2_attr_last_name = $auth_settings['oauth2_attr_last_name'] ?? '';
if ( ! empty( $oauth2_attr_last_name ) && ! empty( $attributes[ $oauth2_attr_last_name ] ) ) {
if ( is_string( $attributes[ $oauth2_attr_last_name ] ) ) {
$last_name = $attributes[ $oauth2_attr_last_name ];
} elseif ( is_array( $attributes[ $oauth2_attr_last_name ] ) ) {
$last_name = trim( implode( ' ', $attributes[ $oauth2_attr_last_name ] ) );
}
}

return array(
'email' => $externally_authenticated_email,
'username' => sanitize_user( $username ),
'first_name' => '',
'last_name' => '',
'first_name' => $first_name,
'last_name' => $last_name,
'authenticated_by' => 'oauth2',
'oauth2_provider' => $auth_settings['oauth2_provider'],
'oauth2_attributes' => $attributes,
Expand Down
8 changes: 8 additions & 0 deletions src/authorizer/class-authorization.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ public function check_user_access( $user, $user_emails, $user_data = array() ) {
! empty( $user_data['authenticated_by'] ) && 'ldap' === $user_data['authenticated_by'] &&
! empty( $auth_settings['ldap_attr_update_on_login'] ) &&
( '1' === $auth_settings['ldap_attr_update_on_login'] || ( 'update-if-empty' === $auth_settings['ldap_attr_update_on_login'] && empty( $user->first_name ) ) )
) || (
! empty( $user_data['authenticated_by'] ) && 'oauth2' === $user_data['authenticated_by'] &&
! empty( $auth_settings['oauth2_attr_update_on_login'] ) &&
( '1' === $auth_settings['oauth2_attr_update_on_login'] || ( 'update-if-empty' === $auth_settings['oauth2_attr_update_on_login'] && empty( $user->first_name ) ) )
)
);

Expand All @@ -76,6 +80,10 @@ public function check_user_access( $user, $user_emails, $user_data = array() ) {
! empty( $user_data['authenticated_by'] ) && 'ldap' === $user_data['authenticated_by'] &&
! empty( $auth_settings['ldap_attr_update_on_login'] ) &&
( '1' === $auth_settings['ldap_attr_update_on_login'] || ( 'update-if-empty' === $auth_settings['ldap_attr_update_on_login'] && empty( $user->last_name ) ) )
) || (
! empty( $user_data['authenticated_by'] ) && 'oauth2' === $user_data['authenticated_by'] &&
! empty( $auth_settings['oauth2_attr_update_on_login'] ) &&
( '1' === $auth_settings['oauth2_attr_update_on_login'] || ( 'update-if-empty' === $auth_settings['oauth2_attr_update_on_login'] && empty( $user->last_name ) ) )
)
);

Expand Down
48 changes: 37 additions & 11 deletions src/authorizer/class-options.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,17 +167,20 @@ public function get_all( $admin_mode = Helper::SINGLE_CONTEXT, $override_mode =
*/

// Override external service (Oauth2) and associated options.
$auth_settings['oauth2'] = $auth_multisite_settings['oauth2'];
$auth_settings['oauth2_provider'] = $auth_multisite_settings['oauth2_provider'];
$auth_settings['oauth2_custom_label'] = $auth_multisite_settings['oauth2_custom_label'];
$auth_settings['oauth2_clientid'] = $auth_multisite_settings['oauth2_clientid'];
$auth_settings['oauth2_clientsecret'] = $auth_multisite_settings['oauth2_clientsecret'];
$auth_settings['oauth2_hosteddomain'] = $auth_multisite_settings['oauth2_hosteddomain'];
$auth_settings['oauth2_tenant_id'] = $auth_multisite_settings['oauth2_tenant_id'];
$auth_settings['oauth2_url_authorize'] = $auth_multisite_settings['oauth2_url_authorize'];
$auth_settings['oauth2_url_token'] = $auth_multisite_settings['oauth2_url_token'];
$auth_settings['oauth2_url_resource'] = $auth_multisite_settings['oauth2_url_resource'];
$auth_settings['oauth2_auto_login'] = $auth_multisite_settings['oauth2_auto_login'] ?? '';
$auth_settings['oauth2'] = $auth_multisite_settings['oauth2'];
$auth_settings['oauth2_auto_login'] = $auth_multisite_settings['oauth2_auto_login'] ?? '';
$auth_settings['oauth2_provider'] = $auth_multisite_settings['oauth2_provider'];
$auth_settings['oauth2_custom_label'] = $auth_multisite_settings['oauth2_custom_label'];
$auth_settings['oauth2_clientid'] = $auth_multisite_settings['oauth2_clientid'];
$auth_settings['oauth2_clientsecret'] = $auth_multisite_settings['oauth2_clientsecret'];
$auth_settings['oauth2_hosteddomain'] = $auth_multisite_settings['oauth2_hosteddomain'];
$auth_settings['oauth2_tenant_id'] = $auth_multisite_settings['oauth2_tenant_id'];
$auth_settings['oauth2_url_authorize'] = $auth_multisite_settings['oauth2_url_authorize'];
$auth_settings['oauth2_url_token'] = $auth_multisite_settings['oauth2_url_token'];
$auth_settings['oauth2_url_resource'] = $auth_multisite_settings['oauth2_url_resource'];
$auth_settings['oauth2_attr_first_name'] = $auth_multisite_settings['oauth2_attr_first_name'] ?? '';
$auth_settings['oauth2_attr_last_name'] = $auth_multisite_settings['oauth2_attr_last_name'] ?? '';
$auth_settings['oauth2_attr_update_on_login'] = $auth_multisite_settings['oauth2_attr_update_on_login'] ?? '';

// Override external service (Google) and associated options.
$auth_settings['google'] = $auth_multisite_settings['google'];
Expand Down Expand Up @@ -421,6 +424,15 @@ public function set_default_options( $args = array() ) {
if ( ! array_key_exists( 'oauth2_url_resource', $auth_settings ) ) {
$auth_settings['oauth2_url_resource'] = '';
}
if ( ! array_key_exists( 'oauth2_attr_first_name', $auth_settings ) ) {
$auth_settings['oauth2_attr_first_name'] = '';
}
if ( ! array_key_exists( 'oauth2_attr_last_name', $auth_settings ) ) {
$auth_settings['oauth2_attr_last_name'] = '';
}
if ( ! array_key_exists( 'oauth2_attr_update_on_login', $auth_settings ) ) {
$auth_settings['oauth2_attr_update_on_login'] = '';
}
if ( ! array_key_exists( 'oauth2_auto_login', $auth_settings ) ) {
$auth_settings['oauth2_auto_login'] = '';
}
Expand Down Expand Up @@ -671,6 +683,15 @@ public function set_default_options( $args = array() ) {
if ( ! array_key_exists( 'oauth2_url_resource', $auth_multisite_settings ) ) {
$auth_multisite_settings['oauth2_url_resource'] = '';
}
if ( ! array_key_exists( 'oauth2_attr_first_name', $auth_multisite_settings ) ) {
$auth_multisite_settings['oauth2_attr_first_name'] = '';
}
if ( ! array_key_exists( 'oauth2_attr_last_name', $auth_multisite_settings ) ) {
$auth_multisite_settings['oauth2_attr_last_name'] = '';
}
if ( ! array_key_exists( 'oauth2_attr_update_on_login', $auth_multisite_settings ) ) {
$auth_multisite_settings['oauth2_attr_update_on_login'] = '';
}
if ( ! array_key_exists( 'oauth2_auto_login', $auth_multisite_settings ) ) {
$auth_multisite_settings['oauth2_auto_login'] = '';
}
Expand Down Expand Up @@ -899,6 +920,11 @@ public function sanitize_options( $auth_settings ) {
// Sanitize OAuth2 auto-login (checkbox: value can only be '1' or empty string).
$auth_settings['oauth2_auto_login'] = array_key_exists( 'oauth2_auto_login', $auth_settings ) && strlen( $auth_settings['oauth2_auto_login'] ) > 0 ? '1' : '';

// Sanitize Oauth2 attribute update (select: value can only be 'update-if-empty', '1', or empty string).
if ( ! isset( $auth_settings['oauth2_attr_update_on_login'] ) || ! in_array( $auth_settings['oauth2_attr_update_on_login'], array( '', '1', 'update-if-empty' ), true ) ) {
$auth_settings['oauth2_attr_update_on_login'] = '';
}

// Sanitize Enable Google Logins (checkbox: value can only be '1' or empty string).
$auth_settings['google'] = array_key_exists( 'google', $auth_settings ) && strlen( $auth_settings['google'] ) > 0 ? '1' : '';

Expand Down
68 changes: 68 additions & 0 deletions src/authorizer/options/external/class-oauth2.php
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,74 @@ public function print_text_oauth2_url_resource( $args = '' ) {
}


/**
* Settings print callback.
*
* @param string $args Args (e.g., multisite admin mode).
* @return void
*/
public function print_text_oauth2_attr_first_name( $args = '' ) {
// Get plugin option.
$options = Options::get_instance();
$option = 'oauth2_attr_first_name';
$auth_settings_option = $options->get( $option, Helper::get_context( $args ), 'allow override', 'print overlay' );

// Print option elements.
?>
<input type="text" id="auth_settings_<?php echo esc_attr( $option ); ?>" name="auth_settings[<?php echo esc_attr( $option ); ?>]" value="<?php echo esc_attr( $auth_settings_option ); ?>" placeholder="" />
<p class="description"><?php esc_html_e( 'Example: given_name', 'authorizer' ); ?></p>
<?php
}


/**
* Settings print callback.
*
* @param string $args Args (e.g., multisite admin mode).
* @return void
*/
public function print_text_oauth2_attr_last_name( $args = '' ) {
// Get plugin option.
$options = Options::get_instance();
$option = 'oauth2_attr_last_name';
$auth_settings_option = $options->get( $option, Helper::get_context( $args ), 'allow override', 'print overlay' );

// Print option elements.
?>
<input type="text" id="auth_settings_<?php echo esc_attr( $option ); ?>" name="auth_settings[<?php echo esc_attr( $option ); ?>]" value="<?php echo esc_attr( $auth_settings_option ); ?>" placeholder="" />
<p class="description"><?php esc_html_e( 'Example: family_name', 'authorizer' ); ?></p>
<?php
}


/**
* Settings print callback.
*
* @param string $args Args (e.g., multisite admin mode).
* @return void
*/
public function print_select_oauth2_attr_update_on_login( $args = '' ) {
// Get plugin option.
$options = Options::get_instance();
$option = 'oauth2_attr_update_on_login';
$auth_settings_option = $options->get( $option, Helper::get_context( $args ), 'allow override', 'print overlay' );
$values = array(
'' => __( 'Do not update first and last name fields on login', 'authorizer' ),
'1' => __( 'Update first and last name fields on login', 'authorizer' ),
'update-if-empty' => __( 'Update first and last name fields on login only if they are empty', 'authorizer' ),
);

// Print option elements.
?>
<select id="auth_settings_<?php echo esc_attr( $option ); ?>" name="auth_settings[<?php echo esc_attr( $option ); ?>]">
<?php foreach ( $values as $value => $label ) : ?>
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $auth_settings_option, $value ); ?>><?php echo esc_html( $label ); ?></option>
<?php endforeach; ?>
</select>
<?php
}


/**
* Settings print callback.
*
Expand Down