thephpleague / oauth2-client

Easy integration with OAuth 2.0 service providers.
http://oauth2-client.thephpleague.com
MIT License
3.65k stars 751 forks source link

Uncaught exception 'InvalidArgumentException' with message 'URI must be a string or Psr\Http\Message\UriInterface' #433

Closed stefthoen closed 9 years ago

stefthoen commented 9 years ago

Hi,

I use this code to try to get an access token, but I get an InvalidArgumentException:

public function save_access_token() {

    if( isset( $_GET['code'] ) ) {
        $token = $this->provider->getAccessToken('authorization_code', [
            'code' => $_GET['code']
        ]);
    }
}

Fatal error: Uncaught exception 'InvalidArgumentException' with message 'URI must be a string or Psr\Http\Message\UriInterface' in /Users/stef/Sites/wcmoneybirdplugin/wp/wp-content/plugins/woocommerce-moneybird/vendor/guzzlehttp/psr7/src/Request.php:46 Stack trace: #0 /Users/stef/Sites/wcmoneybirdplugin/wp/wp-content/plugins/woocommerce-moneybird/vendor/league/oauth2-client/src/Tool/RequestFactory.php(44): GuzzleHttp\Psr7\Request->__construct('POST', NULL, Array, 'client_id=221aa...', '1.1') #1 /Users/stef/Sites/wcmoneybirdplugin/wp/wp-content/plugins/woocommerce-moneybird/vendor/league/oauth2-client/src/Tool/RequestFactory.php(85): League\OAuth2\Client\Tool\RequestFactory->getRequest('POST', NULL, Array, 'client_id=221aa...', '1.1') #2 /Users/stef/Sites/wcmoneybirdplugin/wp/wp-content/plugins/woocommerce-moneybird/vendor/league/oauth2-client/src/Provider/AbstractProvider.php(589): League\OAuth2\Client\Tool\RequestFactory->getRequestWithOptions('POST', NULL, Array) #3 /Users/stef/Sites/wcmoneybirdplugin/wp/wp-content/plug in /Users/stef/Sites/wcmoneybirdplugin/wp/wp-content/plugins/woocommerce-moneybird/vendor/guzzlehttp/psr7/src/Request.php on line 46

Below I'll attach the Moneybird class that extends the AbstractProvider and the file where I authenticate my app and try to get an access token. Do you have any idea what I could be doing wrong? Please let me know if you need anything else. Thanks!

class-wc-moneybird.php

<?php

class WC_MoneyBird {

    protected $client_id;
    protected $client_secret;
    protected $administration_id;
    protected $token;
    protected $mb_base_url;
    protected $token_path;
    protected $authorize_path;
    protected $wp_admin_settings_url;
    protected $provider;

    public function __construct() {
        add_filter( 'woocommerce_settings_tabs_array', 
            array( $this, 'add_settings_tab' ), 50 );

        add_action( 'woocommerce_settings_tabs_moneybird', 
            array( $this, 'settings_tab' ) );
        add_action( 'woocommerce_update_options_moneybird', 
            array( $this, 'update_settings' ) );
        add_action( 'woocommerce_admin_field_custom_type', 
            array( $this, 'add_button_to_woocommerce_settings' ) );
        add_action( 'woocommerce_order_status_completed', 
            array( $this, 'send_completed_order_to_moneybird' ) );
        add_action( 'init', array( $this, 'authorize' ) );
        add_action( 'init', array( $this, 'save_access_token' ) );

        $this->client_id = get_option( 'wc_moneybird_client_id' );
        $this->client_secret = get_option( 'wc_moneybird_client_secret' );
        $this->administration_id = get_option( 'wc_moneybird_administration_id' );
        $this->mb_base_url = 'https://moneybird.com/api/v2/' . 
            $this->administration_id . '/';
        $this->token_path = 'https://moneybird.com/oauth/token';
        $this->authorize_path = 'https://moneybird.com/oauth/authorize';
        $this->wp_admin_settings_url = home_url() . '/wp-admin/admin.php?page=wc-settings&tab=moneybird';

        $this->provider = new Uprise\OAuth2\Client\Moneybird\Provider\Moneybird([
            'clientId'       => $this->client_id,
            'clientSecret'   => $this->client_secret,
            'redirectUri'    => $this->wp_admin_settings_url,
            'scopes'         => ['sales_invoices'],
        ]);

    }

    public function authorize() {
        if( ! isset( $_GET['authorize'] ) || $_GET['authorize'] != '1' ) {
            return;
        }

        $authUrl = $this->provider->getAuthorizationUrl();

        $_SESSION['oauth2state'] = $this->provider->getState();

        header('Location: '.$authUrl);
        exit();
    }

