mirror of
				https://github.com/elyby/oauth2-server.git
				synced 2025-05-31 14:12:07 +05:30 
			
		
		
		
	Merge branch 'V5-WIP' into move_identifier_generation
This commit is contained in:
		@@ -11,6 +11,7 @@ interface ClientEntityInterface
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the client's identifier
 | 
			
		||||
     *
 | 
			
		||||
     * @param $identifier
 | 
			
		||||
     */
 | 
			
		||||
    public function setIdentifier($identifier);
 | 
			
		||||
@@ -23,7 +24,42 @@ interface ClientEntityInterface
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the client's name
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $name
 | 
			
		||||
     */
 | 
			
		||||
    public function setName($name);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $secret
 | 
			
		||||
     */
 | 
			
		||||
    public function setSecret($secret);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Validate the secret provided by the client
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $submittedSecret
 | 
			
		||||
     *
 | 
			
		||||
     * @return boolean
 | 
			
		||||
     */
 | 
			
		||||
    public function validateSecret($submittedSecret);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the client's redirect uri
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $redirectUri
 | 
			
		||||
     */
 | 
			
		||||
    public function setRedirectUri($redirectUri);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the registered redirect URI
 | 
			
		||||
     *
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function getRedirectUri();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns true if the client is capable of keeping it's secrets secret
 | 
			
		||||
     * @return boolean
 | 
			
		||||
     */
 | 
			
		||||
    public function canKeepASecret();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,8 +9,17 @@ trait ClientEntityTrait
 | 
			
		||||
    protected $name;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the client's name
 | 
			
		||||
     * @return string
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    protected $secret;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    protected $redirectUri;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    public function getName()
 | 
			
		||||
    {
 | 
			
		||||
@@ -18,11 +27,50 @@ trait ClientEntityTrait
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the client's name
 | 
			
		||||
     * @param string $name
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    public function setName($name)
 | 
			
		||||
    {
 | 
			
		||||
        $this->name = $name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    public function canKeepASecret()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->secret !== null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    public function setSecret($secret)
 | 
			
		||||
    {
 | 
			
		||||
        $this->secret = $secret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    public function validateSecret($submittedSecret)
 | 
			
		||||
    {
 | 
			
		||||
        return strcmp((string) $submittedSecret, $this->secret) === 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    public function setRedirectUri($redirectUri)
 | 
			
		||||
    {
 | 
			
		||||
        $this->redirectUri = $redirectUri;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    public function getRedirectUri()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->redirectUri;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,8 +21,11 @@ use League\OAuth2\Server\Entities\RefreshTokenEntity;
 | 
			
		||||
use League\OAuth2\Server\Entities\ScopeEntity;
 | 
			
		||||
use League\OAuth2\Server\Exception\OAuthServerException;
 | 
			
		||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
 | 
			
		||||
use OAuth2ServerExamples\Repositories\AuthCodeRepository;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -54,6 +57,16 @@ abstract class AbstractGrant implements GrantTypeInterface
 | 
			
		||||
     */
 | 
			
		||||
    protected $scopeRepository;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface
 | 
			
		||||
     */
 | 
			
		||||
    private $authCodeRepository;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface
 | 
			
		||||
     */
 | 
			
		||||
    private $refreshTokenRepository;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
@@ -93,6 +106,22 @@ abstract class AbstractGrant implements GrantTypeInterface
 | 
			
		||||
        $this->scopeRepository = $scopeRepository;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository
 | 
			
		||||
     */
 | 
			
		||||
    public function setRefreshTokenRepository(RefreshTokenRepositoryInterface $refreshTokenRepository)
 | 
			
		||||
    {
 | 
			
		||||
        $this->refreshTokenRepository = $refreshTokenRepository;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface $authCodeRepository
 | 
			
		||||
     */
 | 
			
		||||
    public function setAuthCodeRepository(AuthCodeRepositoryInterface $authCodeRepository)
 | 
			
		||||
    {
 | 
			
		||||
        $this->authCodeRepository = $authCodeRepository;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $pathToPrivateKey
 | 
			
		||||
     */
 | 
			
		||||
@@ -125,21 +154,32 @@ abstract class AbstractGrant implements GrantTypeInterface
 | 
			
		||||
        $this->refreshTokenTTL = $refreshTokenTTL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return AuthCodeRepositoryInterface
 | 
			
		||||
     */
 | 
			
		||||
    protected function getAuthCodeRepository()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->authCodeRepository;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return RefreshTokenRepositoryInterface
 | 
			
		||||
     */
 | 
			
		||||
    protected function getRefreshTokenRepository()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->refreshTokenRepository;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Validate the client
 | 
			
		||||
     *
 | 
			
		||||
     * @param \Psr\Http\Message\ServerRequestInterface $request
 | 
			
		||||
     * @param bool                                     $validateSecret
 | 
			
		||||
     * @param bool                                     $validateRedirectUri
 | 
			
		||||
     *
 | 
			
		||||
     * @return \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface
 | 
			
		||||
     * @throws \League\OAuth2\Server\Exception\OAuthServerException
 | 
			
		||||
     */
 | 
			
		||||
    protected function validateClient(
 | 
			
		||||
        ServerRequestInterface $request,
 | 
			
		||||
        $validateSecret = true,
 | 
			
		||||
        $validateRedirectUri = false
 | 
			
		||||
    ) {
 | 
			
		||||
    protected function validateClient(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        $clientId = $this->getRequestParameter(
 | 
			
		||||
            'client_id',
 | 
			
		||||
            $request,
 | 
			
		||||
@@ -149,30 +189,34 @@ abstract class AbstractGrant implements GrantTypeInterface
 | 
			
		||||
            throw OAuthServerException::invalidRequest('client_id', null, '`%s` parameter is missing');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $client = $this->clientRepository->getClientEntity(
 | 
			
		||||
            $clientId,
 | 
			
		||||
            $this->getIdentifier()
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        if (!$client instanceof ClientEntityInterface) {
 | 
			
		||||
            throw OAuthServerException::invalidClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If the client is confidential require the client secret
 | 
			
		||||
        $clientSecret = $this->getRequestParameter(
 | 
			
		||||
            'client_secret',
 | 
			
		||||
            $request,
 | 
			
		||||
            $this->getServerParameter('PHP_AUTH_PW', $request)
 | 
			
		||||
        );
 | 
			
		||||
        if (is_null($clientSecret) && $validateSecret === true) {
 | 
			
		||||
 | 
			
		||||
        if ($client->canKeepASecret() && is_null($clientSecret)) {
 | 
			
		||||
            throw OAuthServerException::invalidRequest('client_secret', null, '`%s` parameter is missing');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $redirectUri = $this->getRequestParameter('redirect_uri', $request, null);
 | 
			
		||||
        if (is_null($redirectUri) && $validateRedirectUri === true) {
 | 
			
		||||
            throw OAuthServerException::invalidRequest('redirect_uri', null, '`%s` parameter is missing');
 | 
			
		||||
        if ($client->canKeepASecret() && $client->validateSecret($clientSecret) === false) {
 | 
			
		||||
            $this->getEmitter()->emit(new Event('client.authentication.failed', $request));
 | 
			
		||||
            throw OAuthServerException::invalidClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $client = $this->clientRepository->getClientEntity(
 | 
			
		||||
            $clientId,
 | 
			
		||||
            $clientSecret,
 | 
			
		||||
            $redirectUri,
 | 
			
		||||
            $this->getIdentifier()
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        if (!$client instanceof ClientEntityInterface) {
 | 
			
		||||
            $this->getEmitter()->emit(new Event('client.authentication.failed', $request));
 | 
			
		||||
 | 
			
		||||
        // If a redirect URI is provided ensure it matches what is pre-registered
 | 
			
		||||
        $redirectUri = $this->getRequestParameter('redirect_uri', $request, null);
 | 
			
		||||
        if ($redirectUri !== null && (strcmp($client->getRedirectUri(), $redirectUri) !== 0)) {
 | 
			
		||||
            throw OAuthServerException::invalidClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -303,6 +347,8 @@ abstract class AbstractGrant implements GrantTypeInterface
 | 
			
		||||
            $accessToken->addScope($scope);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->accessTokenRepository->persistNewAccessToken($accessToken);
 | 
			
		||||
 | 
			
		||||
        return $accessToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -336,6 +382,8 @@ abstract class AbstractGrant implements GrantTypeInterface
 | 
			
		||||
            $authCode->addScope($scope);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->authCodeRepository->persistNewAuthCode($authCode);
 | 
			
		||||
 | 
			
		||||
        return $authCode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -351,6 +399,8 @@ abstract class AbstractGrant implements GrantTypeInterface
 | 
			
		||||
        $refreshToken->setExpiryDateTime((new \DateTime())->add($this->refreshTokenTTL));
 | 
			
		||||
        $refreshToken->setAccessToken($accessToken);
 | 
			
		||||
 | 
			
		||||
        $this->refreshTokenRepository->persistNewRefreshToken($refreshToken);
 | 
			
		||||
 | 
			
		||||
        return $refreshToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,10 +23,6 @@ class AuthCodeGrant extends AbstractGrant
 | 
			
		||||
     * @var \DateInterval
 | 
			
		||||
     */
 | 
			
		||||
    private $authCodeTTL;
 | 
			
		||||
    /**
 | 
			
		||||
     * @var \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface
 | 
			
		||||
     */
 | 
			
		||||
    private $authCodeRepository;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var \League\OAuth2\Server\Repositories\UserRepositoryInterface
 | 
			
		||||
@@ -43,10 +39,6 @@ class AuthCodeGrant extends AbstractGrant
 | 
			
		||||
     */
 | 
			
		||||
    private $pathToAuthorizeTemplate;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface
 | 
			
		||||
     */
 | 
			
		||||
    private $refreshTokenRepository;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface     $authCodeRepository
 | 
			
		||||
@@ -64,8 +56,8 @@ class AuthCodeGrant extends AbstractGrant
 | 
			
		||||
        $pathToLoginTemplate = null,
 | 
			
		||||
        $pathToAuthorizeTemplate = null
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->authCodeRepository = $authCodeRepository;
 | 
			
		||||
        $this->refreshTokenRepository = $refreshTokenRepository;
 | 
			
		||||
        $this->setAuthCodeRepository($authCodeRepository);
 | 
			
		||||
        $this->setRefreshTokenRepository($refreshTokenRepository);
 | 
			
		||||
        $this->userRepository = $userRepository;
 | 
			
		||||
        $this->authCodeTTL = $authCodeTTL;
 | 
			
		||||
        $this->pathToLoginTemplate = ($pathToLoginTemplate === null)
 | 
			
		||||
@@ -89,26 +81,7 @@ class AuthCodeGrant extends AbstractGrant
 | 
			
		||||
    protected function respondToAuthorizationRequest(
 | 
			
		||||
        ServerRequestInterface $request
 | 
			
		||||
    ) {
 | 
			
		||||
        $clientId = $this->getQueryStringParameter(
 | 
			
		||||
            'client_id',
 | 
			
		||||
            $request,
 | 
			
		||||
            $this->getServerParameter('PHP_AUTH_USER', $request)
 | 
			
		||||
        );
 | 
			
		||||
        if (is_null($clientId)) {
 | 
			
		||||
            throw OAuthServerException::invalidRequest('client_id', null, '`%s` parameter is missing');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $redirectUri = $this->getQueryStringParameter('redirect_uri', $request, null);
 | 
			
		||||
        if (is_null($redirectUri)) {
 | 
			
		||||
            throw OAuthServerException::invalidRequest('redirect_uri', null, '`%s` parameter is missing');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $client = $this->clientRepository->getClientEntity(
 | 
			
		||||
            $clientId,
 | 
			
		||||
            null,
 | 
			
		||||
            $redirectUri,
 | 
			
		||||
            $this->getIdentifier()
 | 
			
		||||
        );
 | 
			
		||||
        $client = $this->validateClient($request);
 | 
			
		||||
 | 
			
		||||
        if ($client instanceof ClientEntityInterface === false) {
 | 
			
		||||
            $this->emitter->emit(new Event('client.authentication.failed', $request));
 | 
			
		||||
@@ -116,7 +89,7 @@ class AuthCodeGrant extends AbstractGrant
 | 
			
		||||
            throw OAuthServerException::invalidClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $scopes = $this->validateScopes($request, $client, $redirectUri);
 | 
			
		||||
        $scopes = $this->validateScopes($request, $client, $client->getRedirectUri());
 | 
			
		||||
        $queryString = http_build_query($request->getQueryParams());
 | 
			
		||||
        $postbackUri = new Uri(
 | 
			
		||||
            sprintf(
 | 
			
		||||
@@ -168,8 +141,9 @@ class AuthCodeGrant extends AbstractGrant
 | 
			
		||||
        // The user hasn't logged in yet so show a login form
 | 
			
		||||
        if ($userId === null) {
 | 
			
		||||
            $engine = new Engine(dirname($this->pathToLoginTemplate));
 | 
			
		||||
            $pathParts = explode(DIRECTORY_SEPARATOR, $this->pathToLoginTemplate);
 | 
			
		||||
            $html = $engine->render(
 | 
			
		||||
                'login_user',
 | 
			
		||||
                end($pathParts),
 | 
			
		||||
                [
 | 
			
		||||
                    'error'        => $loginError,
 | 
			
		||||
                    'postback_uri' => (string) $postbackUri->withQuery($queryString),
 | 
			
		||||
@@ -183,8 +157,9 @@ class AuthCodeGrant extends AbstractGrant
 | 
			
		||||
        // The user hasn't approved the client yet so show an authorize form
 | 
			
		||||
        if ($userId !== null && $userHasApprovedClient === null) {
 | 
			
		||||
            $engine = new Engine(dirname($this->pathToAuthorizeTemplate));
 | 
			
		||||
            $pathParts = explode(DIRECTORY_SEPARATOR, $this->pathToAuthorizeTemplate);
 | 
			
		||||
            $html = $engine->render(
 | 
			
		||||
                'authorize_client',
 | 
			
		||||
                end($pathParts),
 | 
			
		||||
                [
 | 
			
		||||
                    'client'       => $client,
 | 
			
		||||
                    'scopes'       => $scopes,
 | 
			
		||||
@@ -212,7 +187,7 @@ class AuthCodeGrant extends AbstractGrant
 | 
			
		||||
 | 
			
		||||
        $stateParameter = $this->getQueryStringParameter('state', $request);
 | 
			
		||||
 | 
			
		||||
        $redirectUri = new Uri($redirectUri);
 | 
			
		||||
        $redirectUri = new Uri($client->getRedirectUri());
 | 
			
		||||
        parse_str($redirectUri->getQuery(), $redirectPayload);
 | 
			
		||||
        if ($stateParameter !== null) {
 | 
			
		||||
            $redirectPayload['state'] = $stateParameter;
 | 
			
		||||
@@ -226,7 +201,6 @@ class AuthCodeGrant extends AbstractGrant
 | 
			
		||||
                $redirectUri,
 | 
			
		||||
                $scopes
 | 
			
		||||
            );
 | 
			
		||||
            $this->authCodeRepository->persistNewAuthCode($authCode);
 | 
			
		||||
 | 
			
		||||
            $redirectPayload['code'] = KeyCrypt::encrypt(
 | 
			
		||||
                json_encode(
 | 
			
		||||
@@ -263,6 +237,12 @@ class AuthCodeGrant extends AbstractGrant
 | 
			
		||||
        ResponseTypeInterface $responseType,
 | 
			
		||||
        DateInterval $accessTokenTTL
 | 
			
		||||
    ) {
 | 
			
		||||
        // The redirect URI is required in this request
 | 
			
		||||
        $redirectUri = $this->getQueryStringParameter('redirect_uri', $request, null);
 | 
			
		||||
        if (is_null($redirectUri)) {
 | 
			
		||||
            throw OAuthServerException::invalidRequest('redirect_uri', null, '`%s` parameter is missing');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Validate request
 | 
			
		||||
        $client = $this->validateClient($request);
 | 
			
		||||
        $encryptedAuthCode = $this->getRequestParameter('code', $request, null);
 | 
			
		||||
@@ -278,7 +258,7 @@ class AuthCodeGrant extends AbstractGrant
 | 
			
		||||
                throw OAuthServerException::invalidRequest('code', 'Authorization code has expired');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ($this->authCodeRepository->isAuthCodeRevoked($authCodePayload->auth_code_id) === true) {
 | 
			
		||||
            if ($this->getAuthCodeRepository()->isAuthCodeRevoked($authCodePayload->auth_code_id) === true) {
 | 
			
		||||
                throw OAuthServerException::invalidRequest('code', 'Authorization code has been revoked');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -297,8 +277,6 @@ class AuthCodeGrant extends AbstractGrant
 | 
			
		||||
            $authCodePayload->scopes
 | 
			
		||||
        );
 | 
			
		||||
        $refreshToken = $this->issueRefreshToken($accessToken);
 | 
			
		||||
        $this->accessTokenRepository->persistNewAccessToken($accessToken);
 | 
			
		||||
        $this->refreshTokenRepository->persistNewRefreshToken($refreshToken);
 | 
			
		||||
 | 
			
		||||
        // Inject tokens into response type
 | 
			
		||||
        $responseType->setAccessToken($accessToken);
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,6 @@ class ClientCredentialsGrant extends AbstractGrant
 | 
			
		||||
 | 
			
		||||
        // Issue and persist access token
 | 
			
		||||
        $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $client->getIdentifier(), $scopes);
 | 
			
		||||
        $this->accessTokenRepository->persistNewAccessToken($accessToken);
 | 
			
		||||
 | 
			
		||||
        // Inject access token into response type
 | 
			
		||||
        $responseType->setAccessToken($accessToken);
 | 
			
		||||
 
 | 
			
		||||
@@ -29,11 +29,6 @@ class PasswordGrant extends AbstractGrant
 | 
			
		||||
     */
 | 
			
		||||
    private $userRepository;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface
 | 
			
		||||
     */
 | 
			
		||||
    private $refreshTokenRepository;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param \League\OAuth2\Server\Repositories\UserRepositoryInterface         $userRepository
 | 
			
		||||
     * @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository
 | 
			
		||||
@@ -43,7 +38,7 @@ class PasswordGrant extends AbstractGrant
 | 
			
		||||
        RefreshTokenRepositoryInterface $refreshTokenRepository
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->userRepository = $userRepository;
 | 
			
		||||
        $this->refreshTokenRepository = $refreshTokenRepository;
 | 
			
		||||
        $this->setRefreshTokenRepository($refreshTokenRepository);
 | 
			
		||||
 | 
			
		||||
        $this->refreshTokenTTL = new \DateInterval('P1M');
 | 
			
		||||
    }
 | 
			
		||||
@@ -64,8 +59,6 @@ class PasswordGrant extends AbstractGrant
 | 
			
		||||
        // Issue and persist new tokens
 | 
			
		||||
        $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $user->getIdentifier(), $scopes);
 | 
			
		||||
        $refreshToken = $this->issueRefreshToken($accessToken);
 | 
			
		||||
        $this->accessTokenRepository->persistNewAccessToken($accessToken);
 | 
			
		||||
        $this->refreshTokenRepository->persistNewRefreshToken($refreshToken);
 | 
			
		||||
 | 
			
		||||
        // Inject tokens into response
 | 
			
		||||
        $responseType->setAccessToken($accessToken);
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@
 | 
			
		||||
namespace League\OAuth2\Server\Grant;
 | 
			
		||||
 | 
			
		||||
use League\Event\Event;
 | 
			
		||||
use League\OAuth2\Server\Entities\ScopeEntity;
 | 
			
		||||
use League\OAuth2\Server\Exception\OAuthServerException;
 | 
			
		||||
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
 | 
			
		||||
@@ -23,17 +24,12 @@ use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 */
 | 
			
		||||
class RefreshTokenGrant extends AbstractGrant
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @var \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface
 | 
			
		||||
     */
 | 
			
		||||
    private $refreshTokenRepository;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(RefreshTokenRepositoryInterface $refreshTokenRepository)
 | 
			
		||||
    {
 | 
			
		||||
        $this->refreshTokenRepository = $refreshTokenRepository;
 | 
			
		||||
        $this->setRefreshTokenRepository($refreshTokenRepository);
 | 
			
		||||
 | 
			
		||||
        $this->refreshTokenTTL = new \DateInterval('P1M');
 | 
			
		||||
    }
 | 
			
		||||
@@ -47,13 +43,17 @@ class RefreshTokenGrant extends AbstractGrant
 | 
			
		||||
        \DateInterval $accessTokenTTL
 | 
			
		||||
    ) {
 | 
			
		||||
        // Validate request
 | 
			
		||||
        $client          = $this->validateClient($request);
 | 
			
		||||
        $client = $this->validateClient($request);
 | 
			
		||||
        $oldRefreshToken = $this->validateOldRefreshToken($request, $client->getIdentifier());
 | 
			
		||||
        $scopes          = $this->validateScopes($request, $client);
 | 
			
		||||
        $scopes = $this->validateScopes($request, $client);
 | 
			
		||||
 | 
			
		||||
        // If no new scopes are requested then give the access token the original session scopes
 | 
			
		||||
        if (count($scopes) === 0) {
 | 
			
		||||
            $scopes = $oldRefreshToken['scopes'];
 | 
			
		||||
            $scopes = array_map(function ($scopeId) {
 | 
			
		||||
                $scope = new ScopeEntity();
 | 
			
		||||
                $scope->setIdentifier($scopeId);
 | 
			
		||||
                return $scope;
 | 
			
		||||
            }, $oldRefreshToken['scopes']);
 | 
			
		||||
        } else {
 | 
			
		||||
            // The OAuth spec says that a refreshed access token can have the original scopes or fewer so ensure
 | 
			
		||||
            // the request doesn't include any new scopes
 | 
			
		||||
@@ -68,13 +68,13 @@ class RefreshTokenGrant extends AbstractGrant
 | 
			
		||||
 | 
			
		||||
        // Expire old tokens
 | 
			
		||||
        $this->accessTokenRepository->revokeAccessToken($oldRefreshToken['access_token_id']);
 | 
			
		||||
        $this->refreshTokenRepository->revokeRefreshToken($oldRefreshToken['refresh_token_id']);
 | 
			
		||||
        $this->getRefreshTokenRepository()->revokeRefreshToken($oldRefreshToken['refresh_token_id']);
 | 
			
		||||
 | 
			
		||||
        // Issue and persist new tokens
 | 
			
		||||
        $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $oldRefreshToken['user_id'], $scopes);
 | 
			
		||||
        $refreshToken = $this->issueRefreshToken($accessToken);
 | 
			
		||||
        $this->accessTokenRepository->persistNewAccessToken($accessToken);
 | 
			
		||||
        $this->refreshTokenRepository->persistNewRefreshToken($refreshToken);
 | 
			
		||||
        $this->getRefreshTokenRepository()->persistNewRefreshToken($refreshToken);
 | 
			
		||||
 | 
			
		||||
        // Inject tokens into response
 | 
			
		||||
        $responseType->setAccessToken($accessToken);
 | 
			
		||||
@@ -120,7 +120,7 @@ class RefreshTokenGrant extends AbstractGrant
 | 
			
		||||
            throw OAuthServerException::invalidRefreshToken('Token has expired');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($this->refreshTokenRepository->isRefreshTokenRevoked($refreshTokenData['refresh_token_id']) === true) {
 | 
			
		||||
        if ($this->getRefreshTokenRepository()->isRefreshTokenRevoked($refreshTokenData['refresh_token_id']) === true) {
 | 
			
		||||
            throw OAuthServerException::invalidRefreshToken('Token has been revoked');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,12 +19,10 @@ interface ClientRepositoryInterface extends RepositoryInterface
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a client
 | 
			
		||||
     *
 | 
			
		||||
     * @param string      $grantType        The grant type used
 | 
			
		||||
     * @param string      $clientIdentifier The client's identifier
 | 
			
		||||
     * @param string|null $clientSecret     The client's secret
 | 
			
		||||
     * @param string|null $redirectUri      The client's redirect URI
 | 
			
		||||
     * @param string      $grantType        The grant type used
 | 
			
		||||
     *
 | 
			
		||||
     * @return \League\OAuth2\Server\Entities\Interfaces\ClientEntityInterface
 | 
			
		||||
     */
 | 
			
		||||
    public function getClientEntity($grantType, $clientIdentifier, $clientSecret = null, $redirectUri = null);
 | 
			
		||||
    public function getClientEntity($clientIdentifier, $grantType);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,33 +10,56 @@ use League\OAuth2\Server\Entities\Interfaces\AuthCodeEntityInterface;
 | 
			
		||||
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
 | 
			
		||||
use League\OAuth2\Server\Entities\ScopeEntity;
 | 
			
		||||
use League\OAuth2\Server\Grant\AbstractGrant;
 | 
			
		||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface;
 | 
			
		||||
use Zend\Diactoros\ServerRequest;
 | 
			
		||||
 | 
			
		||||
class AbstractGrantTest extends \PHPUnit_Framework_TestCase
 | 
			
		||||
{
 | 
			
		||||
    public function testGetSet()
 | 
			
		||||
    {
 | 
			
		||||
        $clientRepositoryMock = $this->getMock(ClientRepositoryInterface::class);
 | 
			
		||||
        $accessTokenRepositoryMock = $this->getMock(AccessTokenRepositoryInterface::class);
 | 
			
		||||
        $scopeRepositoryMock = $this->getMock(ScopeRepositoryInterface::class);
 | 
			
		||||
        /** @var AbstractGrant $grantMock */
 | 
			
		||||
        $grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
 | 
			
		||||
        $grantMock->setPathToPrivateKey('./private.key');
 | 
			
		||||
        $grantMock->setPathToPublicKey('./public.key');
 | 
			
		||||
        $grantMock->setEmitter(new Emitter());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testValidateClientPublic()
 | 
			
		||||
    {
 | 
			
		||||
        $client = new ClientEntity();
 | 
			
		||||
 | 
			
		||||
        $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
 | 
			
		||||
        $clientRepositoryMock->method('getClientEntity')->willReturn($client);
 | 
			
		||||
 | 
			
		||||
        /** @var AbstractGrant $grantMock */
 | 
			
		||||
        $grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
 | 
			
		||||
        $grantMock->setClientRepository($clientRepositoryMock);
 | 
			
		||||
        $grantMock->setAccessTokenRepository($accessTokenRepositoryMock);
 | 
			
		||||
        $grantMock->setScopeRepository($scopeRepositoryMock);
 | 
			
		||||
        $grantMock->setPathToPrivateKey('./private.key');
 | 
			
		||||
        $grantMock->setPathToPublicKey('./public.key');
 | 
			
		||||
        $grantMock->setEmitter(new Emitter());
 | 
			
		||||
        $grantMock->setRefreshTokenTTL(new \DateInterval('PT1H'));
 | 
			
		||||
 | 
			
		||||
        $abstractGrantReflection = new \ReflectionClass($grantMock);
 | 
			
		||||
 | 
			
		||||
        $serverRequest = new ServerRequest();
 | 
			
		||||
        $serverRequest = $serverRequest->withParsedBody(
 | 
			
		||||
            [
 | 
			
		||||
                'client_id' => 'foo',
 | 
			
		||||
            ]
 | 
			
		||||
        );
 | 
			
		||||
        $validateClientMethod = $abstractGrantReflection->getMethod('validateClient');
 | 
			
		||||
        $validateClientMethod->setAccessible(true);
 | 
			
		||||
 | 
			
		||||
        $result = $validateClientMethod->invoke($grantMock, $serverRequest, true, true);
 | 
			
		||||
        $this->assertEquals($client, $result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testValidateClient()
 | 
			
		||||
    public function testValidateClientConfidential()
 | 
			
		||||
    {
 | 
			
		||||
        $client = new ClientEntity();
 | 
			
		||||
        $client->setSecret('bar');
 | 
			
		||||
        $client->setRedirectUri('http://foo/bar');
 | 
			
		||||
 | 
			
		||||
        $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
 | 
			
		||||
        $clientRepositoryMock->method('getClientEntity')->willReturn($client);
 | 
			
		||||
 | 
			
		||||
@@ -89,6 +112,7 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
 | 
			
		||||
    public function testValidateClientMissingClientSecret()
 | 
			
		||||
    {
 | 
			
		||||
        $client = new ClientEntity();
 | 
			
		||||
        $client->setSecret('bar');
 | 
			
		||||
        $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
 | 
			
		||||
        $clientRepositoryMock->method('getClientEntity')->willReturn($client);
 | 
			
		||||
 | 
			
		||||
@@ -112,9 +136,10 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
 | 
			
		||||
    /**
 | 
			
		||||
     * @expectedException \League\OAuth2\Server\Exception\OAuthServerException
 | 
			
		||||
     */
 | 
			
		||||
    public function testValidateClientMissingRedirectUri()
 | 
			
		||||
    public function testValidateClientInvalidClientSecret()
 | 
			
		||||
    {
 | 
			
		||||
        $client = new ClientEntity();
 | 
			
		||||
        $client->setSecret('bar');
 | 
			
		||||
        $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
 | 
			
		||||
        $clientRepositoryMock->method('getClientEntity')->willReturn($client);
 | 
			
		||||
 | 
			
		||||
@@ -124,6 +149,60 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
 | 
			
		||||
 | 
			
		||||
        $abstractGrantReflection = new \ReflectionClass($grantMock);
 | 
			
		||||
 | 
			
		||||
        $serverRequest = new ServerRequest();
 | 
			
		||||
        $serverRequest = $serverRequest->withParsedBody([
 | 
			
		||||
            'client_id' => 'foo',
 | 
			
		||||
            'client_secret' => 'foo',
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        $validateClientMethod = $abstractGrantReflection->getMethod('validateClient');
 | 
			
		||||
        $validateClientMethod->setAccessible(true);
 | 
			
		||||
 | 
			
		||||
        $validateClientMethod->invoke($grantMock, $serverRequest, true, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @expectedException \League\OAuth2\Server\Exception\OAuthServerException
 | 
			
		||||
     */
 | 
			
		||||
    public function testValidateClientInvalidRedirectUri()
 | 
			
		||||
    {
 | 
			
		||||
        $client = new ClientEntity();
 | 
			
		||||
        $client->setRedirectUri('http://foo/bar');
 | 
			
		||||
        $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
 | 
			
		||||
        $clientRepositoryMock->method('getClientEntity')->willReturn($client);
 | 
			
		||||
 | 
			
		||||
        /** @var AbstractGrant $grantMock */
 | 
			
		||||
        $grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
 | 
			
		||||
        $grantMock->setClientRepository($clientRepositoryMock);
 | 
			
		||||
 | 
			
		||||
        $abstractGrantReflection = new \ReflectionClass($grantMock);
 | 
			
		||||
 | 
			
		||||
        $serverRequest = new ServerRequest();
 | 
			
		||||
        $serverRequest = $serverRequest->withParsedBody([
 | 
			
		||||
            'client_id'     => 'foo',
 | 
			
		||||
            'redirect_uri'  =>  'http://bar/foo'
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        $validateClientMethod = $abstractGrantReflection->getMethod('validateClient');
 | 
			
		||||
        $validateClientMethod->setAccessible(true);
 | 
			
		||||
 | 
			
		||||
        $validateClientMethod->invoke($grantMock, $serverRequest, true, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @expectedException \League\OAuth2\Server\Exception\OAuthServerException
 | 
			
		||||
     */
 | 
			
		||||
    public function testValidateClientBadClient()
 | 
			
		||||
    {
 | 
			
		||||
        $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
 | 
			
		||||
        $clientRepositoryMock->method('getClientEntity')->willReturn(null);
 | 
			
		||||
 | 
			
		||||
        /** @var AbstractGrant $grantMock */
 | 
			
		||||
        $grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
 | 
			
		||||
        $grantMock->setClientRepository($clientRepositoryMock);
 | 
			
		||||
 | 
			
		||||
        $abstractGrantReflection = new \ReflectionClass($grantMock);
 | 
			
		||||
 | 
			
		||||
        $serverRequest = new ServerRequest();
 | 
			
		||||
        $serverRequest = $serverRequest->withParsedBody([
 | 
			
		||||
            'client_id'     => 'foo',
 | 
			
		||||
@@ -133,7 +212,7 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
 | 
			
		||||
        $validateClientMethod = $abstractGrantReflection->getMethod('validateClient');
 | 
			
		||||
        $validateClientMethod->setAccessible(true);
 | 
			
		||||
 | 
			
		||||
        $validateClientMethod->invoke($grantMock, $serverRequest, true, true);
 | 
			
		||||
        $validateClientMethod->invoke($grantMock, $serverRequest, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testCanRespondToRequest()
 | 
			
		||||
@@ -151,9 +230,12 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
 | 
			
		||||
 | 
			
		||||
    public function testIssueRefreshToken()
 | 
			
		||||
    {
 | 
			
		||||
        $refreshTokenRepoMock = $this->getMock(RefreshTokenRepositoryInterface::class);
 | 
			
		||||
 | 
			
		||||
        /** @var AbstractGrant $grantMock */
 | 
			
		||||
        $grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
 | 
			
		||||
        $grantMock->setRefreshTokenTTL(new \DateInterval('PT1M'));
 | 
			
		||||
        $grantMock->setRefreshTokenRepository($refreshTokenRepoMock);
 | 
			
		||||
 | 
			
		||||
        $abstractGrantReflection = new \ReflectionClass($grantMock);
 | 
			
		||||
        $issueRefreshTokenMethod = $abstractGrantReflection->getMethod('issueRefreshToken');
 | 
			
		||||
@@ -169,8 +251,11 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
 | 
			
		||||
 | 
			
		||||
    public function testIssueAccessToken()
 | 
			
		||||
    {
 | 
			
		||||
        $accessTokenRepoMock = $this->getMock(AccessTokenRepositoryInterface::class);
 | 
			
		||||
 | 
			
		||||
        /** @var AbstractGrant $grantMock */
 | 
			
		||||
        $grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
 | 
			
		||||
        $grantMock->setAccessTokenRepository($accessTokenRepoMock);
 | 
			
		||||
 | 
			
		||||
        $abstractGrantReflection = new \ReflectionClass($grantMock);
 | 
			
		||||
        $issueAccessTokenMethod = $abstractGrantReflection->getMethod('issueAccessToken');
 | 
			
		||||
@@ -190,8 +275,11 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
 | 
			
		||||
 | 
			
		||||
    public function testIssueAuthCode()
 | 
			
		||||
    {
 | 
			
		||||
        $authCodeRepoMock = $this->getMock(AuthCodeRepositoryInterface::class);
 | 
			
		||||
 | 
			
		||||
        /** @var AbstractGrant $grantMock */
 | 
			
		||||
        $grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
 | 
			
		||||
        $grantMock->setAuthCodeRepository($authCodeRepoMock);
 | 
			
		||||
 | 
			
		||||
        $abstractGrantReflection = new \ReflectionClass($grantMock);
 | 
			
		||||
        $issueAuthCodeMethod = $abstractGrantReflection->getMethod('issueAuthCode');
 | 
			
		||||
@@ -286,4 +374,15 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
 | 
			
		||||
 | 
			
		||||
        $grantMock->validateScopes($serverRequest, new ClientEntity());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testGenerateUniqueIdentifier()
 | 
			
		||||
    {
 | 
			
		||||
        $grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
 | 
			
		||||
 | 
			
		||||
        $abstractGrantReflection = new \ReflectionClass($grantMock);
 | 
			
		||||
        $method = $abstractGrantReflection->getMethod('generateUniqueIdentifier');
 | 
			
		||||
        $method->setAccessible(true);
 | 
			
		||||
 | 
			
		||||
        $this->assertTrue(is_string($method->invoke($grantMock)));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										48
									
								
								tests/Grant/ClientCredentialsGrantTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								tests/Grant/ClientCredentialsGrantTest.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace LeagueTests\Grant;
 | 
			
		||||
 | 
			
		||||
use League\OAuth2\Server\Entities\ClientEntity;
 | 
			
		||||
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
 | 
			
		||||
use League\OAuth2\Server\Grant\ClientCredentialsGrant;
 | 
			
		||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
 | 
			
		||||
use LeagueTests\Stubs\StubResponseType;
 | 
			
		||||
use Zend\Diactoros\ServerRequest;
 | 
			
		||||
 | 
			
		||||
class ClientCredentialsGrantTest extends \PHPUnit_Framework_TestCase
 | 
			
		||||
{
 | 
			
		||||
    public function testGetIdentifier()
 | 
			
		||||
    {
 | 
			
		||||
        $grant = new ClientCredentialsGrant();
 | 
			
		||||
        $this->assertEquals('client_credentials', $grant->getIdentifier());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testRespondToRequest()
 | 
			
		||||
    {
 | 
			
		||||
        $client = new ClientEntity();
 | 
			
		||||
        $client->setSecret('bar');
 | 
			
		||||
        $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
 | 
			
		||||
        $clientRepositoryMock->method('getClientEntity')->willReturn($client);
 | 
			
		||||
 | 
			
		||||
        $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
 | 
			
		||||
        $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
 | 
			
		||||
 | 
			
		||||
        $grant = new ClientCredentialsGrant();
 | 
			
		||||
        $grant->setClientRepository($clientRepositoryMock);
 | 
			
		||||
        $grant->setAccessTokenRepository($accessTokenRepositoryMock);
 | 
			
		||||
 | 
			
		||||
        $serverRequest = new ServerRequest();
 | 
			
		||||
        $serverRequest = $serverRequest->withParsedBody(
 | 
			
		||||
            [
 | 
			
		||||
                'client_id'     => 'foo',
 | 
			
		||||
                'client_secret' => 'bar',
 | 
			
		||||
            ]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $responseType = new StubResponseType();
 | 
			
		||||
        $grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
 | 
			
		||||
        
 | 
			
		||||
        $this->assertTrue($responseType->getAccessToken() instanceof AccessTokenEntityInterface);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								tests/Grant/PasswordGrantTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								tests/Grant/PasswordGrantTest.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace LeagueTests\Grant;
 | 
			
		||||
 | 
			
		||||
use League\OAuth2\Server\Entities\ClientEntity;
 | 
			
		||||
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
 | 
			
		||||
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
 | 
			
		||||
use League\OAuth2\Server\Grant\PasswordGrant;
 | 
			
		||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
 | 
			
		||||
use LeagueTests\Stubs\StubResponseType;
 | 
			
		||||
use LeagueTests\Stubs\UserEntity;
 | 
			
		||||
use Zend\Diactoros\ServerRequest;
 | 
			
		||||
 | 
			
		||||
class PasswordGrantTest extends \PHPUnit_Framework_TestCase
 | 
			
		||||
{
 | 
			
		||||
    public function testGetIdentifier()
 | 
			
		||||
    {
 | 
			
		||||
        $userRepositoryMock = $this->getMock(UserRepositoryInterface::class);
 | 
			
		||||
        $refreshTokenRepositoryMock = $this->getMock(RefreshTokenRepositoryInterface::class);
 | 
			
		||||
 | 
			
		||||
        $grant = new PasswordGrant($userRepositoryMock, $refreshTokenRepositoryMock);
 | 
			
		||||
        $this->assertEquals('password', $grant->getIdentifier());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testRespondToRequest()
 | 
			
		||||
    {
 | 
			
		||||
        $client = new ClientEntity();
 | 
			
		||||
        $client->setSecret('bar');
 | 
			
		||||
        $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
 | 
			
		||||
        $clientRepositoryMock->method('getClientEntity')->willReturn($client);
 | 
			
		||||
 | 
			
		||||
        $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
 | 
			
		||||
        $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
 | 
			
		||||
 | 
			
		||||
        $userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
 | 
			
		||||
        $userEntity = new UserEntity();
 | 
			
		||||
        $userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
 | 
			
		||||
 | 
			
		||||
        $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
 | 
			
		||||
        $refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
 | 
			
		||||
 | 
			
		||||
        $grant = new PasswordGrant($userRepositoryMock, $refreshTokenRepositoryMock);
 | 
			
		||||
        $grant->setClientRepository($clientRepositoryMock);
 | 
			
		||||
        $grant->setAccessTokenRepository($accessTokenRepositoryMock);
 | 
			
		||||
 | 
			
		||||
        $serverRequest = new ServerRequest();
 | 
			
		||||
        $serverRequest = $serverRequest->withParsedBody(
 | 
			
		||||
            [
 | 
			
		||||
                'client_id'     => 'foo',
 | 
			
		||||
                'client_secret' => 'bar',
 | 
			
		||||
                'username'      => 'foo',
 | 
			
		||||
                'password'      => 'bar',
 | 
			
		||||
            ]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $responseType = new StubResponseType();
 | 
			
		||||
        $grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
 | 
			
		||||
 | 
			
		||||
        $this->assertTrue($responseType->getAccessToken() instanceof AccessTokenEntityInterface);
 | 
			
		||||
        $this->assertTrue($responseType->getRefreshToken() instanceof RefreshTokenEntityInterface);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										83
									
								
								tests/Grant/RefreshTokenGrantTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								tests/Grant/RefreshTokenGrantTest.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace LeagueTests\Grant;
 | 
			
		||||
 | 
			
		||||
use League\OAuth2\Server\Entities\ClientEntity;
 | 
			
		||||
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
 | 
			
		||||
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
 | 
			
		||||
use League\OAuth2\Server\Grant\PasswordGrant;
 | 
			
		||||
use League\OAuth2\Server\Grant\RefreshTokenGrant;
 | 
			
		||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\UserRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Utils\KeyCrypt;
 | 
			
		||||
use LeagueTests\Stubs\StubResponseType;
 | 
			
		||||
use LeagueTests\Stubs\UserEntity;
 | 
			
		||||
use OAuth2ServerExamples\Repositories\RefreshTokenRepository;
 | 
			
		||||
use Zend\Diactoros\ServerRequest;
 | 
			
		||||
 | 
			
		||||
class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase
 | 
			
		||||
{
 | 
			
		||||
    public function testGetIdentifier()
 | 
			
		||||
    {
 | 
			
		||||
        $refreshTokenRepositoryMock = $this->getMock(RefreshTokenRepositoryInterface::class);
 | 
			
		||||
 | 
			
		||||
        $grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
 | 
			
		||||
        $this->assertEquals('refresh_token', $grant->getIdentifier());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testRespondToRequest()
 | 
			
		||||
    {
 | 
			
		||||
        $client = new ClientEntity();
 | 
			
		||||
        $client->setIdentifier('foo');
 | 
			
		||||
        $client->setSecret('bar');
 | 
			
		||||
        $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
 | 
			
		||||
        $clientRepositoryMock->method('getClientEntity')->willReturn($client);
 | 
			
		||||
 | 
			
		||||
        $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
 | 
			
		||||
        $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf();
 | 
			
		||||
 | 
			
		||||
        $userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock();
 | 
			
		||||
        $userEntity = new UserEntity();
 | 
			
		||||
        $userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity);
 | 
			
		||||
 | 
			
		||||
        $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
 | 
			
		||||
        $refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf();
 | 
			
		||||
 | 
			
		||||
        $grant = new RefreshTokenGrant($refreshTokenRepositoryMock);
 | 
			
		||||
        $grant->setClientRepository($clientRepositoryMock);
 | 
			
		||||
        $grant->setAccessTokenRepository($accessTokenRepositoryMock);
 | 
			
		||||
        $grant->setPathToPublicKey('file://'.__DIR__.'/../Utils/public.key');
 | 
			
		||||
        $grant->setPathToPrivateKey('file://'.__DIR__.'/../Utils/private.key');
 | 
			
		||||
 | 
			
		||||
        $oldRefreshToken = KeyCrypt::encrypt(
 | 
			
		||||
            json_encode(
 | 
			
		||||
                [
 | 
			
		||||
                    'client_id'        => 'foo',
 | 
			
		||||
                    'refresh_token_id' => 'zyxwvu',
 | 
			
		||||
                    'access_token_id'  => 'abcdef',
 | 
			
		||||
                    'scopes'           => ['foo'],
 | 
			
		||||
                    'user_id'          => 123,
 | 
			
		||||
                    'expire_time'      => time() + 3600,
 | 
			
		||||
                ]
 | 
			
		||||
            ),
 | 
			
		||||
            'file://'.__DIR__.'/../Utils/private.key'
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $serverRequest = new ServerRequest();
 | 
			
		||||
        $serverRequest = $serverRequest->withParsedBody(
 | 
			
		||||
            [
 | 
			
		||||
                'client_id'     => 'foo',
 | 
			
		||||
                'client_secret' => 'bar',
 | 
			
		||||
                'refresh_token' => $oldRefreshToken,
 | 
			
		||||
            ]
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $responseType = new StubResponseType();
 | 
			
		||||
        $grant->respondToRequest($serverRequest, $responseType, new \DateInterval('PT5M'));
 | 
			
		||||
 | 
			
		||||
        $this->assertTrue($responseType->getAccessToken() instanceof AccessTokenEntityInterface);
 | 
			
		||||
        $this->assertTrue($responseType->getRefreshToken() instanceof RefreshTokenEntityInterface);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										56
									
								
								tests/ServerTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								tests/ServerTest.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace LeagueTests;
 | 
			
		||||
 | 
			
		||||
use League\OAuth2\Server\Entities\ClientEntity;
 | 
			
		||||
use League\OAuth2\Server\Grant\ClientCredentialsGrant;
 | 
			
		||||
use League\OAuth2\Server\Server;
 | 
			
		||||
use LeagueTests\Stubs\StubResponseType;
 | 
			
		||||
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
 | 
			
		||||
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
 | 
			
		||||
use Psr\Http\Message\ResponseInterface;
 | 
			
		||||
 | 
			
		||||
class ServerTest extends \PHPUnit_Framework_TestCase
 | 
			
		||||
{
 | 
			
		||||
    public function testRespondToRequestInvalidGrantType()
 | 
			
		||||
    {
 | 
			
		||||
        $server = new Server(
 | 
			
		||||
            $this->getMock(ClientRepositoryInterface::class),
 | 
			
		||||
            $this->getMock(AccessTokenRepositoryInterface::class),
 | 
			
		||||
            $this->getMock(ScopeRepositoryInterface::class),
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            new StubResponseType()
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M'));
 | 
			
		||||
 | 
			
		||||
        $response = $server->respondToRequest();
 | 
			
		||||
        $this->assertTrue($response instanceof ResponseInterface);
 | 
			
		||||
        $this->assertEquals(400, $response->getStatusCode());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testRespondToRequest()
 | 
			
		||||
    {
 | 
			
		||||
        $clientRepository = $this->getMock(ClientRepositoryInterface::class);
 | 
			
		||||
        $clientRepository->method('getClientEntity')->willReturn(new ClientEntity());
 | 
			
		||||
 | 
			
		||||
        $server = new Server(
 | 
			
		||||
            $clientRepository,
 | 
			
		||||
            $this->getMock(AccessTokenRepositoryInterface::class),
 | 
			
		||||
            $this->getMock(ScopeRepositoryInterface::class),
 | 
			
		||||
            '',
 | 
			
		||||
            '',
 | 
			
		||||
            new StubResponseType()
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M'));
 | 
			
		||||
 | 
			
		||||
        $_POST['grant_type'] = 'client_credentials';
 | 
			
		||||
        $_POST['client_id'] = 'foo';
 | 
			
		||||
        $_POST['client_secret'] = 'bar';
 | 
			
		||||
        $response = $server->respondToRequest();
 | 
			
		||||
        $this->assertEquals(200, $response->getStatusCode());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								tests/Stubs/StubResponseType.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								tests/Stubs/StubResponseType.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace LeagueTests\Stubs;
 | 
			
		||||
 | 
			
		||||
use League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface;
 | 
			
		||||
use League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface;
 | 
			
		||||
use League\OAuth2\Server\ResponseTypes\AbstractResponseType;
 | 
			
		||||
use Psr\Http\Message\ResponseInterface;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
use Zend\Diactoros\Response;
 | 
			
		||||
 | 
			
		||||
class StubResponseType extends AbstractResponseType
 | 
			
		||||
{
 | 
			
		||||
    public function __construct() {}
 | 
			
		||||
 | 
			
		||||
    public function getAccessToken()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->accessToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function getRefreshToken()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->refreshToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param \League\OAuth2\Server\Entities\Interfaces\AccessTokenEntityInterface $accessToken
 | 
			
		||||
     */
 | 
			
		||||
    public function setAccessToken(AccessTokenEntityInterface $accessToken)
 | 
			
		||||
    {
 | 
			
		||||
        $this->accessToken = $accessToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param \League\OAuth2\Server\Entities\Interfaces\RefreshTokenEntityInterface $refreshToken
 | 
			
		||||
     */
 | 
			
		||||
    public function setRefreshToken(RefreshTokenEntityInterface $refreshToken)
 | 
			
		||||
    {
 | 
			
		||||
        $this->refreshToken = $refreshToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param ServerRequestInterface $request
 | 
			
		||||
     *
 | 
			
		||||
     * @return ServerRequestInterface
 | 
			
		||||
     */
 | 
			
		||||
    public function determineAccessTokenInHeader(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        // TODO: Implement determineAccessTokenInHeader() method.
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param ResponseInterface $response
 | 
			
		||||
     *
 | 
			
		||||
     * @return ResponseInterface
 | 
			
		||||
     */
 | 
			
		||||
    public function generateHttpResponse(ResponseInterface $response)
 | 
			
		||||
    {
 | 
			
		||||
        return new Response();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								tests/Stubs/UserEntity.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								tests/Stubs/UserEntity.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace LeagueTests\Stubs;
 | 
			
		||||
 | 
			
		||||
use League\OAuth2\Server\Entities\Interfaces\UserEntityInterface;
 | 
			
		||||
 | 
			
		||||
class UserEntity implements UserEntityInterface
 | 
			
		||||
{
 | 
			
		||||
    public function getIdentifier()
 | 
			
		||||
    {
 | 
			
		||||
        return 123;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user