How to prevent some WP users from being able to login to Discourse

We have WordPress and Discourse working together nicely with the WP-Discourse plugin. BUT there’s one thing we’d ideally like to do and I’m not sure what the most unobtrusive way to do it is.

We have several membership levels in WordPress and one of them is sort of a “Guest Access” membership. We don’t want people who have Guest Access membership to be able to login to Discourse.

The only way I can think of handling would be to edit the WP-Discouse plugin just at the one line where attempts to do the SSO and return false if the member is part of the Guest Access membership group but it’s less than ideal.

Any other ideas? Thanks!

1 Like

There is a wpdc_sso_provider_before_sso_redirect action hook that can be used to bypass SSO. The hook is fired right before the SSO login redirect to Discourse. It is passed the current WordPress user_id and user object as parameters: https://github.com/discourse/wp-discourse/blob/master/lib/sso-provider/discourse-sso.php#L189.

The basic idea is that if a user doesn’t meet the condition you have set for logging into Discourse, you redirect them to some page and then call exit. If the user does meet your condition, do nothing.

add_action( 'wpdc_sso_provider_before_sso_redirect', 'wpdc_custom_check_user_membership', 10, 2 );
function wpdc_custom_check_user_membership( $user_id, $user ) {
    if ( /* Some condition that returns true if the user doesn't meet the membership requirement */ ) {
	    wp_safe_redirect( home_url() );

	    exit;

    }
}

If you have enabled the Create or Sync Discourse Users on Login option, you will also need to prevent WordPress users from being automatically created on Discourse when they login to your WordPress site. As of WP Discourse version 1.6.9 you can do this by hooking into the wpdc_bypass_sync_sso filter. That filter hook is passed three parameters: $bypass_sync (defaults to false), $user_id, and $user (a WordPress user object.) The code for it is here.

To bypass the sync_sso_record function, you need to hook into the filter with a function that will return true for users you would like to not be synced with Discourse.

add_filter( 'wpdc_bypass_sync_sso', 'wpdc_custom_bypass_sync_sso', 10, 3 );
function wpdc_custom_bypass_sync_sso( $bypass_sync, $user_id, $user ) {
    if ( /* Some condition that returns true if the user doesn't meet the membership requirement */  ) {

        $bypass_sync = true;
    }

    return $bypass_sync;
}
8 Likes

Hi @simon. Thx! That action works in terms of preventing the user from logging in which is awesome! However, the wp-discourse plugin seems to still automatically create the user in Discourse (I think it happens upon them logging in). Is there a way to prevent that from happening? I see that there’s a action called wpdc_sso_provider_before_create_user which I tried using but no dice. I tried using it like so:

add_action( 'wpdc_sso_provider_before_create_user', 'wpdc_custom_before_create_user', 10, 2 );
function wpdc_custom_before_create_user( $user_login, $user ) {
	
	if ( ...my condition here... ) {
	    return(false);	
	}

}

(we don’t want to them to be a member of the forum at all because they’ll get the summary emails and so forth)

2 Likes

Right, if the Create or Sync Discourse Users on Login option is set, users will be automatically created on Discourse when they login to WordPress. There isn’t a great way to override this for a specific user yet. I’m going to update the plugin today. I’ll add a hook to the sync_sso_record function that can be used to keep specific WordPress users from being created on Discourse. I’ll update this topic when that has been done.

4 Likes

Have a look at the updated topic to see how to prevent users from being automatically created on Discourse when they login to WordPress. You’ll need to get the latest version of the plugin from the WordPress repo for this to work.

4 Likes

Fantastic! This seems to work. Thanks so much!

3 Likes

Yes, I am using the WP Discourse.

Thanks for sharing this code about how to prevent some WP users from being able to login to Discourse. Big help!

I just have 3 additional questions for whenever you are able to reply:

  1. Should I add that code to my theme’s functions.php file?

  2. When a member cancels, they transition in wordpress from being a “s2Member Level 1” to a “Subscriber” - should I put if ( /* Subscriber */ ) { in order to make it work?

  3. If want to redirect Subscribers to a different page aside from the homepage, do I just change home_url with a the url of my billing update page? (wp_safe_redirect( myfishingcapecod.com/billing-update-page/() );

Thank you very much for the support. Huge help!

The code can either be added to your theme’s functions.php file, or to a separate plugin. It would be best to use a development site to test the code before adding it to your main site.

The condition will need to return true if you don’t want the user to be able to login to Discourse, so you’ll probably want to check that the user does not have the required membership level. You’ll need to look at the s2Member documentation to find out how to do this. I’ve never used the plugin, but it looks like you can get the membership level for the current user with:

get_user_field( 's2member_access_level' );

If that is correct, the condition would be something like this. (You’ll need to test this):

if ( ! 1 >= get_user_field( 's2member_access_level' ) ) {
        
    }

Yes, you can redirect the users to any page you like.

2 Likes

Great! Thank you @simon :+1:t2:

I will get to work, and will post my results back here.

2 Likes