summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'OAuth/tests/phpunit/Lib/OAuthServerTest.php')
-rw-r--r--OAuth/tests/phpunit/Lib/OAuthServerTest.php259
1 files changed, 259 insertions, 0 deletions
diff --git a/OAuth/tests/phpunit/Lib/OAuthServerTest.php b/OAuth/tests/phpunit/Lib/OAuthServerTest.php
new file mode 100644
index 00000000..db508934
--- /dev/null
+++ b/OAuth/tests/phpunit/Lib/OAuthServerTest.php
@@ -0,0 +1,259 @@
+<?php
+/**
+ * The MIT License
+ *
+ * Copyright (c) 2007 Andy Smith
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files ( the "Software" ), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace MediaWiki\Extensions\OAuth\Tests\Lib;
+
+use MediaWiki\Extensions\OAuth\Lib\OAuthConsumer;
+use MediaWiki\Extensions\OAuth\Lib\OAuthException;
+use MediaWiki\Extensions\OAuth\Lib\OAuthRequest;
+use MediaWiki\Extensions\OAuth\Lib\OAuthServer;
+use MediaWiki\Extensions\OAuth\Lib\OAuthSignatureMethod_HMAC_SHA1;
+use MediaWiki\Extensions\OAuth\Lib\OAuthSignatureMethod_PLAINTEXT;
+use MediaWiki\Extensions\OAuth\Lib\OAuthToken;
+
+/**
+ * Tests of OAuthUtil
+ * @group OAuth
+ */
+class OAuthServerTest extends \PHPUnit\Framework\TestCase {
+
+ private $consumer;
+ private $request_token;
+ private $access_token;
+ private $hmac_sha1;
+ private $plaintext;
+ private $server;
+
+ protected function setUp() : void {
+ $this->consumer = new OAuthConsumer('key', 'secret');
+ $this->request_token = new OAuthToken('requestkey', 'requestsecret');
+ $this->access_token = new OAuthToken('accesskey', 'accesssecret');
+
+ $this->hmac_sha1 = new OAuthSignatureMethod_HMAC_SHA1();
+ $this->plaintext = new OAuthSignatureMethod_PLAINTEXT();
+
+ $this->server = new OAuthServer( new Mock_OAuthDataStore() );
+ $this->server->add_signature_method( $this->hmac_sha1 );
+ $this->server->add_signature_method( $this->plaintext );
+ }
+
+ public function testAcceptValidRequest() {
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
+ $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
+ [$consumer, $token] = $this->server->verify_request( $request );
+ $this->assertEquals( $this->consumer, $consumer );
+ $this->assertEquals( $this->access_token, $token );
+
+ $request->sign_request( $this->hmac_sha1, $this->consumer, $this->access_token );
+ [$consumer, $token] = $this->server->verify_request( $request );
+ $this->assertEquals( $this->consumer, $consumer );
+ $this->assertEquals( $this->access_token, $token );
+ }
+
+ public function testAcceptRequestWithoutVersion() {
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
+ $request->unset_parameter('oauth_version');
+ $request->sign_request( $this->hmac_sha1, $this->consumer, $this->access_token );
+
+ [ $consumer, $token ] = $this->server->verify_request( $request );
+ $this->assertEquals( $this->consumer, $consumer );
+ $this->assertEquals( $this->access_token, $token );
+ }
+
+ public function testRejectRequestSignedWithRequestToken() {
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->request_token, 'POST', 'http://example.com');
+ $request->sign_request( $this->plaintext, $this->consumer, $this->request_token );
+
+ $this->expectException(OAuthException::class);
+ $this->server->verify_request( $request );
+ }
+
+ public function requiredParameterProvider() {
+ // The list of required parameters is taken from
+ // Chapter 7 ("Accessing Protected Resources")
+ return array(
+ array( 'oauth_consumer_key' ),
+ array( 'oauth_token' ),
+ array( 'oauth_signature_method' ),
+ array( 'oauth_signature' ),
+ array( 'oauth_timestamp' ),
+ array( 'oauth_nonce' ),
+ );
+ }
+
+ /**
+ * @dataProvider requiredParameterProvider
+ */
+ public function testRejectRequestWithMissingParameters( $required ) {
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
+ $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
+ $request->unset_parameter( $required );
+ $this->expectException(OAuthException::class);
+ $this->server->verify_request($request);
+ }
+
+ public function testRejectPastTimestamp() {
+ // We change the timestamp to be 10 hours ago, it should throw an exception
+
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
+ $request->set_parameter( 'oauth_timestamp', $request->get_parameter('oauth_timestamp') - 10*60*60, false);
+ $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
+
+ $this->expectException(OAuthException::class);
+ $this->server->verify_request($request);
+ }
+
+ public function testRejectFutureTimestamp() {
+ // We change the timestamp to be 10 hours in the future, it should throw an exception
+
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
+ $request->set_parameter( 'oauth_timestamp', $request->get_parameter('oauth_timestamp') + 10*60*60, false);
+ $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
+
+ $this->expectException(OAuthException::class);
+ $this->server->verify_request($request);
+ }
+
+ public function testRejectUsedNonce() {
+ // We give a known nonce and should see an exception
+
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
+ // The Mock datastore is set to say that the `nonce` nonce is known
+ $request->set_parameter( 'oauth_nonce', 'nonce', false);
+ $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
+
+ $this->expectException(OAuthException::class);
+ $this->server->verify_request($request);
+ }
+
+ public function testRejectInvalidSignature() {
+ // We change the signature post-signing to be something invalid
+
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
+ $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
+ $request->set_parameter( 'oauth_signature', '__whatever__', false);
+
+ $this->expectException(OAuthException::class);
+ $this->server->verify_request($request);
+ }
+
+ public function testRejectInvalidConsumer() {
+ // We use the consumer-key "unknown", which isn't known by the datastore.
+
+ $unknown_consumer = new OAuthConsumer('unknown', '__unused__');
+
+ $request = OAuthRequest::from_consumer_and_token( $unknown_consumer, $this->access_token, 'POST', 'http://example.com');
+ $request->sign_request( $this->plaintext, $unknown_consumer, $this->access_token );
+
+ $this->expectException(OAuthException::class);
+ $this->server->verify_request( $request );
+ }
+
+ public function testRejectInvalidToken() {
+ // We use the access-token "unknown" which isn't known by the datastore
+
+ $unknown_token = new OAuthToken('unknown', '__unused__');
+
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, $unknown_token, 'POST', 'http://example.com');
+ $request->sign_request( $this->plaintext, $this->consumer, $unknown_token );
+
+ $this->expectException(OAuthException::class);
+ $this->server->verify_request( $request );
+ }
+
+ public function testRejectUnknownSignatureMethod() {
+ // We use a server that only supports HMAC-SHA1, but requests with PLAINTEXT signature
+
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
+ $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
+
+ $server = new OAuthServer( new Mock_OAuthDataStore() );
+ $server->add_signature_method( $this->hmac_sha1 );
+
+ $this->expectException(OAuthException::class);
+ $server->verify_request( $request );
+ }
+
+ public function testRejectUnknownVersion() {
+ // We use the version "1.0a" which isn't "1.0", so reject the request
+
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
+ $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
+ $request->set_parameter('oauth_version', '1.0a', false);
+
+ $this->expectException(OAuthException::class);
+ $this->server->verify_request( $request );
+ }
+
+ public function testCreateRequestToken() {
+ // We request a new Request Token
+
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, NULL, 'POST', 'http://example.com');
+ $request->sign_request( $this->plaintext, $this->consumer, NULL );
+
+ $token = $this->server->fetch_request_token($request);
+ $this->assertEquals($this->request_token, $token);
+ }
+
+ public function testRejectSignedRequestTokenRequest() {
+ // We request a new Request Token, but the request is signed with a token which should fail
+
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->request_token, 'POST', 'http://example.com');
+ $request->sign_request( $this->plaintext, $this->consumer, $this->request_token );
+
+ $this->expectException(OAuthException::class);
+ $token = $this->server->fetch_request_token($request);
+ }
+
+ public function testCreateAccessToken() {
+ // We request a new Access Token
+
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->request_token, 'POST', 'http://example.com');
+ $request->sign_request( $this->plaintext, $this->consumer, $this->request_token );
+
+ $token = $this->server->fetch_access_token($request);
+ $this->assertEquals($this->access_token, $token);
+ }
+
+ public function testRejectUnsignedAccessTokenRequest() {
+ // We request a new Access Token, but we didn't sign the request with a Access Token
+
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, NULL, 'POST', 'http://example.com');
+ $request->sign_request( $this->plaintext, $this->consumer, NULL );
+
+ $this->expectException(OAuthException::class);
+ $token = $this->server->fetch_access_token($request);
+ }
+
+ public function testRejectAccessTokenSignedAccessTokenRequest() {
+ // We request a new Access Token, but the request is signed with an access token, so fail!
+
+ $request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->access_token, 'POST', 'http://example.com');
+ $request->sign_request( $this->plaintext, $this->consumer, $this->access_token );
+
+ $this->expectException(OAuthException::class);
+ $token = $this->server->fetch_access_token($request);
+ }
+}