Updated respondToAuthorizationRequest to use Plates templates instead of custom ResponseType

This commit is contained in:
Alex Bilbie 2016-02-12 11:55:41 +00:00
parent 1c913fe75e
commit 2025749fa4

View File

@ -3,23 +3,19 @@
namespace League\OAuth2\Server\Grant; namespace League\OAuth2\Server\Grant;
use DateInterval; use DateInterval;
use League\OAuth2\Server\Entities\Interfaces\UserEntityInterface;
use League\OAuth2\Server\Exception\OAuthServerException; use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface; use League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface;
use League\OAuth2\Server\ResponseTypes\AuthorizeClientResponseTypeInterface; use League\OAuth2\Server\Repositories\UserRepositoryInterface;
use League\OAuth2\Server\ResponseTypes\LoginUserResponseTypeInterface;
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface; use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
use League\OAuth2\Server\Utils\KeyCrypt; use League\OAuth2\Server\Utils\KeyCrypt;
use League\Plates\Engine;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Zend\Diactoros\Response; use Zend\Diactoros\Response;
use Zend\Diactoros\Uri; use Zend\Diactoros\Uri;
class AuthCodeGrant extends AbstractGrant class AuthCodeGrant extends AbstractGrant
{ {
/**
* @var \League\OAuth2\Server\ResponseTypes\LoginUserResponseTypeInterface
*/
private $loginUserResponseType;
/** /**
* @var \DateInterval * @var \DateInterval
*/ */
@ -28,27 +24,41 @@ class AuthCodeGrant extends AbstractGrant
* @var \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface * @var \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface
*/ */
private $authCodeRepository; private $authCodeRepository;
/**
* @var \League\OAuth2\Server\ResponseTypes\AuthorizeClientResponseTypeInterface
*/
private $authorizeClientResponseType;
/** /**
* @param \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface $authCodeRepository * @var \League\OAuth2\Server\Repositories\UserRepositoryInterface
* @param \DateInterval $authCodeTTL */
* @param \League\OAuth2\Server\ResponseTypes\LoginUserResponseTypeInterface $loginUserResponseType private $userRepository;
* @param \League\OAuth2\Server\ResponseTypes\AuthorizeClientResponseTypeInterface $authorizeClientResponseType
/**
* @var null|string
*/
private $pathToLoginTemplate;
/**
* @var null|string
*/
private $pathToAuthorizeTemplate;
/**
* @param \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface $authCodeRepository
* @param \League\OAuth2\Server\Repositories\UserRepositoryInterface $userRepository
* @param \DateInterval $authCodeTTL
* @param string|null $pathToLoginTemplate
* @param string|null $pathToAuthorizeTemplate
*/ */
public function __construct( public function __construct(
AuthCodeRepositoryInterface $authCodeRepository, AuthCodeRepositoryInterface $authCodeRepository,
UserRepositoryInterface $userRepository,
\DateInterval $authCodeTTL, \DateInterval $authCodeTTL,
LoginUserResponseTypeInterface $loginUserResponseType, $pathToLoginTemplate = null,
AuthorizeClientResponseTypeInterface $authorizeClientResponseType $pathToAuthorizeTemplate = null
) { ) {
$this->authCodeRepository = $authCodeRepository; $this->authCodeRepository = $authCodeRepository;
$this->userRepository = $userRepository;
$this->authCodeTTL = $authCodeTTL; $this->authCodeTTL = $authCodeTTL;
$this->loginUserResponseType = $loginUserResponseType; $this->pathToLoginTemplate = $pathToLoginTemplate;
$this->authorizeClientResponseType = $authorizeClientResponseType; $this->pathToAuthorizeTemplate = $pathToAuthorizeTemplate;
} }
@ -92,31 +102,99 @@ class AuthCodeGrant extends AbstractGrant
$scopes = $this->validateScopes($request, $client, $redirectUri); $scopes = $this->validateScopes($request, $client, $redirectUri);
$queryString = http_build_query($request->getQueryParams()); $queryString = http_build_query($request->getQueryParams());
$postbackUri = new Uri(
sprintf(
'//%s%s',
$request->getServerParams()['HTTP_HOST'],
$request->getServerParams()['REQUEST_URI']
)
);
$userId = null;
$userHasApprovedClient = $userHasApprovedClient = $this->getRequestParameter('action', null);
// Check if the user has been validated // Check if the user has been validated
$userIdCookieParam = $this->getCookieParameter('oauth_user_id', $request, null); $oauthCookie = $this->getCookieParameter('oauth_authorize_request', $request, null);
if ($userIdCookieParam === null) { if ($oauthCookie !== null) {
return $this->loginUserResponseType->handle($client, $scopes, $queryString, $this->pathToPrivateKey);
} else {
try { try {
$userId = KeyCrypt::decrypt($userIdCookieParam, $this->pathToPublicKey); $oauthCookiePayload = json_decode(KeyCrypt::decrypt($oauthCookie, $this->pathToPublicKey));
$userId = $oauthCookiePayload->user_id;
$userHasApprovedClient = $oauthCookiePayload->client_is_authorized;
} catch (\LogicException $e) { } catch (\LogicException $e) {
throw OAuthServerException::serverError($e->getMessage()); throw OAuthServerException::serverError($e->getMessage());
} }
} }
// Check the user has approved the request // The username + password might be available in $_POST
$userApprovedCookieParam = $this->getCookieParameter('oauth_user_approved_client', $request, null); $usernameParameter = $this->getRequestParameter('username', null);
if ($userApprovedCookieParam === null) { $passwordParameter = $this->getRequestParameter('password', null);
return $this->authorizeClientResponseType->handle($client, $scopes, $queryString, $this->pathToPrivateKey);
} else { $loginError = null;
try {
$userApprovedClient = KeyCrypt::decrypt($userApprovedCookieParam, $this->pathToPublicKey); // Assert if the user has logged in already
} catch (\LogicException $e) { if ($userId === null && $usernameParameter !== null && $passwordParameter !== null) {
throw OAuthServerException::serverError($e->getMessage()); $userEntity = $this->userRepository->getUserEntityByUserCredentials(
$usernameParameter,
$passwordParameter
);
if ($userEntity instanceof UserEntityInterface) {
$userId = $userEntity->getIdentifier();
} else {
$loginError = 'Incorrect username or password';
} }
} }
// The user hasn't logged in yet so show a login form
if ($userId === null) {
$engine = new Engine();
$html = $engine->render(
($this->pathToLoginTemplate === null)
? __DIR__ . '/../ResponseTypes/DefaultTemplates/login_user.php'
: $this->pathToLoginTemplate,
[
'error' => $loginError,
'postback_uri' => (string) $postbackUri->withQuery($queryString),
]
);
return new Response\HtmlResponse($html);
}
// The user hasn't approved the client yet so show an authorize form
if ($userId !== null && $userHasApprovedClient === null) {
$engine = new Engine();
$html = $engine->render(
($this->pathToLoginTemplate === null)
? __DIR__ . '/../ResponseTypes/DefaultTemplates/authorize_client.php'
: $this->pathToAuthorizeTemplate,
[
'client' => $client,
'scopes' => $scopes,
'postback_uri' => (string) $postbackUri->withQuery($queryString),
]
);
return new Response\HtmlResponse(
$html,
200,
[
'Set-Cookie' => sprintf(
'oauth_authorize_request=%s; Expires=%s',
KeyCrypt::encrypt(
json_encode([
'user_id' => $userId,
'client_is_authorized' => null,
]),
$this->pathToPrivateKey
),
(new \DateTime())->add(new \DateInterval('PT5M'))->format('D, d M Y H:i:s e')
),
]
);
}
$stateParameter = $this->getQueryStringParameter('state', $request); $stateParameter = $this->getQueryStringParameter('state', $request);
$redirectUri = new Uri($redirectUri); $redirectUri = new Uri($redirectUri);
@ -125,7 +203,7 @@ class AuthCodeGrant extends AbstractGrant
$redirectPayload['state'] = $stateParameter; $redirectPayload['state'] = $stateParameter;
} }
if ($userApprovedClient === 1) { if ($userHasApprovedClient === true) {
$authCode = $this->issueAuthCode( $authCode = $this->issueAuthCode(
$this->authCodeTTL, $this->authCodeTTL,
$client, $client,
@ -137,13 +215,7 @@ class AuthCodeGrant extends AbstractGrant
$redirectPayload['code'] = $authCode->getIdentifier(); $redirectPayload['code'] = $authCode->getIdentifier();
return new Response( return new Response\RedirectResponse($redirectUri->withQuery(http_build_query($redirectPayload)));
'php://memory',
302,
[
'Location' => $redirectUri->withQuery(http_build_query($redirectPayload)),
]
);
} }
$exception = OAuthServerException::accessDenied('The user denied the request', (string) $redirectUri); $exception = OAuthServerException::accessDenied('The user denied the request', (string) $redirectUri);