WordPress.org

Make WordPress Core

Opened 22 months ago

Last modified 18 months ago

#21163 new defect (bug)

Blogger Importer Invalid Tokens

Reported by: Workshopshed Owned by:
Milestone: WordPress.org Priority: normal
Severity: normal Version:
Component: Import Keywords:
Focuses: Cc:

Description

When the users clicks on the authorise button google responds with an invalid token error. This is obviously a bit puzzling for the users.

See http://wordpress.org/support/topic/plugin-blogger-importer-invalid-token

The problem seems to be that the form with the authorise button is actually passing blank tokens.

I can't reproduce the problem but I've reproduced their symptoms by switching the URL in get_oauth_link to a non existant one. This returns blank tokens to the form. If you then submit that form you get the invalid token error.

Although this following patch is not actually a fix, we can report the error properly with a change to get_oauth_link and greet and hence it will be easier to diagnose issues.

       // Shows the welcome screen and the magic auth link.
        function greet()
        {
            $next_url = get_option('siteurl') . '/wp-admin/index.php?import=blogger&noheader=true';
            $auth_url = $this->get_oauth_link();
            $title = __('Import Blogger', 'blogger-importer');
            $welcome = __('Howdy! This importer allows you to import posts and comments from your Blogger account into your WordPress site.', 'blogger-importer');
            $prereqs = __('To use this importer, you must have a Google account and an upgraded (New, was Beta) blog hosted on blogspot.com or a custom domain (not FTP).', 'blogger-importer');
            $stepone = __('The first thing you need to do is tell Blogger to let WordPress access your account. You will be sent back here after providing authorization.', 'blogger-importer');
            $auth = esc_attr__('Authorize', 'blogger-importer');
            $errormsg = __('Error occurred getting OAuth tokens from Google', 'blogger-importer')

            echo "
		<div class='wrap'>
		" . screen_icon() . "
		<h2>$title</h2>
		<p>$welcome</p><p>$prereqs</p><p>$stepone</p>";
        
            if (!is_wp_error($auth_url)) {
		    echo "<form action='{$auth_url['url']}' method='get'>
				<p class='submit' style='text-align:left;'>
					<input type='submit' class='button' value='$auth' />
					<input type='hidden' name='oauth_token' value='{$auth_url['oauth_token']}' />
					<input type='hidden' name='oauth_callback' value='{$auth_url['oauth_callback']}' />
				</p>
			</form>
		</div>\n";
            }
            else {
                    echo $errormsg;
                    echo '<pre>
                    '.$auth_url->get_error_message().'
                    </pre>' ;
            }
        }

        function get_oauth_link()
        {
            // Establish an Blogger_OAuth consumer
            $base_url = get_option('siteurl') . '/wp-admin';
            $request_token_endpoint = 'https://www.google.com/accounts/OAuthGetRequestToken';
            $authorize_endpoint = 'https://www.google.com/accounts/OAuthAuthorizeToken';

            $test_consumer = new Blogger_OAuthConsumer('anonymous', 'anonymous', null); // anonymous is a google thing to allow non-registered apps to work

            //prepare to get request token
            $sig_method = new Blogger_OAuthSignatureMethod_HMAC_SHA1();
            $parsed = parse_url($request_token_endpoint);
            $params = array('callback' => $base_url, 'scope' => 'http://www.blogger.com/feeds/', 'xoauth_displayname' => 'WordPress');

            $req_req = Blogger_OAuthRequest::from_consumer_and_token($test_consumer, null, "GET", $request_token_endpoint, $params);
            $req_req->sign_request($sig_method, $test_consumer, null);

            // go get the request tokens from Google
            $req_response = wp_remote_get($req_req->to_url(), array('sslverify' => false));
            if (is_wp_error($req_response))
            {
                return $req_response;
            }
            $req_token = wp_remote_retrieve_body($req_response);

            // parse the tokens
            parse_str($req_token, $tokens);

            $oauth_token = $tokens['oauth_token'];
            $oauth_token_secret = $tokens['oauth_token_secret'];

            $callback_url = "$base_url/index.php?import=blogger&noheader=true&token=$oauth_token&token_secret=$oauth_token_secret";

            return array('url' => $authorize_endpoint, 'oauth_token' => $oauth_token, 'oauth_callback' => $callback_url);
        }

