OAuthServerTest.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php
  2. require_once dirname(__FILE__) . '/common.php';
  3. require_once dirname(__FILE__) . '/Mock_OAuthDataStore.php';
  4. /**
  5. * Tests of OAuthUtil
  6. */
  7. class OAuthServerTest extends PHPUnit_Framework_TestCase {
  8. private $consumer;
  9. private $request_token;
  10. private $access_token;
  11. private $hmac_sha1;
  12. private $plaintext;
  13. private $server;
  14. public function setUp() {
  15. $this->consumer = new OAuthConsumer('key', 'secret');
  16. $this->request_token = new OAuthToken('requestkey', 'requestsecret');
  17. $this->access_token = new OAuthToken('accesskey', 'accesssecret');
  18. $this->hmac_sha1 = new OAuthSignatureMethod_HMAC_SHA1();
  19. $this->plaintext = new OAuthSignatureMethod_PLAINTEXT();
  20. $this->server = new OAuthServer( new Mock_OAuthDataStore() );
  21. $this->server->add_signature_method( $this->hmac_sha1 );
  22. $this->server->add_signature_method( $this->plaintext );
  23. }
  24. public function testAcceptValidRequest() {
  25. $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  26. $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  27. list($consumer, $token) = $this->server->verify_request( $request );
  28. $this->assertEquals( $this->consumer, $consumer );
  29. $this->assertEquals( $this->access_token, $token );
  30. $request->sign_request( $this->hmac_sha1, $this->consumer, $this->access_token );
  31. list($consumer, $token) = $this->server->verify_request( $request );
  32. $this->assertEquals( $this->consumer, $consumer );
  33. $this->assertEquals( $this->access_token, $token );
  34. }
  35. public function testAcceptRequestWithoutVersion() {
  36. $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  37. $request->unset_parameter('oauth_version');
  38. $request->sign_request( $this->hmac_sha1, $this->consumer, $this->access_token );
  39. $this->server->verify_request( $request );
  40. }
  41. public function testRejectRequestSignedWithRequestToken() {
  42. $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->request_token, 'POST', 'http://example.com');
  43. $request->sign_request( $this->plaintext, $this->consumer, $this->request_token );
  44. $this->setExpectedException('OAuthException');
  45. $this->server->verify_request( $request );
  46. }
  47. public function testRejectRequestWithMissingParameters() {
  48. // The list of required parameters is taken from
  49. // Chapter 7 ("Accessing Protected Resources")
  50. $required_parameters = array(
  51. 'oauth_consumer_key',
  52. 'oauth_token',
  53. 'oauth_signature_method',
  54. 'oauth_signature',
  55. 'oauth_timestamp',
  56. 'oauth_nonce'
  57. );
  58. foreach( $required_parameters AS $required ) {
  59. $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  60. $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  61. try {
  62. $request->unset_parameter( $required );
  63. $this->server->verify_request($request);
  64. $this->fail('Allowed a request without `' . $required . '`');
  65. } catch( OAuthException $e ) { /* expected */ }
  66. }
  67. }
  68. public function testRejectPastTimestamp() {
  69. // We change the timestamp to be 10 hours ago, it should throw an exception
  70. $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  71. $request->set_parameter( 'oauth_timestamp', $request->get_parameter('oauth_timestamp') - 10*60*60, false);
  72. $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  73. $this->setExpectedException('OAuthException');
  74. $this->server->verify_request($request);
  75. }
  76. public function testRejectFutureTimestamp() {
  77. // We change the timestamp to be 10 hours in the future, it should throw an exception
  78. $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  79. $request->set_parameter( 'oauth_timestamp', $request->get_parameter('oauth_timestamp') + 10*60*60, false);
  80. $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  81. $this->setExpectedException('OAuthException');
  82. $this->server->verify_request($request);
  83. }
  84. public function testRejectUsedNonce() {
  85. // We give a known nonce and should see an exception
  86. $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  87. // The Mock datastore is set to say that the `nonce` nonce is known
  88. $request->set_parameter( 'oauth_nonce', 'nonce', false);
  89. $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  90. $this->setExpectedException('OAuthException');
  91. $this->server->verify_request($request);
  92. }
  93. public function testRejectInvalidSignature() {
  94. // We change the signature post-signing to be something invalid
  95. $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  96. $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  97. $request->set_parameter( 'oauth_signature', '__whatever__', false);
  98. $this->setExpectedException('OAuthException');
  99. $this->server->verify_request($request);
  100. }
  101. public function testRejectInvalidConsumer() {
  102. // We use the consumer-key "unknown", which isn't known by the datastore.
  103. $unknown_consumer = new OAuthConsumer('unknown', '__unused__');
  104. $request = OAuthRequest::from_consumer_and_token( $unknown_consumer, $this->access_token, 'POST', 'http://example.com');
  105. $request->sign_request( $this->plaintext, $unknown_consumer, $this->access_token );
  106. $this->setExpectedException('OAuthException');
  107. $this->server->verify_request( $request );
  108. }
  109. public function testRejectInvalidToken() {
  110. // We use the access-token "unknown" which isn't known by the datastore
  111. $unknown_token = new OAuthToken('unknown', '__unused__');
  112. $request = OAuthRequest::from_consumer_and_token( $this->consumer, $unknown_token, 'POST', 'http://example.com');
  113. $request->sign_request( $this->plaintext, $this->consumer, $unknown_token );
  114. $this->setExpectedException('OAuthException');
  115. $this->server->verify_request( $request );
  116. }
  117. public function testRejectUnknownSignatureMethod() {
  118. // We use a server that only supports HMAC-SHA1, but requests with PLAINTEXT signature
  119. $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  120. $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  121. $server = new OAuthServer( new Mock_OAuthDataStore() );
  122. $server->add_signature_method( $this->hmac_sha1 );
  123. $this->setExpectedException('OAuthException');
  124. $server->verify_request( $request );
  125. }
  126. public function testRejectUnknownVersion() {
  127. // We use the version "1.0a" which isn't "1.0", so reject the request
  128. $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  129. $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  130. $request->set_parameter('oauth_version', '1.0a', false);
  131. $this->setExpectedException('OAuthException');
  132. $this->server->verify_request( $request );
  133. }
  134. public function testCreateRequestToken() {
  135. // We request a new Request Token
  136. $request = OAuthRequest::from_consumer_and_token( $this->consumer, NULL, 'POST', 'http://example.com');
  137. $request->sign_request( $this->plaintext, $this->consumer, NULL );
  138. $token = $this->server->fetch_request_token($request);
  139. $this->assertEquals($this->request_token, $token);
  140. }
  141. public function testRejectSignedRequestTokenRequest() {
  142. // We request a new Request Token, but the request is signed with a token which should fail
  143. $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->request_token, 'POST', 'http://example.com');
  144. $request->sign_request( $this->plaintext, $this->consumer, $this->request_token );
  145. $this->setExpectedException('OAuthException');
  146. $token = $this->server->fetch_request_token($request);
  147. }
  148. public function testCreateAccessToken() {
  149. // We request a new Access Token
  150. $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->request_token, 'POST', 'http://example.com');
  151. $request->sign_request( $this->plaintext, $this->consumer, $this->request_token );
  152. $token = $this->server->fetch_access_token($request);
  153. $this->assertEquals($this->access_token, $token);
  154. }
  155. public function testRejectUnsignedAccessTokenRequest() {
  156. // We request a new Access Token, but we didn't sign the request with a Access Token
  157. $request = OAuthRequest::from_consumer_and_token( $this->consumer, NULL, 'POST', 'http://example.com');
  158. $request->sign_request( $this->plaintext, $this->consumer, NULL );
  159. $this->setExpectedException('OAuthException');
  160. $token = $this->server->fetch_access_token($request);
  161. }
  162. public function testRejectAccessTokenSignedAccessTokenRequest() {
  163. // We request a new Access Token, but the request is signed with an access token, so fail!
  164. $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
  165. $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
  166. $this->setExpectedException('OAuthException');
  167. $token = $this->server->fetch_access_token($request);
  168. }
  169. }