Skip to content

Commit

Permalink
Merge branch 'master' into refactor_routes
Browse files Browse the repository at this point in the history
  • Loading branch information
crissi committed Jan 22, 2020
2 parents 7e981d2 + 1498647 commit ec54a79
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,9 @@ CHANGELOG
[Next release](https://github.com/rebing/graphql-laravel/compare/4.0.0...master)
--------------

### Added
- Add support for custom authorization message

2019-12-09, 4.0.0
-----------------
### Added
Expand Down
27 changes: 27 additions & 0 deletions Readme.md
Expand Up @@ -710,6 +710,33 @@ class UsersQuery extends Query
}
```

You can also provide a custom error message when the authorization fails (defaults to Unauthorized):

```php
use Auth;
use Closure;
use GraphQL\Type\Definition\ResolveInfo;

class UsersQuery extends Query
{
public function authorize($root, array $args, $ctx, ResolveInfo $resolveInfo = null, Closure $getSelectFields = null): bool
{
if (isset($args['id'])) {
return Auth::id() == $args['id'];
}

return true;
}

public function getAuthorizationMessage(): string
{
return 'You are not authorized to perform this action';
}

// ...
}
```

### Privacy

You can set custom privacy attributes for every Type's Field. If a field is not
Expand Down
7 changes: 6 additions & 1 deletion src/Support/Field.php
Expand Up @@ -210,7 +210,7 @@ protected function getResolver(): ?Closure

// Authorize
if (true != call_user_func_array($authorize, $arguments)) {
throw new AuthorizationError('Unauthorized');
throw new AuthorizationError($this->getAuthorizationMessage());
}

$method = new ReflectionMethod($this, 'resolve');
Expand Down Expand Up @@ -290,6 +290,11 @@ public function getAttributes(): array
return $attributes;
}

public function getAuthorizationMessage(): string
{
return 'Unauthorized';
}

/**
* Convert the Fluent instance to an array.
*
Expand Down
53 changes: 53 additions & 0 deletions tests/Support/Objects/ExamplesAuthorizeMessageQuery.php
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace Rebing\GraphQL\Tests\Support\Objects;

use Closure;
use GraphQL\Type\Definition\ResolveInfo;
use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Rebing\GraphQL\Support\Query;

class ExamplesAuthorizeMessageQuery extends Query
{
protected $attributes = [
'name' => 'Examples authorize query',
];

public function authorize($root, array $args, $ctx, ResolveInfo $resolveInfo = null, Closure $getSelectFields = null): bool
{
return false;
}

public function getAuthorizationMessage(): string
{
return 'You are not authorized to perform this action';
}

public function type(): Type
{
return Type::listOf(GraphQL::type('Example'));
}

public function args(): array
{
return [
'index' => ['name' => 'index', 'type' => Type::int()],
];
}

public function resolve($root, $args, $context, ResolveInfo $resolveInfo, Closure $getSelectFields)
{
$data = include __DIR__.'/data.php';

if (isset($args['index'])) {
return [
$data[$args['index']],
];
}

return $data;
}
}
8 changes: 8 additions & 0 deletions tests/Support/Objects/queries.php
Expand Up @@ -58,6 +58,14 @@
}
',

'examplesWithAuthorizeMessage' => '
query QueryExamplesAuthorizeMessage {
examplesAuthorizeMessage {
test
}
}
',

'examplesWithError' => '
query QueryExamplesWithError {
examplesQueryNotFound {
Expand Down
2 changes: 2 additions & 0 deletions tests/TestCase.php
Expand Up @@ -17,6 +17,7 @@
use Rebing\GraphQL\GraphQLServiceProvider;
use Rebing\GraphQL\Support\Facades\GraphQL;
use Rebing\GraphQL\Tests\Support\Objects\ExampleFilterInputType;
use Rebing\GraphQL\Tests\Support\Objects\ExamplesAuthorizeMessageQuery;
use Rebing\GraphQL\Tests\Support\Objects\ExamplesAuthorizeQuery;
use Rebing\GraphQL\Tests\Support\Objects\ExamplesConfigAliasQuery;
use Rebing\GraphQL\Tests\Support\Objects\ExamplesFilteredQuery;
Expand Down Expand Up @@ -53,6 +54,7 @@ protected function getEnvironmentSetUp($app)
'query' => [
'examples' => ExamplesQuery::class,
'examplesAuthorize' => ExamplesAuthorizeQuery::class,
'examplesAuthorizeMessage' => ExamplesAuthorizeMessageQuery::class,
'examplesPagination' => ExamplesPaginationQuery::class,
'examplesFiltered' => ExamplesFilteredQuery::class,
'examplesConfigAlias' => ExamplesConfigAliasQuery::class,
Expand Down
18 changes: 18 additions & 0 deletions tests/Unit/EndpointTest.php
Expand Up @@ -103,6 +103,24 @@ public function testGetUnauthorized(): void
$this->assertNull($content['data']['examplesAuthorize']);
}

/**
* Test get with unauthorized query and custom error message.
*/
public function testGetUnauthorizedWithCustomError(): void
{
$response = $this->call('GET', '/graphql', [
'query' => $this->queries['examplesWithAuthorizeMessage'],
]);

$this->assertEquals($response->getStatusCode(), 200);

$content = $response->getData(true);
$this->assertArrayHasKey('data', $content);
$this->assertArrayHasKey('errors', $content);
$this->assertEquals($content['errors'][0]['message'], 'You are not authorized to perform this action');
$this->assertNull($content['data']['examplesAuthorizeMessage']);
}

/**
* Test support batched queries.
*/
Expand Down
12 changes: 12 additions & 0 deletions tests/Unit/GraphQLQueryTest.php
Expand Up @@ -120,6 +120,18 @@ public function testQueryAndReturnResultWithAuthorize(): void
$this->assertEquals('Unauthorized', $result['errors'][0]['message']);
}

/**
* Test query with authorize.
*/
public function testQueryAndReturnResultWithCustomAuthorizeMessage(): void
{
$result = $this->graphql($this->queries['examplesWithAuthorizeMessage'], [
'expectErrors' => true,
]);
$this->assertNull($result['data']['examplesAuthorizeMessage']);
$this->assertEquals('You are not authorized to perform this action', $result['errors'][0]['message']);
}

/**
* Test query with schema.
*/
Expand Down

0 comments on commit ec54a79

Please sign in to comment.