Skip to content

Commit 5afe2bd

Browse files
committed
Add the main Server class that handles all requests.
1 parent 2abfb69 commit 5afe2bd

1 file changed

Lines changed: 129 additions & 0 deletions

File tree

src/Server.php

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Pdsinterop\Solid\Auth;
4+
5+
use League\OAuth2\Server\AuthorizationServer;
6+
use League\OAuth2\Server\Entities\UserEntityInterface;
7+
use League\OAuth2\Server\Exception\OAuthServerException;
8+
use Pdsinterop\Solid\Auth\Entity\User;
9+
use Pdsinterop\Solid\Auth\Enum\OpenId\OpenIdConnectMetadata as OidcMeta;
10+
use Psr\Http\Message\ResponseInterface as Response;
11+
use Psr\Http\Message\ServerRequestInterface as Request;
12+
13+
class Server
14+
{
15+
////////////////////////////// CLASS PROPERTIES \\\\\\\\\\\\\\\\\\\\\\\\\\\\
16+
17+
/** @var AuthorizationServer */
18+
private $authorizationServer;
19+
/** @var Config */
20+
private $config;
21+
/** @var Response */
22+
private $response;
23+
24+
//////////////////////////////// PUBLIC API \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
25+
26+
final public function __construct(
27+
AuthorizationServer $authorizationServer,
28+
Config $config,
29+
Response $response
30+
) {
31+
$this->authorizationServer = $authorizationServer;
32+
$this->config = $config;
33+
$this->response = $response;
34+
}
35+
36+
final public function respondToAccessTokenRequest(Request $request) : Response
37+
{
38+
$authorizationServer = $this->authorizationServer;
39+
$response = $this->response;
40+
41+
try {
42+
return $authorizationServer->respondToAccessTokenRequest($request, $response);
43+
} catch (OAuthServerException $serverException) {
44+
return $this->createOauthServerExceptionResponse($response, $serverException);
45+
}
46+
}
47+
48+
final public function respondToWellKnowRequest() : Response
49+
{
50+
$response = $this->response;
51+
52+
$serverConfig = $this->config->getServer();
53+
54+
return $this->createJsonResponse($response, $serverConfig);
55+
}
56+
57+
final public function respondToAuthorizationRequest(
58+
Request $request,
59+
User $user = null,
60+
bool $authorizationApproved = null,
61+
callable $callback = null
62+
) : Response {
63+
$serverConfig = $this->config->getServer();
64+
$authorizationServer = $this->authorizationServer;
65+
$response = $this->response;
66+
67+
try {
68+
// Validate the HTTP request and return an AuthorizationRequest object.
69+
$authRequest = $authorizationServer->validateAuthorizationRequest($request);
70+
} catch (OAuthServerException $serverException) {
71+
return $this->createOauthServerExceptionResponse($response, $serverException);
72+
}
73+
74+
if ($user instanceof UserEntityInterface) {
75+
// Once the user has logged in set the user on the AuthorizationRequest
76+
$authRequest->setUser($user);
77+
}
78+
79+
if ($user === null && $authorizationApproved === null) {
80+
/*/ Step 1 Redirect the user to a login endpoint /*/
81+
$loginUrl = ''; //@FIXME: The LOGIN_URL is NOT part of any RFC Spec so it can not (yet) be retrieved using `$serverConfig->get(Foo::LOGIN_URL);`
82+
$response = $response->withHeader('Location', $loginUrl)->withStatus(302);
83+
} elseif ($user instanceof UserEntityInterface && $authorizationApproved === null) {
84+
/*/ Step 2: Redirect the user to an authorization form where the user can approve the scopes requested by the client./*/
85+
$authorizationPageUrl = $serverConfig->get(OidcMeta::AUTHORIZATION_ENDPOINT);
86+
$response = $response->withHeader('Location', $authorizationPageUrl)->withStatus(302);
87+
} elseif (is_bool($authorizationApproved)) {
88+
/*/ Step 3: Update approval status and redirect to Client `redirect_uri /*/
89+
90+
// Once the user has approved or denied the client update the status
91+
$authRequest->setAuthorizationApproved($authorizationApproved);
92+
93+
// Return the HTTP redirect response
94+
$response = $authorizationServer->completeAuthorizationRequest($authRequest, $response);
95+
} else {
96+
// @CHECKME: 404 or throw Exception?
97+
$response = $response->withStatus(404);
98+
}
99+
100+
// Allow calling code to retrieve or validate data from $authRequest
101+
if (is_callable($callback)) {
102+
// @CHECKME: Should this give access to the League\OAuth2 object or do we need to inject a Pdsinterop\Solid intermediate?
103+
$callback($authRequest);
104+
}
105+
106+
return $response;
107+
}
108+
109+
////////////////////////////// UTILITY METHODS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\
110+
111+
private function createOauthServerExceptionResponse(Response $response, OAuthServerException $serverException): Response
112+
{
113+
return $serverException->generateHttpResponse($response, false, JSON_PRETTY_PRINT);
114+
}
115+
116+
private function createJsonResponse(Response $response, $json = null) : Response
117+
{
118+
if ($json !== null) {
119+
120+
if ( ! is_string($json)) {
121+
$json = json_encode($json, JSON_PRETTY_PRINT);
122+
}
123+
124+
$response->getBody()->write($json);
125+
}
126+
127+
return $response->withHeader('content-type', 'application/json; charset=UTF-8');
128+
}
129+
}

0 commit comments

Comments
 (0)