-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Soap Auth Client and fix issues with dates and composite collecti…
…on requests and responses (#8)
1 parent
12884bb
commit 441aafb
Showing
20 changed files
with
426 additions
and
194 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
/** | ||
* Created by PhpStorm. | ||
* User: alex.boyce | ||
* Date: 9/27/18 | ||
* Time: 6:02 PM | ||
*/ | ||
|
||
namespace AE\SalesforceRestSdk\Tests\AuthProvider; | ||
|
||
use AE\SalesforceRestSdk\AuthProvider\SoapProvider; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
class SoapAuthProviderTest extends TestCase | ||
{ | ||
public function testReauthorize() | ||
{ | ||
$auth = new SoapProvider( | ||
getenv("SF_USER"), | ||
getenv("SF_PASS"), | ||
getenv("SF_LOGIN_URL") | ||
); | ||
|
||
$header = $auth->authorize(); | ||
|
||
$this->assertNotNull($header); | ||
$this->assertNotNull($auth->getToken()); | ||
$this->assertNotNull($auth->getInstanceUrl()); | ||
|
||
$class = new \ReflectionClass(SoapProvider::class); | ||
|
||
$tokenProperty = $class->getProperty('token'); | ||
$tokenProperty->setAccessible(true); | ||
$tokenProperty->setValue($auth, 'BAD_VALUE'); | ||
|
||
$header = $auth->reauthorize(); | ||
|
||
$this->assertNotNull($header); | ||
$this->assertNotNull($auth->getToken()); | ||
$this->assertNotNull($auth->getInstanceUrl()); | ||
$this->assertEquals('Bearer', $auth->getTokenType()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
<?php | ||
/** | ||
* Created by PhpStorm. | ||
* User: alex.boyce | ||
* Date: 9/6/18 | ||
* Time: 3:27 PM | ||
*/ | ||
|
||
namespace AE\SalesforceRestSdk\AuthProvider; | ||
|
||
use GuzzleHttp\Client; | ||
|
||
class OAuthProvider implements AuthProviderInterface | ||
{ | ||
/** | ||
* @var bool | ||
*/ | ||
private $isAuthorized = false; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $token; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $tokenType; | ||
|
||
/** | ||
* @var Client | ||
*/ | ||
private $httpClient; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $username; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $password; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $clientId; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $clientSecret; | ||
|
||
/** | ||
* @var null|string | ||
*/ | ||
private $instanceUrl; | ||
|
||
public function __construct(string $clientId, string $clientSecret, string $username, string $password, string $url) | ||
{ | ||
$this->clientId = $clientId; | ||
$this->clientSecret = $clientSecret; | ||
$this->username = $username; | ||
$this->password = $password; | ||
|
||
$this->httpClient = new Client( | ||
[ | ||
'base_uri' => $url, | ||
] | ||
); | ||
} | ||
|
||
/** | ||
* @param bool $reauth | ||
* | ||
* @throws SessionExpiredOrInvalidException | ||
* @return string | ||
*/ | ||
public function authorize($reauth = false): string | ||
{ | ||
if (!$reauth && $this->isAuthorized && strlen($this->token) > 0) { | ||
return "{$this->tokenType} {$this->token}"; | ||
} | ||
|
||
$response = $this->httpClient->post( | ||
'/services/oauth2/token', | ||
[ | ||
'form_params' => [ | ||
'grant_type' => 'password', | ||
'client_id' => $this->clientId, | ||
'client_secret' => $this->clientSecret, | ||
'username' => $this->username, | ||
'password' => $this->password, | ||
], | ||
'headers' => [ | ||
'Content-Type' => 'application/x-www-form-urlencoded', | ||
'Accept' => 'application/json', | ||
], | ||
] | ||
); | ||
|
||
$body = (string)$response->getBody(); | ||
$parts = json_decode($body, true); | ||
|
||
if (401 === $response->getStatusCode()) { | ||
throw new SessionExpiredOrInvalidException($parts['message'], $parts['errorCode']); | ||
} | ||
|
||
$this->tokenType = $parts['token_type']; | ||
$this->token = $parts['access_token']; | ||
$this->instanceUrl = $parts['instance_url']; | ||
|
||
$this->isAuthorized = true; | ||
|
||
return "{$this->tokenType} {$this->token}"; | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function reauthorize(): string | ||
{ | ||
return $this->authorize(true); | ||
} | ||
|
||
|
||
public function revoke(): void | ||
{ | ||
$this->token = null; | ||
$this->tokenType = null; | ||
$this->isAuthorized = false; | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function getToken(): ?string | ||
{ | ||
return $this->token; | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function getTokenType(): ?string | ||
{ | ||
return $this->tokenType; | ||
} | ||
|
||
/** | ||
* @return bool | ||
*/ | ||
public function isAuthorized(): bool | ||
{ | ||
return $this->isAuthorized; | ||
} | ||
|
||
/** | ||
* @return null|string | ||
*/ | ||
public function getInstanceUrl(): ?string | ||
{ | ||
return $this->instanceUrl; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
<?php | ||
/** | ||
* Created by PhpStorm. | ||
* User: alex.boyce | ||
* Date: 10/23/18 | ||
* Time: 9:08 AM | ||
*/ | ||
|
||
namespace AE\SalesforceRestSdk\AuthProvider; | ||
|
||
use GuzzleHttp\Client; | ||
use GuzzleHttp\Exception\RequestException; | ||
|
||
class SoapProvider implements AuthProviderInterface | ||
{ | ||
public const VERSION = "44.0"; | ||
/** | ||
* @var bool | ||
*/ | ||
private $isAuthorized = false; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $token; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $tokenType = 'Bearer'; | ||
|
||
/** | ||
* @var Client | ||
*/ | ||
private $httpClient; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $username; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $password; | ||
|
||
/** | ||
* @var null|string | ||
*/ | ||
private $instanceUrl; | ||
|
||
public function __construct(string $username, string $password, string $url = 'https://login.salesforce.com/') | ||
{ | ||
$this->username = $username; | ||
$this->password = $password; | ||
$this->httpClient = new Client( | ||
[ | ||
'base_uri' => $url, | ||
'headers' => [ | ||
'Content-Type' => 'text/xml', | ||
'SOAPAction' => '""', | ||
], | ||
] | ||
); | ||
} | ||
|
||
public function authorize($reauth = false) | ||
{ | ||
if (!$reauth && $this->isAuthorized && strlen($this->token) > 0) { | ||
return "{$this->tokenType} {$this->token}"; | ||
} | ||
|
||
$body | ||
= "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"> | ||
<soapenv:Body> | ||
<login xmlns=\"urn:partner.soap.sforce.com\"> | ||
<username>{$this->username}</username> | ||
<password>{$this->password}</password> | ||
</login> | ||
</soapenv:Body> | ||
</soapenv:Envelope>"; | ||
|
||
try { | ||
$response = $this->httpClient->post( | ||
'/services/Soap/u/'.self::VERSION, | ||
[ | ||
'body' => $body, | ||
] | ||
); | ||
|
||
$soapBody = (string)$response->getBody(); | ||
|
||
$matches = []; | ||
if (false != preg_match( | ||
'/<serverUrl>(?<serverUrl>.*?)<\/serverUrl>.*?<sessionId>(?<sessionId>.*?)<\/sessionId>/', | ||
$soapBody, | ||
$matches | ||
)) { | ||
$this->instanceUrl = $matches['serverUrl']; | ||
$this->token = $matches['sessionId']; | ||
} else { | ||
throw new SessionExpiredOrInvalidException("Failed to login to Salesforce.", "INVALID_CREDENTIALS"); | ||
} | ||
|
||
return "{$this->tokenType} {$this->token}"; | ||
} catch (RequestException $e) { | ||
$response = $e->getResponse(); | ||
$body = (string) $response->getBody(); | ||
throw new SessionExpiredOrInvalidException( | ||
"Failed to authenticate with Salesforce.", | ||
"INVALID_CREDENTIALS" | ||
); | ||
} | ||
} | ||
|
||
public function reauthorize() | ||
{ | ||
return $this->authorize(true); | ||
} | ||
|
||
public function revoke(): void | ||
{ | ||
$this->token = null; | ||
$this->isAuthorized = false; | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function getToken(): ?string | ||
{ | ||
return $this->token; | ||
} | ||
|
||
/** | ||
* @return string | ||
*/ | ||
public function getTokenType(): ?string | ||
{ | ||
return $this->tokenType; | ||
} | ||
|
||
/** | ||
* @return bool | ||
*/ | ||
public function isAuthorized(): bool | ||
{ | ||
return $this->isAuthorized; | ||
} | ||
|
||
/** | ||
* @return null|string | ||
*/ | ||
public function getInstanceUrl(): ?string | ||
{ | ||
return $this->instanceUrl; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters