public function getAuthorization(Request $request, UserInfoInterface $userInfo) { $authorizeRequest = new AuthorizeRequest($request); $clientId = $authorizeRequest->getClientId(); $responseType = $authorizeRequest->getResponseType(); $redirectUri = $authorizeRequest->getRedirectUri(); $scope = $authorizeRequest->getScope(); $state = $authorizeRequest->getState(); $clientData = $this->storage->getClient($clientId); if (false === $clientData) { throw new BadRequestException('client not registered'); } if (null === $redirectUri) { $redirectUri = $clientData->getRedirectUri(); } else { if (!$clientData->verifyRedirectUri($redirectUri, $this->allowRegExpRedirectUriMatch)) { throw new BadRequestException('specified redirect_uri not the same as registered redirect_uri'); } // we now use the provided redirect_uri... } if ($responseType !== $clientData->getType()) { return new ClientResponse($clientData, $request, $redirectUri, array('error' => 'unsupported_response_type', 'error_description' => 'response_type not supported by client profile')); } $scopeObj = new Scope($scope); $allowedScopeObj = new Scope($clientData->getAllowedScope()); if (!$scopeObj->hasOnlyScope($allowedScopeObj)) { return new ClientResponse($clientData, $request, $redirectUri, array('error' => 'invalid_scope', 'error_description' => 'not authorized to request this scope')); } if ($clientData->getDisableUserConsent()) { // we do not require approval by the user, add implicit approval $this->addApproval($clientData, $userInfo->getUserId(), $scope); } $approval = $this->storage->getApprovalByResourceOwnerId($clientId, $userInfo->getUserId()); $approvedScopeObj = new Scope($approval['scope']); if (false === $approval || false === $scopeObj->hasOnlyScope($approvedScopeObj)) { // we do not yet have an approval at all, or client wants more // permissions, so we ask the user for approval $response = new Response(); $response->setBody($this->templateManager->render('askAuthorization', array('resourceOwnerId' => $userInfo->getUserId(), 'sslEnabled' => 'https' === $request->getUrl()->getScheme(), 'contactEmail' => $clientData->getContactEmail(), 'scopes' => $scopeObj->toArray(), 'clientName' => $clientData->getName(), 'clientId' => $clientData->getId(), 'clientDescription' => $clientData->getDescription()))); return $response; } else { // we already have approval if ('token' === $responseType) { // implicit grant // FIXME: return existing access token if it exists for this exact client, resource owner and scope? $accessToken = $this->io->getRandomHex(); $this->storage->storeAccessToken($accessToken, $this->io->getTime(), $clientId, $userInfo->getUserId(), $scope, $this->accessTokenExpiry); return new ClientResponse($clientData, $request, $redirectUri, array('access_token' => $accessToken, 'expires_in' => $this->accessTokenExpiry, 'token_type' => 'bearer', 'scope' => $scope)); } else { // authorization code grant $authorizationCode = $this->io->getRandomHex(); $this->storage->storeAuthorizationCode($authorizationCode, $userInfo->getUserId(), $this->io->getTime(), $clientId, $authorizeRequest->getRedirectUri(), $scope); return new ClientResponse($clientData, $request, $redirectUri, array('code' => $authorizationCode)); } } }
public function hasOnlyScope(Scope $that) { if (0 === count($this->toArray())) { return true; } foreach ($this->toArray() as $s) { if (!in_array($s, $that->toArray())) { return false; } } return true; }
public function handleRefreshToken(TokenRequest $tokenRequest, ClientData $clientData) { $refreshToken = $tokenRequest->getRefreshToken(); $scope = $tokenRequest->getScope(); $result = $this->db->getApprovalByRefreshToken($clientData->getId(), $refreshToken); if (false === $result) { throw new BadRequestException('invalid_grant', 'the refresh_token was not found'); } $token = array(); $token['access_token'] = $this->io->getRandomHex(); $token['expires_in'] = $this->accessTokenExpiry; if (null !== $scope) { // the client wants to obtain a specific scope $requestedScope = new Scope($scope); $authorizedScope = new Scope($result['scope']); if ($requestedScope->hasOnlyScope($authorizedScope)) { // if it is a subset of the authorized scope we honor that $token['scope'] = $requestedScope->toString(); } else { // if not the client gets the authorized scope $token['scope'] = $result['scope']; } } else { $token['scope'] = $result['scope']; } $token['token_type'] = 'bearer'; $this->db->storeAccessToken($token['access_token'], $this->io->getTime(), $clientData->getId(), $result['resource_owner_id'], $token['scope'], $token['expires_in']); return $token; }