/**
  * {@inheritdoc}
  */
 public function checkRefreshToken(RefreshTokenInterface $token, ClientInterface $client)
 {
     if ($client->getPublicId() !== $token->getClientPublicId()) {
         throw $this->getExceptionManager()->getException(ExceptionManagerInterface::BAD_REQUEST, ExceptionManagerInterface::INVALID_GRANT, 'Invalid refresh token');
     }
     if ($token->hasExpired()) {
         throw $this->getExceptionManager()->getException(ExceptionManagerInterface::BAD_REQUEST, ExceptionManagerInterface::INVALID_GRANT, 'Refresh token has expired');
     }
 }
 /**
  * {@inheritdoc}
  */
 public function grantAccessToken(ServerRequestInterface $request, ClientInterface $client, GrantTypeResponseInterface &$grant_type_response)
 {
     if ($client->isPublic()) {
         throw $this->getExceptionManager()->getBadRequestException(ExceptionManagerInterface::ERROR_INVALID_CLIENT, 'The client is not a confidential client');
     }
     $issue_refresh_token = $this->isRefreshTokenIssuedWithAccessToken();
     $grant_type_response->setResourceOwnerPublicId($client->getPublicId());
     $grant_type_response->setUserAccountPublicId(null);
     $grant_type_response->setRefreshTokenIssued($issue_refresh_token);
     $grant_type_response->setRefreshTokenScope($grant_type_response->getRequestedScope());
 }
 protected function addAuthCode($code, $expiresAt, ClientInterface $client, EndUserInterface $end_user, array $query_params, $redirectUri, array $scope = [], $issueRefreshToken = false)
 {
     $class = $this->getClass();
     /*
      * @var \SpomkyLabs\OAuth2ServerBundle\Plugin\AuthCodeGrantTypePlugin\Model\AuthCodeInterface
      */
     $authcode = new $class();
     $authcode->setRedirectUri($redirectUri)->setQueryParams($query_params)->setIssueRefreshToken($issueRefreshToken)->setToken($code)->setResourceOwnerPublicId($end_user->getPublicId())->setExpiresAt($expiresAt)->setClientPublicId($client->getPublicId())->setScope($scope);
     $this->getEntityManager()->persist($authcode);
     $this->getEntityManager()->flush();
     return $authcode;
 }
 public function createUsedRefreshToken(ClientInterface $client, ResourceOwnerInterface $resource_owner, $refresh_token)
 {
     $class = $this->getClass();
     $expired_date = (new \Datetime('now +1 year'))->format('U');
     $token = new $class();
     /*
      * @var $token \OAuth2\Token\RefreshTokenInterface
      */
     $token->setToken($refresh_token)->setExpiresAt($expired_date)->setResourceOwnerPublicId($resource_owner->getPublicId())->setClientPublicId($client->getPublicId())->setUsed(true);
     $this->getEntityManager()->persist($token);
     $this->getEntityManager()->flush();
     return $token;
 }
 /**
  * {@inheritdoc}
  */
 public function grantAccessToken(ServerRequestInterface $request, ClientInterface $client, GrantTypeResponseInterface &$grant_type_response)
 {
     if (!$client instanceof ConfidentialClientInterface) {
         throw $this->getExceptionManager()->getException(ExceptionManagerInterface::BAD_REQUEST, ExceptionManagerInterface::INVALID_CLIENT, 'The client is not a confidential client');
     }
     $issue_refresh_token = $this->getConfiguration()->get('issue_refresh_token_with_client_credentials_grant_type', false);
     $scope = RequestBody::getParameter($request, 'scope');
     $grant_type_response->setRequestedScope($scope);
     $grant_type_response->setAvailableScope(null);
     $grant_type_response->setResourceOwnerPublicId($client->getPublicId());
     $grant_type_response->setRefreshTokenIssued($issue_refresh_token);
     $grant_type_response->setRefreshTokenScope($scope);
     $grant_type_response->setRefreshTokenRevoked(null);
 }
 /**
  * {@inheritdoc}
  */
 public function createAuthCode(ClientInterface $client, UserAccountInterface $resource_owner, array $query_params, $redirectUri, array $scope = [], $issueRefreshToken = false)
 {
     $auth_code = $this->createEmptyAuthorizationCode();
     $auth_code->setScope($scope);
     $auth_code->setResourceOwnerPublicId($resource_owner->getUserPublicId());
     $auth_code->setUserAccountPublicId($resource_owner->getPublicId());
     $auth_code->setClientPublicId($client->getPublicId());
     $auth_code->setExpiresAt(time() + $this->getLifetime($client));
     $auth_code->setToken($this->generateAuthorizationCode());
     $auth_code->setIssueRefreshToken($issueRefreshToken);
     $auth_code->setQueryParams($query_params);
     $auth_code->setMetadata('redirect_uri', $redirectUri);
     $this->updateAuthCode($auth_code);
     $this->saveAuthorizationCode($auth_code);
     return $auth_code;
 }
 /**
  * {@inheritdoc}
  */
 public function createRefreshToken(ClientInterface $client, ResourceOwnerInterface $resource_owner, array $scope = [], array $metadatas = [])
 {
     $refresh_token = $this->createEmptyRefreshToken();
     $refresh_token->setScope($scope);
     if ($resource_owner instanceof UserAccountInterface) {
         $refresh_token->setResourceOwnerPublicId($resource_owner->getUserPublicId());
         $refresh_token->setUserAccountPublicId($resource_owner->getPublicId());
     } else {
         $refresh_token->setResourceOwnerPublicId($resource_owner->getPublicId());
     }
     $refresh_token->setClientPublicId($client->getPublicId());
     $refresh_token->setExpiresAt(time() + $this->getLifetime($client));
     $refresh_token->setToken($this->generateToken());
     $refresh_token->setMetadatas($metadatas);
     $this->updateRefreshToken($refresh_token);
     $this->saveRefreshToken($refresh_token);
     return $refresh_token;
 }
 protected function addAccessToken($token, $expiresAt, ClientInterface $client, ResourceOwnerInterface $resourceOwner, array $scope = [], BaseRefreshTokenInterface $refresh_token = null)
 {
     if (null !== $this->event_dispatcher) {
         $this->event_dispatcher->dispatch(Events::OAUTH2_PRE_ACCESS_TOKEN_CREATION, new PreAccessTokenCreationEvent($client, $scope, $resourceOwner, $refresh_token));
     }
     $class = $this->getClass();
     /*
      * @var \SpomkyLabs\OAuth2ServerBundle\Plugin\SimpleStringAccessTokenPlugin\Model\SimpleStringAccessTokenInterface
      */
     $access_token = new $class();
     $access_token->setToken($token)->setExpiresAt($expiresAt)->setClientPublicId($client->getPublicId())->setScope($scope);
     if (null !== $resourceOwner) {
         $access_token->setResourceOwnerPublicId($resourceOwner->getPublicId());
     }
     if (null !== $refresh_token) {
         $access_token->setRefreshToken($refresh_token->getToken());
     }
     $this->getEntityManager()->persist($access_token);
     $this->getEntityManager()->flush();
     if (null !== $this->event_dispatcher) {
         $this->event_dispatcher->dispatch(Events::OAUTH2_POST_ACCESS_TOKEN_CREATION, new PostAccessTokenCreationEvent($access_token));
     }
     return $access_token;
 }
 /**
  * @param \OAuth2\Token\AccessTokenInterface|\OAuth2\Token\RefreshTokenInterface $token
  * @param \OAuth2\Client\ClientInterface|null                                    $client
  *
  * @return bool
  */
 private function isClientVerified($token, ClientInterface $client = null)
 {
     if (null !== $client) {
         // The client ID of the token is the same as client authenticated
         return $token->getClientPublicId() === $client->getPublicId();
     } else {
         // We try to get the client
         $client = $this->getClientManagerSupervisor()->getClient($token->getClientPublicId());
         // Return false if the client is a confidential client (confidential client must be authenticated)
         return !$client instanceof ConfidentialClientInterface;
     }
 }
 /**
  * @param \Psr\Http\Message\ServerRequestInterface $request
  * @param \Psr\Http\Message\ResponseInterface      $response
  * @param \OAuth2\Client\ClientInterface           $client
  */
 private function handlePut(ServerRequestInterface $request, ResponseInterface &$response, ClientInterface $client)
 {
     $request_parameters = RequestBody::getParameters($request);
     $this->checkPreservedParameters($request_parameters);
     $this->checkSoftwareStatement($request_parameters);
     $client_data = $client->all();
     foreach (['registration_access_token', 'registration_client_uri', 'client_secret_expires_at', 'client_id_issued_at'] as $k) {
         if (array_key_exists($k, $client_data)) {
             unset($client_data[$k]);
         }
     }
     $diff_data = array_diff_key($client_data, $request_parameters);
     Assertion::true(empty($diff_data), 'The request must include all client metadata fields.');
     Assertion::eq($request_parameters['client_id'], $client->getPublicId(), 'Inconsistent "client_id" parameter.');
     unset($request_parameters['client_id']);
     $request_parameters = array_merge($request_parameters, ['registration_access_token' => null, 'registration_client_uri' => null, 'client_secret_expires_at' => null]);
     foreach ($request_parameters as $k => $v) {
         if (empty($v)) {
             $client->remove($k);
             unset($request_parameters[$k]);
         }
     }
     $this->getClientRuleManager()->processParametersForClient($client, $request_parameters);
     $this->getClientManager()->saveClient($client);
     $this->processResponseWithClient($response, $client);
 }
 /**
  * @param \OAuth2\Endpoint\TokenType\RevocationTokenTypeInterface $token_type
  * @param string                                                  $token
  * @param \OAuth2\Client\ClientInterface                          $client
  *
  * @return bool
  */
 private function tryRevokeToken(RevocationTokenTypeInterface $token_type, $token, ClientInterface $client)
 {
     $result = $token_type->getToken($token);
     if ($result instanceof TokenInterface) {
         if ($result->getClientPublicId() === $client->getPublicId()) {
             $token_type->revokeToken($result);
             return true;
         }
     }
     return false;
 }
 /**
  * {@inheritdoc}
  */
 protected function getRegistrationClientUri(ClientInterface $client)
 {
     return $this->router->generate('oauth2_server_client_configuration', ['client_id' => $client->getPublicId()], UrlGeneratorInterface::ABSOLUTE_URL);
 }
 /**
  * @param \OAuth2\Token\AuthCodeInterface $authCode
  * @param \OAuth2\Client\ClientInterface  $client
  *
  * @throws \OAuth2\Exception\BaseExceptionInterface
  */
 protected function checkAuthCode(AuthCodeInterface $authCode, ClientInterface $client)
 {
     if ($client->getPublicId() !== $authCode->getClientPublicId()) {
         throw $this->getExceptionManager()->getException(ExceptionManagerInterface::BAD_REQUEST, ExceptionManagerInterface::INVALID_GRANT, "Code doesn't exist or is invalid for the client.");
     }
     if ($authCode->hasExpired()) {
         throw $this->getExceptionManager()->getException(ExceptionManagerInterface::BAD_REQUEST, ExceptionManagerInterface::INVALID_GRANT, 'The authorization code has expired.');
     }
 }
 /**
  * @param \Psr\Http\Message\ResponseInterface                        $response
  * @param \OAuth2\Endpoint\TokenType\IntrospectionTokenTypeInterface $token_type
  * @param string                                                     $token
  * @param \OAuth2\Client\ClientInterface                             $client
  *
  * @return bool
  */
 private function tryIntrospectToken(ResponseInterface &$response, IntrospectionTokenTypeInterface $token_type, $token, ClientInterface $client)
 {
     $result = $token_type->getToken($token);
     if ($result instanceof TokenInterface) {
         if ($result->getClientPublicId() === $client->getPublicId() || true === $this->isClientAResourceServer($client)) {
             $data = $token_type->introspectToken($result, $client);
             $this->populateResponse($response, $data);
             return true;
         }
     }
     return false;
 }
 /**
  * {@inheritdoc}
  */
 public function introspectToken(TokenInterface $token, ClientInterface $client)
 {
     if (!$token instanceof AccessTokenInterface) {
         return [];
     }
     $result = ['active' => !$token->hasExpired(), 'client_id' => $token->getClientPublicId(), 'token_type' => $token->getTokenTypeParameter('token_type'), 'exp' => $token->getExpiresAt()];
     // If the client is the subject, we add this information.
     //
     // The subject is not added if the client is not a resource owner.
     // The reason is that if the client received an ID Token, the subject may have been computed (pairwise) and
     // the subject returned here may be different. As per the OpenID Connect specification, the client must reject the token
     // if subject are different and we want to avoid this case.
     if ($client->getPublicId() === $token->getResourceOwnerPublicId()) {
         $result['sub'] = $token->getResourceOwnerPublicId();
     }
     // If the client is a resource server, we return all the information stored in the access token including the metadata
     if ($client->has('is_resource_server') && true === $client->get('is_resource_server')) {
         $result['sub'] = $token->getResourceOwnerPublicId();
     }
     if (!empty($token->getScope())) {
         $result['scp'] = $token->getScope();
     }
     if ($token instanceof JWTAccessTokenInterface) {
         $result = array_merge($result, $this->getJWTInformation($token->getJWS()));
     }
     return $result;
 }
 /**
  * {@inheritdoc}
  */
 public function grantAccessToken(ServerRequestInterface $request, ClientInterface $client, GrantTypeResponseInterface &$grant_type_response)
 {
     if (false === $client->hasPublicKeySet()) {
         throw $this->getExceptionManager()->getBadRequestException(ExceptionManagerInterface::ERROR_INVALID_CLIENT, 'The client is not a client with signature capabilities.');
     }
     $jwt = $grant_type_response->getAdditionalData('jwt');
     try {
         $this->getJWTLoader()->verify($jwt, $client->getPublicKeySet());
     } catch (\Exception $e) {
         throw $this->getExceptionManager()->getBadRequestException(ExceptionManagerInterface::ERROR_INVALID_REQUEST, $e->getMessage());
     }
     $issue_refresh_token = $this->isRefreshTokenIssuedWithAccessToken();
     $grant_type_response->setResourceOwnerPublicId($client->getPublicId());
     $grant_type_response->setUserAccountPublicId(null);
     $grant_type_response->setRefreshTokenIssued($issue_refresh_token);
     $grant_type_response->setRefreshTokenScope($grant_type_response->getRequestedScope());
 }
 /**
  * @param string                                       $token
  * @param int                                          $expiresAt
  * @param \OAuth2\Client\ClientInterface               $client
  * @param array                                        $scope
  * @param \OAuth2\ResourceOwner\ResourceOwnerInterface $resourceOwner
  *
  * @return mixed
  */
 protected function addRefreshToken($token, $expiresAt, ClientInterface $client, ResourceOwnerInterface $resourceOwner, array $scope = [])
 {
     $class = $this->getClass();
     /*
      * @var \OAuth2\Token\RefreshTokenInterface
      */
     $refresh_token = new $class();
     $refresh_token->setClientPublicId($client->getPublicId())->setExpiresAt($expiresAt)->setResourceOwnerPublicId($resourceOwner->getPublicId())->setToken($token)->setScope($scope);
     $this->save($refresh_token);
     return $refresh_token;
 }
 /**
  * @param \OAuth2\Token\AccessTokenInterface  $access_token
  * @param \OAuth2\Client\ClientInterface|null $resource_server
  *
  * @return array
  */
 protected function preparePayload(AccessTokenInterface $access_token, ClientInterface $resource_server = null)
 {
     $aud = [$this->getIssuer()];
     if (null !== $resource_server) {
         $access_token[] = $resource_server->getPublicId();
     }
     $payload = ['jti' => Base64Url::encode(random_bytes(25)), 'iss' => $this->getIssuer(), 'aud' => $aud, 'iat' => time(), 'nbf' => time(), 'exp' => $access_token->getExpiresAt(), 'sub' => $access_token->getClientPublicId(), 'token_type' => $access_token->getTokenTypeParameter('token_type'), 'scp' => $access_token->getScope(), 'resource_owner' => $access_token->getResourceOwnerPublicId(), 'user_account' => $access_token->getUserAccountPublicId()];
     $payload['metadatas'] = $access_token->getMetadatas();
     if (0 !== ($expires_at = $access_token->getExpiresAt())) {
         $payload['exp'] = $expires_at;
     }
     if (!empty($access_token->getParameters())) {
         $parameters = $access_token->getParameters();
         //This part should be updated to support 'cnf' (confirmation) claim (see POP).
         $payload['other'] = $parameters;
     }
     if (null !== $access_token->getRefreshToken()) {
         $payload['refresh_token'] = $access_token->getRefreshToken();
     }
     return $payload;
 }