Mitar has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/153983

Change subject: Allow adding custom parameters to the callback for OAuth.
......................................................................

Allow adding custom parameters to the callback for OAuth.

Change-Id: I0a88818969a37145171c310050de2b3daadf72fa
---
M backend/MWOAuthConsumer.php
M backend/MWOAuthDataStore.php
M backend/MWOAuthServer.php
M i18n/en.json
M i18n/qqq.json
5 files changed, 74 insertions(+), 28 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/OAuth 
refs/changes/83/153983/1

diff --git a/backend/MWOAuthConsumer.php b/backend/MWOAuthConsumer.php
index ce2fe66..e70375f 100644
--- a/backend/MWOAuthConsumer.php
+++ b/backend/MWOAuthConsumer.php
@@ -189,18 +189,6 @@
        }
 
        /**
-        * @param string $verifyCode verification code
-        * @param string $requestKey original request key from /initiate
-        * @return string the url for redirection
-        */
-       public function generateCallbackUrl( $verifyCode, $requestKey ) {
-               return wfAppendQuery( $this->callbackUrl, array(
-                       'oauth_verifier' => $verifyCode,
-                       'oauth_token'    => $requestKey
-               ) );
-       }
-
-       /**
         * Check if the consumer is still pending approval and is owned by $user
         *
         * @param \User $user
diff --git a/backend/MWOAuthDataStore.php b/backend/MWOAuthDataStore.php
index c51cb9d..bdc120c 100644
--- a/backend/MWOAuthDataStore.php
+++ b/backend/MWOAuthDataStore.php
@@ -64,6 +64,30 @@
        }
 
        /**
+        * @param OAuthConsumer $consumer
+        * @param string $verifyCode verification code
+        * @param string $requestKey original request key from /initiate
+        * @return string the url for redirection
+        */
+       public function generateCallbackUrl( $consumer, $verifyCode, 
$requestKey ) {
+               $cacheKey = MWOAuthUtils::getCacheKey( 'callback', 
$consumer->key, 'request', $requestKey );
+               $callback = $this->cache->get( $cacheKey );
+               if ( $callback === null || !is_string( $callback ) ) {
+                       throw new MWOAuthException( 
'mwoauthdatastore-callback-not-found' );
+               }
+               $this->cache->delete( $cacheKey );
+
+               if ( $callback === 'oob' ) {
+                 $callback = $consumer->get( 'callbackUrl' );
+               }
+
+               return wfAppendQuery( $callback, array(
+                       'oauth_verifier' => $verifyCode,
+                       'oauth_token'    => $requestKey
+               ) );
+       }
+
+       /**
         * Check that nonce has not been seen before. Add it on check, so we 
don't repeat it.
         * Note, timestamp has already been checked, so this should be a fresh 
nonce.
         *
@@ -102,15 +126,17 @@
         * Generate a new token (attached to this consumer), save it in the 
cache, and return it
         *
         * @param MWOAuthConsumer|OAuthConsumer $consumer
-        * @param null $callback
+        * @param 'oob' $callback
         * @return MWOAuthToken
         */
