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

Feature oAuth2 #6

Merged
merged 11 commits into from
May 2, 2019
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ composer.phar
composer.lock
.DS_Store
Thumbs.db
.idea
.idea
phpunit.xml
46 changes: 25 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,22 +81,22 @@ php artisan route:list
You will notice that there are some test routes, which you can look at for examples. Once your environment is in `production` in your `.env` file these routes will no longer be available.

```php
_goto
_goto/webinars
_goto/webinars/all
_goto/webinars/create
_goto/webinars/webinarKey}/sessions/{sessionKey}/attendees/{registrantKey}/show
_goto/webinars/{webinarKey}/delete
_goto/webinars/{webinarKey}/registrants
_goto/webinars/{webinarKey}/registrants/create
_goto/webinars/{webinarKey}/registrants/{registrantKey}/delete
_goto/webinars/{webinarKey}/registrants/{registrantKey}/show
_goto/webinars/{webinarKey}/sessions
_goto/webinars/{webinarKey}/sessions/{sessionKey}/attendees
_goto/webinars/{webinarKey}/sessions/{sessionKey}/performance
_goto/webinars/{webinarKey}/sessions/{sessionKey}/show
_goto/webinars/{webinarKey}/show
_goto/webinars/{webinarKey}/update
_goto
_goto/webinars
_goto/webinars/all
_goto/webinars/create
_goto/webinars/webinarKey}/sessions/{sessionKey}/attendees/{registrantKey}/show
_goto/webinars/{webinarKey}/delete
_goto/webinars/{webinarKey}/registrants
_goto/webinars/{webinarKey}/registrants/create
_goto/webinars/{webinarKey}/registrants/{registrantKey}/delete
_goto/webinars/{webinarKey}/registrants/{registrantKey}/show
_goto/webinars/{webinarKey}/sessions
_goto/webinars/{webinarKey}/sessions/{sessionKey}/attendees
_goto/webinars/{webinarKey}/sessions/{sessionKey}/performance
_goto/webinars/{webinarKey}/sessions/{sessionKey}/show
_goto/webinars/{webinarKey}/show
_goto/webinars/{webinarKey}/update
```

## Authentication Token Caching
Expand All @@ -118,19 +118,19 @@ When using this package you'll notice it is closely aligned to the API documenta

### Examples

In the following location `vendor/slakbal/gotowebinar/src/routes` , there is a `routes.php` file with the above mentioned routes.
In the following location `vendor/slakbal/gotowebinar/src/routes` , there is a `routes.php` file with the above mentioned routes.

For example:

```php
//Some of the body parameters have defaults, but can be explicitly overridden.
$eventParams = [
$eventParams = [
//required
'subject' => 'XXXXX Test XXXXX*', //required
'description' => 'Test Description*', //required
'startTime' => Carbon::now()->addDays(2)->toW3cString(), //required eg "2016-03-23T19:00:00Z"
'endTime' => Carbon::now()->addDays(2)->addHour()->toW3cString(), //require eg "2016-03-23T20:00:00Z"

//optional with defaults
'timeZone' => 'Europe/Berlin', //if not given the default is: config('app.timezone') from framework config
'type' => 'single_session', //if not given the default is: single_session
Expand Down Expand Up @@ -176,14 +176,14 @@ $gotoResponse->webinarKey
## Exception Handling and Logging

When using the package methods it is recommended to call them within a `try`, `catch` block. For example:

```php
try {
$gotoResponse = GotoWebinar::createWebinar($eventParams);
} catch (GotoException $e) {
//do something, go somewhere or notifify someone
}
```
```

The package will automatically log most errors for you to the Laravel log file, so you don't need to log them again. For example:

