BearND has uploaded a new change for review.

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

Change subject: Always request edit token before Wikidata description edits
......................................................................

Always request edit token before Wikidata description edits

Note that the edit token is fetched from Wikidata. This is a
step towards making description edits using logged in credentials.
We still want to request a token for the non-logged in case
since the hard-coded token will go away soon. See T40417.

Bug: T150705
Bug: T146641
Change-Id: I91599b410dfbc6136838e9301290866ee733aaa8
---
M app/src/main/java/org/wikipedia/descriptions/DescriptionEditClient.java
M app/src/main/java/org/wikipedia/descriptions/DescriptionEditFragment.java
M 
app/src/main/java/org/wikipedia/descriptions/centralauth/CentralAuthTokenClient.java
M app/src/main/java/org/wikipedia/edit/token/EditTokenClient.java
M app/src/test/java/org/wikipedia/descriptions/DescriptionEditClientTest.java
5 files changed, 73 insertions(+), 30 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia 
refs/changes/24/325324/1

diff --git 
a/app/src/main/java/org/wikipedia/descriptions/DescriptionEditClient.java 
b/app/src/main/java/org/wikipedia/descriptions/DescriptionEditClient.java
index 268e81b..5a437e7 100644
--- a/app/src/main/java/org/wikipedia/descriptions/DescriptionEditClient.java
+++ b/app/src/main/java/org/wikipedia/descriptions/DescriptionEditClient.java
@@ -21,8 +21,8 @@
  * Data Client to submit a new or updated description to wikidata.org.
  */
 class DescriptionEditClient {
-    private static final String ANONYMOUS_TOKEN = "+\\";
-    private static final WikiSite WIKI_DATA_SITE = new 
WikiSite("www.wikidata.org", "");
+    static final String ANONYMOUS_TOKEN = "+\\";
+    static final WikiSite WIKI_DATA_SITE = new WikiSite("www.wikidata.org", 
"");
 
     @NonNull private final MwCachedService<Service> cachedService
             = new MwCachedService<>(Service.class);
@@ -36,29 +36,32 @@
     /**
      * Submit a new value for the Wikidata description associated with the 
given Wikipedia page.
      *
-     * @param pageTitle   specifies the Wikipedia page the Wikidata item is 
linked to
-     * @param description the new value for the Wikidata description
-     * @param cb          called when this is done successfully or failed
+     * @param pageTitle        specifies the Wikipedia page the Wikidata item 
is linked to
+     * @param description      the new value for the Wikidata description
+     * @param editToken        a token from Wikidata
+     * @param cb               called when this is done successfully or failed
      * @return Call object which can be used to cancel the request
      */
     public Call<DescriptionEdit> request(@NonNull PageTitle pageTitle,
                                          @NonNull String description,
+                                         @NonNull String editToken,
                                          @NonNull Callback cb) {
         return request(cachedService.service(WIKI_DATA_SITE), pageTitle, 
description,
-                pageTitle.getWikiSite().languageCode(), User.isLoggedIn(), cb);
+                pageTitle.getWikiSite().languageCode(), editToken, 
User.isLoggedIn(), cb);
     }
 
     @SuppressWarnings("WeakerAccess") @VisibleForTesting
     Call<DescriptionEdit> request(@NonNull Service service,
-                                  @NonNull final PageTitle pageTitle,
-                                  @NonNull final String description,
-                                  @NonNull final String languageCode,
-                                  final boolean loggedIn,
+                                  @NonNull PageTitle pageTitle,
+                                  @NonNull String description,
+                                  @NonNull String languageCode,
+                                  @NonNull String editToken,
+                                  boolean loggedIn,
                                   @NonNull final Callback cb) {
 
         Call<DescriptionEdit> call = service.edit(languageCode, languageCode + 
"wiki",
-                pageTitle.getPrefixedText(), description, ANONYMOUS_TOKEN, 
null,
-                /* TODO: loggedIn ? "user" : */ null);
+                pageTitle.getPrefixedText(), description, editToken,
+                /* loggedIn ? "user" : */ null);
         call.enqueue(new retrofit2.Callback<DescriptionEdit>() {
             @Override
             public void onResponse(Call<DescriptionEdit> call,
@@ -111,7 +114,6 @@
                                    @NonNull @Field("title") String title,
                                    @NonNull @Field("value") String 
newDescription,
                                    @NonNull @Field("token") String token,
-                                   @Nullable @Field("centralauthtoken") String 
centralAuthToken,
                                    @Nullable @Field("assert") String user
         );
     }
diff --git 
a/app/src/main/java/org/wikipedia/descriptions/DescriptionEditFragment.java 
b/app/src/main/java/org/wikipedia/descriptions/DescriptionEditFragment.java
index 74e9e9b..27fa69c 100644
--- a/app/src/main/java/org/wikipedia/descriptions/DescriptionEditFragment.java
+++ b/app/src/main/java/org/wikipedia/descriptions/DescriptionEditFragment.java
@@ -14,6 +14,8 @@
 
 import org.wikipedia.Constants;
 import org.wikipedia.R;
+import org.wikipedia.edit.token.EditToken;
+import org.wikipedia.edit.token.EditTokenClient;
 import org.wikipedia.json.GsonMarshaller;
 import org.wikipedia.json.GsonUnmarshaller;
 import org.wikipedia.page.PageTitle;
@@ -24,13 +26,16 @@
 import butterknife.Unbinder;
 import retrofit2.Call;
 
+import static org.wikipedia.descriptions.DescriptionEditClient.WIKI_DATA_SITE;
+
 public class DescriptionEditFragment extends Fragment {
     private static final String ARG_TITLE = "title";
 
     @BindView(R.id.fragment_description_edit_view) DescriptionEditView 
editView;
     private Unbinder unbinder;
     private PageTitle pageTitle;
-    @Nullable private Call<DescriptionEdit> call;
+    @Nullable private Call<EditToken> editTokenCall;
+    @Nullable private Call<DescriptionEdit> descriptionEditCall;
 
     @NonNull
     public static DescriptionEditFragment newInstance(@NonNull PageTitle 
title) {
@@ -72,10 +77,7 @@
     }
 
     @Override public void onDestroy() {
-        if (call != null) {
-            call.cancel();
-            call = null;
-        }
+        cancelCalls();
         pageTitle = null;
         super.onDestroy();
     }
@@ -104,16 +106,48 @@
         }
     }
 
