Updated grants

This commit is contained in:
Alex Bilbie 2015-04-05 21:10:41 +01:00
parent b831d19f8d
commit 6a78d53d03
3 changed files with 103 additions and 106 deletions

View File

@ -16,7 +16,7 @@ use League\Event\Event;
use League\OAuth2\Server\Entities\AccessTokenEntity; use League\OAuth2\Server\Entities\AccessTokenEntity;
use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface; use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
use League\OAuth2\Server\Exception; use League\OAuth2\Server\Exception;
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface; use League\OAuth2\Server\TokenTypes\TokenTypeInterface;
use League\OAuth2\Server\Utils\SecureKey; use League\OAuth2\Server\Utils\SecureKey;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -36,18 +36,18 @@ class ClientCredentialsGrant extends AbstractGrant
* Return an access token * Return an access token
* *
* @param \Symfony\Component\HttpFoundation\Request $request * @param \Symfony\Component\HttpFoundation\Request $request
* @param \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType * @param \League\OAuth2\Server\TokenTypes\TokenTypeInterface $tokenType
* @param \DateInterval $accessTokenTTL * @param \DateInterval $accessTokenTTL
* @param string $scopeDelimiter * @param string $scopeDelimiter
* *
* @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface * @return \League\OAuth2\Server\TokenTypes\TokenTypeInterface
* @throws \League\OAuth2\Server\Exception\InvalidClientException * @throws \League\OAuth2\Server\Exception\InvalidClientException
* @throws \League\OAuth2\Server\Exception\InvalidRequestException * @throws \League\OAuth2\Server\Exception\InvalidRequestException
* @throws \League\OAuth2\Server\Exception\InvalidScopeException * @throws \League\OAuth2\Server\Exception\InvalidScopeException
*/ */
public function getAccessTokenAsType( public function getAccessTokenAsType(
Request $request, Request $request,
ResponseTypeInterface $responseType, TokenTypeInterface $tokenType,
DateInterval $accessTokenTTL, DateInterval $accessTokenTTL,
$scopeDelimiter = ' ' $scopeDelimiter = ' '
) { ) {
@ -95,8 +95,8 @@ class ClientCredentialsGrant extends AbstractGrant
$this->accessTokenRepository->create($accessToken); $this->accessTokenRepository->create($accessToken);
// Inject access token into token type // Inject access token into token type
$responseType->setAccessToken($accessToken); $tokenType->setAccessToken($accessToken);
return $responseType; return $tokenType;
} }
} }

View File

@ -12,7 +12,7 @@
namespace League\OAuth2\Server\Grant; namespace League\OAuth2\Server\Grant;
use DateInterval; use DateInterval;
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface; use League\OAuth2\Server\TokenTypes\TokenTypeInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
/** /**
@ -38,15 +38,15 @@ interface GrantTypeInterface
* Return an access token * Return an access token
* *
* @param \Symfony\Component\HttpFoundation\Request $request * @param \Symfony\Component\HttpFoundation\Request $request
* @param \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType * @param \League\OAuth2\Server\TokenTypes\TokenTypeInterface $tokenType
* @param \DateInterval $accessTokenTTL * @param \DateInterval $accessTokenTTL
* @param string $scopeDelimiter * @param string $scopeDelimiter
* *
* @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface * @return \League\OAuth2\Server\TokenTypes\TokenTypeInterface
*/ */
public function getAccessTokenAsType( public function getAccessTokenAsType(
Request $request, Request $request,
ResponseTypeInterface $responseType, TokenTypeInterface $tokenType,
DateInterval $accessTokenTTL, DateInterval $accessTokenTTL,
$scopeDelimiter = ' ' $scopeDelimiter = ' '
); );

View File

@ -11,13 +11,21 @@
namespace League\OAuth2\Server\Grant; namespace League\OAuth2\Server\Grant;
use League\OAuth2\Server\Entity\AccessTokenEntity; use DateInterval;
use League\OAuth2\Server\Entity\ClientEntity; use League\Event\Emitter;
use League\OAuth2\Server\Entity\RefreshTokenEntity; use League\Event\Event;
use League\OAuth2\Server\Entity\SessionEntity; use League\OAuth2\Server\Entities\AccessTokenEntity;
use League\OAuth2\Server\Event; use League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface;
use League\OAuth2\Server\Entities\Interfaces\UserEntityInterface;
use League\OAuth2\Server\Exception; use League\OAuth2\Server\Exception;
use League\OAuth2\Server\Util\SecureKey; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
use League\OAuth2\Server\TokenTypes\TokenTypeInterface;
use League\OAuth2\Server\Utils\SecureKey;
use Symfony\Component\HttpFoundation\Request;
/** /**
* Password grant class * Password grant class
@ -31,13 +39,6 @@ class PasswordGrant extends AbstractGrant
*/ */
protected $identifier = 'password'; protected $identifier = 'password';
/**
* Response type
*
* @var string
*/
protected $responseType;
/** /**
* Callback to authenticate a user's name and password * Callback to authenticate a user's name and password
* *
@ -46,137 +47,133 @@ class PasswordGrant extends AbstractGrant
protected $callback; protected $callback;
/** /**
* Access token expires in override * @var \League\OAuth2\Server\Repositories\UserRepositoryInterface
*
* @var int
*/ */
protected $accessTokenTTL; protected $userRepository;
/** /**
* Set the callback to verify a user's username and password * @var \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface
*
* @param callable $callback The callback function
*
* @return void
*/ */
public function setVerifyCredentialsCallback(callable $callback) protected $refreshTokenRepository;
{
$this->callback = $callback; /**
* @param \League\Event\Emitter $emitter
* @param \League\OAuth2\Server\Repositories\ClientRepositoryInterface $clientRepository
* @param \League\OAuth2\Server\Repositories\ScopeRepositoryInterface $scopeRepository
* @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository
* @param \League\OAuth2\Server\Repositories\UserRepositoryInterface $userRepository
* @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository
*/
public function __construct(
Emitter $emitter,
ClientRepositoryInterface $clientRepository,
ScopeRepositoryInterface $scopeRepository,
AccessTokenRepositoryInterface $accessTokenRepository,
UserRepositoryInterface $userRepository,
RefreshTokenRepositoryInterface $refreshTokenRepository = null
) {
$this->userRepository = $userRepository;
$this->refreshTokenRepository = $refreshTokenRepository;
parent::__construct($emitter, $clientRepository, $scopeRepository, $accessTokenRepository);
} }
/** /**
* Return the callback function * Return an access token
* *
* @return callable * @param \Symfony\Component\HttpFoundation\Request $request
* @param \League\OAuth2\Server\TokenTypes\TokenTypeInterface $tokenType
* @param \DateInterval $accessTokenTTL
* @param string $scopeDelimiter
* *
* @throws * @return \League\OAuth2\Server\TokenTypes\TokenTypeInterface
* @throws \League\OAuth2\Server\Exception\InvalidClientException
* @throws \League\OAuth2\Server\Exception\InvalidCredentialsException
* @throws \League\OAuth2\Server\Exception\InvalidRequestException
* @throws \League\OAuth2\Server\Exception\InvalidScopeException
*/ */
protected function getVerifyCredentialsCallback() public function getAccessTokenAsType(
{ Request $request,
if (is_null($this->callback) || !is_callable($this->callback)) { TokenTypeInterface $tokenType,
throw new Exception\ServerErrorException('Null or non-callable callback set on Password grant'); DateInterval $accessTokenTTL,
} $scopeDelimiter = ' '
) {
return $this->callback;
}
/**
* Complete the password grant
*
* @return array
*
* @throws
*/
public function completeFlow()
{
// Get the required params // Get the required params
$clientId = $this->server->getRequest()->request->get('client_id', $this->server->getRequest()->getUser()); $clientId = $request->request->get('client_id', $request->getUser());
if (is_null($clientId)) { if (is_null($clientId)) {
throw new Exception\InvalidRequestException('client_id'); throw new Exception\InvalidRequestException('client_id');
} }
$clientSecret = $this->server->getRequest()->request->get('client_secret', $clientSecret = $request->request->get('client_secret',
$this->server->getRequest()->getPassword()); $request->getPassword());
if (is_null($clientSecret)) { if (is_null($clientSecret)) {
throw new Exception\InvalidRequestException('client_secret'); throw new Exception\InvalidRequestException('client_secret');
} }
// Validate client ID and client secret // Validate client ID and client secret
$client = $this->server->getClientStorage()->get( $client = $this->clientRepository->get(
$clientId, $clientId,
$clientSecret, $clientSecret,
null, null,
$this->getIdentifier() $this->getIdentifier()
); );
if (($client instanceof ClientEntity) === false) { if (($client instanceof ClientEntityInterface) === false) {
$this->server->getEventEmitter()->emit(new Event\ClientAuthenticationFailedEvent($this->server->getRequest())); $this->emitter->emit(new Event('client.authentication.failed', $request));
throw new Exception\InvalidClientException(); throw new Exception\InvalidClientException();
} }
$username = $this->server->getRequest()->request->get('username', null); $username = $request->request->get('username', null);
if (is_null($username)) { if (is_null($username)) {
throw new Exception\InvalidRequestException('username'); throw new Exception\InvalidRequestException('username');
} }
$password = $this->server->getRequest()->request->get('password', null); $password = $request->request->get('password', null);
if (is_null($password)) { if (is_null($password)) {
throw new Exception\InvalidRequestException('password'); throw new Exception\InvalidRequestException('password');
} }
// Check if user's username and password are correct // Check if user's username and password are correct
$userId = call_user_func($this->getVerifyCredentialsCallback(), $username, $password); $user = $this->userRepository->getByCredentials($username, $password);
if ($userId === false) { if (($user instanceof UserEntityInterface) === false) {
$this->server->getEventEmitter()->emit(new Event\UserAuthenticationFailedEvent($this->server->getRequest())); $this->emitter->emit(new Event('user.authentication.failed', $request));
throw new Exception\InvalidCredentialsException(); throw new Exception\InvalidCredentialsException();
} }
// Validate any scopes that are in the request // Validate any scopes that are in the request
$scopeParam = $this->server->getRequest()->request->get('scope', ''); $scopeParamValue = $request->request->get('scope', '');
$scopes = $this->validateScopes($scopeParam, $client); $scopes = $this->validateScopes($scopeParamValue, $scopeDelimiter, $client);
// Create a new session
$session = new SessionEntity($this->server);
$session->setOwner('user', $userId);
$session->associateClient($client);
// Generate an access token // Generate an access token
$accessToken = new AccessTokenEntity($this->server); $accessToken = new AccessTokenEntity();
$accessToken->setId(SecureKey::generate()); $accessToken->setIdentifier(SecureKey::generate());
$accessToken->setExpireTime($this->getAccessTokenTTL() + time()); $accessToken->setExpiryDateTime((new \DateTime())->add($accessTokenTTL));
$accessToken->setOwner('user', $user->getIdentifier());
$accessToken->setClient($client);
// Associate scopes with the session and access token // Associate scopes with the access token
foreach ($scopes as $scope) { foreach ($scopes as $scope) {
$session->associateScope($scope); $accessToken->addScope($scope);
} }
foreach ($session->getScopes() as $scope) { $tokenType->setAccessToken($accessToken);
$accessToken->associateScope($scope);
}
$this->server->getTokenType()->setSession($session);
$this->server->getTokenType()->setParam('access_token', $accessToken->getId());
$this->server->getTokenType()->setParam('expires_in', $this->getAccessTokenTTL());
// Associate a refresh token if set // Associate a refresh token if set
if ($this->server->hasGrantType('refresh_token')) { if ($this->refreshTokenRepository instanceof RefreshTokenRepositoryInterface) {
$refreshToken = new RefreshTokenEntity($this->server); // $refreshToken = new RefreshTokenEntity($this->server);
$refreshToken->setId(SecureKey::generate()); // $refreshToken->setId(SecureKey::generate());
$refreshToken->setExpireTime($this->server->getGrantType('refresh_token')->getRefreshTokenTTL() + time()); // $refreshToken->setExpireTime($this->server->getGrantType('refresh_token')->getRefreshTokenTTL() + time());
$this->server->getTokenType()->setParam('refresh_token', $refreshToken->getId()); // $refreshToken->setAccessToken($accessToken);
// $this->server->getTokenType()->setParam('refresh_token', $refreshToken->getId());
// $tokenType->setParam('refresh_token', $refreshToken);
} }
// Save everything // Save the access token
$session->save(); $this->accessTokenRepository->create($accessToken);
$accessToken->setSession($session);
$accessToken->save();
if ($this->server->hasGrantType('refresh_token')) { // Inject the access token into token type
$refreshToken->setAccessToken($accessToken); $tokenType->setAccessToken($accessToken);
$refreshToken->save();
}
return $this->server->getTokenType()->generateResponse(); return $tokenType;
} }
} }