Users losing group status?

Hi all,

I’m currently using Discourse as a successor to a MailMan listserv. It’s been working very well so far. Membership is handled through a Wordpress site and the PaidMembershipsPro plugin. Group membership is sent through the SSO payload. So far, so good.

Some users have been finding that they stop receiving emails every so often, and when I check their account status, their group membership has disappeared. Nothing has changed on the Wordpress end.

I’m not sure what might be causing this, or where should I look to try to solve the problem. Any suggestions?

Doubt it helps but couldn’t hurt to mention

I see random system action revoking email in our logs

2 Likes

I expect that happens when emails are bounced, but I don’t think it explains losing group status.

1 Like

No, it does not explain that, in my case I was able to ask people if they were getting emails and they didn’t seem to notice anything so…

wish you well :sunglasses:

Enable verbose sso logging in Discourse settings and check the SSO payload in /logs.

5 Likes

Thanks.

It looks like I’m getting some “nonce already expired” messages (as reported here which seem to correspond to the users losing group status.

Any suggestions? I’ve had to disable group membership updates via SSO until this is sorted because I’ve gotten so many complaints!

Are you using the WP Discourse plugin for SSO? How are you adding the groups to the SSO payload?

Do you have the sso overrides groups Site Setting enabled on Discourse? If that setting is enabled, group membership will be lost for a user if a group isn’t specified in the SSO payload.

2 Likes

Yes, we’re using WP-Discourse. Groups are added through a custom script (using add_filter( 'wpdc_sso_params', 'wpdc_custom_sso_params' );) that checks membership status and changes the add_groups and remove_groups parameters based on the results.

sso_overrides_groups is disabled

1 Like

This seems unlikely. When the nonce is expired the user should not be updated in any way. SSO login just fails.

Are you sure that the add_groups and remove_groups parameters are being set correctly? You can check this in your logs by filtering for ‘User was logged on’ and looking at the ‘info’ tab.

33%20PM

4 Likes

(You’re probably right about the expired nonce being a red herring, it doesn’t correspond consistently in the logs to the people who are losing group access.)

The add/remove parameters passed in the SSO payload seem to be setting correctly in the logs, which is even more confusing.

Have you have enabled the ‘Create or Sync Discourse Users on Login’ option (found on the WP Discourse SSO Provider tab)? If so, an SSO payload is also sent when a user logs into your WordPress site. This payload also hooks into the wpdc_sso_params filter. Unfortunately, the results of this call to Discourse are not logged.

I’m going to make a small change to the WP Discourse code today so that the call made when ‘Create or Sync Discourse Users on Login’ is enabled does not happen if the request originates from Discourse.

Yes, this setting is enabled. That probably explains all the seemingly random SSO calls that I see in the logs.

Just for my information and education, could you explain why the change that you are proposing might help?

I’m not sure that it will help - my goal in making the change was to eliminate an unnecessary API call. The updated code (version 1.7.6) is available in the WordPress repo now.

Yes, it actually does create a log entry when a new user is created, but not when a user is updated. The log entry will begin with Verbose SSO log: New User (user_id:.

If you can share the code that you’re using to hook into the wpdc_sso_params filter, I can test it out.

1 Like

Knowing me, it will be a silly PHP mistake.

add_filter( 'wpdc_sso_params', 'wpdc_custom_sso_params' );
function wpdc_custom_sso_params( $params ) {
    
require_once( ABSPATH . 'wp-includes/pluggable.php' );

$user = wp_get_current_user();
if ( in_array( 'subscriber', (array) $user->roles ) ) {
    $user_sub = 1;
}
    
    if ( in_array( 'spectator', (array) $user->roles ) ) {
  //using spectator role as a standin for verified user who is pending vetting for provider forum but needs access to other forums in the meantime
        $user_spec = 1;
}
    
    $add_groups = array();
    $remove_groups = array();

	if (  pmpro_hasMembershipLevel('1',  $user->ID) && $user_sub = 1 ) {
		$add_groups[] = 'Assessors';
	} else {
		$remove_groups[] = 'Assessors';
	}

	if (  pmpro_hasMembershipLevel('2',  $user->ID) && $user_sub = 1) {
		$add_groups[] = 'Providers';
	} else if  ( pmpro_hasMembershipLevel('2',  $user->ID) && $user_spec = 1) {
		$add_groups[] = 'Assessors';
	}
  	  else {
        $remove_groups[] = 'Providers';
   	 }
       
    	if (pmpro_hasMembershipLevel('3',  $user->ID) ||  pmpro_hasMembershipLevel('4',  $user->ID) ||  pmpro_hasMembershipLevel('6', $user->ID) ) {
		$add_groups[] = 'Members';
	} else {
		$remove_groups[] = 'Members';
	}
        
	$params['add_groups'] = join( ',', $add_groups );
	$params['remove_groups'] = join( ',', $remove_groups );

	return $params;
}

There are a couple of errors in the code. $user_sub = 1 will always return true. It needs to be == or ===.

Here’s the logic I think you want:

The Accessors group is for subscribers who have a membership level of ‘1’ or for spectators who have a membership level of ‘2’.

The Providers group is for subscribers who have a membership level of ‘2’.

The Members group is for any user who has a membership level of ‘3’, ‘4’, or ‘6’.

See if this code works. If users are still being removed from groups, you’ll need to look at the logic in the function and make sure it’s correct. Users will be removed from a group if they don’t meet the condition in the if statement.

add_filter( 'wpdc_sso_params', 'wpdc_custom_sso_params', 10, 2 );
function wpdc_custom_sso_params( $params, $user ) {
	$add_groups = array();
	$remove_groups = array();
	$user_sub = in_array( 'subscriber', $user->roles );
	$user_spec = in_array( 'spectator', $user->roles );

	if (  ( pmpro_hasMembershipLevel( '1',  $user->ID ) && $user_sub ) || ( pmpro_hasMembershipLevel( '2', $user->ID ) && $user_spec ) ) {
		$add_groups[] = 'Assessors';
	} else {
		$remove_groups[] = 'Assessors';
	}

	if ( pmpro_hasMembershipLevel( '2',  $user->ID ) && $user_sub ) {
		$add_groups[] = 'Providers';
	} else {
		$remove_groups[] = 'Providers';
	}

	if ( pmpro_hasMembershipLevel( '3',  $user->ID ) ||  pmpro_hasMembershipLevel( '4',  $user->ID ) ||  pmpro_hasMembershipLevel( '6', $user->ID ) ) {
		$add_groups[] = 'Members';
	} else {
		$remove_groups[] = 'Members';
	}

	$params['add_groups'] = join( ',', $add_groups );
	$params['remove_groups'] = join( ',', $remove_groups );

	return $params;
}
3 Likes

Thanks so much, I’ll give it a try!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.