Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions .github/workflows/continuous_integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ jobs:
- "7.2"
- "7.3"
- "7.4"
- "8.0"

dependencies:
- "highest"
Expand All @@ -32,6 +33,7 @@ jobs:
with:
coverage: "pcov"
php-version: "${{ matrix.php-version }}"
tools: composer:v2

- name: "Cache dependencies installed with composer"
uses: "actions/cache@v1"
Expand All @@ -42,16 +44,23 @@ jobs:

- name: "Install dependencies with composer"
run: "composer install --no-interaction"
if: ${{ matrix.php-version != '8.0' }}

- name: "Install dependencies with composer. Ignoring platform reqs to bypass a problem with ecodev/graphql-upload available only with latest Webonyx on PHP8."
run: "composer install --no-interaction --ignore-platform-reqs"
if: ${{ matrix.php-version == '8.0' }}

- name: "Run tests with phpunit/phpunit"
run: "vendor/bin/phpunit"

- name: "Run static code analysis with phpstan/phpstan"
run: "composer phpstan"

if: ${{ matrix.php-version == '8.0' }}

- name: "Run coding standard checks with squizlabs/php_codesniffer"
run: "composer cs-check"

if: ${{ matrix.php-version == '8.0' }}

- name: "Archive code coverage results"
uses: "actions/upload-artifact@v1"
with:
Expand Down
11 changes: 6 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"phpdocumentor/reflection-docblock": "^4.3 || ^5.0",
"phpdocumentor/type-resolver": "^1.0.1",
"psr/http-message": "^1",
"ecodev/graphql-upload": "^4.0",
"webmozart/assert": "^1.4",
"symfony/cache": "^4.3 | ^5",
"thecodingmachine/cache-utils": "^1",
Expand All @@ -32,20 +31,22 @@
"psr/http-factory": "^1"
},
"require-dev": {
"phpunit/phpunit": "^8.2.4",
"phpunit/phpunit": "^8.2.4||^9.4",
"php-coveralls/php-coveralls": "^2.1",
"mouf/picotainer": "^1.1",
"phpstan/phpstan": "^0.12.25",
"beberlei/porpaginas": "^1.2",
"myclabs/php-enum": "^1.6.6",
"doctrine/coding-standard": "^7.0",
"doctrine/coding-standard": "^8.2",
"phpstan/phpstan-webmozart-assert": "^0.12",
"phpstan/extension-installer": "^1.0",
"thecodingmachine/phpstan-strict-rules": "^0.12",
"laminas/laminas-diactoros": "^2"
"laminas/laminas-diactoros": "^2",
"ecodev/graphql-upload": "^4.0 || ^5.0 || ^6.0"
},
"suggest": {
"beberlei/porpaginas": "If you want automatic pagination in your GraphQL types"
"beberlei/porpaginas": "If you want automatic pagination in your GraphQL types",
"ecodev/graphql-upload": "If you want to support file upload inside GraphQL input types"
},
"autoload": {
"psr-4": {
Expand Down
14 changes: 14 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ title: Changelog
sidebar_label: Changelog
---

## 4.1

Breaking change:

There is one breaking change introduced in the minor version (this was important to allow PHP 8 compatibility).

- The **ecodev/graphql-upload** package (used to get support for file uploads in GraphQL input types) is now a "recommended" dependency only.
If you are using GraphQL file uploads, you need to add this package to your `composer.json`.

New features:

- All annotations can now be accessed as PHP 8 attributes


## 4.0

This is a complete refactoring from 3.x. While existing annotations are kept compatible, the internals have completely
Expand Down
9 changes: 6 additions & 3 deletions docs/annotations_reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ title: Annotations reference
sidebar_label: Annotations reference
---

Note: all annotations are available both in a Doctrine annotation format (`@Query`) and in PHP 8 attribute format (`#[Query]`).
See [Doctrine annotations vs PHP 8 attributes](doctrine_annotations_attributes.md) for more details.

## @Query annotation

The `@Query` annotation is used to declare a GraphQL query.
Expand Down Expand Up @@ -74,7 +77,7 @@ Attribute | Compulsory | Type | Definition
name | *yes* | string | The name of the field.
[outputType](custom_types.md) | *no* | string | Forces the GraphQL output type of the field. Otherwise, return type is used.
phpType | *no* | string | The PHP type of the field (as you would write it in a Docblock)
annotations | *no* | array<Annotations> | A set of annotations that apply to this field. You would typically used a "@Logged" or "@Right" annotation here.
annotations | *no* | array<Annotations> | A set of annotations that apply to this field. You would typically used a "@Logged" or "@Right" annotation here. Available in Doctrine annotations only (not available in the #SourceField PHP 8 attribute)

**Note**: `outputType` and `phpType` are mutually exclusive.

Expand All @@ -89,7 +92,7 @@ Attribute | Compulsory | Type | Definition
name | *yes* | string | The name of the field.
[outputType](custom_types.md) | *no*(*) | string | The GraphQL output type of the field.
phpType | *no*(*) | string | The PHP type of the field (as you would write it in a Docblock)
annotations | *no* | array<Annotations> | A set of annotations that apply to this field. You would typically used a "@Logged" or "@Right" annotation here.
annotations | *no* | array<Annotations> | A set of annotations that apply to this field. You would typically used a "@Logged" or "@Right" annotation here. Available in Doctrine annotations only (not available in the #MagicField PHP 8 attribute)

(*) **Note**: `outputType` and `phpType` are mutually exclusive. You MUST provide one of them.

Expand Down Expand Up @@ -120,7 +123,7 @@ query / mutation / field (according to the `@Logged` and `@Right` annotations).

Attribute | Compulsory | Type | Definition
---------------|------------|------|--------
*default* | *yes* | mixed | The value to return if the user is not authorized.
value | *yes* | mixed | The value to return if the user is not authorized.

## @HideIfUnauthorized annotation

Expand Down
7 changes: 6 additions & 1 deletion docs/argument_resolving.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ As an example, GraphQLite uses *parameter middlewares* internally to:
- Inject the Webonyx GraphQL resolution object when you type-hint on the `ResolveInfo` object. For instance:
```php
/**
* @Query
* @return Product[]
*/
#[Query]
public function products(ResolveInfo $info): array
```
In the query above, the `$info` argument is filled with the Webonyx `ResolveInfo` class thanks to the
Expand Down Expand Up @@ -58,14 +58,19 @@ If you plan to use annotations while resolving arguments, your annotation should

For instance, if we want GraphQLite to inject a service in an argument, we can use `@Autowire(for="myService")`.

For PHP 8 attributes, we only need to put declare the annotation can target parameters: `#[Attribute(Attribute::TARGET_PARAMETER)]`.

The annotation looks like this:

```php
use Attribute;

/**
* Use this annotation to autowire a service from the container into a given parameter of a field/query/mutation.
*
* @Annotation
*/
#[Attribute(Attribute::TARGET_PARAMETER)]
class Autowire implements ParameterAnnotationInterface
{
/**
Expand Down
98 changes: 98 additions & 0 deletions docs/authentication_authorization.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,30 @@ See <a href="implementing-security.md">Connecting GraphQLite to your framework's
## `@Logged` and `@Right` annotations

GraphQLite exposes two annotations (`@Logged` and `@Right`) that you can use to restrict access to a resource.
<!--DOCUSAURUS_CODE_TABS-->
<!--PHP 8+-->
```php
namespace App\Controller;

use TheCodingMachine\GraphQLite\Annotations\Query;
use TheCodingMachine\GraphQLite\Annotations\Logged;
use TheCodingMachine\GraphQLite\Annotations\Right;

class UserController
{
/**
* @return User[]
*/
#[Query]
#[Logged]
#[Right("CAN_VIEW_USER_LIST")]
public function users(int $limit, int $offset): array
{
// ...
}
}
```
<!--PHP 7+-->
```php
namespace App\Controller;

Expand All @@ -44,6 +67,8 @@ class UserController
}
}
```
<!--END_DOCUSAURUS_CODE_TABS-->


In the example above, the query `users` will only be available if the user making the query is logged AND if he
has the `CAN_VIEW_USER_LIST` right.
Expand All @@ -62,6 +87,28 @@ If you do not want an error to be thrown when a user attempts to query a field/q

The `@FailWith` annotation contains the value that will be returned for users with insufficient rights.

<!--DOCUSAURUS_CODE_TABS-->
<!--PHP 8+-->
```php
class UserController
{
/**
* If a user is not logged or if the user has not the right "CAN_VIEW_USER_LIST",
* the value returned will be "null".
*
* @return User[]
*/
#[Query]
#[Logged]
#[Right("CAN_VIEW_USER_LIST")]
#[FailWith(value: null)]
public function users(int $limit, int $offset): array
{
// ...
}
}
```
<!--PHP 7+-->
```php
class UserController
{
Expand All @@ -81,11 +128,37 @@ class UserController
}
}
```
<!--END_DOCUSAURUS_CODE_TABS-->

## Injecting the current user as a parameter

Use the `@InjectUser` annotation to get an instance of the current user logged in.

<!--DOCUSAURUS_CODE_TABS-->
<!--PHP 8+-->
```php
namespace App\Controller;

use TheCodingMachine\GraphQLite\Annotations\Query;
use TheCodingMachine\GraphQLite\Annotations\InjectUser;

class ProductController
{
/**
* @Query
* @return Product
*/
public function product(
int $id,
#[InjectUser]
User $user
): Product
{
// ...
}
}
```
<!--PHP 7+-->
```php
namespace App\Controller;

Expand All @@ -105,6 +178,7 @@ class ProductController
}
}
```
<!--END_DOCUSAURUS_CODE_TABS-->

The `@InjectUser` annotation can be used next to:

Expand All @@ -123,6 +197,29 @@ Some will be available to him and some won't.
If you want to add an extra level of security (or if you want your schema to be kept secret to unauthorized users),
you can use the `@HideIfUnauthorized` annotation.

<!--DOCUSAURUS_CODE_TABS-->
<!--PHP 8+-->
```php
class UserController
{
/**
* If a user is not logged or if the user has not the right "CAN_VIEW_USER_LIST",
* the schema will NOT contain the "users" query at all (so trying to call the
* "users" query will result in a GraphQL "query not found" error.
*
* @return User[]
*/
#[Query]
#[Logged]
#[Right("CAN_VIEW_USER_LIST")]
#[HideIfUnauthorized]
public function users(int $limit, int $offset): array
{
// ...
}
}
```
<!--PHP 7+-->
```php
class UserController
{
Expand All @@ -143,6 +240,7 @@ class UserController
}
}
```
<!--END_DOCUSAURUS_CODE_TABS-->

While this is the most secured mode, it can have drawbacks when working with development tools
(you need to be logged as admin to fetch the complete schema).
Expand Down
Loading