Bartosz Dziewoński has uploaded a new change for review.
https://gerrit.wikimedia.org/r/231711
Change subject: Implement a mediawiki.ForeignApi extension
......................................................................
Implement a mediawiki.ForeignApi extension
Extends mw.ForeignApi with CentralAuth authentication handling,
amending every request with a 'centralauthtoken' parameter, if
required.
Every request to the foreign wiki will be preceded by a
'action=centralauthtoken' request to the local wiki, except in cases
where we detect that it is unproductive or unnecessary.
Depends on Ic20b9682d28633baa87d22e6e9fb71ce507da58d in MediaWiki core.
Bug: T66636
Change-Id: I0fd05ef8b9c9db0fdb59c6cb248f364259f80456
---
M CentralAuth.php
M includes/CentralAuthHooks.php
A modules/ext.centralauth.ForeignApi.js
3 files changed, 133 insertions(+), 0 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/CentralAuth
refs/changes/11/231711/1
diff --git a/CentralAuth.php b/CentralAuth.php
index 693d5de..2486625 100644
--- a/CentralAuth.php
+++ b/CentralAuth.php
@@ -388,6 +388,7 @@
$wgHooks['UnitTestsList'][] = 'CentralAuthHooks::onUnitTestsList';
$wgHooks['SpecialContributionsBeforeMainOutput'][] =
'CentralAuthHooks::onSpecialContributionsBeforeMainOutput';
$wgHooks['SpecialPage_initList'][] =
'CentralAuthHooks::onSpecialPage_initList';
+$wgHooks['ResourceLoaderForeignApiModules'][] =
'CentralAuthHooks::onResourceLoaderForeignApiModules';
// For interaction with the Special:Renameuser extension
$wgHooks['RenameUserWarning'][] = 'CentralAuthHooks::onRenameUserWarning';
@@ -569,5 +570,12 @@
)
) + $commonModuleInfo;
+$wgResourceModules['ext.centralauth.ForeignApi'] = array(
+ 'scripts' => 'ext.centralauth.ForeignApi.js',
+ 'dependencies' => array(
+ 'mw.ForeignApi.core',
+ ),
+) + $commonModuleInfo;
+
// Finish configuration after other extensions and settings are loaded.
$wgExtensionFunctions[] = 'CentralAuthHooks::onRunExtensionFunctions';
diff --git a/includes/CentralAuthHooks.php b/includes/CentralAuthHooks.php
index 0544cc8..5eebe80 100644
--- a/includes/CentralAuthHooks.php
+++ b/includes/CentralAuthHooks.php
@@ -2174,4 +2174,9 @@
);
}
}
+
+ public static function onResourceLoaderForeignApiModules(
&$dependencies, ResourceLoaderContext $context = null ) {
+ $dependencies[] = 'ext.centralauth.ForeignApi';
+ return true;
+ }
}
diff --git a/modules/ext.centralauth.ForeignApi.js
b/modules/ext.centralauth.ForeignApi.js
new file mode 100644
index 0000000..71828e3
--- /dev/null
+++ b/modules/ext.centralauth.ForeignApi.js
@@ -0,0 +1,120 @@
+( function ( mw, $ ) {
+
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
+
+ /**
+ * Extend mw.ForeignApi with CentralAuth authentication handling.
+ *
+ * Every request to the foreign wiki will be preceded by a
'action=centralauthtoken' request to
+ * the local wiki. The foreign request will be extended with the
acquired token to ensure that the
+ * requests to foreign wiki will always be authenticated as the
currently logged-in user on local
+ * wiki.
+ *
+ * If we detect that the current user is anonymous, that the foreign
wiki doesn't have
+ * CentralAuth, or that the requests to foreign wiki will be correctly
authenticated without
+ * sending 'centralauthtoken' every time, the additional requests will
be skipped.
+ *
+ * @class mw.ForeignApi.plugin.CentralAuth
+ * @extends mw.ForeignApi
+ *
+ * @constructor
+ * @param {Object} [options]
+ *
+ * @author Bartosz Dziewoński
+ * @author Jon Robson
+ */
+ function CentralAuthForeignApi( options ) {
+ var foreignApi = this;
+ this.localApi = new mw.Api();
+ // If this is set, the additional requests for
'centralauthtoken' will always be skipped
+ this.noTokenEver = false;
+
+ // Call parent constructor
+ CentralAuthForeignApi.parent.call( this, options );
+
+ if ( !options || !options.url ) {
+ // Actually a local API
+ this.noTokenEver = true;
+ } else if ( mw.config.get( 'wgUserName' ) === null ) {
+ // Anonymous users cannot obtain a centralauthtoken
+ this.noTokenEver = true;
+ } else {
+ // We're logged in here, check to see if we're logged
in on the foreign wiki too, and thus can
+ // skip 'centralauthtoken' requests
+ CentralAuthForeignApi.parent.prototype.get.call( this,
{ action: 'query', meta: 'userinfo' } )
+ .done( function ( resp ) {
+ var userinfo = resp.query.userinfo;
+ if ( userinfo.anon === undefined &&
userinfo.name === mw.config.get( 'wgUserName' ) ) {
+ // We are logged in on the
foreign wiki
+ foreignApi.noTokenEver = true;
+ }
+ } );
+ }
+ }
+
+ OO.inheritClass( CentralAuthForeignApi, mw.ForeignApi );
+
+ /**
+ * Get a 'centralauthtoken' from the local wiki for use on the foreign
wiki.
+ *
+ * @private
+ * @return {jQuery.Promise}
+ */
+ CentralAuthForeignApi.prototype.getCentralAuthToken = function () {
+ var foreignApi = this;
+ return this.localApi.get( { action: 'centralauthtoken' }
).then( function ( resp ) {
+ if ( resp.error ) {
+ // Check some known cases where we'll never get
a token, to avoid wasting requests
+ if ( resp.error.code === 'notloggedin' ) {
+ // Anonymous users cannot obtain a
centralauthtoken
+ foreignApi.noTokenEver = true;
+ }
+ if ( resp.error.code === 'unknown_action' ) {
+ // Remote wiki doesn't have CentralAuth
installed
+ foreignApi.noTokenEver = true;
+ }
+ return $.Deferred().reject( resp.error );
+ } else {
+ return resp.centralauthtoken.centralauthtoken;
+ }
+ } );
+ };
+
+ /**
+ * @inheritdoc
+ */
+ CentralAuthForeignApi.prototype.ajax = function ( parameters,
ajaxOptions ) {
+ var tokenPromise, foreignApi = this;
+ // If we know we can't get a 'centralauthtoken', or if one was
provided, don't request it
+ if ( this.noTokenEver || hasOwnProperty.call( parameters,
'centralauthtoken' ) ) {
+ tokenPromise = $.Deferred().reject().promise();
+ } else {
+ tokenPromise = this.getCentralAuthToken();
+ }
+
+ return tokenPromise.then(
+ function ( centralAuthToken ) {
+ var url, newParameters, newAjaxOptions;
+
+ // Add 'centralauthtoken' query parameter. Per
API documentation, it must also be part of
+ // the request URI, and not just request body
(even in case of POST requests).
+ newParameters = $.extend( { centralauthtoken:
centralAuthToken }, parameters );
+ url = ( ajaxOptions && ajaxOptions.url ) ||
foreignApi.defaults.ajax.url;
+ url += ( url.indexOf( '?' ) !== -1 ? '&' : '?'
) +
+ 'centralauthtoken=' +
encodeURIComponent( centralAuthToken );
+ newAjaxOptions = $.extend( {}, ajaxOptions, {
url: url } );
+
+ return
CentralAuthForeignApi.parent.prototype.ajax.call( foreignApi, newParameters,
newAjaxOptions );
+ },
+ function () {
+ // We couldn't get the token, but continue
anyway. This is expected in some cases, like
+ // anonymous users.
+ return
CentralAuthForeignApi.parent.prototype.ajax.call( foreignApi, parameters,
ajaxOptions );
+ }
+ );
+ };
+
+ // Expose
+ mw.ForeignApi = CentralAuthForeignApi;
+
+}( mediaWiki, jQuery ) );
--
To view, visit https://gerrit.wikimedia.org/r/231711
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0fd05ef8b9c9db0fdb59c6cb248f364259f80456
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/CentralAuth
Gerrit-Branch: master
Gerrit-Owner: Bartosz Dziewoński <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits