Recently my team and I have been working on a feature that allows a user’s Discourse username to be edited from Wordpress with the WP Discourse plugin installed and our Wordpress site set as the SSO provider for Discourse. Currently we have had some success using the Discourse API, where we have a custom meta field in Wordpress that, when updated, calls our site’s Discourse instance with a PUT request to update the user’s username (similar to a solution proposed here: How does one change a username via the API?)
However, there is an existing option within WP Discourse as shown here:
but this field is only used for publishing posts (from WP to Discourse) and does not actually update the user’s Discourse username in Discourse. It syncs when a user changes their username in Discourse, but it does not sync from Wordpress to Discourse when changed.
My question is, will this type of two-way sync be implemented at some point? Why is there an option to allow users to change this username field if it does not sync from Wordpress to Discourse? My team would also be interested in contributing this feature if it is not something already in the works. Our site needs this functionality, and we imagine it would be useful for all WP Discourse sites as well. Please let me know about this!
@angus@simon since you are both involved heavily in WP Discourse and helped us with our SSO issues I think I should direct this question to you guys!
The Discourse Username Editable field in the WordPress plugin may be poorly named. The setting’s copy definitely needs to be updated to make it clear what the setting is intended for. When the Discourse Username Editable setting is enabled, users on the WordPress site can set their Discourse Username on their WordPress profile page. If that setting is not enabled, only an admin on the WordPress site can set the user’s Discourse username. The Discourse username is only used by the plugin for publishing posts from WordPress to Discourse.
When DiscourseConnect is used between WordPress and Discourse, the user’s Discourse username is initially set from their WordPress username. If the auth_overrides_username setting is enabled on the Discourse site, the username on Discourse can only be set from WordPress. If the auth overrides username setting is not enabled on Discourse, users could edit their username on Discourse so the usernames could be out of sync between the two systems.
In terms of the Discourse Username field, ideally, this field would always be set in the background based on the Discourse username. It’s a while since I last looked at the related code, but I believe the Discourse Username field is automatically filled in if the WordPress site is used as the SSO provider for Discourse and the “Create or Sync Discourse Users on Login” option is enabled on the DiscourseConnect Provider options tab on WordPress. The Discourse Username field is also automatically set if Discourse is used as the SSO provider for WordPress (with the DiscourseConnect Client setting.)
Ideally, the Discourse Username field would always be automatically set when WordPress is the SSO provider for Discourse, whether or not the “Create or Sync Discourse Users on Login” option is enabled on Discourse. I don’t think anything can be done for the case where DiscourseConnect isn’t being used between the two sites, but @angus might have ideas about that.
By default, WordPress does not allow users to change their usernames, so this isn’t something we’ve had a lot of questions about. If you want to ensure that usernames are kept in sync between WordPress and Discourse, make sure to enable the auth_overrides_username setting on Discourse. You might also want to enable the “Create or Sync Discourse Users on Login” option on WordPress. With that option enabled, users will be updated on Discourse each time they login to your WordPress site. If that option is not enabled, users will only be updated on Discourse when they log out of Discourse, then log back in with DiscourseConnect.
Thanks for the reply @simon and explanation of the existing feature.
Our site may be a bit of a special case, because we do not want to have the user’s Wordpress username synced with Discourse precisely because Wordpress does not allow users to change their usernames by default. And we do not want to install a plugin that adds this WP username edit functionality due to the instability that it could create.
But since usernames are editable in Discourse, I think it would make sense to extend this functionality into Wordpress via the WP Discourse plugin. This field seems like the perfect place to do that, but I understand that it could conflict with the WP username since that would never change by default. So I take it that this is not something you want us to contribute to the plugin?
Also, allowing users to edit their username in the forum is a major requirement for us. We already have Discourse setup to allow this, but most of our users do not change their Discourse username because it is hidden within the Discourse settings. We want it in plain site within their profile page on our Wordpress site, alongside their other info like name, avatar, etc.
However they will be the same on new signups, as you’re using DiscourseConnect. I’m assuming you’re ok with that, and you’re just concerned about syncing per se (i.e. after account creation)?
How are you envisaging the case when a user creates a Wordpress account and has not yet signed in to Discourse? No Discourse account will exist. In that case the Discourse Username field would not be editable?
Note that the “Update Userdata” webhook (see “Webhooks” in the WP Discourse settings) will update the Discourse Username in Wordpress when it’s changed in Discourse. That’s one part of the two way sync you’re envisaging.
So specifically what you’re after is just for the WP Discourse plugin to update the user’s Discourse username when it changes, yes?
Now, that field is used by different people for different purposes. Some people want to be able to edit that field without updating the username of the Discourse user associated with the account they use with DiscourseConnect.
However, there’s a relatively straightforward solution. We could just add an action somewhere around here so that you could use a PUT request to Discourse to update the username on Discourse, i.e. like you are now. I’d just add that the easy way to do that is to use the abstracted discourse_request method in the WP Plugin’s Utilities, i.e.
use WPDiscourse\Utilities\Utilities as DiscourseUtilities;
$path = ''
$args = array(
$response = DiscourseUtilities::discourse_request( $path, $args );
Using both the Webhook and action callback, you’d have a two-way sync in the way you’re envisaging, assuming you’ve accounted for the two questions I raised above.
Happy to review and merge a PR with an additional action along those lines.
We are actually overriding this behavior with the wpdc_sso_params filter hook because our SSO system integrates Firebase and everyone’s WP username defaults to their Firebase UID, so we are changing the Discourse default to be memberXXX (with XXX being a number). We actually want to change this default to be the user’s Firstname_Lastname at some point as well. But yes our primary concern is users being able to change their username easily via their profile page within our Wordpress site.
In this case I am thinking we can either store the username field and have it sync when the account is created (via the wpdc_sso_params filter hook on the first SSO), or we could force a Discourse account to be created for every member when they sign up on our Wordpress site via the Discourse API. The second option would probably be more advantageous because we would know that everyone has a Discourse account and there would thus be fewer special cases of some users having accounts and others not. But we are really going for a seamless experience, so we want this username to be what the user thinks of as their username for our entire platform. We want it to always be editable, and in the future we will probably use it for more than just Discourse (i.e. in leaderboards, etc.).
Yes this is exactly what we need!
Understood! Thanks for this direction, my team and I will work on testing this with our implementation first and should make a PR soon!