Skip to content

Commit

Permalink
Change main index file to handle OAuth2 Client and Server requests
Browse files Browse the repository at this point in the history
Includes some development/debugging code.
  • Loading branch information
Potherca committed Aug 25, 2020
1 parent 680a693 commit c945e82
Showing 1 changed file with 119 additions and 8 deletions.
127 changes: 119 additions & 8 deletions web/index.php
Original file line number Diff line number Diff line change
@@ -1,19 +1,40 @@
<?php declare(strict_types=1);

/*/ Vendor /*/
use GuzzleHttp\Client as HttpClient;
use Laminas\Diactoros\Response;
use Laminas\Diactoros\ServerRequestFactory;
use Laminas\HttpHandlerRunner\Emitter\SapiEmitter;
use Laminas\HttpHandlerRunner\Exception\EmitterException;
use League\OAuth2\Server\CryptKey;
use League\Route\Http\Exception\HttpExceptionInterface;
use League\Route\Http\Exception\NotFoundException;
use League\Route\Router;
use function MJRider\FlysystemFactory\create as createFileSystem;

/*/ Generic Pdsinterop /*/
use Pdsinterop\Authentication\Enum\OAuth2\GrantType;
use Pdsinterop\Authentication\Enum\OAuth2\Parameter;
use Pdsinterop\Authentication\Enum\ServerPrefix;
use Pdsinterop\Authentication\Enum\Time;
use Pdsinterop\Authentication\Router as ProjectRouter;

/*/ Authentication Client /*/
use Pdsinterop\Authentication\Client\Enum\ClientOption;
use Pdsinterop\Authentication\Client\Provider;
use Pdsinterop\Authentication\Client\Router as ClientRouter;

/*/ Authentication Server /*/
use Pdsinterop\Authentication\Server\Entity\User as UserEntity;
use Pdsinterop\Authentication\Server\Enum\Repository;
use Pdsinterop\Authentication\Server\Expiration;
use Pdsinterop\Authentication\Server\Factory\GrantTypeFactory;
use Pdsinterop\Authentication\Server\Factory\AuthorizationServerFactory;
use Pdsinterop\Authentication\Server\Factory\RepositoryFactory;
use Pdsinterop\Authentication\Server\Keys;
use Pdsinterop\Authentication\Server\Repository\Client as ClientRepository;
use Pdsinterop\Authentication\Server\Router as ServerRouter;

/*/ Resource Server /*/
use Pdsinterop\Authentication\Resource\Handler\Authentication;
use Pdsinterop\Authentication\Resource\Router as ResourceRouter;
Expand All @@ -24,9 +45,27 @@
ob_start();

// =============================================================================
// Configuration
// @TODO: Move configuration to separate object|(s)
// -----------------------------------------------------------------------------
$clientIdentifier = 'PDS Interop OAuth Example App';
$expires = [
'accessToken' => Time::HOURS_1,
'authCode' => Time::MINUTES_10,
'refreshToken' => Time::MONTHS_1,
];

$clientSecret = 'client secret';
$clientIdentifier = 'OAuth Example App';

$encryptionKeyPath = dirname(__DIR__) . '/tests/fixtures/keys/encryption.key';
$privateKeyPath = dirname(__DIR__) . '/tests/fixtures/keys/private.key';

$grantTypes = [
GrantType::AUTH_CODE,
GrantType::CLIENT_CREDENTIALS,
// GrantType::IMPLICIT,
// GrantType::PASSWORD,
// GrantType::REFRESH_TOKEN,
];

$location = getenv('STORAGE_ENDPOINT') ?: 'local:'.dirname(__DIR__) . '/tests/fixtures/files';
// =============================================================================
Expand All @@ -35,6 +74,12 @@
// =============================================================================
// Create Objects from I/O (filesystem, network, globals)
// -----------------------------------------------------------------------------
$encryptionKey = file_get_contents($encryptionKeyPath);

$privateKey = new CryptKey(file_get_contents($privateKeyPath));

$keys = new Keys($privateKey, $encryptionKey);

$request = ServerRequestFactory::fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES);

$host = vsprintf('%s://%s%s', [
Expand All @@ -43,11 +88,46 @@
'Port' => $request->getUri()->getPort() ? ':'.$request->getUri()->getPort() : '',
]);

$isServer = strpos($request->getRequestTarget(), ServerPrefix::AUTHORIZATION) === 0;

