Access Token/Refresh Token are not being associated with currentUserEmail

Access Token/Refresh Token are not being associated with currentUserEmail

I'm working on integrating the Zoho PHP SDK and while I have gotten the Oauth2 flow set up and the database persistence working, it seems that whenever it attempts to utilize the stored Refresh Token to refresh the Access Token it is failing. 

This seems to be occurring because when the Refresh and Access Tokens are initially created, a useridentifier is not being saved in the database. When the Tokens are being initially generated and saved, the useridentifier is set by checking who the Access Token belongs to here: https://github.com/zoho/zcrm-php-sdk/blob/e6dae11c87e1b7c57235c1796b88ea12f9b18b11/src/oauth/ZohoOAuthClient.php#L65

It seems that this check against the Access Token is returning a null value which is causing one to not be set in my database. 

If I modify the $userEmailId variable here https://github.com/zoho/zcrm-php-sdk/blob/e6dae11c87e1b7c57235c1796b88ea12f9b18b11/src/oauth/ZohoOAuthClient.php#L38 to equal a null value, it grabs the Tokens correctly. However, it then gives me an error about the scope. Possibly due to it not being associated with an email address?

Regardless, editing the function like that shouldn't be the way to go. If you try to provide a null value to currentUserEmail in the config it causes this exception to be thrown: https://github.com/zoho/zcrm-php-sdk/blob/e6dae11c87e1b7c57235c1796b88ea12f9b18b11/src/crm/utility/ZCRMConfigUtil.php#L98-L99 So there must be a way to properly associate a set of Tokens with an email address.

If I edit the database to include the correct email address in the column, that gives me the same scope error since that Refresh/Access Token combo doesn't belong to that email address but rather to null or "no one".

Here are the relevant code chunks for my oAuth2 flow and the code snippet I'm using to test grabbing the Tokens to run a simple command. Is there something wrong here? This is a single user setup, so I am just hard coding the Email Address for now. 

Button to start oAuth2 flow
  1. <?php $config = pws_zoho_get_config(); // https://developer.wordpress.org/reference/functions/add_query_arg/ $url = add_query_arg( array( 'scope' => 'ZohoCRM.users.ALL', 'client_id' => $config['client_id'], 'response_type' => 'code', 'access_type' => 'offline', 'redirect_uri' => $config['redirect_uri'], 'currentUserEmail' => $config['currentUserEmail'], ), 'https://accounts.zoho.com/oauth/v2/auth' ); ?> <a class="pws-zoho-api-oauth button-primary" href="<?php echo $url; ?>"> <?php _e( 'Link Zoho CRM API', 'pws-zoho-api-plugin' ); ?> </a>

Generate the Access and Refresh Tokens and store them into the database
  1. <?php use zcrmsdk\crm\setup\restclient\ZCRMRestClient;
    use zcrmsdk\oauth\ZohoOAuth;

    /**
    * Returns credentials for accessing the database
    * This is only really necessary because of how my local environment works
    *
    * @since {{VERSION}}
    * @return array Database Credentials
    */
    function pws_zoho_get_database_credentials() {

    $host = DB_HOST;
    $port = ini_get( 'mysqli.default_port' );

    // Fix for my Docker Environment. Likely won't ever impact any real servers
    if ( strpos( DB_HOST, ':' ) ) {
    $parts = explode( ':', DB_HOST );
    $host = $parts[0];
    $port = $parts[1];
    }
    // https://developer.wordpress.org/reference/functions/apply_filters/
    return apply_filters( 'pws_zoho_get_database_credentials', array(
    'host' => $host,
    'port' => $port,
    'username' => DB_USER,
    'password' => DB_PASSWORD,
    ) );

    }

    /**
    * Quickly obtain the config for the Zoho SDK
    *
    * @since {{VERSION}}
    * @return array Zoho SDK Config
    */
    function pws_zoho_get_config() {

    $client_id = pws_zoho_get_option( 'pws_zoho_client_id' );
    $client_secret = pws_zoho_get_option( 'pws_zoho_client_secret' );

    $db_creds = pws_zoho_get_database_credentials();
    $redirect_uri = urlencode_deep( admin_url( 'options-general.php?page=pws-zoho-api' ) );
    // https://developer.wordpress.org/reference/functions/apply_filters/
    return apply_filters( 'pws_zoho_get_config', array(
    'client_id' => $client_id,
    'client_secret' => $client_secret,
    'redirect_uri' => $redirect_uri,
    'host_address' => $db_creds['host'],
    'db_port' => $db_creds['port'],
    'db_username' => $db_creds['username'],
    'db_password' => $db_creds['password'],
    'currentUserEmail' => 'email.address.redacted@example.com',
    ) );

    }

    $linked = pws_zoho_get_option( 'pws_zoho_app_linked' );

    // If we need to get an OAUTH Token
    // $_GET['state'] is set by the JavaScript for the oAuth2 Popup
    // $_GET['page'] is set properly by our redirect_uri
    if ( isset( $_GET['code'] ) &&
    isset( $_GET['state'] ) &&
    $_GET['state'] == 'saving' &&
    isset( $_GET['page'] ) &&
    $_GET['page'] == 'pws-zoho-api' &&
    ( ! $linked || $linked == '-1' ) ) {

    $configuration = pws_zoho_get_config();
    $notices = (array) get_transient( 'pws_zoho_api_admin_notice' );

    ZohoOAuth::initialize( $configuration );
    $oAuthClient = ZohoOAuth::getClientInstance();

    // This saves both Access and Refresh Tokens to the custom Database
    $oAuthTokens = $oAuthClient->generateAccessToken( $_GET['code'] );

    if ( ! is_a( $oAuthTokens, 'ZohoOAuthException' ) ) {

    pws_zoho_update_option( 'pws_zoho_app_linked', true );
    pws_zoho_update_option( 'pws_zoho_refresh_token', $oAuthTokens->getRefreshToken() );

    set_transient( 'pws_zoho_api_admin_notice', array_merge( $notices, array( array(
    'pws-zoho-api',
    'pws_zoho_api_link_successful',
    __( 'Zoho App Linked Successfully.', 'pws-zoho-api-plugin' ),
    'updated'
    ) ) ) );

    }
    else {

    set_transient( 'pws_zoho_api_admin_notice', array_merge( $notices, array( array(
    'pws-zoho-api',
    'pws_zoho_api_link_failure',
    __( 'Zoho App Failed to Link', 'pws-zoho-api-plugin' ),
    'error'
    ) ) ) );

    }

    wp_redirect( admin_url( 'options-general.php?page=pws-zoho-api' ) );

    }

Here is the simple code I'm running to attempt to test this

  1. use zcrmsdk\crm\crud\ZCRMRecord;
    use zcrmsdk\crm\setup\restclient\ZCRMRestClient;
    function
    pws_zoho_get_record( $record_id = null, $module_api_name = 'pws_website' ) {

    $config = pws_zoho_get_config();
    ZCRMRestClient::initialize( $config );

    return ZCRMRESTClient::getInstance()->getRecordInstance( $module_api_name, $record_id );

    }

    $record = pws_zoho_get_record();
    $record->setFieldValue( 'test', 'yo' );
    $record->create();