PageRenderTime 53ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/test/OAuth2/Controller/AuthorizeControllerTest.php

https://github.com/rich-choy/oauth2-server-php
PHP | 430 lines | 340 code | 76 blank | 14 comment | 0 complexity | 4d4938d6143bf4eb2d92fcfb752e0695 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. namespace OAuth2\Controller;
  3. use OAuth2\Storage\Memory;
  4. use OAuth2\Scope;
  5. use OAuth2\Storage\Bootstrap;
  6. use OAuth2\Server;
  7. use OAuth2\GrantType\AuthorizationCode;
  8. use OAuth2\Request;
  9. use OAuth2\Response;
  10. use OAuth2\Request\TestRequest;
  11. class AuthorizeControllerTest extends \PHPUnit_Framework_TestCase
  12. {
  13. public function testNoClientIdResponse()
  14. {
  15. $server = $this->getTestServer();
  16. $request = new Request();
  17. $server->handleAuthorizeRequest($request, $response = new Response(), false);
  18. $this->assertEquals($response->getStatusCode(), 400);
  19. $this->assertEquals($response->getParameter('error'), 'invalid_client');
  20. $this->assertEquals($response->getParameter('error_description'), 'No client id supplied');
  21. }
  22. public function testInvalidClientIdResponse()
  23. {
  24. $server = $this->getTestServer();
  25. $request = new Request(array(
  26. 'client_id' => 'Fake Client ID', // invalid client id
  27. ));
  28. $server->handleAuthorizeRequest($request, $response = new Response(), false);
  29. $this->assertEquals($response->getStatusCode(), 400);
  30. $this->assertEquals($response->getParameter('error'), 'invalid_client');
  31. $this->assertEquals($response->getParameter('error_description'), 'The client id supplied is invalid');
  32. }
  33. public function testNoRedirectUriSuppliedOrStoredResponse()
  34. {
  35. $server = $this->getTestServer();
  36. $request = new Request(array(
  37. 'client_id' => 'Test Client ID', // valid client id
  38. ));
  39. $server->handleAuthorizeRequest($request, $response = new Response(), false);
  40. $this->assertEquals($response->getStatusCode(), 400);
  41. $this->assertEquals($response->getParameter('error'), 'invalid_uri');
  42. $this->assertEquals($response->getParameter('error_description'), 'No redirect URI was supplied or stored');
  43. }
  44. public function testNoResponseTypeResponse()
  45. {
  46. $server = $this->getTestServer();
  47. $request = new Request(array(
  48. 'client_id' => 'Test Client ID', // valid client id
  49. 'redirect_uri' => 'http://adobe.com', // valid redirect URI
  50. ));
  51. $server->handleAuthorizeRequest($request, $response = new Response(), false);
  52. $this->assertEquals($response->getStatusCode(), 302);
  53. $location = $response->getHttpHeader('Location');
  54. $parts = parse_url($location);
  55. parse_str($parts['query'], $query);
  56. $this->assertEquals($query['error'], 'invalid_request');
  57. $this->assertEquals($query['error_description'], 'Invalid or missing response type');
  58. }
  59. public function testInvalidResponseTypeResponse()
  60. {
  61. $server = $this->getTestServer();
  62. $request = new Request(array(
  63. 'client_id' => 'Test Client ID', // valid client id
  64. 'redirect_uri' => 'http://adobe.com', // valid redirect URI
  65. 'response_type' => 'invalid', // invalid response type
  66. ));
  67. $server->handleAuthorizeRequest($request, $response = new Response(), false);
  68. $this->assertEquals($response->getStatusCode(), 302);
  69. $location = $response->getHttpHeader('Location');
  70. $parts = parse_url($location);
  71. parse_str($parts['query'], $query);
  72. $this->assertEquals($query['error'], 'invalid_request');
  73. $this->assertEquals($query['error_description'], 'Invalid or missing response type');
  74. }
  75. public function testRedirectUriFragmentResponse()
  76. {
  77. $server = $this->getTestServer();
  78. $request = new Request(array(
  79. 'client_id' => 'Test Client ID', // valid client id
  80. 'redirect_uri' => 'http://adobe.com#fragment', // valid redirect URI
  81. 'response_type' => 'code', // invalid response type
  82. ));
  83. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  84. $this->assertEquals($response->getStatusCode(), 400);
  85. $this->assertEquals($response->getParameter('error'), 'invalid_uri');
  86. $this->assertEquals($response->getParameter('error_description'), 'The redirect URI must not contain a fragment');
  87. }
  88. public function testEnforceState()
  89. {
  90. $server = $this->getTestServer(array('enforce_state' => true));
  91. $request = new Request(array(
  92. 'client_id' => 'Test Client ID', // valid client id
  93. 'redirect_uri' => 'http://adobe.com', // valid redirect URI
  94. 'response_type' => 'code',
  95. ));
  96. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  97. $this->assertEquals($response->getStatusCode(), 302);
  98. $location = $response->getHttpHeader('Location');
  99. $parts = parse_url($location);
  100. parse_str($parts['query'], $query);
  101. $this->assertEquals($query['error'], 'invalid_request');
  102. $this->assertEquals($query['error_description'], 'The state parameter is required');
  103. }
  104. public function testDoNotEnforceState()
  105. {
  106. $server = $this->getTestServer(array('enforce_state' => false));
  107. $request = new Request(array(
  108. 'client_id' => 'Test Client ID', // valid client id
  109. 'redirect_uri' => 'http://adobe.com', // valid redirect URI
  110. 'response_type' => 'code',
  111. ));
  112. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  113. $this->assertEquals($response->getStatusCode(), 302);
  114. $this->assertNotContains('error', $response->getHttpHeader('Location'));
  115. }
  116. public function testEnforceScope()
  117. {
  118. $server = $this->getTestServer();
  119. $scopeStorage = new Memory(array('default_scope' => false, 'supported_scopes' => array('testscope')));
  120. $server->setScopeUtil(new Scope($scopeStorage));
  121. $request = new Request(array(
  122. 'client_id' => 'Test Client ID', // valid client id
  123. 'redirect_uri' => 'http://adobe.com', // valid redirect URI
  124. 'response_type' => 'code',
  125. 'state' => 'xyz',
  126. ));
  127. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  128. $this->assertEquals($response->getStatusCode(), 302);
  129. $parts = parse_url($response->getHttpHeader('Location'));
  130. parse_str($parts['query'], $query);
  131. $this->assertEquals($query['error'], 'invalid_client');
  132. $this->assertEquals($query['error_description'], 'This application requires you specify a scope parameter');
  133. $request->query['scope'] = 'testscope';
  134. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  135. $this->assertEquals($response->getStatusCode(), 302);
  136. $this->assertNotContains('error', $response->getHttpHeader('Location'));
  137. }
  138. public function testInvalidRedirectUri()
  139. {
  140. $server = $this->getTestServer();
  141. $request = new Request(array(
  142. 'client_id' => 'Test Client ID with Redirect Uri', // valid client id
  143. 'redirect_uri' => 'http://adobe.com', // invalid redirect URI
  144. 'response_type' => 'code',
  145. ));
  146. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  147. $this->assertEquals($response->getStatusCode(), 400);
  148. $this->assertEquals($response->getParameter('error'), 'redirect_uri_mismatch');
  149. $this->assertEquals($response->getParameter('error_description'), 'The redirect URI provided is missing or does not match');
  150. }
  151. public function testNoRedirectUriWithMultipleRedirectUris()
  152. {
  153. $server = $this->getTestServer();
  154. // create a request with no "redirect_uri" in querystring
  155. $request = new Request(array(
  156. 'client_id' => 'Test Client ID with Multiple Redirect Uris', // valid client id
  157. 'response_type' => 'code',
  158. ));
  159. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  160. $this->assertEquals($response->getStatusCode(), 400);
  161. $this->assertEquals($response->getParameter('error'), 'invalid_uri');
  162. $this->assertEquals($response->getParameter('error_description'), 'A redirect URI must be supplied when multiple redirect URIs are registered');
  163. }
  164. public function testRedirectUriWithValidRedirectUri()
  165. {
  166. $server = $this->getTestServer();
  167. // create a request with no "redirect_uri" in querystring
  168. $request = new Request(array(
  169. 'client_id' => 'Test Client ID with Redirect Uri Parts', // valid client id
  170. 'response_type' => 'code',
  171. 'redirect_uri' => 'http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth',
  172. 'state' => 'xyz',
  173. ));
  174. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  175. $this->assertEquals($response->getStatusCode(), 302);
  176. $this->assertContains('code', $response->getHttpHeader('Location'));
  177. }
  178. public function testRedirectUriWithDifferentQueryAndExactMatchRequired()
  179. {
  180. $server = $this->getTestServer(array('require_exact_redirect_uri' => true));
  181. // create a request with no "redirect_uri" in querystring
  182. $request = new Request(array(
  183. 'client_id' => 'Test Client ID with Redirect Uri Parts', // valid client id
  184. 'response_type' => 'code',
  185. 'redirect_uri' => 'http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&hereisa=querystring',
  186. ));
  187. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  188. $this->assertEquals($response->getStatusCode(), 400);
  189. $this->assertEquals($response->getParameter('error'), 'redirect_uri_mismatch');
  190. $this->assertEquals($response->getParameter('error_description'), 'The redirect URI provided is missing or does not match');
  191. }
  192. public function testRedirectUriWithDifferentQueryAndExactMatchNotRequired()
  193. {
  194. $server = $this->getTestServer(array('require_exact_redirect_uri' => false));
  195. // create a request with no "redirect_uri" in querystring
  196. $request = new Request(array(
  197. 'client_id' => 'Test Client ID with Redirect Uri Parts', // valid client id
  198. 'response_type' => 'code',
  199. 'redirect_uri' => 'http://user:pass@brentertainment.com:2222/authorize/cb?auth_type=oauth&hereisa=querystring',
  200. 'state' => 'xyz',
  201. ));
  202. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  203. $this->assertEquals($response->getStatusCode(), 302);
  204. $this->assertContains('code', $response->getHttpHeader('Location'));
  205. }
  206. public function testMultipleRedirectUris()
  207. {
  208. $server = $this->getTestServer();
  209. $request = new Request(array(
  210. 'client_id' => 'Test Client ID with Multiple Redirect Uris', // valid client id
  211. 'redirect_uri' => 'http://brentertainment.com', // valid redirect URI
  212. 'response_type' => 'code',
  213. 'state' => 'xyz'
  214. ));
  215. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  216. $this->assertEquals($response->getStatusCode(), 302);
  217. $this->assertContains('code', $response->getHttpHeader('Location'));
  218. // call again with different (but still valid) redirect URI
  219. $request->query['redirect_uri'] = 'http://morehazards.com';
  220. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  221. $this->assertEquals($response->getStatusCode(), 302);
  222. $this->assertContains('code', $response->getHttpHeader('Location'));
  223. }
  224. /**
  225. * @see http://tools.ietf.org/html/rfc6749#section-4.1.3
  226. * @see https://github.com/bshaffer/oauth2-server-php/issues/163
  227. */
  228. public function testNoRedirectUriSuppliedDoesNotRequireTokenRedirectUri()
  229. {
  230. $server = $this->getTestServer();
  231. $request = new Request(array(
  232. 'client_id' => 'Test Client ID with Redirect Uri', // valid client id
  233. 'response_type' => 'code',
  234. 'state' => 'xyz',
  235. ));
  236. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  237. $this->assertEquals($response->getStatusCode(), 302);
  238. $this->assertContains('state', $response->getHttpHeader('Location'));
  239. $this->assertStringStartsWith('http://brentertainment.com?code=', $response->getHttpHeader('Location'));
  240. $parts = parse_url($response->getHttpHeader('Location'));
  241. parse_str($parts['query'], $query);
  242. // call token endpoint with no redirect_uri supplied
  243. $request = TestRequest::createPost(array(
  244. 'client_id' => 'Test Client ID with Redirect Uri', // valid client id
  245. 'client_secret' => 'TestSecret2',
  246. 'grant_type' => 'authorization_code',
  247. 'code' => $query['code'],
  248. ));
  249. $server->handleTokenRequest($request, $response = new Response(), true);
  250. $this->assertEquals($response->getStatusCode(), 200);
  251. $this->assertNotNull($response->getParameter('access_token'));
  252. }
  253. public function testUserDeniesAccessResponse()
  254. {
  255. $server = $this->getTestServer();
  256. $request = new Request(array(
  257. 'client_id' => 'Test Client ID', // valid client id
  258. 'redirect_uri' => 'http://adobe.com', // valid redirect URI
  259. 'response_type' => 'code',
  260. 'state' => 'xyz',
  261. ));
  262. $server->handleAuthorizeRequest($request, $response = new Response(), false);
  263. $this->assertEquals($response->getStatusCode(), 302);
  264. $location = $response->getHttpHeader('Location');
  265. $parts = parse_url($location);
  266. parse_str($parts['query'], $query);
  267. $this->assertEquals($query['error'], 'access_denied');
  268. $this->assertEquals($query['error_description'], 'The user denied access to your application');
  269. }
  270. public function testCodeQueryParamIsSet()
  271. {
  272. $server = $this->getTestServer();
  273. $request = new Request(array(
  274. 'client_id' => 'Test Client ID', // valid client id
  275. 'redirect_uri' => 'http://adobe.com', // valid redirect URI
  276. 'response_type' => 'code',
  277. 'state' => 'xyz',
  278. ));
  279. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  280. $this->assertEquals($response->getStatusCode(), 302);
  281. $location = $response->getHttpHeader('Location');
  282. $parts = parse_url($location);
  283. parse_str($parts['query'], $query);
  284. $location = $response->getHttpHeader('Location');
  285. $parts = parse_url($location);
  286. $this->assertEquals('http', $parts['scheme']); // same as passed in to redirect_uri
  287. $this->assertEquals('adobe.com', $parts['host']); // same as passed in to redirect_uri
  288. $this->assertArrayHasKey('query', $parts);
  289. $this->assertFalse(isset($parts['fragment']));
  290. // assert fragment is in "application/x-www-form-urlencoded" format
  291. parse_str($parts['query'], $query);
  292. $this->assertNotNull($query);
  293. $this->assertArrayHasKey('code', $query);
  294. // ensure no error was returned
  295. $this->assertFalse(isset($query['error']));
  296. $this->assertFalse(isset($query['error_description']));
  297. }
  298. public function testSuccessfulRequestReturnsStateParameter()
  299. {
  300. $server = $this->getTestServer(array('allow_implicit' => true));
  301. $request = new Request(array(
  302. 'client_id' => 'Test Client ID', // valid client id
  303. 'redirect_uri' => 'http://adobe.com', // valid redirect URI
  304. 'response_type' => 'code',
  305. 'state' => 'test', // valid state string (just needs to be passed back to us)
  306. ));
  307. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  308. $this->assertEquals($response->getStatusCode(), 302);
  309. $location = $response->getHttpHeader('Location');
  310. $parts = parse_url($location);
  311. $this->assertArrayHasKey('query', $parts);
  312. parse_str($parts['query'], $query);
  313. $this->assertArrayHasKey('state', $query);
  314. $this->assertEquals($query['state'], 'test');
  315. // ensure no error was returned
  316. $this->assertFalse(isset($query['error']));
  317. $this->assertFalse(isset($query['error_description']));
  318. }
  319. public function testSuccessfulRequestStripsExtraParameters()
  320. {
  321. $server = $this->getTestServer(array('allow_implicit' => true));
  322. $request = new Request(array(
  323. 'client_id' => 'Test Client ID', // valid client id
  324. 'redirect_uri' => 'http://adobe.com', // valid redirect URI
  325. 'response_type' => 'code',
  326. 'state' => 'test', // valid state string (just needs to be passed back to us)
  327. 'fake' => 'something', // extra query param
  328. ));
  329. $server->handleAuthorizeRequest($request, $response = new Response(), true);
  330. $this->assertEquals($response->getStatusCode(), 302);
  331. $location = $response->getHttpHeader('Location');
  332. $this->assertNotContains('error', $location);
  333. $parts = parse_url($location);
  334. $this->assertFalse(isset($parts['fake']));
  335. $this->assertArrayHasKey('query', $parts);
  336. parse_str($parts['query'], $query);
  337. $this->assertFalse(isset($parmas['fake']));
  338. $this->assertArrayHasKey('state', $query);
  339. $this->assertEquals($query['state'], 'test');
  340. }
  341. public function testCreateController()
  342. {
  343. $storage = Bootstrap::getInstance()->getMemoryStorage();
  344. $controller = new AuthorizeController($storage);
  345. }
  346. private function getTestServer($config = array())
  347. {
  348. $storage = Bootstrap::getInstance()->getMemoryStorage();
  349. $server = new Server($storage, $config);
  350. // Add the two types supported for authorization grant
  351. $server->addGrantType(new AuthorizationCode($storage));
  352. return $server;
  353. }
  354. }