+    private void cancelCalls() {
+        // in reverse chronological order
+        if (descriptionEditCall != null) {
+            descriptionEditCall.cancel();
+            descriptionEditCall = null;
+        }
+        if (editTokenCall != null) {
+            editTokenCall.cancel();
+            editTokenCall = null;
+        }
+    }
+
     private class EditViewCallback implements DescriptionEditView.Callback {
         @Override
         public void onSaveClick() {
             editView.setError(null);
             editView.setSaveState(true);
 
-            if (call != null) {
-                call.cancel();
-            }
-            call = new DescriptionEditClient().request(pageTitle, 
editView.getDescription(),
+            cancelCalls();
+            requestEditToken();
+        }
+
+        /** fetch edit token from Wikidata */
+        private void requestEditToken() {
+            editTokenCall = new EditTokenClient().request(WIKI_DATA_SITE,
+                    new EditTokenClient.Callback() {
+                        @Override public void success(@NonNull Call<EditToken> 
call,
+                                                      @NonNull String 
editToken) {
+                            postDescription(editToken);
+                        }
+
+                        @Override public void failure(@NonNull Call<EditToken> 
call,
+                                                      @NonNull Throwable 
caught) {
+                            editFailed(caught);
+                        }
+                    });
+        }
+
+        /* send updated description to Wikidata */
+        private void postDescription(@NonNull String editToken) {
+            descriptionEditCall = new 
DescriptionEditClient().request(pageTitle,
+                    editView.getDescription(), editToken,
                     new DescriptionEditClient.Callback() {
                         @Override public void success(@NonNull 
Call<DescriptionEdit> call) {
                             if (getActivity() != null) {
@@ -135,10 +169,16 @@
 
                         @Override public void failure(@NonNull 
Call<DescriptionEdit> call,
                                                       @NonNull Throwable 
caught) {
-                            editView.setSaveState(false);
-                            editView.setError(caught.getMessage());
+                            editFailed(caught);
                         }
                     });
         }
+
+        private void editFailed(@NonNull Throwable caught) {
+            if (editView != null) {
+                editView.setSaveState(false);
+                editView.setError(caught.getMessage());
+            }
+        }
     }
 }
\ No newline at end of file
diff --git 
a/app/src/main/java/org/wikipedia/descriptions/centralauth/CentralAuthTokenClient.java
 
b/app/src/main/java/org/wikipedia/descriptions/centralauth/CentralAuthTokenClient.java
index 51ab11a..0488f2a 100644
--- 
a/app/src/main/java/org/wikipedia/descriptions/centralauth/CentralAuthTokenClient.java
+++ 
b/app/src/main/java/org/wikipedia/descriptions/centralauth/CentralAuthTokenClient.java
@@ -9,7 +9,7 @@
 
 import retrofit2.Call;
 import retrofit2.Response;
-import retrofit2.http.GET;
+import retrofit2.http.POST;
 
 /**
  * When accessing the API using a cross-domain AJAX request (CORS), use this 
to authenticate as the
@@ -61,7 +61,7 @@
     }
 
     @VisibleForTesting interface Service {
-        @GET("w/api.php?action=centralauthtoken&format=json")
+        @POST("w/api.php?action=centralauthtoken&format=json")
         Call<CentralAuthToken> get();
     }
 }
diff --git a/app/src/main/java/org/wikipedia/edit/token/EditTokenClient.java 
b/app/src/main/java/org/wikipedia/edit/token/EditTokenClient.java
index a61de26..cb632bf 100644
--- a/app/src/main/java/org/wikipedia/edit/token/EditTokenClient.java
+++ b/app/src/main/java/org/wikipedia/edit/token/EditTokenClient.java
@@ -1,6 +1,7 @@
 package org.wikipedia.edit.token;
 
 import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.support.annotation.VisibleForTesting;
 
 import org.wikipedia.dataclient.WikiSite;
@@ -14,13 +15,12 @@
 public class EditTokenClient {
     @NonNull private final MwCachedService<Service> cachedService = new 
MwCachedService<>(Service.class);
 
-    @NonNull public Call<EditToken> request(@NonNull final WikiSite wiki,
-                                            @NonNull final Callback cb) {
+    @NonNull public Call<EditToken> request(@NonNull WikiSite wiki, @NonNull 
Callback cb) {
         Service service = cachedService.service(wiki);
         return request(service, cb);
     }
 
-    @VisibleForTesting @NonNull Call<EditToken> request(@NonNull final Service 
service,
+    @VisibleForTesting @NonNull Call<EditToken> request(@NonNull Service 
service,
                                                         @NonNull final 
Callback cb) {
         Call<EditToken> call = service.editToken();
         call.enqueue(new retrofit2.Callback<EditToken>() {
diff --git 
a/app/src/test/java/org/wikipedia/descriptions/DescriptionEditClientTest.java 
b/app/src/test/java/org/wikipedia/descriptions/DescriptionEditClientTest.java
index 70ee28f..07c93ac 100644
--- 
a/app/src/test/java/org/wikipedia/descriptions/DescriptionEditClientTest.java
+++ 
b/app/src/test/java/org/wikipedia/descriptions/DescriptionEditClientTest.java
@@ -20,6 +20,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
+import static org.wikipedia.descriptions.DescriptionEditClient.ANONYMOUS_TOKEN;
 
 public class DescriptionEditClientTest extends MockWebServerTest {
     @NonNull private final DescriptionEditClient subject = new 
DescriptionEditClient();
@@ -106,6 +107,6 @@
     private Call<DescriptionEdit> request(@NonNull Callback cb) {
         final PageTitle pageTitle = new PageTitle("foo", 
WikiSite.forLanguageCode("en"));
         return subject.request(service(Service.class), pageTitle, "some new 
description", "en",
-                false, cb);
+                ANONYMOUS_TOKEN, false, cb);
     }
 }
\ No newline at end of file

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I91599b410dfbc6136838e9301290866ee733aaa8
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: BearND <bsitzm...@wikimedia.org>

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

Reply via email to