$expiration = new Expiration($expires['accessToken'], $expires['authCode'], $expires['refreshToken']);

$user = new UserEntity();
$user->setIdentifier('Empty User');

if (isset($_SESSION['user_id'])) {
$user->setIdentifier($_SESSION['user_id']);
}

$filesystem = createFileSystem($location);

$publicResources = [
'public_resource.txt'
];

/*/ OAuth2 Client options /*/
$options = [
ClientOption::CLIENT_ID => $clientIdentifier,
ClientOption::CLIENT_SECRET => $clientSecret,
ClientOption::REDIRECT_URI => $host . ServerPrefix::CLIENT.'/redirect-url',

// URLs on the Authorization server
// @FIXME: The server URLs should be gotten from a config that is also used by the server
ClientOption::URL_AUTHORIZE => $host . ServerPrefix::AUTHORIZATION.'/authorize',
ClientOption::URL_ACCESS_TOKEN => $host . ServerPrefix::AUTHORIZATION.'/access_token',
ClientOption::URL_RESOURCE_OWNER_DETAILS => $host . ServerPrefix::RESOURCE.'/public_resource.txt',
];
/*/ ======================================================================== /*/


// =============================================================================
// Create factories
// -----------------------------------------------------------------------------
$repositoryFactory = new RepositoryFactory([
Repository::CLIENT => new ClientRepository($clientIdentifier, $clientSecret,$grantTypes),
]);
$grantFactory = new GrantTypeFactory($expiration, $repositoryFactory);
$serverFactory = new AuthorizationServerFactory($repositoryFactory, $grantFactory, $keys, $expiration);
/*/ ======================================================================== /*/


Expand All @@ -57,8 +137,17 @@
$response = new Response();
$router = new Router();

$client = [];
if ('this is needed in development to allow self-signed certificates') {
$client['httpClient'] = new HttpClient(['verify' => false]);
}

$provider = new Provider($options, $client);

$routes = [
'/' => new ProjectRouter($response),
ServerPrefix::AUTHORIZATION => new ServerRouter($response, $serverFactory, $user, $grantTypes),
ServerPrefix::CLIENT => new ClientRouter($response, $provider, $grantTypes),
ServerPrefix::RESOURCE => new ResourceRouter(
$response,
$filesystem,
Expand All @@ -76,6 +165,7 @@
// =============================================================================
// Create response for requested route
// -----------------------------------------------------------------------------
$statusCode = 500;
try {
$response = $router->dispatch($request);
} catch (NotFoundException $exception) {
Expand All @@ -87,14 +177,28 @@
// @FIXME: An exception here means a developer mistake (or "bug") as all exceptions should have been caught in the called route handler, how to handle?
$error = 'dispatch_error';
} finally {
if (isset($exception)) {
if (isset($exception, $error)) {
$message = '<h1>DISPATCH ERROR</h1><pre>' . $exception . '</pre>';
$statusCode = 500;

if (method_exists($exception, 'getStatusCode')) {
$statusCode = $exception->getStatusCode();
}

if ($isServer) {
$response = $response->withHeader('content-type', 'application/json; charset=UTF-8');

$description = $description ?? vsprintf('%s: %s', [
get_class($exception),
$exception->getMessage(),
]);

$message = json_encode([
Parameter::ERROR => $error,
Parameter::ERROR_DESCRIPTION => $description,
'trace' => $exception->getTrace(),
]);
}

$response->getBody()->write($message);
$response = $response->withStatus($statusCode);
}
Expand All @@ -107,17 +211,24 @@
// -----------------------------------------------------------------------------
$emitter = new SapiEmitter();

// Any output means a developer mistake (or "bug")
ob_clean();
// @FIXME: Any output means a developer mistake (or "bug"), how to handle?
$buffer = ob_get_clean();

try {
$emitter->emit($response);
} catch (EmitterException $exception) {
$statusCode = 500;
// @FIXME: An exception here means a developer mistake (or "bug") as all exceptions should have been caught in the called emitter, how to handle?
http_response_code(500);
http_response_code($statusCode);
$message = '<h1>EMITTER ERROR</h1><pre>' . $exception . '</pre>';

if ($isServer) {
$message = json_encode($exception);
}
echo $message;
}

if ($buffer !== '') {
echo "\nOUTPUT: \n{$buffer}";
}

exit;

0 comments on commit c945e82

Please sign in to comment.