p.s. Sorry I've still not mastered DIFF!

Change History (7)

comment:1 Workshopshed22 months ago

Missing a ; on the end of the $errormsg line.

comment:2 SergeyBiryukov22 months ago

  • Milestone changed from Awaiting Review to WordPress.org

comment:3 Workshopshed22 months ago

Looking at the documentation if there is a problem with the parameters passed to google there will be a 400 code returned. So this change with fix that.

https://developers.google.com/accounts/docs/OAuth_ref#RequestToken

However, what I suspect is more likely happening for these users is that the wp_remote calls are locked down so they won't be able to continue anyway

comment:4 Workshopshed22 months ago

Also just spotted

$base_url = get_option('siteurl') . '/wp-admin';

Should that be changed to ?

$base_url = admin_url();
Last edited 22 months ago by Workshopshed (previous) (diff)

comment:5 Workshopshed22 months ago

Updated get_oauth_link

function get_oauth_link()
        {
            // Establish an Blogger_OAuth consumer
            $base_url = admin_url();
            $request_token_endpoint = 'https://www.google.com/accounts/OAuthGetRequestToken';
            $authorize_endpoint = 'https://www.google.com/accounts/OAuthAuthorizeToken';

            $test_consumer = new Blogger_OAuthConsumer('anonymous', 'anonymous', null); // anonymous is a google thing to allow non-registered apps to work

            //prepare to get request token
            //https://developers.google.com/accounts/docs/OAuth_ref#RequestToken
            $sig_method = new Blogger_OAuthSignatureMethod_HMAC_SHA1();
            $parsed = parse_url($request_token_endpoint);
            $params = array('callback' => $base_url, 'scope' => 'http://www.blogger.com/feeds/', 'xoauth_displayname' => 'WordPress');

            $req_req = Blogger_OAuthRequest::from_consumer_and_token($test_consumer, null, "GET", $request_token_endpoint, $params);
            $req_req->sign_request($sig_method, $test_consumer, null);

            // go get the request tokens from Google
            $req_response = wp_remote_get($req_req->to_url(), array('sslverify' => false));
            if (is_wp_error($req_response))
            {
                return $req_response;
            }
            $req_token = wp_remote_retrieve_body($req_response);

            // parse the tokens
            parse_str($req_token, $tokens);

            $oauth_token = $tokens['oauth_token'];
            $oauth_token_secret = $tokens['oauth_token_secret'];
            // todo: add validation so these never get passed as blank

            $callback_url = admin_url('admin.php?import=blogger&noheader=true&token='.$oauth_token.'&token_secret='.$oauth_token_secret);

            return array('url' => $authorize_endpoint, 'oauth_token' => $oauth_token, 'oauth_callback' => $callback_url);
        }
Last edited 22 months ago by Workshopshed (previous) (diff)

comment:6 Workshopshed21 months ago

This change to the status message works, one of the users with the "invalid tokens" error is now getting a DNS timeout error message.

http://wordpress.org/support/topic/plugin-blogger-importer-invalid-token

It looks like an adjustable timeout for the remote gets would be a good idea.

comment:7 Workshopshed18 months ago

Situation reported where "invalid token" will appear and hence criteria to test against.

  • Your sever's clock is out, I reproduced this by changing the code to add 50,000 to the timestamp.
  • You have a firewall stops the server reaching accessing Google
  • You don't have any remote access protocols installed or working (you can test this with Core Control plugin)
  • DNS timeout (as mentioned above)
Note: See TracTickets for help on using tickets.