/** Implements first request processing for Authorization code (Authorization Request processing) * http://tools.ietf.org/html/rfc6749#section-4.1.1 and * http://tools.ietf.org/html/rfc6749#section-4.1.2 * @param OAuth2Request $request * @return mixed|OAuth2AuthorizationResponse * @throws \oauth2\exceptions\UnsupportedResponseTypeException * @throws \oauth2\exceptions\LockedClientException * @throws \oauth2\exceptions\InvalidClientException * @throws \oauth2\exceptions\ScopeNotAllowedException * @throws \oauth2\exceptions\OAuth2GenericException * @throws \oauth2\exceptions\InvalidApplicationType * @throws \oauth2\exceptions\AccessDeniedException * @throws \oauth2\exceptions\UriNotAllowedException * @throws \oauth2\exceptions\InvalidOAuth2Request */ public function handle(OAuth2Request $request) { $reflector = new ReflectionClass($request); $class_name = $reflector->getName(); if ($class_name == 'oauth2\\requests\\OAuth2AuthorizationRequest') { $client_id = $request->getClientId(); $response_type = $request->getResponseType(); if ($response_type !== $this->getResponseType()) { throw new UnsupportedResponseTypeException(sprintf("response_type %s", $response_type)); } $client = $this->client_service->getClientById($client_id); if (is_null($client)) { throw new InvalidClientException($client_id, sprintf("client_id %s does not exists!", $client_id)); } if (!$client->isActive() || $client->isLocked()) { throw new LockedClientException(sprintf($client, 'client id %s is locked', $client)); } if ($client->getApplicationType() != IClient::ApplicationType_Web_App) { throw new InvalidApplicationType($client_id, sprintf("client id %s - Application type must be WEB_APPLICATION", $client_id)); } //check redirect uri $redirect_uri = $request->getRedirectUri(); if (!$client->isUriAllowed($redirect_uri)) { throw new UriNotAllowedException(sprintf("redirect_to %s", $redirect_uri)); } //check requested scope $scope = $request->getScope(); if (!$client->isScopeAllowed($scope)) { throw new ScopeNotAllowedException(sprintf("scope %s", $scope)); } $state = $request->getState(); $authentication_response = $this->auth_service->getUserAuthenticationResponse(); if ($authentication_response == IAuthService::AuthenticationResponse_Cancel) { //clear saved data ... $this->memento_service->clearCurrentRequest(); $this->auth_service->clearUserAuthenticationResponse(); $this->auth_service->clearUserAuthorizationResponse(); throw new AccessDeniedException(); } //check user logged if (!$this->auth_service->isUserLogged()) { $this->memento_service->saveCurrentAuthorizationRequest(); return $this->auth_strategy->doLogin($this->memento_service->getCurrentAuthorizationRequest()); } $approval_prompt = $request->getApprovalPrompt(); $access_type = $request->getAccessType(); $user = $this->auth_service->getCurrentUser(); if (is_null($user)) { throw new OAuth2GenericException("Invalid Current User"); } $authorization_response = $this->auth_service->getUserAuthorizationResponse(); //check for former user consents $former_user_consent = $this->user_consent_service->get($user->getId(), $client->getId(), $scope); if (!(!is_null($former_user_consent) && $approval_prompt == OAuth2Protocol::OAuth2Protocol_Approval_Prompt_Auto)) { if ($authorization_response == IAuthService::AuthorizationResponse_None) { $this->memento_service->saveCurrentAuthorizationRequest(); return $this->auth_strategy->doConsent($this->memento_service->getCurrentAuthorizationRequest()); } else { if ($authorization_response == IAuthService::AuthorizationResponse_DenyOnce) { throw new AccessDeniedException(); } } //save possitive consent if (is_null($former_user_consent)) { $this->user_consent_service->add($user->getId(), $client->getId(), $scope); } } // build current audience ... $audience = $this->scope_service->getStrAudienceByScopeNames(explode(' ', $scope)); $auth_code = $this->token_service->createAuthorizationCode($user->getId(), $client_id, $scope, $audience, $redirect_uri, $access_type, $approval_prompt, !is_null($former_user_consent)); if (is_null($auth_code)) { throw new OAuth2GenericException("Invalid Auth Code"); } // clear save data ... $this->auth_service->clearUserAuthorizationResponse(); $this->memento_service->clearCurrentRequest(); return new OAuth2AuthorizationResponse($redirect_uri, $auth_code->getValue(), $scope, $state); } throw new InvalidOAuth2Request(); }