Skip to content
Snippets Groups Projects
Commit d3233e91 authored by Mateusz Charytoniuk's avatar Mateusz Charytoniuk
Browse files

feat: add oauth2 support

parent 75485433
No related branches found
No related tags found
No related merge requests found
Showing
with 1094 additions and 79 deletions
......@@ -17,7 +17,6 @@
],
"require": {
"php": ">=8.2",
"ext-igbinary": "*",
"distantmagic/graphql-swoole-promise-adapter": "^0.1.1",
"distantmagic/swoole-futures": "^0.1.1",
"doctrine/dbal": "^3.7",
......@@ -40,7 +39,12 @@
"symfony/yaml": "^6.3",
"twig/cache-extra": "^3.7",
"twig/twig": "^3.7",
"webonyx/graphql-php": "^15.6"
"webonyx/graphql-php": "^15.6",
"league/oauth2-server": "^8.5",
"psr/http-message": "^2.0",
"defuse/php-encryption": "^2.4",
"nyholm/psr7": "^1.8",
"nyholm/psr7-server": "^1.1"
},
"require-dev": {
"mockery/mockery": "^1.6",
......@@ -50,6 +54,8 @@
"suggest": {
"ext-ds": "For better memory management",
"ext-intl": "Date formatting",
"ext-igbinary": "For better object serialization",
"ext-openssl": "To generate application keys",
"ext-readline": "Unlocks some console features",
"ext-redis": "HTTP Sessions driver",
"ext-uuid": "Faster UUID generation"
......
This diff is collapsed.
[app]
env = development
esbuild_metafile = esbuild-meta-app.json
scheme = https
[database]
default[driver] = mysql
......
---
collections:
- primary_navigation
description: Changelog
draft: true
layout: dm:page
title: Changelog
---
# Changelog
---
collections:
- name: documents
next: docs/features/index
description: Changelog
layout: dm:document
parent: docs/index
title: Changelog
---
# Changelog
## v0.10.0
- Added {{docs/features/security/oauth2/index}} support.
- Added {{docs/features/http/psr-http-messages}} wrapper.
---
collections:
- name: documents
next: docs/features/index
- documents
layout: dm:document
parent: docs/index
title: Extras
......
......@@ -71,6 +71,8 @@ This is the default configuration file:
```ini file:config.ini
[app]
env = development
esbuild_metafile = esbuild-meta-app.json
scheme = https
[database]
default[driver] = mysql
......
......@@ -79,5 +79,5 @@ final readonly class BlogPostShow extends HttpController
```
If you use an entity in a controller parameters, you might also need to add
{{docs/features/security/authorization}} gate to determine who can use that
entity.
{{docs/features/security/authorization/index}} gate to determine who can use
that entity.
......@@ -57,7 +57,7 @@ final readonly class GraphQL extends HttpResponder
## Authorization
You need to provide the {{docs/features/security/authorization}} gate for
You need to provide the {{docs/features/security/authorization/index}} gate for
`SiteAction::UseGraphQL`:
```php
......
......@@ -51,7 +51,7 @@ resource.
:::note
Using the `RouteParameter` might require to create a Crud Gate. See more at
the {{docs/features/security/authorization}} page.
the {{docs/features/security/authorization/index}} page.
:::
Remember that the framework resolves parameters assigned to the `handle` method
......@@ -63,7 +63,7 @@ resolves during the application bootstrap phase thanks to the
:::note
You can learn more about CRUD actions on the
{{docs/features/security/authorization}} page.
{{docs/features/security/authorization/index}} page.
:::
```php
......
......@@ -70,9 +70,9 @@ Resonance comes with several middleware handlers:
attribute | description
-|-
`Can` | Uses {{docs/features/security/authorization}} to check if user can perform a given Site Action before accesing the responder.
`ContentSecurityPolicy` | Sends selected {{docs/features/security/content-security-policy}} headers with the response.
`ValidatesCSRFToken` | Uses the {{docs/features/security/csrf-protection}} mechanisms to validate CSRF token.
`Can` | Uses {{docs/features/security/authorization/index}} to check if user can perform a given Site Action before accesing the responder.
`ContentSecurityPolicy` | Sends selected {{docs/features/security/content-security-policy/index}} headers with the response.
`ValidatesCSRFToken` | Uses the {{docs/features/security/csrf-protection/index}} mechanisms to validate CSRF token.
You can add them to any HTTP Responder. For example:
......
---
collections:
- documents
layout: dm:document
parent: docs/features/http/index
title: PSR HTTP Messages
description: >
Learn how to convert Swoole server requests to PSR server requests.
---
# PSR HTTP Messages
If you need to convert Swoole's HTTP Request object to it's
[PSR counterpart](https://www.php-fig.org/psr/psr-7/) you can use the
converters.
# Usage
## Swoole Request -> PSR Server Request
You should only convert requests if you need to use some third-party library
that relies on them. Primarily because PSR requests do not provide any
additional features, it's just for standardization. Conversion between request
formats hinders the performance.
`PsrServerRequestConverter` can/should also be used as a singleton.
```php
/**
* @var Distantmagic\Resonance\PsrServerRequestConverter $psrServerRequestRepository
* @var Swoole\Http\Request $request
* @var Psr\Http\Message\ServerRequestInterface $psrRequest
*/
$psrRequest = $psrServerRequestRepository->convertToServerRequest($request);
```
## PSR Response -> Swoole Response
If you want to respond with PSR response, you need to wrap it in
`PsrResponder`:
```php
use Distantmagic\Resonance\HttpResponder;
use Distantmagic\Resonance\HttpResponderInterface;
use Distantmagic\Resonance\HttpResponder\PsrResponder;
use Psr\Http\Message\ResponseInterface;
use Swoole\Http\Request;
use Swoole\Http\Response;
readonly class MyResponder extends HttpResponder
{
public function respond(Request $request, Response $response): HttpResponderInterface
{
// (...) obtain psr response somehow
/**
* @var ResponseInterface $psrResponse
*/
return new PsrResponder($psrResponse);
}
}
```
---
collections:
- documents
- name: documents
next: docs/features/http/index
layout: dm:document
next: docs/features/http/psr-http-messages
parent: docs/features/http/index
title: Sessions
description: >
......
---
collections:
- documents
- name: documents
next: docs/extras/index
layout: dm:document
parent: docs/index
title: Features
......
......@@ -2,7 +2,7 @@
collections:
- documents
layout: dm:document
next: docs/features/security/authorization
next: docs/features/security/authorization/index
parent: docs/features/security/index
title: Authentication
description: >
......
......@@ -2,7 +2,7 @@
collections:
- documents
layout: dm:document
next: docs/features/security/csrf-protection
next: docs/features/security/csrf-protection/index
parent: docs/features/security/index
title: Authorization
description: >
......
......@@ -22,7 +22,7 @@ Modern browsers implement CSP, but it needs to be activated by sending them a
series of specific headers.
`Distantmagic\Resonance\SecurityPolicyHeaders` provides not only
{{docs/features/security/content-security-policy}} headers but also some
{{docs/features/security/content-security-policy/index}} headers but also some
additional headers recommended by
[OWASP's Secure Headers Project](https://owasp.org/www-project-secure-headers/).
......
......@@ -2,7 +2,7 @@
collections:
- documents
layout: dm:document
next: docs/features/security/content-security-policy
next: docs/features/security/content-security-policy/index
parent: docs/features/security/index
title: CSRF Protection
description: >
......@@ -23,7 +23,7 @@ use those first.
:::tip
**Besides** the CSRF protection, it's a good idea to protect your site by
setting
{{docs/features/security/content-security-policy}} wherever they may be
{{docs/features/security/content-security-policy/index}} wherever they may be
applied.
:::
......
......@@ -30,4 +30,4 @@ That means sometimes you must provide an authorization gate (and possibly an
authentication mechanism - unless you want to *explicitly* enable guest access
to all resources).
{{docs/features/security/*!docs/features/security/index}}
{{docs/features/security/*/index}}
---
collections:
- name: documents
next: docs/features/security/oauth2/enabling-grants
layout: dm:document
next: docs/features/security/oauth2/enabling-grants
parent: docs/features/security/oauth2/index
title: Configuration
description: >
Learn how to configure OAuth 2.0 server.
---
# Configuration
## Encryption Keys Paths
You can configure the paths by adding this section to the configuration file:
```ini
[oauth2]
encryption_key = oauth2/defuse.key
jwt_signing_key_passphrase =
jwt_signing_key_private = oauth2/private.key
jwt_signing_key_public = oauth2/public.key
```
## HTTP Authorization Server Endpoint
You need to add an endpoint to your application that exposes OAuth2 server.
The simplest one can forward every request to the OAuth2 authorization
server, the framework takes care of the rest:
```php file:app/HttpResponder/OAuth2AuthorizationServer.php
<?php
namespace App\HttpResponder;
use App\HttpRouteSymbol;
use Distantmagic\Resonance\Attribute\RespondsToHttp;
use Distantmagic\Resonance\Attribute\Singleton;
use Distantmagic\Resonance\HttpResponder;
use Distantmagic\Resonance\HttpResponder\OAuth2\AuthorizationServer;
use Distantmagic\Resonance\HttpResponderInterface;
use Distantmagic\Resonance\RequestMethod;
use Distantmagic\Resonance\SingletonCollection;
use Swoole\Http\Request;
use Swoole\Http\Response;
#[RespondsToHttp(
method: RequestMethod::POST,
pattern: '/oauth2',
routeSymbol: HttpRouteSymbol::OAuth2AuthorizationServer,
)]
#[Singleton(collection: SingletonCollection::HttpResponder)]
final readonly class OAuth2AuthorizationServer extends HttpResponder
{
public function __construct(private AuthorizationServer $authorizationServer) {}
public function respond(Request $request, Response $response): HttpResponderInterface
{
return $this->authorizationServer;
}
}
```
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment