1<?php 2/** 3 * @author Alex Bilbie <hello@alexbilbie.com> 4 * @copyright Copyright (c) Alex Bilbie 5 * @license http://mit-license.org/ 6 * 7 * @link https://github.com/thephpleague/oauth2-server 8 */ 9 10use Defuse\Crypto\Key; 11use League\Event\EmitterAwareInterface; 12use League\Event\EmitterAwareTrait; 13use League\OAuth2\Server\Exception\OAuthServerException; 14use League\OAuth2\Server\Grant\GrantTypeInterface; 15use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; 16use League\OAuth2\Server\Repositories\ClientRepositoryInterface; 17use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; 18use League\OAuth2\Server\RequestTypes\AuthorizationRequest; 19use League\OAuth2\Server\ResponseTypes\AbstractResponseType; 20use League\OAuth2\Server\ResponseTypes\BearerTokenResponse; 21use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface; 22use Psr\Http\Message\ResponseInterface; 23use Psr\Http\Message\ServerRequestInterface; 24 25class AuthorizationServer implements EmitterAwareInterface 26{ 27 use EmitterAwareTrait; 28 29 /** 30 * @var GrantTypeInterface[] 31 */ 32 protected $enabledGrantTypes = []; 33 34 /** 35 * @var DateInterval[] 36 */ 37 protected $grantTypeAccessTokenTTL = []; 38 39 /** 40 * @var ResponseTypeInterface 41 */ 42 protected $responseType; 43 44 /** 45 * @var ClientRepositoryInterface 46 */ 47 private $clientRepository; 48 49 /** 50 * @var AccessTokenRepositoryInterface 51 */ 52 private $accessTokenRepository; 53 54 /** 55 * @var ScopeRepositoryInterface 56 */ 57 private $scopeRepository; 58 59 /** 60 * @var string 61 */ 62 private $defaultScope = ''; 63 64 /** 65 * New server instance. 66 * 67 * @param ClientRepositoryInterface $clientRepository 68 * @param AccessTokenRepositoryInterface $accessTokenRepository 69 * @param ScopeRepositoryInterface $scopeRepository 70 * @param null|ResponseTypeInterface $responseType 71 */ 72 public function __construct( 73 ClientRepositoryInterface $clientRepository, 74 AccessTokenRepositoryInterface $accessTokenRepository, 75 ScopeRepositoryInterface $scopeRepository, 76 ResponseTypeInterface $responseType = null, 77 $encryptionKey = '' 78 ) { 79 $this->clientRepository = $clientRepository; 80 $this->accessTokenRepository = $accessTokenRepository; 81 $this->scopeRepository = $scopeRepository; 82 83 $this->encryptionKey = $encryptionKey; 84 85 if ($responseType === null) { 86 $responseType = new BearerTokenResponse(); 87 } else { 88 $responseType = clone $responseType; 89 } 90 91 $this->responseType = $responseType; 92 } 93 94 /** 95 * Enable a grant type on the server. 96 * 97 * @param GrantTypeInterface $grantType 98 * @param null|DateInterval $accessTokenTTL 99 */ 100 public function enableGrantType(GrantTypeInterface $grantType, DateInterval $accessTokenTTL = null) 101 { 102 if ($accessTokenTTL instanceof DateInterval === false) { 103 $accessTokenTTL = new DateInterval('PT1H'); 104 } 105 106 $grantType->setAccessTokenRepository($this->accessTokenRepository); 107 $grantType->setClientRepository($this->clientRepository); 108 $grantType->setScopeRepository($this->scopeRepository); 109 $grantType->setDefaultScope($this->defaultScope); 110 $grantType->setEmitter($this->getEmitter()); 111 $grantType->setEncryptionKey($this->encryptionKey); 112 113 $this->enabledGrantTypes[$grantType->getIdentifier()] = $grantType; 114 $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] = $accessTokenTTL; 115 } 116 117 /** 118 * Validate an authorization request 119 * 120 * @param ServerRequestInterface $request 121 * 122 * @throws OAuthServerException 123 * 124 * @return AuthorizationRequest 125 */ 126 public function validateAuthorizationRequest(ServerRequestInterface $request) 127 { 128 foreach ($this->enabledGrantTypes as $grantType) { 129 if ($grantType->canRespondToAuthorizationRequest($request)) { 130 return $grantType->validateAuthorizationRequest($request); 131 } 132 } 133 134 throw OAuthServerException::unsupportedGrantType(); 135 } 136 137 /** 138 * Complete an authorization request 139 * 140 * @param AuthorizationRequest $authRequest 141 * @param ResponseInterface $response 142 * 143 * @return ResponseInterface 144 */ 145 public function completeAuthorizationRequest(AuthorizationRequest $authRequest, ResponseInterface $response) 146 { 147 return $this->enabledGrantTypes[$authRequest->getGrantTypeId()] 148 ->completeAuthorizationRequest($authRequest) 149 ->generateHttpResponse($response); 150 } 151 152 /** 153 * Return an access token response. 154 * 155 * @param ServerRequestInterface $request 156 * @param ResponseInterface $response 157 * 158 * @throws OAuthServerException 159 * 160 * @return ResponseInterface 161 */ 162 public function respondToAccessTokenRequest(ServerRequestInterface $request, ResponseInterface $response) 163 { 164 foreach ($this->enabledGrantTypes as $grantType) { 165 if (! $grantType->canRespondToAccessTokenRequest($request)) { 166 continue; 167 } 168 $response_type = $this->getResponseType(); 169 $grant_identifier = $grantType->getIdentifier(); 170 $tokenResponse = $grantType->respondToAccessTokenRequest( 171 $request, 172 $response_type, 173 $this->grantTypeAccessTokenTTL[$grant_identifier] 174 ); 175 176 if ($tokenResponse instanceof ResponseTypeInterface) { 177 return $tokenResponse->generateHttpResponse($response); 178 } 179 } 180 181 throw OAuthServerException::unsupportedGrantType(); 182 } 183 184 /** 185 * Get the token type that grants will return in the HTTP response. 186 * 187 * @return ResponseTypeInterface 188 */ 189 protected function getResponseType() 190 { 191 $responseType = clone $this->responseType; 192 $responseType->setEncryptionKey($this->encryptionKey); 193 194 return $responseType; 195 } 196 197 /** 198 * Set the default scope for the authorization server. 199 * 200 * @param string $defaultScope 201 */ 202 public function setDefaultScope($defaultScope) 203 { 204 $this->defaultScope = $defaultScope; 205 } 206} 207