    public function save_access_token() {

        if( isset( $_GET['code'] ) ) {
            $token = $this->provider->getAccessToken('authorization_code', [
                'code' => $_GET['code']
            ]);
        }
    }

    public function add_button_to_woocommerce_settings( $button ){
        echo '<a class="button-secondary" type="button" href="' . $this->wp_admin_settings_url . '&authorize=1">Authenticate</a>';
    }

    public function add_settings_tab( $settings_tabs ) {
        $settings_tabs['moneybird'] = __( 'MoneyBird', 'woocommerce-moneybird' );
        return $settings_tabs;
    }

    public function settings_tab() {
            woocommerce_admin_fields( self::get_settings() );
    }

    public function update_settings() {
            woocommerce_update_options( self::get_settings() );
    }

    public function send_completed_order_to_moneybird() {
        $provider = new Uprise\OAuth2\Client\Moneybird\Provider\Moneybird([
            'clientId'      => $this->client_id,
            'clientSecret'  => $this->client_secret,
            'redirectUri'   => $this->wp_admin_settings_url,
            'scopes'        => ['sales_invoices']
        ]);
    }

    private function get_settings() {
        $settings = array(
            'section_title' => array(
                'name'     => __( 'Moneybird API Settings', 'woocommerce-moneybird' ),
                'type'     => 'title',
                'desc'     => '',
                'id'       => 'wc_moneybird_section_title'
            ),
            'client_id' => array(
                'name' => __( 'Client ID', 'woocommerce-moneybird' ),
                'type' => 'text',
                'desc' => __( 'Add your MoneyBird app client ID.', 'woocommerce-moneybird' ),
                'id'   => 'wc_moneybird_client_id'
            ),
            'client_secret' => array(
                'name' => __( 'Client Secret', 'woocommerce-moneybird' ),
                'type' => 'text',
                'desc' => __( 'Add your MoneyBird app client secret.', 'woocommerce-moneybird' ),
                'id'   => 'wc_moneybird_client_secret'
            ),
            'administration_id' => array(
                'name' => __( 'Administration ID', 'woocommerce-moneybird' ),
                'type' => 'text',
                'desc' => __( 'Add your MoneyBird Account\'s Administration ID.', 'woocommerce-moneybird' ),
                'id'   => 'wc_moneybird_administration_id'
            ),
            'section_end' => array(
             'type' => 'sectionend',
             'id' => 'wc_moneybird_section_end'
            ),
            'button' => array(
                'name' => __( 'button', 'woocommerce-moneybird' ),
                'type' => 'custom_type',
                'desc' => '',
                'id'   => 'wc_moneybird_button'
            ),
            'section_end' => array(
             'type' => 'sectionend',
             'id' => 'wc_moneybird_section_end'
            )
        );

        return apply_filters( 'wc_moneybird_settings', $settings );
    }
}

?>

Provider/Moneybird.php

<?php

namespace Uprise\OAuth2\Client\Moneybird\Provider;

use League\OAuth2\Client\Provider\AbstractProvider;
use League\OAuth2\Client\Token\AccessToken;
use Psr\Http\Message\ResponseInterface;

class Moneybird extends AbstractProvider {

    public function urlAuthorize() {
        return 'https://moneybird.com/oauth/authorize';
    }

    public function urlAccessToken() {
        return 'https://moneybird.com/oauth/token';
    }

    public function getBaseAuthorizationUrl() {
        return 'https://moneybird.com/oauth/authorize';
    }

    public function urlUserDetails( AccessToken $token ) {

    }

    public function userDetails( $response, AccessToken $token ) {

    }

    public function getBaseAccessTokenUrl( array $params ) {

    }

    public function getResourceOwnerDetailsUrl( AccessToken $token ) {

    }

    public function getDefaultScopes() {

    }

    public function checkResponse( ResponseInterface $response, $data ) {

    }

    public function createResourceOwner( array $response, AccessToken $token ) {

    }
}
shadowhand commented 9 years ago

Based on your implementation of AbstractProvider, it looks like you are trying to use an older version of OAuth2. The methods urlAuthorize and urlAccessToken and urlUserDetails no longer exist in OAuth2 client v1.0+.

I recommend using the Implementing Your Own Provider documentation to make sure your code is complete.

stevenmaguire commented 9 years ago

Nice catch, @shadowhand! < 30 min triage time for an open source project!

stefthoen commented 9 years ago

Thanks! I'll look into it.