Skip to content

Commit

Permalink
Merge pull request #34 from boesing/feature/psr-17-support
Browse files Browse the repository at this point in the history
feature: PSR-17 support
  • Loading branch information
weierophinney authored Mar 30, 2022
2 parents 24f9f29 + 9692e99 commit 05d2c0e
Show file tree
Hide file tree
Showing 23 changed files with 585 additions and 173 deletions.
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@
"league/oauth2-server": "^8.3.3",
"mezzio/mezzio-authentication": "^1.0",
"psr/container": "^1.0 || ^2.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.0.1",
"psr/http-server-middleware": "^1.0"
"psr/http-server-middleware": "^1.0",
"webmozart/assert": "^1.10"
},
"require-dev": {
"laminas/laminas-coding-standard": "~2.3.0",
Expand Down
112 changes: 56 additions & 56 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 23 additions & 7 deletions src/AuthorizationHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@

use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
use Mezzio\Authentication\OAuth2\Response\CallableResponseFactoryDecorator;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

use function is_callable;

/**
* Handles the already validated and competed authorization request
*
Expand All @@ -24,20 +28,32 @@ class AuthorizationHandler implements RequestHandlerInterface
/** @var AuthorizationServer */
private $server;

/** @var callable */
/** @var ResponseFactoryInterface */
private $responseFactory;

public function __construct(AuthorizationServer $server, callable $responseFactory)
/**
* @param (callable():ResponseInterface)|ResponseFactoryInterface $responseFactory
*/
public function __construct(AuthorizationServer $server, $responseFactory)
{
$this->server = $server;
$this->responseFactory = function () use ($responseFactory): ResponseInterface {
return $responseFactory();
};
$this->server = $server;
if (is_callable($responseFactory)) {
$responseFactory = new CallableResponseFactoryDecorator(
static function () use ($responseFactory): ResponseInterface {
return $responseFactory();
}
);
}

$this->responseFactory = $responseFactory;
}

public function handle(ServerRequestInterface $request): ResponseInterface
{
$authRequest = $request->getAttribute(AuthorizationRequest::class);
return $this->server->completeAuthorizationRequest($authRequest, ($this->responseFactory)());
return $this->server->completeAuthorizationRequest(
$authRequest,
$this->responseFactory->createResponse()
);
}
}
5 changes: 3 additions & 2 deletions src/AuthorizationHandlerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@

use League\OAuth2\Server\AuthorizationServer;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;

final class AuthorizationHandlerFactory
{
use Psr17ResponseFactoryTrait;

public function __invoke(ContainerInterface $container): AuthorizationHandler
{
return new AuthorizationHandler(
$container->get(AuthorizationServer::class),
$container->get(ResponseInterface::class)
$this->detectResponseFactory($container)
);
}
}
33 changes: 23 additions & 10 deletions src/AuthorizationMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@

namespace Mezzio\Authentication\OAuth2;

use Exception;
use Exception as BaseException;
use League\OAuth2\Server\AuthorizationServer;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
use Mezzio\Authentication\OAuth2\Response\CallableResponseFactoryDecorator;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

use function is_callable;

/**
* Implements OAuth2 authorization request validation
*
Expand All @@ -32,24 +36,31 @@ class AuthorizationMiddleware implements MiddlewareInterface
/** @var AuthorizationServer */
protected $server;

/** @var callable */
/** @var ResponseFactoryInterface */
protected $responseFactory;

public function __construct(AuthorizationServer $server, callable $responseFactory)
/**
* @param (callable():ResponseInterface)|ResponseFactoryInterface $responseFactory
*/
public function __construct(AuthorizationServer $server, $responseFactory)
{
$this->server = $server;
$this->responseFactory = function () use ($responseFactory): ResponseInterface {
return $responseFactory();
};
$this->server = $server;
if (is_callable($responseFactory)) {
$responseFactory = new CallableResponseFactoryDecorator(
static function () use ($responseFactory): ResponseInterface {
return $responseFactory();
}
);
}

$this->responseFactory = $responseFactory;
}

