I currently have a front end part of a WP site that allows admins to create new users and assign then user roles from a drop down – that works perfectly.

However, I am using a plugin to also authenticate users against an AD/LDAP so I can use it on a corporate level too.

The problem is when the user authenticates against the LDAP for the first time, there is no user assignment and no where in the plugin that I can see on how to do that (using the NextAD plugin).

I however saw that I can do custom checks on the authorisation when logging in, and thought I could add the role there:

function mb_authenticate_user( $user ) {
    // get the user id from log in name
    $mb_user_id = get_user_by('login', $_REQUEST['log'] );
    $mb_user_id = $mb_user_id->ID;

    // empty role on login
    if( empty( mb_current_user_role() ) ) {
        wp_update_user( array( 'ID' => $mb_user_id, 'role' => 'mbToBeAssigned' ) );
    }

    // other custom code checks here too

}
add_filter( 'wp_authenticate_user', 'mb_authenticate_user',     1       );
add_filter( 'authorize',            'mb_authenticate_user'              ); // plugin authentication NextAD

However, in my mb_current_user_role() function,

function mb_current_user_role( $echo = false ) {
    $user="";
    $user = ( is_user_logged_in() ? array_values( wp_get_current_user()->roles ) : null );
    $user = $user[0];

    if( $echo ) {
        echo $user;
    } else {
        return $user;       
    }
}

it is not correctly checking if the user has exisiting roles and is constantly overriding them with the authentication one: mbToBeAssigned

Is there something I’m missing? Or is there a better way to do this? Running on a multisite too.

2 Answers
2

I believe the reason it is overriding all users is how you are evaluating the user role (and when you are doing it).

You’re running your check of the user role in mb_current_user_role() and that function assumes the user is logged in, otherwise it sets $user (initially) to null.

But when that function is run from your mb_authenticate_user() function, the user is not logged in, so every time it’s run, it returns null – regardless of whether the user has a role or not. (Hope I explained that well enough to make sense.)

Also, aside from the fact that WP allows multiple roles for users (hence the array), and there is no guarantee that the roles array will only contain a single role, there is an issue with the following line:

$user = $user[0];

If the user has no role, the index 0 is not set. If you run this with debug mode turned on, I suspect you’d get a PHP notice on this.

So you need to check if that value is set.

I made changes to your mb_current_user_role() function to address these. First, it accepts two arguments, the first of which is the user ID, so your authenticate function should pass the user ID (instead of checking the logged in user for reasons mentioned above).

function mb_current_user_role( $mb_user_id = false, $echo = false ) {
    $user = ( $mb_user_id ) ? array_values( wp_get_current_user()->roles ) : false;
    $user = ( isset( $user[0] ) ) ? $user[0] : false;

    if( $echo ) {
        echo $user;
    } else {
        return $user;
    }
}

Now in your authenticate function, instead of this:

if( empty( mb_current_user_role() ) ) {

Evaluate as this:

if ( false === mb_current_user_role( $mb_user_id->ID ) ) {

You could use the other answer’s approach and eliminate mb_current_user_role() altogether, but fixing mb_current_user_role()‘s problems gives you a usable utility function you can use in other instances as well.

Leave a Reply

Your email address will not be published. Required fields are marked *