3

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.

1

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.

  • thank you for that! When you said that the logic of checking if the user is logged in or not I hit my head in such a simple miss. I appreciate the multiple roles, but this site will be based purely on single assignments. Your answer is very detailed, and made it easier to follow. I only added that $mb_user_id = 0 in the function as default, and the $mb_user_id = get_current_user_id() as it will return 0 if not logged in anyway. – markb Dec 12 '19 at 21:40
1

You could skip that function and just go ahead and check roles.
Please note that I've changed some variables here from your original code.

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

    // empty role on login
    if( !$mb_user->roles ) {
        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
  • thank you for this, but the other answer is more along the lines I was after as the use of the function allows me to continue to use it across the site wide, and over multiple sites too – markb Dec 12 '19 at 21:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.