-       public function new_request_token( $consumer, $callback = null ) {
+       public function new_request_token( $consumer, $callback = 'oob' ) {
                $token = MWOAuthDataStore::newToken();
-               $cacheKey = MWOAuthUtils::getCacheKey( 'token', $consumer->key, 
'request', $token->key );
-               $this->cache->add( $cacheKey, $token, 600 ); //10 minutes. 
Kindof arbitray.
+               $cacheTokenKey = MWOAuthUtils::getCacheKey( 'token', 
$consumer->key, 'request', $token->key );
+               $cacheCallbackKey = MWOAuthUtils::getCacheKey( 'callback', 
$consumer->key, 'request', $token->key );
+               $this->cache->add( $cacheTokenKey, $token, 600 ); //10 minutes. 
Kindof arbitray.
+               $this->cache->add( $cacheCallbackKey, $callback, 600 ); //10 
minutes. Kindof arbitray.
                wfDebugLog( 'OAuth', __METHOD__ .
-                       ": New request token {$token->key} for 
{$consumer->key}" );
+                       ": New request token {$token->key} for {$consumer->key} 
with callback {$callback}" );
                return $token;
        }
 
diff --git a/backend/MWOAuthServer.php b/backend/MWOAuthServer.php
index 384139b..8f1f5ee 100644
--- a/backend/MWOAuthServer.php
+++ b/backend/MWOAuthServer.php
@@ -28,18 +28,50 @@
 
                $this->check_signature( $request, $consumer, $token );
 
-               // In MediaWiki, we require the callback to be established at 
registration
-               // OAuth 1.0a (rfc5849, section 2.1) specifies that 
oauth_callback is required
-               // for the temporary credentials, and "If the client is unable 
to receive callbacks
-               // or a callback URI has been established via other means, the 
parameter value MUST
-               // be set to "oob" (case sensitive), to indicate an out-of-band 
configuration."
                $callback = $request->get_parameter( 'oauth_callback' );
-               if ( $callback !== 'oob' ) {
-                       throw new MWOAuthException( 'callback-not-oob' );
-               }
+
+               $this->checkCallback( $consumer, $callback );
+
                $new_token = $this->data_store->new_request_token( $consumer, 
$callback );
                $new_token->oauth_callback_confirmed = 'true';
                return $new_token;
+       }
+
+       /**
+        * Ensure the callback is "oob" or that it is a strict string prefix of 
a
+        * registered callback. It throws an exception if callback is invalid.
+        *
+        * In MediaWiki, we require the callback to be established at 
registration.
+        * OAuth 1.0a (rfc5849, section 2.1) specifies that oauth_callback is 
required
+        * for the temporary credentials, and "If the client is unable to 
receive callbacks
+        * or a callback URI has been established via other means, the 
parameter value MUST
+        * be set to "oob" (case sensitive), to indicate an out-of-band 
configuration."
+        * Otherwise, client can provide a callback, which must be a strict 
string prefix of
+        * a registered callback. We verify at registration that registered 
callback is a
+        * valid URI, so also one matching the prefix probably is, but we 
verify anyway.
+        *
+        * @param MWOAuthConsumer $consumer
+        * @param string $callback
+        * @throws MWOAuthException
+        */
+       private function checkCallback( $consumer, $callback ) {
+               if ( !$callback ) {
+                       throw new MWOAuthException( 
'callback-not-oob-or-prefix' );
+               }
+               if ( $callback === 'oob' ) {
+                       return;
+               }
+
+               if ( wfParseUrl( $callback ) === null ) {
+                       throw new MWOAuthException( 
'callback-not-oob-or-prefix' );
+               }
+
+               $consumerCallback = $consumer->get( 'callbackUrl' );
+               if ( substr( $callback, 0, strlen( $consumerCallback ) ) !== 
$consumerCallback ) {
+                       throw new MWOAuthException( 
'callback-not-oob-or-prefix' );
+               }
+
+               return;
        }
 
        /**
@@ -197,7 +229,7 @@
                $requestToken->addAccessKey( $accessToken->key );
                $this->data_store->updateRequestToken( $requestToken, $consumer 
);
                wfDebugLog( 'OAuth', "Verification code 
{$requestToken->getVerifyCode()} for $requestTokenKey (client: $consumerKey)" );
-               return $consumer->generateCallbackUrl( 
$requestToken->getVerifyCode(), $requestTokenKey );
+               return $this->data_store->generateCallbackUrl( $consumer, 
$requestToken->getVerifyCode(), $requestTokenKey );
        }
 
        /**
diff --git a/i18n/en.json b/i18n/en.json
index 538dabf..bc1ee48 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -241,7 +241,7 @@
     "mwoauth-grant-viewdeleted": "View deleted information",
     "mwoauth-grant-viewmywatchlist": "View your watchlist",
     "mwoauth-oauth-exception": "An error occurred in the OAuth protocol: $1",
-    "mwoauth-callback-not-oob": "oauth_callback must be set, and must be set 
to \"oob\" (case-sensitive)",
+    "mwoauth-callback-not-oob-or-prefix": "oauth_callback must be set, and 
must be set to \"oob\" (case-sensitive), or be a prefix of a configured 
callback",
     "right-mwoauthproposeconsumer": "Propose new OAuth consumers",
     "right-mwoauthupdateownconsumer": "Update OAuth consumers you control",
     "right-mwoauthmanageconsumer": "Manage OAuth consumers",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 9914e98..e097845 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -246,7 +246,7 @@
        "mwoauth-grant-viewdeleted": "Name for OAuth grant 
\"viewdeleted\".\n{{Related|Mwoauth-grant}}",
        "mwoauth-grant-viewmywatchlist": "Name for OAuth grant 
\"viewmywatchlist\".\n{{Related|Mwoauth-grant}}\n{{Identical|View your 
watchlist}}",
        "mwoauth-oauth-exception": "Used as failure message. Parameters:\n* $1 
- Exception message text",
-       "mwoauth-callback-not-oob": "Warning that the OAuth developer failed to 
include the required \"oauth_callback\" parameter, which must be set to the 
case-sensitive string \"oob\"",
+       "mwoauth-callback-not-oob-or-prefix": "Warning that the OAuth developer 
failed to include the required \"oauth_callback\" parameter, which must be set 
to the case-sensitive string \"oob\", or be a strict (character by character) 
prefix of what was configured at a consumr registration time",
        "right-mwoauthproposeconsumer": "{{doc-right|mwoauthproposeconsumer}}",
        "right-mwoauthupdateownconsumer": 
"{{doc-right|mwoauthupdateownconsumer}}",
        "right-mwoauthmanageconsumer": 
"{{doc-right|mwoauthmanageconsumer}}\n{{Identical|Manage OAuth consumer}}",

-- 
To view, visit https://gerrit.wikimedia.org/r/153983
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I0a88818969a37145171c310050de2b3daadf72fa
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/OAuth
Gerrit-Branch: master
Gerrit-Owner: Mitar <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to