Open danielbachhuber opened 8 years ago
we may want to consider having a feature where user editing is disabled for SAML-provisioned users.
Because per-field edit capabilities isn't really tenable in WordPress, we could instead filter map_meta_cap
and disable editing of the user entirely.
The Shibboleth plugin has a couple clever workarounds for this, that I'm adapting for a planned switchover from that plugin to this one. (So all the code below will be a weird mix of code for this plugin, and code from that one, because I haven't written and tested it all yet.)
When a user is created, they drop a user_meta note to track if the user was created via their plugin. Here you could do something like:
add_action( 'wp_saml_auth_new_user_authenticated', function ( $user_id ) {
update_user_meta( $user_id, 'created_by_saml', true);
} );
(There's an edge case here where a "local" user with the same username as a SAML user might not get this flag set properly. As an example, part of my new-site process involves creating several users whose usernames match their SAML usernames, prior to installing and activating SSO. Maybe add the same hook to wp_saml_auth_existing_user_authenticated too?)
Then, if a user was created this way, first you use a bit of JavaScript to disable the relevant fields.
add_action( 'admin_init', function() {
disable_field_edits();
});
function disable_field_edits() {
$user = wp_get_current_user();
if (get_user_meta( $user->ID, 'created_by_saml' ) == true ) {
add_filter( 'show_password_fields', '__return_false' );
add_action( 'admin_enqueue_scripts', function( $hook ) {
if ('profile.php' != $hook ) {
return;
}
wp_enqueue_script( 'saml-user-edit', plugin_dir_url(__FILE__) . 'user-edit.js' );
});
}
}
jQuery(document).ready(function($) {
jQuery("#first_name").attr("disabled", true);
jQuery("#last_name").attr("disabled", true);
jQuery("#email").attr("disabled", true);
jQuery("#first_name").parents(".form-table").before("<div class=\"updated fade\"><p>Some profile fields cannot be changed from WordPress.</p></div>");
jQuery("#email-description").hide();
});
(The Shibboleth plugin makes this a bit more complicated, since it allows you to specify, for each managed field, whether a user should be allowed to edit it. For me, an all-or-nothing is sufficient.)
Also, just in case a user gets clever and disables JavaScript (thus making the form fields edit-able by the client again), hook into the actual form submission and change the values back before submitting:
add_action( 'personal_options_update', 'shibboleth_prevent_managed_fields_update' );
add_action( 'edit_user_profile_update', 'shibboleth_prevent_managed_fields_update' );
function shibboleth_prevent_managed_fields_update( $user_id ) {
if ( get_user_meta( $user_id, 'created_by_saml' ) ) {
$_POST['first_name'] = $user->first_name;
$_POST['last_name'] = $user->last_name;
$_POST['email'] = $user->user_email;
}
}
I suppose the question here, is whether this is something that comes up often enough that it should be made into a checkbox in this plugin, as opposed to having users implement it themselves. Which is a valid question! There are good arguments both ways.
If a user was created through the SAML IDP, we may want to consider having a feature where user editing is disabled for SAML-provisioned users.
Similarly, we may want to update the details for a SAML-provisioned user each time they log in through their IDP.