Skip to content

Commit 3d1efec

Browse files
Fix - No Precise Error Message After Error Due to Password Change (commons-app#5643)
* initial commit * Fix No Precise Message After Clicking Review Buttons * Fix For ThanksClient * Fix For Depictions * Fix For Categories * Fix For Description & Coordinates * Fix For Description & Coordinates * Fix For Description & Coordinates * Fix For Mark as Read notifications * resolve conflicts * fix merge conflicts
1 parent e56de2c commit 3d1efec

18 files changed

+361
-110
lines changed

app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerActivity.java

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,13 @@
3030
import androidx.core.content.ContextCompat;
3131
import com.google.android.material.floatingactionbutton.FloatingActionButton;
3232
import fr.free.nrw.commons.CameraPosition;
33+
import fr.free.nrw.commons.CommonsApplication;
3334
import fr.free.nrw.commons.Media;
3435
import fr.free.nrw.commons.R;
3536
import fr.free.nrw.commons.Utils;
37+
import fr.free.nrw.commons.auth.SessionManager;
38+
import fr.free.nrw.commons.auth.csrf.CsrfTokenClient;
39+
import fr.free.nrw.commons.auth.csrf.InvalidLoginTokenException;
3640
import fr.free.nrw.commons.coordinates.CoordinateEditHelper;
3741
import fr.free.nrw.commons.filepicker.Constants;
3842
import fr.free.nrw.commons.kvstore.JsonKvStore;
@@ -141,6 +145,8 @@ public class LocationPickerActivity extends BaseActivity implements
141145

142146
@Inject
143147
LocationServiceManager locationManager;
148+
@Inject
149+
SessionManager sessionManager;
144150

145151
/**
146152
* Constants
@@ -404,13 +410,29 @@ public void updateCoordinates(final String Latitude, final String Longitude,
404410
if (media == null) {
405411
return;
406412
}
407-
compositeDisposable.add(coordinateEditHelper.makeCoordinatesEdit(getApplicationContext(),media,
408-
Latitude, Longitude, Accuracy)
409-
.subscribeOn(Schedulers.io())
410-
.observeOn(AndroidSchedulers.mainThread())
411-
.subscribe(s -> {
412-
Timber.d("Coordinates are added.");
413-
}));
413+
414+
try {
415+
compositeDisposable.add(
416+
coordinateEditHelper.makeCoordinatesEdit(getApplicationContext(), media,
417+
Latitude, Longitude, Accuracy)
418+
.subscribeOn(Schedulers.io())
419+
.observeOn(AndroidSchedulers.mainThread())
420+
.subscribe(s -> {
421+
Timber.d("Coordinates are added.");
422+
}));
423+
} catch (Exception e) {
424+
if (e.getLocalizedMessage().equals(CsrfTokenClient.ANONYMOUS_TOKEN_MESSAGE)) {
425+
final String username = sessionManager.getUserName();
426+
final CommonsApplication.BaseLogoutListener logoutListener = new CommonsApplication.BaseLogoutListener(
427+
this,
428+
getString(R.string.invalid_login_message),
429+
username
430+
);
431+
432+
CommonsApplication.getInstance().clearApplicationData(
433+
this, logoutListener);
434+
}
435+
}
414436
}
415437

416438
/**

app/src/main/java/fr/free/nrw/commons/actions/PageEditClient.kt

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package fr.free.nrw.commons.actions
22

3+
import fr.free.nrw.commons.auth.csrf.InvalidLoginTokenException
34
import io.reactivex.Observable
45
import io.reactivex.Single
56
import fr.free.nrw.commons.auth.csrf.CsrfTokenClient
@@ -28,7 +29,11 @@ class PageEditClient(
2829
pageEditInterface.postEdit(pageTitle, summary, text, csrfTokenClient.getTokenBlocking())
2930
.map { editResponse -> editResponse.edit()!!.editSucceeded() }
3031
} catch (throwable: Throwable) {
31-
Observable.just(false)
32+
if (throwable is InvalidLoginTokenException) {
33+
throw throwable
34+
} else {
35+
Observable.just(false)
36+
}
3237
}
3338
}
3439

@@ -44,7 +49,11 @@ class PageEditClient(
4449
pageEditInterface.postAppendEdit(pageTitle, summary, appendText, csrfTokenClient.getTokenBlocking())
4550
.map { editResponse -> editResponse.edit()!!.editSucceeded() }
4651
} catch (throwable: Throwable) {
47-
Observable.just(false)
52+
if (throwable is InvalidLoginTokenException) {
53+
throw throwable
54+
} else {
55+
Observable.just(false)
56+
}
4857
}
4958
}
5059

@@ -58,12 +67,17 @@ class PageEditClient(
5867
fun prependEdit(pageTitle: String, prependText: String, summary: String): Observable<Boolean> {
5968
return try {
6069
pageEditInterface.postPrependEdit(pageTitle, summary, prependText, csrfTokenClient.getTokenBlocking())
61-
.map { editResponse -> editResponse.edit()!!.editSucceeded() }
70+
.map { editResponse -> editResponse.edit()?.editSucceeded() ?: false }
6271
} catch (throwable: Throwable) {
63-
Observable.just(false)
72+
if (throwable is InvalidLoginTokenException) {
73+
throw throwable
74+
} else {
75+
Observable.just(false)
76+
}
6477
}
6578
}
6679

80+
6781
/**
6882
* Set new labels to Wikibase server of commons
6983
* @param summary Edit summary
@@ -79,7 +93,11 @@ class PageEditClient(
7993
value, csrfTokenClient.getTokenBlocking()
8094
).map { it.success }
8195
} catch (throwable: Throwable) {
82-
Observable.just(0)
96+
if (throwable is InvalidLoginTokenException) {
97+
throw throwable
98+
} else {
99+
Observable.just(0)
100+
}
83101
}
84102
}
85103

@@ -93,4 +111,4 @@ class PageEditClient(
93111
it.query()?.pages()?.get(0)?.revisions()?.get(0)?.content()
94112
}
95113
}
96-
}
114+
}

app/src/main/java/fr/free/nrw/commons/actions/ThanksClient.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import fr.free.nrw.commons.CommonsApplication
44
import fr.free.nrw.commons.di.NetworkingModule.NAMED_COMMONS_CSRF
55
import io.reactivex.Observable
66
import fr.free.nrw.commons.auth.csrf.CsrfTokenClient
7+
import fr.free.nrw.commons.auth.csrf.InvalidLoginTokenException
8+
import fr.free.nrw.commons.auth.login.LoginFailedException
79
import javax.inject.Inject
810
import javax.inject.Named
911
import javax.inject.Singleton
@@ -32,8 +34,15 @@ class ThanksClient @Inject constructor(
3234
).map {
3335
mwThankPostResponse -> mwThankPostResponse.result?.success == 1
3436
}
35-
} catch (throwable: Throwable) {
36-
Observable.just(false)
37+
}
38+
catch (throwable: Throwable) {
39+
if (throwable is InvalidLoginTokenException) {
40+
Observable.error(throwable)
41+
}
42+
else {
43+
Observable.just(false)
44+
}
3745
}
3846
}
39-
}
47+
48+
}

app/src/main/java/fr/free/nrw/commons/auth/csrf/CsrfTokenClient.kt

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,19 @@ class CsrfTokenClient(
4848

4949
token = response.body()!!.query()!!.csrfToken()!!
5050
if (sessionManager.isUserLoggedIn && token == ANON_TOKEN) {
51-
throw RuntimeException("App believes we're logged in, but got anonymous token.")
51+
throw InvalidLoginTokenException(ANONYMOUS_TOKEN_MESSAGE)
5252
}
5353
break
54-
} catch (t: Throwable) {
54+
} catch (e: LoginFailedException) {
55+
throw InvalidLoginTokenException(ANONYMOUS_TOKEN_MESSAGE)
56+
}
57+
catch (t: Throwable) {
5558
Timber.w(t)
5659
}
5760
}
5861

5962
if (token.isEmpty() || token == ANON_TOKEN) {
60-
throw IOException(INVALID_TOKEN_ERROR_MESSAGE)
63+
throw InvalidLoginTokenException(ANONYMOUS_TOKEN_MESSAGE)
6164
}
6265
return token
6366
}
@@ -68,7 +71,7 @@ class CsrfTokenClient(
6871
override fun success(token: String?) {
6972
if (sessionManager.isUserLoggedIn && token == ANON_TOKEN) {
7073
retryWithLogin(cb) {
71-
RuntimeException("App believes we're logged in, but got anonymous token.")
74+
InvalidLoginTokenException(ANONYMOUS_TOKEN_MESSAGE)
7275
}
7376
} else {
7477
cb.success(token)
@@ -161,5 +164,8 @@ class CsrfTokenClient(
161164
private const val MAX_RETRIES = 1
162165
private const val MAX_RETRIES_OF_LOGIN_BLOCKING = 2
163166
const val INVALID_TOKEN_ERROR_MESSAGE = "Invalid token, or login failure."
167+
const val ANONYMOUS_TOKEN_MESSAGE = "App believes we're logged in, but got anonymous token."
164168
}
165169
}
170+
class InvalidLoginTokenException(message: String) : Exception(message)
171+

app/src/main/java/fr/free/nrw/commons/delete/DeleteHelper.java

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import fr.free.nrw.commons.Media;
1414
import fr.free.nrw.commons.R;
1515
import fr.free.nrw.commons.actions.PageEditClient;
16+
import fr.free.nrw.commons.auth.csrf.InvalidLoginTokenException;
1617
import fr.free.nrw.commons.notification.NotificationHelper;
1718
import fr.free.nrw.commons.review.ReviewController;
1819
import fr.free.nrw.commons.utils.ViewUtilWrapper;
@@ -66,7 +67,13 @@ public Single<Boolean> makeDeletion(Context context, Media media, String reason)
6667

6768
return delete(media, reason)
6869
.flatMapSingle(result -> Single.just(showDeletionNotification(context, media, result)))
69-
.firstOrError();
70+
.firstOrError()
71+
.onErrorResumeNext(throwable -> {
72+
if (throwable instanceof InvalidLoginTokenException) {
73+
return Single.error(throwable);
74+
}
75+
return Single.error(throwable);
76+
});
7077
}
7178

7279
/**
@@ -104,22 +111,30 @@ private Observable<Boolean> delete(Media media, String reason) {
104111
}
105112

106113
return pageEditClient.prependEdit(media.getFilename(), fileDeleteString + "\n", summary)
107-
.flatMap(result -> {
108-
if (result) {
109-
return pageEditClient.edit("Commons:Deletion_requests/" + media.getFilename(), subpageString + "\n", summary);
110-
}
111-
throw new RuntimeException("Failed to nominate for deletion");
112-
}).flatMap(result -> {
113-
if (result) {
114-
return pageEditClient.appendEdit("Commons:Deletion_requests/" + date, logPageString + "\n", summary);
115-
}
116-
throw new RuntimeException("Failed to nominate for deletion");
117-
}).flatMap(result -> {
118-
if (result) {
119-
return pageEditClient.appendEdit("User_Talk:" + creator, userPageString + "\n", summary);
120-
}
121-
throw new RuntimeException("Failed to nominate for deletion");
122-
});
114+
.onErrorResumeNext(throwable -> {
115+
if (throwable instanceof InvalidLoginTokenException) {
116+
return Observable.error(throwable);
117+
}
118+
return Observable.error(throwable);
119+
})
120+
.flatMap(result -> {
121+
if (result) {
122+
return pageEditClient.edit("Commons:Deletion_requests/" + media.getFilename(), subpageString + "\n", summary);
123+
}
124+
return Observable.error(new RuntimeException("Failed to nominate for deletion"));
125+
})
126+
.flatMap(result -> {
127+
if (result) {
128+
return pageEditClient.appendEdit("Commons:Deletion_requests/" + date, logPageString + "\n", summary);
129+
}
130+
return Observable.error(new RuntimeException("Failed to nominate for deletion"));
131+
})
132+
.flatMap(result -> {
133+
if (result) {
134+
return pageEditClient.appendEdit("User_Talk:" + creator, userPageString + "\n", summary);
135+
}
136+
return Observable.error(new RuntimeException("Failed to nominate for deletion"));
137+
});
123138
}
124139

125140
private boolean showDeletionNotification(Context context, Media media, boolean result) {
@@ -226,14 +241,15 @@ public void askReasonAndExecute(Media media,
226241
.subscribeOn(Schedulers.io())
227242
.observeOn(AndroidSchedulers.mainThread())
228243
.subscribe(aBoolean -> {
229-
if (aBoolean) {
230-
reviewCallback.onSuccess();
244+
reviewCallback.onSuccess();
245+
}, throwable -> {
246+
if (throwable instanceof InvalidLoginTokenException) {
247+
reviewCallback.onTokenException((InvalidLoginTokenException) throwable);
231248
} else {
232249
reviewCallback.onFailure();
233250
}
234251
reviewCallback.enableButtons();
235252
});
236-
237253
});
238254
alert.setNegativeButton(context.getString(R.string.cancel), (dialog, which) -> reviewCallback.onFailure());
239255
d = alert.create();

0 commit comments

Comments
 (0)