Get Discourse Group user is associated with

Hi, I’m looking to grab the Group a user is a member of. It seems like I should be able to get this info via get_discourse_user but this function doesn’t appear to return any Group data. Per this post, it should?

Are you calling the WP Discourse function get_discourse_user? If so, it should be returning the user’s groups in the "groups" array.

Yes, I’m calling it like this.
$discourseUser = \WPDiscourse\Utilities\Utilities::get_discourse_user( $current_user->ID, true );
var_dump($discourseUser);

And it returns this

object(stdClass)#2784 (25) { ["id"]=> int(7) ["username"]=> string(4) "chad" ["name"]=> string(13) "Chad Campbell" ["avatar_template"]=> string(59) "https://avatars.discourse.org/v4/letter/c/ecccb3/{size}.png" ["active"]=> bool(true) ["admin"]=> bool(false) ["moderator"]=> bool(false) ["last_seen_at"]=> string(24) "2019-10-25T15:59:45.439Z" ["last_emailed_at"]=> string(24) "2019-10-25T15:49:07.084Z" ["created_at"]=> string(24) "2019-10-24T21:22:40.526Z" ["last_seen_age"]=> float(2659.60627934) ["last_emailed_age"]=> float(3297.96116042) ["created_at_age"]=> float(69684.5193464) ["username_lower"]=> string(4) "chad" ["trust_level"]=> int(1) ["manual_locked_trust_level"]=> NULL ["flag_level"]=> int(0) ["title"]=> NULL ["suspended"]=> bool(false) ["time_read"]=> int(0) ["staged"]=> bool(false) ["days_visited"]=> int(2) ["posts_read_count"]=> int(0) ["topics_entered"]=> int(0) ["post_count"]=> int(0) }

The true parameter in the function call will get the function to search the user on Discourse by their email address if no user is found based on the WordPress user id. This means that the user has not logged into Discourse with SSO yet. When a user is found based on their email address, less information is returned from Discourse than when a user is found based on their WordPress id.

Possibly the function could be improved to make the return value clearer. For now, if there is no groups array in the response, you can know that the user was found by their email address.

1 Like

Got it. Thanks for the explanation, Simon!

Hey Simon,

I’ve logged into Discouse via SSO and I’m seeing this error when setting the email parameter to false.

object(WP_Error)#2718 (2) { ["errors"]=> array(1) { ["wpdc_response_error"]=> array(1) { [0]=> string(42) "The Discourse user could not be retrieved." } } ["error_data"]=> array(0) { } }

When set to True it’s still not returning groups.

A little confused as the SSO configuration logs me into Wordpress and Discourse (also able to log out of both via Wordpress), so everything assumes to work as expected, but still can’t see Groups returned.

When you set the function call’s second parameter to false, or just leave out the parameter (it defaults to false), the function will attempt to retrieve the user from Discourse by their WordPress id. If the user has logged into Discourse with SSO, then the function should return a user and their groups.

To debug this, go to the Discourse admin page of the user you are trying to retrieve. Scroll to the bottom of the page and see if there is a Single Sign On section. If there is, make sure that the External ID in that section matches the WordPress user id that you’re using with the call to get_discourse_user.

If there is no Single Sign On section on the user’s Discourse admin page, then the user has not yet logged into Discourse with SSO.

1 Like

Yeah, I’m not seeing that section exists for any of the users I’ve tested.

It really seems I’m logging in via SSO though.
Here is the flow. (not logged into Wordpress or Discourse)

From Wordpress I click on the Log in with Discourse link
It sends me to the Discourse site
I login with my Discourse credentials
Successfully redirected back to Wordpress site
I’m now logged into both sites

What am I missing from the process to make it officially SSO?

I see the problem now. You are using Discourse as the SSO provider for WordPress. That function is meant to be used when WordPress is the SSO provider for Discourse. The function is poorly named. The name should make it clear what the use case is.

For the case where Discourse is the SSO provider for WordPress, what you need to do is make an authenticated API request to /admin/users/$user_id.json. $user_id needs to be set to the user’s Discourse id. For users who have logged into WordPress via Discourse, you can get their Discourse user id with:

get_user_meta( $wp_user_id, 'discourse_sso_user_id', true );
3 Likes

Ah, ok. I’ll start diving into your API docs. Thanks for pointing me in the right direction!

1 Like