Expand Down Expand Up @@ -389,6 +389,10 @@ Retrieve all collated attendee questions and answers for polls from a specific w
GotoWebinar::getSessionPolls($webinarKey, $sessionKey);
```

## Testing

For your installation, add your own `phpunit.xml` file to add to your environment

Your contribution or bug fixes are welcome!

Enjoy!
Expand Down
11 changes: 6 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
}
],
"require": {
"php": ">=7.0.0",
"php": ">=7.1.0",
"nategood/httpful": "^0.2",
"guzzlehttp/guzzle": "^6.1",
"illuminate/support": "~5"
"illuminate/support": "~5",
"guzzlehttp/guzzle": "~6.3",
"orchestra/testbench": "~3.7"
},
"require-dev": {
"phpunit/phpunit": "~6.0"
"phpunit/phpunit": "~7.0"
},
"autoload": {
"psr-4": {
Expand All @@ -30,7 +31,7 @@
},
"autoload-dev": {
"psr-4": {
"Slakbal\\Gotowebinar\\Test\\": "tests"
"Slakbal\\Gotowebinar\\Test\\": "tests/"
}
},
"extra": {
Expand Down
4 changes: 2 additions & 2 deletions config/goto.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
'username' => env('GOTO_DIRECT_USER', '[email protected]'),
'password' => env('GOTO_CONSUMER_SECRET', 'someSecret'),
'client_id' => env('GOTO_CONSUMER_KEY', 'someConsumerKey'),
'client_secret' => env('GOTO_CLIENT_SECRET', 'someConsumerSecret')
],

];
];
32 changes: 32 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
</whitelist>
</filter>
<php>
<env name="APP_ENV" value="testing"/>
<env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="MAIL_DRIVER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="GOTO_CONSUMER_KEY" value=""/>
<env name="GOTO_CONSUMER_SECRET" value=""/>
<env name="GOTO_DIRECT_USER" value=""/>
</php>
</phpunit>
10 changes: 4 additions & 6 deletions src/DirectLogin.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class DirectLogin

use GotoClient;

protected $path = 'oauth/access_token';
protected $path = 'oauth/v2/token';


public function authenticate()
Expand All @@ -22,10 +22,8 @@ private function getParameters()
{
return [
'grant_type' => "password",
'user_id' => config('goto.direct.username'),
'password' => config('goto.direct.password'),
'client_id' => config('goto.direct.client_id'),
'username' => config('goto.direct.username'),
'password' => config('goto.direct.password')
];
}

}
}
4 changes: 0 additions & 4 deletions src/Traits/AccessObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,10 @@ private function directLogin()
$directAuth = new DirectLogin();

try {

$this->authObject = $directAuth->authenticate(); //the method returns authObject

} catch (GotoAuthenticateException $e) {

$this->clearAccessObject(); //make sure the object is cleared from the cache to force a login retry
throw $e; //bubble the exception up by rethrowing

}

$this->rememberAccessObject($this->authObject); //cache the authObject
Expand Down
71 changes: 28 additions & 43 deletions src/Traits/GotoClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ trait GotoClient


//returns the body of the rest response
function sendRequest($verb, $path, $parameters = null, $payload = null)
public function sendRequest($verb, $path, $parameters = null, $payload = null)
{
$verb = strtoupper(trim($verb));

Expand Down Expand Up @@ -91,7 +91,7 @@ function sendRequest($verb, $path, $parameters = null, $payload = null)
}


function getUrl($baseUri, $path, $parameters = null)
public function getUrl($baseUri, $path, $parameters = null)
{
if (is_null($parameters)) {
return $this->getBasePath($baseUri, $path);
Expand All @@ -101,52 +101,51 @@ function getUrl($baseUri, $path, $parameters = null)
}


function getBasePath($baseUri, $path)
public function getBasePath($baseUri, $path)
{
return trim($baseUri, '/') . '/' . trim($path, '/');
}


function getPathRelativeToOrganizer($relativePathSection = null)
public function getPathRelativeToOrganizer($relativePathSection = null)
{
return sprintf('organizers/%s/', $this->getOrganizerKey()) . trim($relativePathSection, '/');
}


function getPathRelativeToAccount($relativePathSection = null)
public function getPathRelativeToAccount($relativePathSection = null)
{
return sprintf('accounts/%s/', $this->getAccountKey()) . trim($relativePathSection, '/');
}


function getAuthObject($path, $parameters = null)
public function getAuthObject($path, $parameters = null)
{
try {

$this->response = Request::get($this->getUrl($this->AUTH_uri, $path, $parameters))
->strictSSL($this->verify_ssl)
->addHeaders($this->determineHeaders())
->timeout($this->timeout)
->expectsJson()
->send();

$this->response = Request::post($this->getUrl($this->AUTH_uri, $path))
->strictSSL($this->verify_ssl)
->addHeaders($this->determineHeaders())
->timeout($this->timeout)
->body($parameters, 'form')
->expects('json')
->send();
} catch (\Exception $e) {

$this->throwResponseException('GET', $this->response, $e->getMessage());
$this->throwResponseException('POST', $this->response, $e->getMessage());
}

//the authObject is in the body of the response object
return $this->response->body;
}


private function determineHeaders()
{
//if the accessObject exist it means the API can probably authenticate by token, thus add it to the headers
if (cache()->has('GOTO_ACCESS_OBJECT')) {
$this->headers['Authorization'] = $this->getAccessToken();
} else {
$this->headers = [
'Authorization' => 'Basic ' . base64_encode(config('goto.direct.client_id') . ':' . config('goto.direct.client_secret'))
];
}

return $this->headers;
}

Expand All @@ -157,39 +156,28 @@ private function throwResponseException($verb, $response, $exceptionMessage = nu

($exceptionMessage) ? Log::error('GOTOWEBINAR: HTTP Exception: ' . $this->message . ' - ' . $exceptionMessage . ' Payload: ' . json_encode($response->payload)) : null;

if ($response->hasErrors()) {

if ($response->hasBody()) {

switch ($response->code) {

case Response::HTTP_CONFLICT:

Log::error('GOTOWEBINAR: ' . $verb . ' - ' . $this->message . ': ' . $response->body->description);
throw new GotoException($this->message . ' - ' . $response->body->description);
if ($response->hasErrors() && $response->hasBody()) {
switch ($response->code) {
case Response::HTTP_CONFLICT:
Log::error('GOTOWEBINAR: ' . $verb . ' - ' . $this->message . ': ' . $response->body->description);
throw new GotoException($this->message . ' - ' . $response->body->description);

break;

default:
break;

Log::error('GOTOWEBINAR: ' . $verb . ' - ' . $this->message . ': ' . $response->body->description);
throw new GotoException($this->message . ' - ' . $response->body->description);
}
default:
Log::error('GOTOWEBINAR: ' . $verb . ' - ' . $this->message . ': ' . $response->body->description);
throw new GotoException($this->message . ' - ' . $response->body->description);
}

}

throw new GotoException($this->message . ' - There was an error, make sure the API endpoint-url exist and if all the required data is given to the request');

}


private function getResponseMessage($responseCode)
{
return isset($responseCode) ? Response::$statusTexts[$responseCode] . ' (' . $responseCode . ')' : 'unknown status';
}


/**
* @param $response
*
Expand All @@ -200,13 +188,11 @@ private function processResultCode($verb, $response)
if ($response->code >= Response::HTTP_BAD_REQUEST) { //if any error range
$this->throwResponseException($verb, $response);
} else {

if (in_array($verb, [
'DELETE',
'UPDATE',
'PUT',
])) {

if (is_null($response->body) || empty($response->body)) {
return true; //return true if it was not an error and if the VERB was completed
}
Expand All @@ -215,5 +201,4 @@ private function processResultCode($verb, $response)

return $response->body;
}

}
}
5 changes: 1 addition & 4 deletions src/Webinar.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,10 @@

class Webinar extends GotoAbstract
{

use WebinarOperations, RegistrantOperations, SessionOperations, AttendeeOperations;


function __construct($authType = 'direct')
public function __construct($authType = 'direct')
{
parent::__construct($authType = 'direct');
}

}
Loading