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