diff --git a/composer.json b/composer.json
index e9125efe..f9ef87e4 100644
--- a/composer.json
+++ b/composer.json
@@ -35,7 +35,8 @@
"scripts": {
"test": "SHELL_INTERACTIVE=1 vendor/bin/phpunit --colors=always --verbose ",
"test-ci": "vendor/bin/phpunit --coverage-text --coverage-clover=build/coverage.xml",
- "phpcs": "SHELL_INTERACTIVE=1 ./vendor/bin/phpcs --standard=phpcs-ruleset.xml -s",
+ "phpcs": "./vendor/bin/phpcs --standard=phpcs-ruleset.xml -s .",
+ "phpcs-path": "SHELL_INTERACTIVE=1 ./vendor/bin/phpcs --standard=phpcs-ruleset.xml -s",
"phpcbf": "./vendor/bin/phpcbf --standard=phpcs-ruleset.xml .",
"phpcbf-path": "SHELL_INTERACTIVE=1 ./vendor/bin/phpcbf --standard=phpcs-ruleset.xml",
"sniffs": "./vendor/bin/phpcs --standard=phpcs-ruleset.xml -e"
diff --git a/phpcs-ruleset.xml b/phpcs-ruleset.xml
index 63f17085..6ff94bb0 100644
--- a/phpcs-ruleset.xml
+++ b/phpcs-ruleset.xml
@@ -61,10 +61,12 @@
+
+
@@ -75,7 +77,10 @@
-
+
+
+
+
diff --git a/src/API/Management/ClientGrants.php b/src/API/Management/ClientGrants.php
index f551cdbe..25b6a319 100644
--- a/src/API/Management/ClientGrants.php
+++ b/src/API/Management/ClientGrants.php
@@ -2,75 +2,193 @@
namespace Auth0\SDK\API\Management;
-use Auth0\SDK\API\Header\ContentType;
+use Auth0\SDK\Exception\CoreException;
+/**
+ * Class ClientGrants.
+ * Handles requests to the Client Grants endpoint of the v2 Management API.
+ *
+ * @package Auth0\SDK\API\Management
+ */
class ClientGrants extends GenericResource
{
+
/**
+ * Get all Client Grants, by page if desired.
+ * Required scope: "read:client_grants"
+ *
+ * @param array $params Additional URL parameters to send:
+ * - "audience" to filter be a specific API audience identifier.
+ * - "client_id" to return an object.
+ * - "include_totals" to return an object.
+ * @param null|integer $page The page number, zero based.
+ * @param null|integer $per_page The amount of entries per page.
*
- * @param string $id
- * @param null|string $audience
* @return mixed
+ *
+ * @throws \Exception Thrown by the Guzzle HTTP client when there is a problem with the API call.
+ *
+ * @link https://auth0.com/docs/api/management/v2#!/Client_Grants/get_client_grants
*/
- public function get($id, $audience = null)
+ public function getAll(array $params = [], $page = null, $per_page = null)
{
- $request = $this->apiClient->get()
- ->addPath('client-grants');
+ if (null !== $page) {
+ $params['page'] = abs(intval($page));
+ }
- if ($audience !== null) {
- $request = $request->withParam('audience', $audience);
+ if (null !== $per_page) {
+ $params['per_page'] = abs(intval($per_page));
}
- return $request->call();
+ return $this->apiClient->method('get')
+ ->addPath('client-grants')
+ ->withDictParams($params)
+ ->call();
+ }
+
+ /**
+ * Get Client Grants by audience.
+ * Required scope: "read:client_grants"
+ *
+ * @param string $audience API Audience to filter by.
+ * @param null|integer $page The page number, zero based.
+ * @param null|integer $per_page The amount of entries per page.
+ *
+ * @return mixed
+ *
+ * @throws CoreException Thrown when $audience is empty or not a string.
+ * @throws \Exception Thrown by the Guzzle HTTP client when there is a problem with the API call.
+ *
+ * @link https://auth0.com/docs/api/management/v2#!/Client_Grants/get_client_grants
+ */
+ public function getByAudience($audience, $page = null, $per_page = null)
+ {
+ if (empty($audience) || ! is_string($audience)) {
+ throw new CoreException('Empty or invalid "audience" parameter.');
+ }
+
+ return $this->getAll(['audience' => $audience], $page, $per_page);
+ }
+
+ /**
+ * Get Client Grants by Client ID.
+ * Required scope: "read:client_grants"
+ *
+ * @param string $client_id Client ID to filter by.
+ * @param null|integer $page The page number, zero based.
+ * @param null|integer $per_page The amount of entries per page.
+ *
+ * @return mixed
+ *
+ * @throws CoreException Thrown when $client_id is empty or not a string.
+ * @throws \Exception Thrown by the Guzzle HTTP client when there is a problem with the API call.
+ *
+ * @link https://auth0.com/docs/api/management/v2#!/Client_Grants/get_client_grants
+ */
+ public function getByClientId($client_id, $page = null, $per_page = null)
+ {
+ if (empty($client_id) || ! is_string($client_id)) {
+ throw new CoreException('Empty or invalid "client_id" parameter.');
+ }
+
+ return $this->getAll(['client_id' => $client_id], $page, $per_page);
+ }
+
+ /**
+ * Create a new Client Grant.
+ * Required scope: "create:client_grants"
+ *
+ * @param string $client_id Client ID to receive the grant.
+ * @param string $audience Audience identifier for the API being granted.
+ * @param array $scope Array of scopes for the grant.
+ *
+ * @return mixed
+ *
+ * @throws CoreException Thrown when $client_id or $audience are empty or not a string.
+ * @throws \Exception Thrown by the Guzzle HTTP client when there is a problem with the API call.
+ *
+ * @link https://auth0.com/docs/api/management/v2#!/Client_Grants/post_client_grants
+ */
+ public function create($client_id, $audience, array $scope = [])
+ {
+ if (empty($client_id) || ! is_string($client_id)) {
+ throw new CoreException('Empty or invalid "client_id" parameter.');
+ }
+
+ if (empty($audience) || ! is_string($audience)) {
+ throw new CoreException('Empty or invalid "audience" parameter.');
+ }
+
+ return $this->apiClient->method('post')
+ ->addPath('client-grants')
+ ->withBody(json_encode([
+ 'client_id' => $client_id,
+ 'audience' => $audience,
+ 'scope' => $scope,
+ ]))
+ ->call();
}
/**
+ * Delete a Client Grant by ID.
+ * Required scope: "delete:client_grants"
+ *
+ * @param string $id Client Grant ID to delete.
*
- * @param string $client_id
- * @param string $audience
- * @param string $scope
* @return mixed
+ *
+ * @throws \Exception Thrown by the Guzzle HTTP client when there is a problem with the API call.
+ *
+ * @link https://auth0.com/docs/api/management/v2#!/Client_Grants/delete_client_grants_by_id
*/
- public function create($client_id, $audience, $scope)
+ public function delete($id)
{
- return $this->apiClient->post()
- ->addPath('client-grants')
- ->withHeader(new ContentType('application/json'))
- ->withBody(json_encode([
- 'client_id' => $client_id,
- 'audience' => $audience,
- 'scope' => $scope,
- ]))
- ->call();
+ return $this->apiClient->method('delete')
+ ->addPath('client-grants', $id)
+ ->call();
}
/**
+ * Update an existing Client Grant.
+ * Required scope: "update:client_grants"
+ *
+ * @param string $id Client Grant ID to update.
+ * @param array $scope Array of scopes to update; will replace existing scopes, not merge.
*
- * @param string $id
- * @param null|string $audience
* @return mixed
+ *
+ * @throws \Exception Thrown by the Guzzle HTTP client when there is a problem with the API call.
+ *
+ * @link https://auth0.com/docs/api/management/v2#!/Client_Grants/patch_client_grants_by_id
*/
- public function delete($id, $audience = null)
+ public function update($id, array $scope)
{
- return $this->apiClient->delete()
- ->addPath('client-grants', $id)
- ->call();
+ return $this->apiClient->method('patch')
+ ->addPath('client-grants', $id)
+ ->withBody(json_encode(['scope' => $scope,]))
+ ->call();
}
/**
+ * Get a Client Grant.
+ * TODO: Deprecate, cannot get a Client Grant by ID.
+ *
+ * @param string $id Client Grant ID.
+ * @param null|string $audience Client Grant audience to filter by.
*
- * @param string $id
- * @param string $scope
* @return mixed
+ *
+ * @throws \Exception Thrown by the Guzzle HTTP client when there is a problem with the API call.
*/
- public function update($id, $scope)
+ public function get($id, $audience = null)
{
- return $this->apiClient->patch()
- ->addPath('client-grants', $id)
- ->withHeader(new ContentType('application/json'))
- ->withBody(json_encode([
- 'scope' => $scope,
- ]))
- ->call();
+ $request = $this->apiClient->get()
+ ->addPath('client-grants');
+
+ if ($audience !== null) {
+ $request = $request->withParam('audience', $audience);
+ }
+
+ return $request->call();
}
}
diff --git a/tests/API/ApiTests.php b/tests/API/ApiTests.php
index 70b41683..19d5b2cf 100644
--- a/tests/API/ApiTests.php
+++ b/tests/API/ApiTests.php
@@ -2,11 +2,18 @@
namespace Auth0\Tests\API;
use Auth0\SDK\API\Helpers\TokenGenerator;
+use Auth0\SDK\API\Management;
use josegonzalez\Dotenv\Loader;
class ApiTests extends \PHPUnit_Framework_TestCase
{
+ /**
+ *
+ * @var array
+ */
+ protected static $env = [];
+
protected function getEnv()
{
return self::getEnvStatic();
@@ -46,4 +53,33 @@ protected static function getTokenStatic($env, $scopes)
);
return $generator->generate($scopes);
}
+
+ /**
+ * Return an API client used during self::setUpBeforeClass().
+ *
+ * @param string $endpoint Endpoint name used for token generation.
+ * @param array $actions Actions required for token generation.
+ *
+ * @return mixed
+ */
+ protected static function getApiStatic($endpoint, array $actions)
+ {
+ self::$env = self::getEnvStatic();
+ $token = self::getTokenStatic(self::$env, [$endpoint => ['actions' => $actions]]);
+ $api_client = new Management($token, self::$env['DOMAIN']);
+ return $api_client->$endpoint;
+ }
+
+ /**
+ * Does an error message contain a specific string?
+ *
+ * @param \Exception $e - Error object.
+ * @param string $str - String to find in the error message.
+ *
+ * @return boolean
+ */
+ protected function errorHasString(\Exception $e, $str)
+ {
+ return ! (false === strpos($e->getMessage(), $str));
+ }
}
diff --git a/tests/API/BasicCrudTest.php b/tests/API/BasicCrudTest.php
index 25376493..fe77fb93 100644
--- a/tests/API/BasicCrudTest.php
+++ b/tests/API/BasicCrudTest.php
@@ -12,13 +12,6 @@ abstract class BasicCrudTest extends ApiTests
*/
protected $domain;
- /**
- * Environment variables, generated in self::__construct().
- *
- * @var array
- */
- protected $env;
-
/**
* API client to test.
*
@@ -93,8 +86,8 @@ abstract protected function afterUpdate($updated_entity);
public function __construct()
{
parent::__construct();
- $this->env = $this->getEnv();
- $this->domain = $this->env['DOMAIN'];
+ self::$env = $this->getEnv();
+ $this->domain = self::$env['DOMAIN'];
$this->api = $this->getApiClient();
$this->rand = rand();
}
@@ -122,19 +115,6 @@ protected function getId($entity)
return $entity[$this->id_name];
}
- /**
- * Does an error message contain a specific string?
- *
- * @param \Exception $e - Error object.
- * @param string $str - String to find in the error message.
- *
- * @return boolean
- */
- protected function errorHasString(\Exception $e, $str)
- {
- return ! (false === strpos($e->getMessage(), $str));
- }
-
/**
* Check that HTTP options have been set correctly.
*/
diff --git a/tests/API/Management/AuthApiTest.php b/tests/API/Management/AuthApiTest.php
index 7dbed183..f4131153 100644
--- a/tests/API/Management/AuthApiTest.php
+++ b/tests/API/Management/AuthApiTest.php
@@ -59,7 +59,7 @@ public function testOauthToken()
$token = $api->client_credentials(
[
- 'audience' => 'tests'
+ 'audience' => 'https://'.$env['DOMAIN'].'/api/v2/'
]
);
diff --git a/tests/API/Management/ClientGrantsTest.php b/tests/API/Management/ClientGrantsTest.php
new file mode 100644
index 00000000..e33f2c48
--- /dev/null
+++ b/tests/API/Management/ClientGrantsTest.php
@@ -0,0 +1,173 @@
+getAll();
+ $this->assertNotEmpty($all_results);
+
+ $expected_client_id = $all_results[0]['client_id'] ?: null;
+ $this->assertNotNull($expected_client_id);
+
+ $expected_audience = $all_results[0]['audience'] ?: null;
+ $this->assertNotNull($expected_audience);
+
+ $audience_results = self::$api->getByAudience($expected_audience);
+ $this->assertNotEmpty($audience_results);
+ $this->assertEquals($expected_audience, $audience_results[0]['audience']);
+
+ $client_id_results = self::$api->getByClientId($expected_client_id);
+ $this->assertNotEmpty($client_id_results);
+ $this->assertEquals($expected_client_id, $client_id_results[0]['client_id']);
+ }
+
+ /**
+ * Test that pagination parameters are passed to the endpoint.
+ *
+ * @return void
+ *
+ * @throws \Exception Thrown by the Guzzle HTTP client when there is a problem with the API call.
+ */
+ public function testGetWithPagination()
+ {
+ $expected_count = 2;
+
+ $results_1 = self::$api->getAll([], 0, $expected_count);
+ $this->assertCount($expected_count, $results_1);
+
+ $expected_page = 1;
+ $results_2 = self::$api->getAll([], $expected_page, 1);
+ $this->assertCount(1, $results_2);
+ $this->assertEquals($results_1[$expected_page]['client_id'], $results_2[0]['client_id']);
+ $this->assertEquals($results_1[$expected_page]['audience'], $results_2[0]['audience']);
+ }
+
+ /**
+ * Test that the "include_totals" parameter works.
+ *
+ * @return void
+ *
+ * @throws \Exception Thrown by the Guzzle HTTP client when there is a problem with the API call.
+ */
+ public function testGetAllIncludeTotals()
+ {
+ $expected_page = 1;
+ $expected_count = 2;
+
+ $results = self::$api->getAll(['include_totals' => true], $expected_page, $expected_count);
+ $this->assertArrayHasKey('total', $results);
+ $this->assertEquals($expected_page * $expected_count, $results['start']);
+ $this->assertEquals($expected_count, $results['limit']);
+ $this->assertNotEmpty($results['client_grants']);
+ }
+
+ /**
+ * Test that we can create, update, and delete a Client Grant.
+ *
+ * @return void
+ *
+ * @throws CoreException Thrown when there is a problem with parameters passed to the method.
+ * @throws \Exception Thrown by the Guzzle HTTP client when there is a problem with the API call.
+ */
+ public function testCreateUpdateDeleteGrant()
+ {
+ $client_id = self::$env['APP_CLIENT_ID'];
+ $audience = self::TESTS_API_AUDIENCE;
+
+ // Create a Client Grant with just one of the testing scopes.
+ $create_result = self::$api->create($client_id, $audience, [self::$scopes[0]]);
+ $this->assertArrayHasKey('id', $create_result);
+ $this->assertEquals($client_id, $create_result['client_id']);
+ $this->assertEquals($audience, $create_result['audience']);
+ $this->assertEquals([self::$scopes[0]], $create_result['scope']);
+
+ $grant_id = $create_result['id'];
+
+ // Test patching the created Client Grant.
+ $update_result = self::$api->update($grant_id, self::$scopes);
+ $this->assertEquals(self::$scopes, $update_result['scope']);
+
+ // Test deleting the created Client Grant.
+ $delete_result = self::$api->delete($grant_id);
+ $this->assertNull($delete_result);
+ }
+
+ /**
+ * Test that create method throws errors correctly.
+ *
+ * @return void
+ *
+ * @throws \Exception Thrown by the Guzzle HTTP client when there is a problem with the API call.
+ */
+ public function testCreateGrantExceptions()
+ {
+ $throws_missing_client_id_exception = false;
+ try {
+ self::$api->create('', self::TESTS_API_AUDIENCE, []);
+ } catch (CoreException $e) {
+ $throws_missing_client_id_exception = $this->errorHasString($e, 'Empty or invalid "client_id" parameter');
+ }
+
+ $this->assertTrue($throws_missing_client_id_exception);
+
+ $throws_missing_audience_exception = false;
+ try {
+ self::$api->create(self::$env['APP_CLIENT_ID'], '', []);
+ } catch (CoreException $e) {
+ $throws_missing_audience_exception = $this->errorHasString($e, 'Empty or invalid "audience" parameter');
+ }
+
+ $this->assertTrue($throws_missing_audience_exception);
+ }
+}
diff --git a/tests/API/Management/ClientsTest.php b/tests/API/Management/ClientsTest.php
index 6981742c..04720986 100644
--- a/tests/API/Management/ClientsTest.php
+++ b/tests/API/Management/ClientsTest.php
@@ -26,7 +26,7 @@ class ClientsTest extends BasicCrudTest
*/
protected function getApiClient()
{
- $token = $this->getToken($this->env, [ 'clients' => [ 'actions' => ['create', 'read', 'delete', 'update' ] ] ]);
+ $token = $this->getToken(self::$env, [ 'clients' => [ 'actions' => ['create', 'read', 'delete', 'update' ] ] ]);
$api = new Management($token, $this->domain);
return $api->clients;
}
diff --git a/tests/API/Management/ConnectionsTest.php b/tests/API/Management/ConnectionsTest.php
index 353a407d..16eff94e 100644
--- a/tests/API/Management/ConnectionsTest.php
+++ b/tests/API/Management/ConnectionsTest.php
@@ -27,7 +27,7 @@ class ConnectionsTest extends BasicCrudTest
protected function getApiClient()
{
$token = $this->getToken(
- $this->env, [
+ self::$env, [
'connections' => ['actions' => ['create', 'read', 'delete', 'update']],
'users' => ['actions' => ['delete']],
]
diff --git a/tests/API/Management/LogsTest.php b/tests/API/Management/LogsTest.php
index d5aa5a72..ce72d185 100644
--- a/tests/API/Management/LogsTest.php
+++ b/tests/API/Management/LogsTest.php
@@ -65,7 +65,7 @@ public function testLogSearchAndGetById()
public function testLogSearchPagination()
{
$expected_count = 5;
- $search_results= self::$api->search([
+ $search_results = self::$api->search([
// Fields here to speed up API call.
'fields' => '_id,log_id',
'include_fields' => true,
diff --git a/tests/API/Management/UsersTest.php b/tests/API/Management/UsersTest.php
index cee5c2e3..4fbafcfd 100644
--- a/tests/API/Management/UsersTest.php
+++ b/tests/API/Management/UsersTest.php
@@ -40,7 +40,7 @@ class UsersTest extends BasicCrudTest
*/
protected function getApiClient()
{
- $token = $this->getToken($this->env, ['users' => ['actions' => ['create', 'read', 'delete', 'update']]]);
+ $token = $this->getToken(self::$env, ['users' => ['actions' => ['create', 'read', 'delete', 'update']]]);
$api = new Management($token, $this->domain);
return $api->users;
}