User avatar preference spontaneously changing to "Custom picture"

I am currently on v1.8.0.beta4 +283. I just upgraded to beta from stable. The problem I am reporting here was happening also on stable v 1.7.2. I upgraded to the beta channel hoping for a fix, but it’s the same. It was not happening on stable prior to 1.7.

Since the stable upgrade from 1.6.x to 1.7.0, and now also on v1.8 beta, I am seeing random blank avatars in our forum. When I look at the users that are affected, I see that in the preferences for that user, the profile picture setting has been changed to “Custom picture” but there is no custom picture and so the avatar is either completely blank or appears as the generic avatar. When I checked with users for whom I am seeing this, they are NOT manually setting the preference to “Custom picture.” It is somehow happening “by itself” behind the scenes.

We are using WordPress SSO via the wp-discourse plugin (to which I am a code contributor), but I do not have the override avatar from SSO payload setting turned on.

Here is what my “avatar” related settings look like:

1 Like

Moved this from “Bug” to “Support” in hopes that maybe someone will look at it…

I think this can be taken care of by the wp-discourse plugin by adding an ‘SSO overrides avatar’ setting. Doing that will also solve the problem of Gravatars not being updated on Discourse when they are changed on WordPress.

1 Like

Hi Simon. So are you saying you think that this behavior is because of the WP SSO even though I have the setting for overriding the avatar turned off in Discourse?

How would the SSO login be changing the profile pic setting?

Yes, the problem I’m seeing is when a user has an existing account on both Discourse and WordPress, but the accounts have not yet been synced. In that case, when the user first logs in with SSO, if the avatar_url is present in the SSO parameters, the job download_avatar_from_url is enqueued. This checks for the user’s uploaded_avatar_id. If that isn’t present, then the avatar_url from the SSO parameters is used. This happens whether or not the SiteSetting sso_overrides_avatar has been set.

We can get around this in the wp-discourse plugin by adding a ‘SSO overrides avatar’ setting. If it is not set, then the WordPress avatar_url won’t be sent with the SSO parameters. If it is set, the avatar_url will be sent with the SSO parameters, and also force_avatar_update can be added to the parameters and set to true. Doing that will make it possible for avatars to be updated on Discourse when the Gravatar image is changed through WordPress.

What I can’t figure out is a good way to check on WordPress if the default avatar (usually the mystery person) is being used. I think in most cases, people would rather keep the default Discourse avatar instead of having it overridden with this:

Yeah, I came to the same conclusion yesterday when I looked at the SSO payload in the plugin, so since we don’t use avatars at all on the WP site I’m managing, I just commented out the avatar_url line as a proof of concept and viola - no more blank avatars.

So I would have sent you a quick PR, but when I started to think about it, I didn’t know how to validate whether we’d be sending a valid avatar_url or not. The WP function get_avatar_url is supposed to return false if there isn’t one defined, so it would be easy enough to only send the avatar_url if ( false !== get_avatar_url(get_current_user_id()) ) and that would probably be an improvement, but I don’t know for sure if that would solve the problem entirely because you could be sending invalid (but non-false) URLs depending on how your WP environment is set up.

Maybe the right thing to do is both your setting in the wp-discourse plugin so WP admins can turn off any avatar syncing (like I would in the case of this particular integration) and to also implement the logic I wrote above so that we never send avatar_url when get_avatar_url returns false.

1 Like

The problem is that when it’s using the default avatar, get_avatar_url returns a valid URL, just not the one we want. It might be possible to add an avatar_updated flag that’s triggered when the avatar_url is updated, and then only send the avatar_url if it has been set.

I see that you’ve made various attempts at fixing this in recent versions of the plugin, but can’t tell exactly what it’s doing right now. You had an admin setting for a few commits there, but then you nixed it.

Is the plugin right now defaulting to not syncing the avatar_url?

It’s still sending the avatar_url, but setting the default to 404:

	protected function get_avatar_url( $user_id ) {
		$avatar_url = get_avatar_url( $user_id, array(
			'default' => '404',
		) );

		return apply_filters( 'wpdc_sso_avatar_url', $avatar_url, $user_id );

If a user has a Gravatar, Discourse will use it. If they don’t have an gravatar associated with their email address, they should now be getting the Discourse default avatar.

It seems that even if an avatar URL isn’t sent to Discourse, if there is a gravatar associated with the user’s email, Discourse will find and use it.


I just upgraded to 1.3.3 and I see that you renamed some option_names for the sso related settings in the wp_options table. That made my install “forget” its settings when I upgraded.

From a WP plugin dev point of view, it’s considered poor form to change the names of settings options without also migrating the old settings on an upgrade. Many (probably most) users will blithely upgrade and not check to see if settings have changed. Because WP core devs are pushing for this more and more, many WP sites even have automatic plugin upgrades enabled and likely in the future more will. In this case, changed option names (or any backward incompatibility in a plugin update) will break a site’s functionality with nobody looking.

Which options were forgotten? Except for the SSO options I only changed the name of a few of the labels and their order on the options page. I did migrate the SSO options to the new settings, but maybe made a mistake when I did it.

Edit: I see now. Thanks! I’ll fix that right away.

Cool - just in case, for me the settings that were forgotten were:

  • enable-sso
  • sso-secret
  • redirect-without-login

i didn’t have it set so don’t know, but assume because it was in the same group also:

  • login-path

Thanks, the problem was that I was transferring the old options in the WordPress activation hook. I had assumed that it got called when a plugin is updated from the WordPress repo, but doesn’t get called.

There will be a fix in the repo right away. Thanks for pointing this out.