jenkins-bot has submitted this change and it was merged.

Change subject: ForeignApi: Allow posting for anonymous users
......................................................................


ForeignApi: Allow posting for anonymous users

When a user is logged out, get a CSRF token from the remote wiki and
make a POST request using it.

Bug: T95960
Change-Id: Ic5afa3a78c91fd374278aa28296e5560db29f85a
---
M resources/mobile.foreignApi/ForeignApi.js
A tests/qunit/modules/test_ForeignApi.js
2 files changed, 76 insertions(+), 10 deletions(-)

Approvals:
  Phuedx: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/resources/mobile.foreignApi/ForeignApi.js 
b/resources/mobile.foreignApi/ForeignApi.js
index 62a7680..2e762b3 100644
--- a/resources/mobile.foreignApi/ForeignApi.js
+++ b/resources/mobile.foreignApi/ForeignApi.js
@@ -46,6 +46,7 @@
                },
                /**
                 * Post to API with support for central auth tokens
+                * If the user is anonymous, then post using the csrftoken 
received from the remote wiki.
                 * @param {String} tokenType Ignored. `'csrf'` is always used
                 * @param {Object} data Data to be preprocessed and added to 
options
                 * @param {Object} options Parameters passed to $.ajax()
@@ -56,27 +57,51 @@
                                d = $.Deferred();
 
                        options = options || {};
+                       options.xhrFields = {
+                               withCredentials: true
+                       };
+                       // In case it is a file upload we need to append origin 
to query string.
+                       options.url = self.apiUrl + '?origin=' + 
self.getOrigin();
+
+                       data.origin = self.getOrigin();
+
                        // first let's sort out the token
                        self.getCentralAuthToken().done( function ( 
centralAuthTokenOne ) {
                                self.getToken( tokenType, centralAuthTokenOne 
).done( function ( token ) {
                                        self.getCentralAuthToken().done( 
function ( centralAuthTokenTwo ) {
-                                               data.format = 'json';
                                                data.centralauthtoken = 
centralAuthTokenTwo;
                                                data.token = token;
-                                               data.origin = self.getOrigin();
-
-                                               options.xhrFields = {
-                                                       withCredentials: true
-                                               };
-                                               // In case it is a file upload 
we need to append origin to query string.
-                                               options.url = self.apiUrl + 
'?origin=' + self.getOrigin();
-
                                                Api.prototype.post.call( self, 
data, options ).done( function ( resp ) {
                                                        d.resolve( resp );
                                                } ).fail( $.proxy( d, 'reject' 
) );
                                        } ).fail( $.proxy( d, 'reject' ) );
                                } ).fail( $.proxy( d, 'reject' ) );
-                       } ).fail( $.proxy( d, 'reject' ) );
+                       } ).fail( function ( code ) {
+                               if ( code !== 'notloggedin' ) {
+                                       d.reject();
+                                       return;
+                               }
+                               // So the user is not logged in locally.
+                               // Get the remote CSRF token
+                               Api.prototype.ajax.call(
+                                       self, {
+                                               action: 'query',
+                                               meta: 'tokens',
+                                               type: 'csrf'
+                                       }, {
+                                               url: options.url
+                                       }
+                               ).done( function ( resp ) {
+                                       if ( resp.query && resp.query.tokens && 
resp.query.tokens.csrftoken ) {
+                                               data.token = 
resp.query.tokens.csrftoken;
+                                               Api.prototype.post.call( self, 
data, options ).done( function ( resp ) {
+                                                       d.resolve( resp );
+                                               } ).fail( $.proxy( d, 'reject' 
) );
+                                       } else {
+                                               d.reject();
+                                       }
+                               } ).fail( $.proxy( d, 'reject' ) );
+                       } );
                        return d;
                },
                /** @inheritdoc */
diff --git a/tests/qunit/modules/test_ForeignApi.js 
b/tests/qunit/modules/test_ForeignApi.js
new file mode 100644
index 0000000..65904a9
--- /dev/null
+++ b/tests/qunit/modules/test_ForeignApi.js
@@ -0,0 +1,41 @@
+( function ( M, $ ) {
+       var ForeignApi = M.require( 'modules/ForeignApi' ),
+               api = M.require( 'api' );
+
+       QUnit.module( 'MobileFrontend ForeignApi' );
+
+       // Test whether postWithToken() works when the user is logged out
+       QUnit.test( '#postWithToken - anon', 1, function ( assert ) {
+               var self = this,
+                       foreignApi = new ForeignApi(),
+                       editToken = mw.user.tokens.get( 'editToken' ),
+                       spy = this.sandbox.spy( api.Api.prototype, 'post' );
+
+               // Make sure the central auth token cannot be received
+               this.stub( foreignApi, 'getCentralAuthToken' ).returns(
+                       $.Deferred().rejectWith( self, [ 'notloggedin' ] )
+               );
+
+               // And ajax must return the csrftoken
+               this.stub( api.Api.prototype, 'ajax' ).returns(
+                       $.Deferred().resolveWith( self, [ {
+                               query: {
+                                       tokens: {
+                                               csrftoken: editToken
+                                       }
+                               }
+                       } ] )
+               );
+
+               // Now, let's post some data
+               foreignApi.postWithToken( 'csrf', { some: 'data' }, {} );
+
+               // POST must be called with the editToken, and not with the 
centralAuthToken
+               assert.ok( spy.calledWith( {
+                       origin: foreignApi.getOrigin(),
+                       some: 'data',
+                       token: editToken
+               } ), 'Posting to ForeignApi with token when the user is logged 
out works!' );
+       } );
+
+}( mw.mobileFrontend, jQuery ) );

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ic5afa3a78c91fd374278aa28296e5560db29f85a
Gerrit-PatchSet: 7
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: Bmansurov <bmansu...@wikimedia.org>
Gerrit-Reviewer: Anomie <bjor...@wikimedia.org>
Gerrit-Reviewer: Bmansurov <bmansu...@wikimedia.org>
Gerrit-Reviewer: Jdlrobson <jrob...@wikimedia.org>
Gerrit-Reviewer: Kaldari <rkald...@wikimedia.org>
Gerrit-Reviewer: Legoktm <legoktm.wikipe...@gmail.com>
Gerrit-Reviewer: Phuedx <g...@samsmith.io>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to