/**
* {@inheritDoc}
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$response = ($this->responseFactory)();

try {
$authRequest = $this->server->validateAuthorizationRequest($request);

Expand All @@ -59,10 +70,12 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface

return $handler->handle($request->withAttribute(AuthorizationRequest::class, $authRequest));
} catch (OAuthServerException $exception) {
$response = $this->responseFactory->createResponse();
// The validation throws this exception if the request is not valid
// for example when the client id is invalid
return $exception->generateHttpResponse($response);
} catch (Exception $exception) {
} catch (BaseException $exception) {
$response = $this->responseFactory->createResponse();
return (new OAuthServerException($exception->getMessage(), 0, 'unknown_error', 500))
->generateHttpResponse($response);
}
Expand Down
5 changes: 3 additions & 2 deletions src/AuthorizationMiddlewareFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@

use League\OAuth2\Server\AuthorizationServer;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;

final class AuthorizationMiddlewareFactory
{
use Psr17ResponseFactoryTrait;

public function __invoke(ContainerInterface $container): AuthorizationMiddleware
{
return new AuthorizationMiddleware(
$container->get(AuthorizationServer::class),
$container->get(ResponseInterface::class)
$this->detectResponseFactory($container)
);
}
}
32 changes: 23 additions & 9 deletions src/OAuth2Adapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\ResourceServer;
use Mezzio\Authentication\AuthenticationInterface;
use Mezzio\Authentication\OAuth2\Response\CallableResponseFactoryDecorator;
use Mezzio\Authentication\UserInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

use function is_callable;

class OAuth2Adapter implements AuthenticationInterface
{
/** @var ResourceServer */
Expand All @@ -19,18 +23,28 @@ class OAuth2Adapter implements AuthenticationInterface
/** @var callable */
protected $responseFactory;

/** @var callable */
/** @var ResponseFactoryInterface */
protected $userFactory;

/**
* @param (callable():ResponseInterface)|ResponseFactoryInterface $responseFactory
*/
public function __construct(
ResourceServer $resourceServer,
callable $responseFactory,
$responseFactory,
callable $userFactory
) {
$this->resourceServer = $resourceServer;
$this->responseFactory = function () use ($responseFactory): ResponseInterface {
return $responseFactory();
};
$this->resourceServer = $resourceServer;

if (is_callable($responseFactory)) {
$responseFactory = new CallableResponseFactoryDecorator(
static function () use ($responseFactory): ResponseInterface {
return $responseFactory();
}
);
}

$this->responseFactory = $responseFactory;
$this->userFactory = function (
string $identity,
array $roles = [],
Expand Down Expand Up @@ -72,11 +86,11 @@ public function authenticate(ServerRequestInterface $request): ?UserInterface
*/
public function unauthorizedResponse(ServerRequestInterface $request): ResponseInterface
{
return ($this->responseFactory)()
return $this->responseFactory
->createResponse(401)
->withHeader(
'WWW-Authenticate',
'Bearer realm="OAuth2 token"'
)
->withStatus(401);
);
}
}
5 changes: 3 additions & 2 deletions src/OAuth2AdapterFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
use League\OAuth2\Server\ResourceServer;
use Mezzio\Authentication\UserInterface;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;

class OAuth2AdapterFactory
{
use Psr17ResponseFactoryTrait;

public function __invoke(ContainerInterface $container): OAuth2Adapter
{
$resourceServer = $container->has(ResourceServer::class)
Expand All @@ -25,7 +26,7 @@ public function __invoke(ContainerInterface $container): OAuth2Adapter

return new OAuth2Adapter(
$resourceServer,
$container->get(ResponseInterface::class),
$this->detectResponseFactory($container),
$container->get(UserInterface::class)
);
}
Expand Down
Loading

0 comments on commit 05d2c0e

Please sign in to comment.