Dbrant has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/337453 )

Change subject: Improve implicit re-login behavior when editing descriptions.
......................................................................

Improve implicit re-login behavior when editing descriptions.

This adds some logic to the base class MwPostResponse that lets us know
when the user needs to be re-logged-in automatically, before we retry
fetching the edit token and attempting the edit again. This is in contrast
with our current behavior of explicitly re-logging-in the user upon every
single edit.

This also updates the retry logic when saving a description, by resetting
the retry counter to 0 when the Save button is clicked. (Previously the
retry counter was never reset.)

Note: 2FA users will still need to go to the Login activity to log in
correctly, prior to making additional edits.

Change-Id: I8e2a3f8997ae529798d19124a81728206836693e
---
M app/src/main/java/org/wikipedia/dataclient/mwapi/MwPostResponse.java
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/edit/Edit.java
M app/src/main/java/org/wikipedia/edit/EditClient.java
5 files changed, 41 insertions(+), 39 deletions(-)


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

diff --git 
a/app/src/main/java/org/wikipedia/dataclient/mwapi/MwPostResponse.java 
b/app/src/main/java/org/wikipedia/dataclient/mwapi/MwPostResponse.java
index 2a97519..6dfcb72 100644
--- a/app/src/main/java/org/wikipedia/dataclient/mwapi/MwPostResponse.java
+++ b/app/src/main/java/org/wikipedia/dataclient/mwapi/MwPostResponse.java
@@ -6,4 +6,12 @@
     public boolean success(@Nullable String result) {
         return super.success() && "success".equals(result);
     }
+
+    public boolean badLoginState() {
+        return "assertuserfailed".equals(code());
+    }
+
+    public boolean badToken() {
+        return "badtoken".equals(code());
+    }
 }
\ No newline at end of file
diff --git 
a/app/src/main/java/org/wikipedia/descriptions/DescriptionEditClient.java 
b/app/src/main/java/org/wikipedia/descriptions/DescriptionEditClient.java
index c6bb52c..ca49875 100644
--- a/app/src/main/java/org/wikipedia/descriptions/DescriptionEditClient.java
+++ b/app/src/main/java/org/wikipedia/descriptions/DescriptionEditClient.java
@@ -38,6 +38,7 @@
     public interface Callback {
         void success(@NonNull Call<DescriptionEdit> call);
         void abusefilter(@NonNull Call<DescriptionEdit> call, @Nullable String 
code, @Nullable String info);
+        void invalidLogin(@NonNull Call<DescriptionEdit> call, @NonNull 
Throwable caught);
         void failure(@NonNull Call<DescriptionEdit> call, @NonNull Throwable 
caught);
     }
 
@@ -111,14 +112,17 @@
     private void handleError(@NonNull Call<DescriptionEdit> call, @NonNull 
DescriptionEdit body,
                              @NonNull Callback cb) {
         MwServiceError error = body.getError();
-        if (error != null && error.hasMessageName(ABUSEFILTER_DISALLOWED)) {
+        String info = body.info();
+        RuntimeException exception = new RuntimeException(info != null
+                ? info : "An unknown error occurred");
+
+        if (body.badLoginState() || body.badToken()) {
+            cb.invalidLogin(call, exception);
+        } else if (error != null && 
error.hasMessageName(ABUSEFILTER_DISALLOWED)) {
             cb.abusefilter(call, ABUSEFILTER_DISALLOWED, 
error.getMessageHtml(ABUSEFILTER_DISALLOWED));
         } else if (error != null && error.hasMessageName(ABUSEFILTER_WARNING)) 
{
             cb.abusefilter(call, ABUSEFILTER_WARNING, 
error.getMessageHtml(ABUSEFILTER_WARNING));
         } else {
-            String info = body.info();
-            RuntimeException exception = new RuntimeException(info != null
-                    ? info : "An unknown error occurred");
             cb.failure(call, RetrofitException.unexpectedError(exception));
         }
     }
diff --git 
a/app/src/main/java/org/wikipedia/descriptions/DescriptionEditFragment.java 
b/app/src/main/java/org/wikipedia/descriptions/DescriptionEditFragment.java
index 772d883..4389a12 100644
--- a/app/src/main/java/org/wikipedia/descriptions/DescriptionEditFragment.java
+++ b/app/src/main/java/org/wikipedia/descriptions/DescriptionEditFragment.java
@@ -163,18 +163,10 @@
             editView.setError(null);
             editView.setSaveState(true);
 
+            retries = 0;
             cancelCalls();
 
-            if (User.isLoggedIn()) {
-                refreshLoginTokens(User.getUser(), new RetryCallback() {
-                    @Override
-                    public void retry() { // success callback
-                        requestEditToken();
-                    }
-                });
-            } else {
-                requestEditToken();
-            }
+            requestEditToken();
 
             if (funnel != null) {
                 funnel.logSaveAttempt();
@@ -193,17 +185,7 @@
                         @Override public void failure(@NonNull Call<CsrfToken> 
call,
                                                       @NonNull Throwable 
caught) {
                             L.w("could not get edit token: ", caught);
-                            if (retries < MAX_RETRIES && User.getUser() != 
null) {
-                                retries++;
-                                refreshLoginTokens(User.getUser(), new 
RetryCallback() {
-                                    @Override public void retry() {
-                                        L.i("retrying...");
-                                        requestEditToken();
-                                    }
-                                });
-                            } else {
-                                editFailed(caught);
-                            }
+                            retryWithLogin(caught);
                         }
                     });
         }
