Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WordPress user creation may fail after Twitter authentication #799

Closed
mt8 opened this issue Jul 9, 2020 · 12 comments
Closed

WordPress user creation may fail after Twitter authentication #799

mt8 opened this issue Jul 9, 2020 · 12 comments

Comments

@mt8
Copy link

mt8 commented Jul 9, 2020

Description

Creating a WordPress username fails if Twitter profile contains unusable characters for WordPress username.

Reproduction

I use Japanese characters on my Twitter profile. If try to Twitter authentication, WordPress user creation will fail.

スクリーンショット 2020-07-09 15 10 34

This is because the following code sets user_login to username.

		// Create the user data array for updating first- and lastname
		$user_data = [
			'user_email'   => $email,
			'user_login'   => $username,
			'user_pass'    => $password,
			'first_name'   => $firstname,
			'last_name'    => $lastname,
			'display_name' => $username,
			'description'  => $description,
		];

https://github.com/auth0/wp-auth0/blob/master/lib/WP_Auth0_Users.php#L78

I am solving this with code like this:

    add_filter( 'auth0_create_user_data', 'my_auth0_create_user_data' , 10, 2 );
    function my_auth0_create_user_data( $user_data, $userinfo )
    {
        if ( ! is_null( $userinfo ) && is_object( $userinfo ) ) {
            $identities = property_exists( $userinfo, 'identities' ) ? $userinfo->identities : [];
            if ( is_array( $identities ) && ! empty( $identities ) ) {
                $identitiy = $identities[0];
                if ( ! is_null( $identitiy ) && is_object( $identitiy ) ) {
                    $provider = property_exists( $identitiy, 'provider' ) ? $identitiy->provider : '';
                    if ( 'twitter' == $provider ) {
                        //set user_login to twitter account name ( @example )
                        $user_data['user_login'] = $userinfo->screen_name;
                    }
                }
            }
        }
        return $user_data;
    }

I suggest fixing the plugin as it can happen in other languages as well.

Thanks

Environment

  • WordPress 5.4.2
  • Plugin Version 4.1.0
  • PHP 7.2.9
@joshcanhelp
Copy link
Contributor

@mt8 - Apologies for the long delay here. The work-around you're describing won't always work since identities does not always come with the user data and, on my end, I'm not seeing screen_name as part of the identity that comes in.

Can you tell me the exact error you're seeing? Output from the Auth0 plugin log as well as any relevant PHP error logs would be helpful as well. I'm wondering if this might just be a matter of converting the incoming name or possibly and issue with the character encoding on your database.

@mt8
Copy link
Author

mt8 commented Sep 30, 2020

@joshcanhelp Hi,

on my end, I'm not seeing screen_name as part of the identity that comes in.

In what cases does this happen?

@joshcanhelp
Copy link
Contributor

Simply turning on the connection and using it:

Screen Shot 2020-09-30 at 7 50 28 AM

@mt8
Copy link
Author

mt8 commented Sep 30, 2020

@JoanDelilahPepin Thanks.
What is the difference between getting sceen_name and not getting it? I can always get it in my environment.

@joshcanhelp
Copy link
Contributor

I'm not entirely sure, to be honest. All that data comes from Twitter.

Aside from that, though ... can you tell me what the error you're seeing is and when you see it? The plugin error log and your server's PHP error log might also have clues here. Since we can't rely on screen_name, we can look into handling the encoding better.

@mt8
Copy link
Author

mt8 commented Sep 30, 2020

@joshcanhelp Thank you for your reply. Okey. Reproduce and report the error again.

@mt8
Copy link
Author

mt8 commented Oct 2, 2020

@joshcanhelp

I got this error, when I tried to twitter auth login.

There was a problem with your log in: Cannot create a user with an empty login name.  [error code: unknown]

Here is my twitter account.
https://twitter.com/mt8_dot_biz

「モトハチ」 is the screen_name for my account.
The problem is that the plugin is trying to use screen_name for WordPress user_login.

@joshcanhelp
Copy link
Contributor

So, I misspoke before, I do see the screen_name field on my Twitter user. I think that is the one we want to use, though, at least according to their documentation:

https://developer.twitter.com/en/docs/twitter-api/v1/data-dictionary/overview/user-object

Do you see what mt8_dot_biz is coming through as in the Auth0 user? If so, we can get that mapped to the right place.

@mt8
Copy link
Author

mt8 commented Oct 8, 2020

@joshcanhelp

sorry. I also said wrong.

screen_name: mt8_dot_biz
name: モトハチ

The current plugin seems to be trying to set name to WordPress User's user_login.

@joshcanhelp
Copy link
Contributor

No worries, just wanted to make sure I had my information correct.

So ... what we need to do is:

  1. Map the name we need to use to a custom ID claim
  2. Use that custom ID claim when creating the user

The first step needs to happen in a Rule. This should do the trick:

function twitterScreenNameToCustomClaim(user, context, callback) {
  if (user.screen_name) {
    console.log("Screen name: " + user.screen_name);
    context.idToken['https://example.com/screen-name'] = user.screen_name;
  }
  return callback(null, user, context);
}

The second part needs to happen in custom code in your theme or in a custom plugin. I just tested this out and it works on my end:

function example_auth0_create_user_data( array $user_data, $userinfo ) {
	$userinfo = (array) $userinfo;
	if ($userinfo['screen_name']) {
		$user_data['user_login'] = $userinfo['screen_name'];
	} elseif ( ! empty( $userinfo['https://example.com/screen-name'] ) ) {
		$user_data['user_login'] = $userinfo['https://custom-claim/screen-name'];
	}
	return $user_data;
}
add_action( 'auth0_create_user_data', 'example_auth0_create_user_data', 10, 2 );

@mt8
Copy link
Author

mt8 commented Oct 8, 2020

@joshcanhelp

Thank you for your reply and for providing a great solution.
It worked perfectly.

Ideally, it works only with plugins without these support (Rule / WordPress filter).

Perfect for someone like me who understands Rules and WordPress filters, but for those who don't, they'll give up on Twitter connections.

I would be grateful if you could consider this.

@joshcanhelp
Copy link
Contributor

I appreciate the feedback here. The identity mapping of the Twitter connection is not likely to change anytime soon as that would break anyone relying on how it works already. The problem here is that screen_name is specific to Twitter and doesn't really map to any standard identity claims. As such, it's relegated to custom claims like this one.

We are rolling out a better system for doing custom claims, though, one that does not require a URL-type schema. That should allow folks to map screen_name to, say username, which is picked up automatically by the plugin.

Again, thank you for the feedback and for posting the successful test results! Hopefully this can help others in the future 🙇

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants