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

OAuth2 support #205

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
60 changes: 58 additions & 2 deletions QuickBooks/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -1435,8 +1435,64 @@ public function oauthRequestResolve($token)
}

abstract protected function _oauthRequestResolve($token);

/**

/**
* OAuth2 functions
*/

public function oauth2Load($key, $app_username, $app_tenant)
{
if ($data = $this->_oauth2Load($app_username, $app_tenant))
{
if (!empty($data['oauth2_access_token']))
{
if (strlen($key) > 0)
{
$AES = QuickBooks_Encryption_Factory::create('aes');

$data['oauth2_access_token'] = $AES->decrypt($key, $data['oauth2_access_token']);
$data['oauth2_refresh_token'] = $AES->decrypt($key, $data['oauth2_refresh_token']);
}
}

return $data;
}

return false;
}

abstract protected function _oauth2Load($app_username, $app_tenant);

public function oauth2AccessWrite($key, $app_username, $app_tenant, $access_token, $refresh_token, $access_token_expire, $refresh_token_expire, $realm, $flavor = '')
{
if (strlen($key) > 0)
{
$AES = QuickBooks_Encryption_Factory::create('aes');

$encrypted_access_token = $AES->encrypt($key, $access_token);
$encrypted_refresh_token = $AES->encrypt($key, $refresh_token);
}
else
{
$encrypted_access_token = $access_token;
$encrypted_refresh_token = $refresh_token;
}

return $this->_oauth2AccessWrite($app_username, $app_tenant, $encrypted_access_token, $encrypted_refresh_token, $access_token_expire, $refresh_token_expire, $realm, $flavor);
}

abstract protected function _oauth2AccessWrite($app_username, $app_tenant, $access_token, $refresh_token, $access_token_expire, $refresh_token_expire, $realm, $flavor = '');

public function oauth2AccessDelete($app_username, $app_tenant)
{
return $this->_oauth2AccessDelete($app_username, $app_tenant);
}

abstract protected function _oauth2AccessDelete($app_username, $app_tenant);

abstract protected function _oauth2RequestResolve($app_username, $app_tenant);

/**
* Log a message to the QuickBooks log
*
* @param string $msg The message to place in the log
Expand Down
138 changes: 137 additions & 1 deletion QuickBooks/Driver/Sql.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,12 @@
*/
define('QUICKBOOKS_DRIVER_SQL_OAUTHTABLE', 'oauth');

/**
* Default table for OAuth2 stuff
* @var string
*/
define('QUICKBOOKS_DRIVER_SQL_OAUTH2TABLE', 'oauth2');

/**
*
*
Expand Down Expand Up @@ -2199,7 +2205,7 @@ protected function _oauthRequestWrite($app_username, $app_tenant, $token, $token
}
}

protected function _oauthAccessWrite($request_token, $token, $token_secret, $realm, $flavor)
protected function _oauthAccessWrite($request_token, $token, $token_secret, $realm, $flavor = '')
{
$errnum = 0;
$errmsg = '';
Expand Down Expand Up @@ -2257,6 +2263,114 @@ protected function _oauthAccessDelete($app_username, $app_tenant)
return $this->affected() > 0;
}

/** OAuth2 functions **/

protected function _oauth2Load($app_username, $app_tenant)
{
$errnum = 0;
$errmsg = '';

$tableName = $this->_mapTableName(QUICKBOOKS_DRIVER_SQL_OAUTH2TABLE);

if ($arr = $this->fetch($this->query("
SELECT
*
FROM
" . $tableName . "
WHERE
app_username = '%s' AND app_tenant = '%s' ", $errnum, $errmsg, null, null, array( $app_username, $app_tenant ))))
{
$this->query("
UPDATE
" . $tableName . "
SET
touch_datetime = '%s'
WHERE
app_username = '%s' AND app_tenant = '%s' ", $errnum, $errmsg, null, null, array( date('Y-m-d H:i:s'), $app_username, $app_tenant ));
}

return $arr;
}

protected function _oauth2AccessWrite($app_username, $app_tenant, $access_token, $refresh_token, $access_token_expire, $refresh_token_expire, $realm, $flavor = '')
{
$errnum = 0;
$errmsg = '';

// Check if it exists or not first
$vars = array($app_username, $app_tenant, $access_token, $refresh_token, $access_token_expire, $refresh_token_expire, $realm, date('Y-m-d H:i:s') );

$more = "";

if ($flavor)
{
$more .= ", qb_flavor = '%s' ";
$vars[] = $flavor;
}

$tableName = $this->_mapTableName(QUICKBOOKS_DRIVER_SQL_OAUTH2TABLE);

$query = "
SET
app_username = '%s',
app_tenant = '%s',
oauth2_access_token = '%s',
oauth2_refresh_token = '%s',
oauth2_access_token_expires = '%s',
oauth2_refresh_token_expires = '%s',
qb_realm = '%s',
access_datetime = '%s'
";
if (!$this->_oauth2RequestResolve($app_username, $app_tenant))
{
// Not exists... INSERT!
$query = "INSERT INTO " . $tableName . $query . $more;
}
else
{
// Exists... Update!
$vars[] = $app_username;
$vars[] = $app_tenant;

$query = "UPDATE " . $tableName . $query . $more . "
WHERE app_username = '%s'
AND app_tenant = '%s'
";
}

return $this->query($query, $errnum, $errmsg, null, null, $vars);
}

protected function _oauth2AccessDelete($app_username, $app_tenant)
{
$errnum = 0;
$errmsg = '';

// Exists... DELETE!
$this->query("
DELETE FROM
" . $this->_mapTableName(QUICKBOOKS_DRIVER_SQL_OAUTH2TABLE) . "
WHERE
app_username = '%s' AND
app_tenant = '%s' ", $errnum, $errmsg, null, null, array( $app_username, $app_tenant ));

return $this->affected() > 0;
}

protected function _oauth2RequestResolve($app_username, $app_tenant)
{
$errnum = 0;
$errmsg = '';

return $this->fetch($this->query("
SELECT
*
FROM
" . $this->_mapTableName(QUICKBOOKS_DRIVER_SQL_OAUTH2TABLE) . "
WHERE
app_username = '%s' AND app_tenant = '%s' ", $errnum, $errmsg, null, null, array( $app_username, $app_tenant )));
}

/**
* Write a message to the log file
*
Expand Down Expand Up @@ -3052,6 +3166,28 @@ protected function _initialize($init_options = array())
//print_r($arr_sql);
//exit;

$table = $this->_mapTableName(QUICKBOOKS_DRIVER_SQL_OAUTH2TABLE);
$def = array(
'quickbooks_oauth2_id' => array( QUICKBOOKS_DRIVER_SQL_SERIAL ),
'app_username' => array( QUICKBOOKS_DRIVER_SQL_VARCHAR, 255 ),
'app_tenant' => array( QUICKBOOKS_DRIVER_SQL_VARCHAR, 255 ),
'oauth2_access_token' => array( QUICKBOOKS_DRIVER_SQL_VARCHAR, 1024, 'null' ),
'oauth2_refresh_token' => array( QUICKBOOKS_DRIVER_SQL_VARCHAR, 1024, 'null' ),
'oauth2_access_token_expires' => array( QUICKBOOKS_DRIVER_SQL_DATETIME, null, 'null' ),
'oauth2_refresh_token_expires' => array( QUICKBOOKS_DRIVER_SQL_DATETIME, null, 'null' ),
'qb_realm' => array( QUICKBOOKS_DRIVER_SQL_VARCHAR, 32, 'null' ),
'qb_flavor' => array( QUICKBOOKS_DRIVER_SQL_VARCHAR, 12, 'null' ),
'qb_user' => array( QUICKBOOKS_DRIVER_SQL_VARCHAR, 64, 'null' ),
'request_datetime' => array( QUICKBOOKS_DRIVER_SQL_DATETIME ),
'access_datetime' => array( QUICKBOOKS_DRIVER_SQL_DATETIME, null, 'null' ),
'touch_datetime' => array( QUICKBOOKS_DRIVER_SQL_DATETIME, null, 'null' ),
);
$primary = 'quickbooks_oauth2_id';
$keys = array( );
$uniques = array( array( 'app_username', 'app_tenant' ) );

$arr_sql = array_merge($arr_sql, $this->_generateCreateTable($table, $def, $primary, $keys, $uniques));

// Support for mirroring the QuickBooks database in an SQL database
if ($config['quickbooks_sql_enabled'])
{
Expand Down
37 changes: 35 additions & 2 deletions QuickBooks/IPP.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
// OAuth
QuickBooks_Loader::load('/QuickBooks/IPP/OAuth.php');

// OAuth2
QuickBooks_Loader::load('/QuickBooks/IPP/OAuth2.php');

// IntuitAnywhere widgets
QuickBooks_Loader::load('/QuickBooks/IPP/IntuitAnywhere.php');

Expand Down Expand Up @@ -88,7 +91,8 @@ class QuickBooks_IPP
const API_GETENTITLEMENTVALUESANDUSERROLE = 'API_GetEntitlementValuesAndUserRole';

const AUTHMODE_FEDERATED = 'federated';
const AUTHMODE_OAUTH = 'oauth';
const AUTHMODE_OAUTH = 'oauth';
const AUTHMODE_OAUTH2 = 'oauth2';

/**
*
Expand Down Expand Up @@ -381,6 +385,11 @@ public function context($ticket = null, $token = null, $check_if_valid = true)

// @todo Support for checking if it's valid or not
}
elseif ($this->_authmode == QuickBooks_IPP::AUTHMODE_OAUTH2)
{
$Context = new QuickBooks_IPP_Context($this, null, $token);

}
else
{
if (is_null($ticket))
Expand Down Expand Up @@ -510,7 +519,7 @@ public function authcreds()
}

/**
* Set the authorization mode for HTTP requests (Federated, or OAuth)
* Set the authorization mode for HTTP requests (Federated, or OAuth, OAuth2)
*
* @param string $authmode The new auth mode
* @return string The currently set auth mode
Expand Down Expand Up @@ -1618,6 +1627,30 @@ protected function _request($Context, $type, $url, $action, $data, $post = true)
}
}
}
elseif ($this->_authmode == QuickBooks_IPP::AUTHMODE_OAUTH2)
{
// If we have credentials, sign the request
if ($this->_authcred['oauth2_access_token'] and
$this->_authcred['oauth2_refresh_token'])
{
// Sign the request
$OAuth = new QuickBooks_IPP_OAuth2($this->_authcred['oauth2_client_id'], $this->_authcred['oauth2_client_secret'], $this->_authcred['qb_realm'], $this->_authcred['oauth2_access_token'], $this->_authcred['oauth2_refresh_token']);

if ($post)
{
$action = QuickBooks_IPP_OAuth2::METHOD_POST;
}
else
{
$action = QuickBooks_IPP_OAuth2::METHOD_GET;
}

$sign = $OAuth->sign($action, $url);

// Always use the header, regardless of POST or GET
$headers['Authorization'] = $sign;
}
}
else if (is_object($Context))
{
// FEDERATED authentication
Expand Down
Loading