@@ -211,17 +193,24 @@
         /**
          * Refresh all tokens/cookies, then retry the previous request.
          * This is needed when the edit token was not retrieved because the 
login session expired.
-         *
-         * @param user user info to be able to log in
-         * @param retryCallback a repeat of the action which failed before
-         * @throws IllegalArgumentException if user is not logged in
          */
-        private void refreshLoginTokens(User user, @NonNull RetryCallback 
retryCallback) {
-            WikipediaApp app = WikipediaApp.getInstance();
-            app.getCsrfTokenStorage().clearAllTokens();
-            app.getCookieManager().clearAllCookies();
+        private void retryWithLogin(@NonNull Throwable caught) {
+            if (retries < MAX_RETRIES && User.getUser() != null) {
+                retries++;
 
-            login(user, retryCallback);
+                WikipediaApp app = WikipediaApp.getInstance();
+                app.getCsrfTokenStorage().clearAllTokens();
+                app.getCookieManager().clearAllCookies();
+
+                login(User.getUser(), new RetryCallback() {
+                    @Override public void retry() {
+                        L.i("retrying...");
+                        requestEditToken();
+                    }
+                });
+            } else {
+                editFailed(caught);
+            }
         }
 
         private void login(@NonNull final User user, @NonNull final 
RetryCallback retryCallback) {
@@ -279,6 +268,11 @@
                             }
                         }
 
+                        @Override public void invalidLogin(@NonNull 
Call<DescriptionEdit> call,
+                                                           @NonNull Throwable 
caught) {
+                            retryWithLogin(caught);
+                        }
+
                         @Override public void failure(@NonNull 
Call<DescriptionEdit> call,
                                                       @NonNull Throwable 
caught) {
                             editFailed(caught);
diff --git a/app/src/main/java/org/wikipedia/edit/Edit.java 
b/app/src/main/java/org/wikipedia/edit/Edit.java
index 9b36a6d..b8d6d0b 100644
--- a/app/src/main/java/org/wikipedia/edit/Edit.java
+++ b/app/src/main/java/org/wikipedia/edit/Edit.java
@@ -15,10 +15,6 @@
         return edit != null;
     }
 
-    boolean badLoginState() {
-        return "assertuserfailed".equals(code());
-    }
-
     class Result {
         @SuppressWarnings("unused") @Nullable private String result;
         @SuppressWarnings("unused") private int newrevid;
diff --git a/app/src/main/java/org/wikipedia/edit/EditClient.java 
b/app/src/main/java/org/wikipedia/edit/EditClient.java
index 494d89c..09cde8b 100644
--- a/app/src/main/java/org/wikipedia/edit/EditClient.java
+++ b/app/src/main/java/org/wikipedia/edit/EditClient.java
@@ -50,7 +50,7 @@
                     if (response.body().hasEditResult()) {
                         handleEditResult(response.body().edit(), call, cb);
                     } else if (response.body().hasError()) {
-                        RuntimeException e = response.body().badLoginState()
+                        RuntimeException e = response.body().badLoginState() 
|| response.body().badToken()
                                 ? new UserNotLoggedInException()
                                 : new MwException(response.body().getError());
                         cb.failure(call, e);

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I8e2a3f8997ae529798d19124a81728206836693e
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Dbrant <[email protected]>

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

Reply via email to