ServerTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. <?php
  2. namespace League\OAuth1\Client\Tests;
  3. use InvalidArgumentException;
  4. use League\OAuth1\Client\Credentials\ClientCredentials;
  5. use League\OAuth1\Client\Credentials\RsaClientCredentials;
  6. use League\OAuth1\Client\Signature\RsaSha1Signature;
  7. use Mockery as m;
  8. use PHPUnit\Framework\TestCase;
  9. use Psr\Http\Message\ResponseInterface;
  10. class ServerTest extends TestCase
  11. {
  12. /**
  13. * Setup resources and dependencies.
  14. */
  15. public static function setUpBeforeClass(): void
  16. {
  17. parent::setUpBeforeClass();
  18. require_once __DIR__ . '/stubs/ServerStub.php';
  19. }
  20. protected function tearDown(): void
  21. {
  22. m::close();
  23. parent::tearDown();
  24. }
  25. public function testCreatingWithArray()
  26. {
  27. $server = new ServerStub($this->getMockClientCredentials());
  28. $credentials = $server->getClientCredentials();
  29. $this->assertInstanceOf('League\OAuth1\Client\Credentials\ClientCredentialsInterface', $credentials);
  30. $this->assertEquals('myidentifier', $credentials->getIdentifier());
  31. $this->assertEquals('mysecret', $credentials->getSecret());
  32. $this->assertEquals('http://app.dev/', $credentials->getCallbackUri());
  33. }
  34. public function testCreatingWithArrayRsa()
  35. {
  36. $config = [
  37. 'identifier' => 'app_key',
  38. 'secret' => 'secret',
  39. 'callback_uri' => 'https://example.com/callback',
  40. 'rsa_public_key' => __DIR__ . '/test_rsa_publickey.pem',
  41. 'rsa_private_key' => __DIR__ . '/test_rsa_privatekey.pem',
  42. ];
  43. $server = new ServerStub($config);
  44. $credentials = $server->getClientCredentials();
  45. $this->assertInstanceOf(RsaClientCredentials::class, $credentials);
  46. $signature = $server->getSignature();
  47. $this->assertInstanceOf(RsaSha1Signature::class, $signature);
  48. }
  49. public function testCreatingWithObject()
  50. {
  51. $credentials = new ClientCredentials;
  52. $credentials->setIdentifier('myidentifier');
  53. $credentials->setSecret('mysecret');
  54. $credentials->setCallbackUri('http://app.dev/');
  55. $server = new ServerStub($credentials);
  56. $this->assertEquals($credentials, $server->getClientCredentials());
  57. }
  58. public function testCreatingWithInvalidInput()
  59. {
  60. $this->expectException(InvalidArgumentException::class);
  61. new ServerStub(uniqid());
  62. }
  63. public function testGettingTemporaryCredentials()
  64. {
  65. $server = m::mock('League\OAuth1\Client\Tests\ServerStub[createHttpClient]', [$this->getMockClientCredentials()]);
  66. $server->shouldReceive('createHttpClient')->andReturn($client = m::mock('stdClass'));
  67. $me = $this;
  68. $client->shouldReceive('post')->with('http://www.example.com/temporary', m::on(function ($options) use ($me) {
  69. $headers = $options['headers'];
  70. $me->assertTrue(isset($headers['Authorization']));
  71. // OAuth protocol specifies a strict number of
  72. // headers should be sent, in the correct order.
  73. // We'll validate that here.
  74. $pattern
  75. = '/OAuth oauth_consumer_key=".*?", oauth_nonce="[a-zA-Z0-9]+", oauth_signature_method="HMAC-SHA1", oauth_timestamp="\d{10}", oauth_version="1.0", oauth_callback="'
  76. . preg_quote('http%3A%2F%2Fapp.dev%2F', '/') . '", oauth_signature=".*?"/';
  77. $matches = preg_match($pattern, $headers['Authorization']);
  78. $me->assertEquals(1, $matches, 'Asserting that the authorization header contains the correct expression.');
  79. return true;
  80. }))->once()->andReturn($response = m::mock('stdClass'));
  81. $response->shouldReceive('getBody')
  82. ->andReturn('oauth_token=temporarycredentialsidentifier&oauth_token_secret=temporarycredentialssecret&oauth_callback_confirmed=true');
  83. $credentials = $server->getTemporaryCredentials();
  84. $this->assertInstanceOf('League\OAuth1\Client\Credentials\TemporaryCredentials', $credentials);
  85. $this->assertEquals('temporarycredentialsidentifier', $credentials->getIdentifier());
  86. $this->assertEquals('temporarycredentialssecret', $credentials->getSecret());
  87. }
  88. public function testGettingAuthorizationUrl()
  89. {
  90. $server = new ServerStub($this->getMockClientCredentials());
  91. $expected = 'http://www.example.com/authorize?oauth_token=foo';
  92. $this->assertEquals($expected, $server->getAuthorizationUrl('foo'));
  93. $credentials = m::mock('League\OAuth1\Client\Credentials\TemporaryCredentials');
  94. $credentials->shouldReceive('getIdentifier')->andReturn('foo');
  95. $this->assertEquals($expected, $server->getAuthorizationUrl($credentials));
  96. }
  97. public function testGettingAuthorizationUrlWithOptions()
  98. {
  99. $server = new ServerStub($this->getMockClientCredentials());
  100. $expected = 'http://www.example.com/authorize?oauth_token=foo';
  101. $this->assertEquals($expected, $server->getAuthorizationUrl('foo', ['oauth_token' => 'bar']));
  102. $expected = 'http://www.example.com/authorize?test=bar&oauth_token=foo';
  103. $this->assertEquals($expected, $server->getAuthorizationUrl('foo', ['test' => 'bar']));
  104. }
  105. public function testGettingTokenCredentialsFailsWithManInTheMiddle()
  106. {
  107. $server = new ServerStub($this->getMockClientCredentials());
  108. $credentials = m::mock('League\OAuth1\Client\Credentials\TemporaryCredentials');
  109. $credentials->shouldReceive('getIdentifier')->andReturn('foo');
  110. $this->expectException(InvalidArgumentException::class);
  111. $server->getTokenCredentials($credentials, 'bar', 'verifier');
  112. }
  113. public function testGettingTokenCredentials()
  114. {
  115. $server = m::mock('League\OAuth1\Client\Tests\ServerStub[createHttpClient]', [$this->getMockClientCredentials()]);
  116. $temporaryCredentials = m::mock('League\OAuth1\Client\Credentials\TemporaryCredentials');
  117. $temporaryCredentials->shouldReceive('getIdentifier')->andReturn('temporarycredentialsidentifier');
  118. $temporaryCredentials->shouldReceive('getSecret')->andReturn('temporarycredentialssecret');
  119. $server->shouldReceive('createHttpClient')->andReturn($client = m::mock('stdClass'));
  120. $me = $this;
  121. $client->shouldReceive('post')->with('http://www.example.com/token', m::on(function ($options) use ($me) {
  122. $headers = $options['headers'];
  123. $body = $options['form_params'];
  124. $me->assertTrue(isset($headers['Authorization']));
  125. $me->assertFalse(isset($headers['User-Agent']));
  126. // OAuth protocol specifies a strict number of
  127. // headers should be sent, in the correct order.
  128. // We'll validate that here.
  129. $pattern
  130. = '/OAuth oauth_consumer_key=".*?", oauth_nonce="[a-zA-Z0-9]+", oauth_signature_method="HMAC-SHA1", oauth_timestamp="\d{10}", oauth_version="1.0", oauth_token="temporarycredentialsidentifier", oauth_signature=".*?"/';
  131. $matches = preg_match($pattern, $headers['Authorization']);
  132. $me->assertEquals(1, $matches, 'Asserting that the authorization header contains the correct expression.');
  133. $me->assertSame($body, ['oauth_verifier' => 'myverifiercode']);
  134. return true;
  135. }))->once()->andReturn($response = m::mock('stdClass'));
  136. $response->shouldReceive('getBody')
  137. ->andReturn('oauth_token=tokencredentialsidentifier&oauth_token_secret=tokencredentialssecret');
  138. $credentials = $server->getTokenCredentials($temporaryCredentials, 'temporarycredentialsidentifier', 'myverifiercode');
  139. $this->assertInstanceOf('League\OAuth1\Client\Credentials\TokenCredentials', $credentials);
  140. $this->assertEquals('tokencredentialsidentifier', $credentials->getIdentifier());
  141. $this->assertEquals('tokencredentialssecret', $credentials->getSecret());
  142. }
  143. public function testGettingTokenCredentialsWithUserAgent()
  144. {
  145. $userAgent = 'FooBar';
  146. $server = m::mock('League\OAuth1\Client\Tests\ServerStub[createHttpClient]', [$this->getMockClientCredentials()]);
  147. $temporaryCredentials = m::mock('League\OAuth1\Client\Credentials\TemporaryCredentials');
  148. $temporaryCredentials->shouldReceive('getIdentifier')->andReturn('temporarycredentialsidentifier');
  149. $temporaryCredentials->shouldReceive('getSecret')->andReturn('temporarycredentialssecret');
  150. $server->shouldReceive('createHttpClient')->andReturn($client = m::mock('stdClass'));
  151. $me = $this;
  152. $client->shouldReceive('post')->with('http://www.example.com/token', m::on(function ($options) use ($me, $userAgent) {
  153. $headers = $options['headers'];
  154. $body = $options['form_params'];
  155. $me->assertTrue(isset($headers['Authorization']));
  156. $me->assertTrue(isset($headers['User-Agent']));
  157. $me->assertEquals($userAgent, $headers['User-Agent']);
  158. // OAuth protocol specifies a strict number of
  159. // headers should be sent, in the correct order.
  160. // We'll validate that here.
  161. $pattern
  162. = '/OAuth oauth_consumer_key=".*?", oauth_nonce="[a-zA-Z0-9]+", oauth_signature_method="HMAC-SHA1", oauth_timestamp="\d{10}", oauth_version="1.0", oauth_token="temporarycredentialsidentifier", oauth_signature=".*?"/';
  163. $matches = preg_match($pattern, $headers['Authorization']);
  164. $me->assertEquals(1, $matches, 'Asserting that the authorization header contains the correct expression.');
  165. $me->assertSame($body, ['oauth_verifier' => 'myverifiercode']);
  166. return true;
  167. }))->once()->andReturn($response = m::mock('stdClass'));
  168. $response->shouldReceive('getBody')
  169. ->andReturn('oauth_token=tokencredentialsidentifier&oauth_token_secret=tokencredentialssecret');
  170. $credentials = $server->setUserAgent($userAgent)
  171. ->getTokenCredentials($temporaryCredentials, 'temporarycredentialsidentifier', 'myverifiercode');
  172. $this->assertInstanceOf('League\OAuth1\Client\Credentials\TokenCredentials', $credentials);
  173. $this->assertEquals('tokencredentialsidentifier', $credentials->getIdentifier());
  174. $this->assertEquals('tokencredentialssecret', $credentials->getSecret());
  175. }
  176. public function testGettingUserDetails()
  177. {
  178. $server = m::mock(
  179. 'League\OAuth1\Client\Tests\ServerStub[createHttpClient,protocolHeader]',
  180. [$this->getMockClientCredentials()]
  181. );
  182. $temporaryCredentials = m::mock('League\OAuth1\Client\Credentials\TokenCredentials');
  183. $temporaryCredentials->shouldReceive('getIdentifier')->andReturn('tokencredentialsidentifier');
  184. $temporaryCredentials->shouldReceive('getSecret')->andReturn('tokencredentialssecret');
  185. $server->shouldReceive('createHttpClient')->andReturn($client = m::mock('stdClass'));
  186. $me = $this;
  187. $client->shouldReceive('get')->with('http://www.example.com/user', m::on(function ($options) use ($me) {
  188. $headers = $options['headers'];
  189. $me->assertTrue(isset($headers['Authorization']));
  190. // OAuth protocol specifies a strict number of
  191. // headers should be sent, in the correct order.
  192. // We'll validate that here.
  193. $pattern
  194. = '/OAuth oauth_consumer_key=".*?", oauth_nonce="[a-zA-Z0-9]+", oauth_signature_method="HMAC-SHA1", oauth_timestamp="\d{10}", oauth_version="1.0", oauth_token="tokencredentialsidentifier", oauth_signature=".*?"/';
  195. $matches = preg_match($pattern, $headers['Authorization']);
  196. $me->assertEquals(1, $matches, 'Asserting that the authorization header contains the correct expression.');
  197. return true;
  198. }))->once()->andReturn($response = m::mock(ResponseInterface::class));
  199. $response->shouldReceive('getBody')->once()->andReturn(json_encode([
  200. 'foo' => 'bar',
  201. 'id' => 123,
  202. 'contact_email' => 'baz@qux.com',
  203. 'username' => 'fred',
  204. ]));
  205. $user = $server->getUserDetails($temporaryCredentials);
  206. $this->assertInstanceOf('League\OAuth1\Client\Server\User', $user);
  207. $this->assertEquals('bar', $user->firstName);
  208. $this->assertEquals(123, $server->getUserUid($temporaryCredentials));
  209. $this->assertEquals('baz@qux.com', $server->getUserEmail($temporaryCredentials));
  210. $this->assertEquals('fred', $server->getUserScreenName($temporaryCredentials));
  211. }
  212. public function testGettingHeaders()
  213. {
  214. $server = new ServerStub($this->getMockClientCredentials());
  215. $tokenCredentials = m::mock('League\OAuth1\Client\Credentials\TokenCredentials');
  216. $tokenCredentials->shouldReceive('getIdentifier')->andReturn('mock_identifier');
  217. $tokenCredentials->shouldReceive('getSecret')->andReturn('mock_secret');
  218. // OAuth protocol specifies a strict number of
  219. // headers should be sent, in the correct order.
  220. // We'll validate that here.
  221. $pattern
  222. = '/OAuth oauth_consumer_key=".*?", oauth_nonce="[a-zA-Z0-9]+", oauth_signature_method="HMAC-SHA1", oauth_timestamp="\d{10}", oauth_version="1.0", oauth_token="mock_identifier", oauth_signature=".*?"/';
  223. // With a GET request
  224. $headers = $server->getHeaders($tokenCredentials, 'GET', 'http://example.com/');
  225. $this->assertTrue(isset($headers['Authorization']));
  226. $matches = preg_match($pattern, $headers['Authorization']);
  227. $this->assertEquals(1, $matches, 'Asserting that the authorization header contains the correct expression.');
  228. // With a POST request
  229. $headers = $server->getHeaders($tokenCredentials, 'POST', 'http://example.com/', ['body' => 'params']);
  230. $this->assertTrue(isset($headers['Authorization']));
  231. $matches = preg_match($pattern, $headers['Authorization']);
  232. $this->assertEquals(1, $matches, 'Asserting that the authorization header contains the correct expression.');
  233. }
  234. protected function getMockClientCredentials()
  235. {
  236. return [
  237. 'identifier' => 'myidentifier',
  238. 'secret' => 'mysecret',
  239. 'callback_uri' => 'http://app.dev/',
  240. ];
  241. }
  242. }